s9keaz128 UART Bootloader 单片机篇(上)

这篇具有很好参考价值的文章主要介绍了s9keaz128 UART Bootloader 单片机篇(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:前言

网络上充斥着各种各样的串口升级方案,基本都是基于Y-Mode协议下载。采用这种升级方案学习还是可以,用在产品上还是有点欠缺。如下载完成后,需要把时间发送到设备就不好搞了。如下这个设备返回的信息,最后一项就是固件更新时间。

固件名称: KEA128

编译时间: 2022/03/02 14:25:18

固件版本: 1.0.3

硬件版本: 1.0.3

产品序列号: 30304536001 A2210000002D

功能名称: App

固件更新时间: 2022/03/02 14:26:46

串口升级演示视频

项目源码下载:

【免费】s9keaz128串口升级方案1:上位机qt5源码2:单片机底层与应用程序3:烧写文档4:原理图资源-CSDN文库

二:升级协议

1:获取固件信息

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

01

00 00

-

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

01

LL   HH

 “版本”

校验和

5A

2:运行命令

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

02

04 00

地址(xx xx xx xx)

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

02

01   00

 00-失败  01-成功

校验和

5A

3:擦除Flash命令

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

03

08 00

地址(AA AA AA AA)

长度(LL LL LL LL)

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

03

01   00

 00-失败  01-成功

校验和

5A

4:写数据命令

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

04

LL LL

数据

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

04

01   00

 00-失败  01-成功

校验和

5A

5:设置写地址命令

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

05

04 00

地址(AA AA AA AA)

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

05

01   00

 00-失败  01-成功

校验和

5A

6:数据校验命令

PC发送:

头部

功能

数据长度

数据

校验

结束

55 AA

06

13 00

当前时间如“2024/02/02 10:00:00”

校验和

5A

设备返回:

头部

功能

数据长度

数据

校验

结束

55 AA

06

01   00

 00-失败  01-成功

校验和

5A

三:数据接收与处理

数据接收采用环形缓冲区,串口中断接收数据后放入缓冲区,主函数对数据监听与处理。大致如下处理流程

1:串口接收数据后放入环形缓冲区

2:从环形缓存区取出一帧数据

3:处理数据

四:关键性软件

void Boot_Executive(void)

{

    uint8_t head_data[USER_CMD_STRUCT_LEN];

    int offset;

    uint8_t CallFucNumber;

    uint8_t func;

    unsigned int  lenght;

    uint8_t end;   

    uint8_t checkSum;           

    unsigned int queueAvailLen;

start:

     //获取环形缓存区数据长度

      queueAvailLen = fifo_used(&uart1_fifo);

      if(queueAvailLen >= USER_CMD_STRUCT_LEN) //缓冲器中有数据

      {

          //偷看下数据最小长度

        fifo_out_peek(&uart1_fifo,head_data,USER_CMD_STRUCT_LEN);

        //查找头部 55 AA

offset = finSerialDatahead(head_data,USER_CMD_STRUCT_LEN);

        if(offset>0)

        {

            fifo_out_clear(&uart1_fifo,offset);//删除前面无效数据

            goto start;

        }

           func    = head_data[2];

           lenght =  (uint8_t)head_data[4];

             lenght <<= 8;

           lenght |= (uint8_t)head_data[3];

          if(lenght>512) //一帧数据最大长度设置

          {

              fifo_out_clear(&uart1_fifo,2);//去掉头部

              goto start;

          }

          if(queueAvailLen>=(int)(lenght+7))//可能有完整一帧数据

          {

            //都不数据已无用清除

            fifo_out_clear(&uart1_fifo,USER_CMD_STRUCT_LEN-2);           

            //获取数据部分

fifo_out_peek(&uart1_fifo,uart_frame,lenght+2);

            //获取尾部数据5A

end = uart_frame[lenght+1];

//对数据区计算校验

            checkSum = uart_checkSum(func,&uart_frame[0],lenght);

            //判断尾部与校验和 

            if(end ==0x5a && checkSum == uart_frame[lenght])

            {

              CallFucNumber = sizeof(UserUartFunctionCall)/sizeof(UartOutProCessFunc);

               if(func<CallFucNumber)

               {

                 if(UserUartFunctionCall[func]!=NULL)

                 {

                        g_BootLoaderCmd.autoFlag = 0;

                   UserUartFunctionCall[func](func,&uart_frame[0],lenght);

                 }

               }

               //开始处理数据

                fifo_out_clear(&uart1_fifo,lenght+2);

             }else

             {

                fifo_out_clear(&uart1_fifo,lenght+2); //清除头部

               //"数据帧异常";

             }

          }

       }

       Boot_ExecutiveJump(&g_BootLoaderCmd);

}

1:判断数据是否大于等于最小数据长度7字节。

2:读取7字节,查找头部 55 AA  位置

3:头位置不是0清除前面无效数据返回到第一步。

4:判断帧数据长度;长度大于最大长度代表帧异常,清除头部 55 AA两字节返回第一步。

5:判断缓冲区数据长度是否大于等于数据长度+7,表示是否有完整帧。

6:计算数据校验和,以及对尾部5A判断 异常清除头部 55 AA两字节返回第一步。

7:处理数据数据。

处理功能集合,通过函数指针调用:

typedef void (*UartOutProCessFunc)(uint8_t func,uint8_t *buf,uint32_t len);

UartOutProCessFunc UserUartFunctionCall[]=

{

    NULL, //0

    get_board_info, //1

    run_app_command,//2

    erase_flash_command, //3

    write_data_command,//4

    set_start_address_command,//5

    verify_data_command,//6

     

};

例如运行命令:

void run_app_command(uint8_t func,uint8_t *buf,uint32_t len)

{

      uint32_t adrress=0;

      uint8_t  status;

      adrress = CharToIntBigEnd(&buf[0],4);        

      if((adrress>=APP_START_ADDR) && (adrress<FLASH_END_ADDR))

      {

        g_BootLoaderCmd.jump_address = adrress;

        g_BootLoaderCmd.status = 0x01; //需要跳转

        status = 1;

      }

      else

      {

         status = 0;

      }

      uart_WriteFrame(func,&status,1);  //返回状态         

 }

返回数据处理:

uint8_t uart_WriteFrame(uint8_t func,uint8_t *buf,unsigned int lenght)

{

     unsigned int i;

     if(lenght>MAX_FRAME_DATA_NUMBER) return 1;

      uart2_Txbuf[0] = 0x55;

      uart2_Txbuf[1] = 0xAA;

      uart2_Txbuf[2] = func;

      uart2_Txbuf[3] = lenght&0xff;

      uart2_Txbuf[4] = (lenght>>8)&0xff;

      memcpy(&uart2_Txbuf[5],buf,lenght);

      uart2_Txbuf[5+lenght] = uart_checkSum(func,buf,lenght);

      uart2_Txbuf[6+lenght] = 0x5a;

      for(i=0;i<lenght+7;i++)

      UART_PutChar(UART0,uart2_Txbuf[i]);

   return 0;

}

不断对上位机发送的命令处理,以及对处理状态的应答。经过一些列处理后完成对单片机Flash的擦除,写,校验。

五:工程

s9keaz128amlh烧录,单片机,嵌入式硬件

s9keaz128amlh烧录,单片机,嵌入式硬件

s9keaz128amlh烧录,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-836333.html

到了这里,关于s9keaz128 UART Bootloader 单片机篇(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单片机——通信协议(UART协议解析篇)

            在嵌入式系统设计中,UART通信是一种广泛使用的串行通信协议,它通过 两条信号线实现全双工 的数据传输和接收。UART通信协议以其简单、灵活和易于集成的特点,在嵌入式设备之间以及与外部设备进行通信时发挥着重要作用。本文将详细介绍 UART 通信的 工作原

    2024年02月04日
    浏览(37)
  • 如何将bootloader和APP程序一次性烧录到单片机中

      在做单片机的IAP升级时,通常需要两个程序,一个bootloader程序,一个app程序。首先将bootloader程序烧写到单片机中,然后通过串口将app程序写入到单片机内容,在平时学习和测试的时候这种方法没啥问题,但是如果产品需要量产,每次少些程序的时候都有通过这种方法的

    2024年02月09日
    浏览(35)
  • 单片机(STM32,GD32,NXP等)中BootLoader的严谨实现详解

    Bootloader( 引导加载程序 )的主要任务是引导加载并运行应用程序,我们的软件升级逻辑也一般在BootLoader中实现。本文将详细介绍BootLoader在单片机中的实现,包括 STM32、GD32、NXP Kinetis 等等的所有单片机,因为无论是什么样的芯片,它实现的逻辑都是一样的。 注意,本篇文章主

    2024年02月02日
    浏览(47)
  • 51内核单片机实现Bootloader跳转到用户程序,要求两个程序都要支持中断

    本文使用的单片机为笙科的A9129F6,Flash大小为64KB,SRAM大小为8KB。 Flash空间规划如下。 起始地址 结束地址 用途 0x0000 0x3fff Bootloader 程序 0x4000 0xefff 用户程序( APP 程序) 0xf000 0xffff 存放设备 配置信息 程序间跳转实现起来很简单,只需要使用函数指针就行了。 但是难点在于

    2024年02月16日
    浏览(29)
  • 【单片机】基于STM32的UART串口通信

    简单讲解一下UART通信协议,以及UART能够实现的一些功能,还有有关使用STM32CubeMX来配置芯片的一些操作。实验内容基于 正点原子精英板 开发板,单片机芯片为 STM32F103ZET6 。 在后面我会以我使用的STM32F429开发板来举例讲解(其他STM32系列芯片大多数都可以按照这些步骤来操作

    2024年01月17日
    浏览(56)
  • 51单片机UART串口通信实现接收PC的字符串

            基本思路是触发串口接收中断之后,在串口中断服务函数中处理接收到的字节并将其连接成字符串存入全局变量中。 隐含的额外工作有: 1.区分是发送中断还是接收中断,两者都会进入同一个中断服务子函数; 2.判断已接收到了句末,暂停接收,并通过标志位告知

    2023年04月20日
    浏览(82)
  • 单片机UART一对多:同时读取多个传感器基于modbus协议

    很多传感器现在都做成了串口模块,如激光测距传感器TOF050,在开发时使用串口功能模块不仅大大加快了我们的开发进度,还能降低功能模块直接的耦合度,专业是功能交给专业的模块做,也能保证质量。 图:TOF050激光测距模块 以TOF050模块为例,当我们同时需要接4个激光测

    2024年02月08日
    浏览(34)
  • STM32单片机初学8-SPI flash(W25Q128)数据读写

            当使用单片机进行项目开发,涉及大量数据需要储存时(例如使用了屏幕作为显示设备,常常需要存储图片、动画等数据),单靠单片机内部的Flash往往是不够用的。         如STM32F103系列,内部Flash最多只能达到512KByte,假设要储存240*240分辨率、64K彩色图片,

    2024年02月03日
    浏览(32)
  • 【单片机】UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB、SD卡、1-WIRE、Ethernet等常见通信方式

    在单片机开发中,UART、I2C、RS485等普遍在用,这里做一个简单的介绍 UART口指的是一种物理接口形式(硬件)。 UART是异步(指不使用时钟同步,依靠帧长进行判断),全双工(收发可以同时进行)串口总线。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收

    2024年02月11日
    浏览(31)
  • AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序

    1.AT24C01/AT24C02系列EEPROM芯片单片机读写驱动程序 2.AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序 3.AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序 4.x24Cxx系列EEPROM芯片C语言通用读写程序 在前两篇博文中,分别记录了AT24C01、AT24C02,以及AT24C04、

    2024年02月02日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包