GD32 OTA/Bootloader驱动函数

驱动函数需要修改一个文件rt_fota.c,添加内部flash操作相关文件,删除外部flash操作相关文件,移植过程注意事项及其它外设移植细节参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于bootloader及flash移植相关内容,移植完成后使用及验证方法同stm32

原开源项目位于https://gitee.com/spunky_973/rt-fota,只适配了stm32f4系列,未实现hash校验;本博客所做改动仅为适配GD32F4XX系列,及添加了hash校验(已提交PR),同时修改片外升级为片内升级,进一步缩小bootloader大小,开源地址为https://gitee.com/yangfei_addoil/rt-fota-gd32

rt_fota.c

//添加hash校验  通过RT_FOTA_USE_HASH进行开启关闭
//hash  fnv1a
#define FNV_SEED  0x811c9dc5
#define DATA_LEN  355232int rt_fota_check_hash(const char *part_name);static uint32_t fnv1a_r(uint8_t oneByte, uint32_t hash)
{return ((oneByte ^ hash) * 0x1000193);
}static uint32_t calc(uint8_t * data, uint32_t hash, long len)
{for (int i = 0; i < len; i++){hash = fnv1a_r(data[i], hash);}return hash;
}#ifdef RT_FOTA_USE_HASH
/*** @brief  check hash value* @note* @param  part_name: flash name** @retval rt_fota_err_t* @author yangFei* @date   20220620* @note   similar to rt_fota_upgrade,add before rt_fota_upgrade of rt_fota_thread_entry*/
int rt_fota_check_hash(const char *part_name)
{uint32_t hash_value = 0;int fota_err = RT_FOTA_NO_ERR;const struct fal_partition *part;rt_fota_part_head_t part_head = RT_NULL;tiny_aes_context *aes_ctx = RT_NULL;rt_uint8_t *aes_iv = RT_NULL;rt_uint8_t *crypt_buf = RT_NULL;int fw_raw_pos = 0;int fw_raw_len = 0;rt_uint32_t total_copy_size = 0;rt_uint8_t block_hdr_buf[RT_FOTA_BLOCK_HEADER_SIZE];    rt_uint32_t block_hdr_pos = RT_FOTA_ALGO_BUFF_SIZE;rt_uint32_t block_size = 0;rt_uint32_t dcprs_size = 0;qlz_state_decompress *dcprs_state = RT_NULL;rt_uint8_t *cmprs_buff = RT_NULL;rt_uint8_t *dcprs_buff = RT_NULL;rt_uint32_t padding_size = 0;if (part_name == RT_NULL){LOG_D("Invaild paramenter input!");fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}part = fal_partition_find(part_name);if (part == RT_NULL){       LOG_D("check hash partition[%s] not found.", part_name);fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}/* Application partition erase */fota_err = rt_fota_erase_app_part();if (fota_err != RT_FOTA_NO_ERR){goto __exit_check_hash;}/* rt_fota_erase_app_part() has check fota_part_head vaild already */part_head = &fota_part_head;crypt_buf = rt_malloc(RT_FOTA_ALGO_BUFF_SIZE);if (crypt_buf == RT_NULL){LOG_D("Not enough memory for firmware buffer.");fota_err = RT_FOTA_NO_MEM_ERR;goto __exit_check_hash;}/* AES256 algorithm enable */if ((part_head->fota_algo & RT_FOTA_CRYPT_STAT_MASK) == RT_FOTA_CRYPT_ALGO_AES256){aes_ctx = rt_malloc(sizeof(tiny_aes_context)); aes_iv = rt_malloc(rt_strlen(RT_FOTA_ALGO_AES_IV) + 1);       if (aes_ctx == RT_NULL || aes_iv == RT_NULL){LOG_D("Not enough memory for firmware hash verify.");fota_err = RT_FOTA_NO_MEM_ERR;goto __exit_check_hash;}rt_memset(aes_iv, 0x0, rt_strlen(RT_FOTA_ALGO_AES_IV) + 1);rt_memcpy(aes_iv, RT_FOTA_ALGO_AES_IV, rt_strlen(RT_FOTA_ALGO_AES_IV));tiny_aes_setkey_dec(aes_ctx, (rt_uint8_t *)RT_FOTA_ALGO_AES_KEY, 256);}else if ((part_head->fota_algo & RT_FOTA_CRYPT_STAT_MASK) == RT_FOTA_CRYPT_ALGO_XOR){LOG_I("Not surpport XOR.");fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}/* If enable fastlz compress function */    if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_FASTLZ) {cmprs_buff = rt_malloc(RT_FOTA_CMPRS_BUFFER_SIZE + RT_FOTA_FASTLZ_BUFFER_PADDING);dcprs_buff = rt_malloc(RT_FOTA_CMPRS_BUFFER_SIZE);    if (cmprs_buff == RT_NULL || dcprs_buff == RT_NULL){LOG_D("Not enough memory for firmware hash verify.");fota_err = RT_FOTA_NO_MEM_ERR;goto __exit_check_hash;}padding_size = RT_FOTA_FASTLZ_BUFFER_PADDING;}else if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_QUICKLZ) {cmprs_buff = rt_malloc(RT_FOTA_CMPRS_BUFFER_SIZE + RT_FOTA_QUICKLZ_BUFFER_PADDING);dcprs_buff = rt_malloc(RT_FOTA_CMPRS_BUFFER_SIZE);    dcprs_state = rt_malloc(sizeof(qlz_state_decompress));if (cmprs_buff == RT_NULL || dcprs_buff == RT_NULL || dcprs_state == RT_NULL){LOG_D("Not enough memory for firmware hash verify.");fota_err = RT_FOTA_NO_MEM_ERR;goto __exit_check_hash;}padding_size = RT_FOTA_QUICKLZ_BUFFER_PADDING;rt_memset(dcprs_state, 0x0, sizeof(qlz_state_decompress));}else if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_GZIP) {LOG_I("Not surpport GZIP.");fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}while (fw_raw_pos < part_head->com_size){if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) != RT_FOTA_CRYPT_ALGO_NONE) {      if (block_hdr_pos >= RT_FOTA_ALGO_BUFF_SIZE){fw_raw_len = rt_fota_read_part(part, fw_raw_pos, aes_ctx, aes_iv, crypt_buf, RT_FOTA_ALGO_BUFF_SIZE);if (fw_raw_len < 0){LOG_D("AES256 algorithm failed.");fota_err = RT_FOTA_PART_READ_ERR;goto __exit_check_hash;}fw_raw_pos += fw_raw_len;rt_memcpy(block_hdr_buf, crypt_buf, RT_FOTA_BLOCK_HEADER_SIZE);block_size = block_hdr_buf[0] * (1 << 24) + block_hdr_buf[1] * (1 << 16) + block_hdr_buf[2] * (1 << 8) + block_hdr_buf[3];rt_memset(cmprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE + padding_size);rt_memcpy(cmprs_buff, &crypt_buf[RT_FOTA_BLOCK_HEADER_SIZE], block_size);block_hdr_pos = RT_FOTA_BLOCK_HEADER_SIZE + block_size;}else{rt_uint8_t hdr_tmp_pos = 0;while (block_hdr_pos < RT_FOTA_ALGO_BUFF_SIZE){if (hdr_tmp_pos < RT_FOTA_BLOCK_HEADER_SIZE){block_hdr_buf[hdr_tmp_pos++] = crypt_buf[block_hdr_pos++];}else{block_size = block_hdr_buf[0] * (1 << 24) + block_hdr_buf[1] * (1 << 16) + block_hdr_buf[2] * (1 << 8) + block_hdr_buf[3];rt_memset(cmprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE + padding_size);if (block_size > (RT_FOTA_ALGO_BUFF_SIZE - block_hdr_pos)){                             rt_memcpy(cmprs_buff, &crypt_buf[block_hdr_pos], (RT_FOTA_ALGO_BUFF_SIZE - block_hdr_pos));fw_raw_len = rt_fota_read_part(part, fw_raw_pos, aes_ctx, aes_iv, crypt_buf, RT_FOTA_ALGO_BUFF_SIZE);if (fw_raw_len < 0){LOG_D("AES256 algorithm failed.");fota_err = RT_FOTA_PART_READ_ERR;goto __exit_check_hash;}fw_raw_pos += fw_raw_len;rt_memcpy(&cmprs_buff[RT_FOTA_ALGO_BUFF_SIZE - block_hdr_pos], &crypt_buf[0], (block_size +  block_hdr_pos) - RT_FOTA_ALGO_BUFF_SIZE);block_hdr_pos = (block_size +  block_hdr_pos) - RT_FOTA_ALGO_BUFF_SIZE;}else{rt_memcpy(cmprs_buff, &crypt_buf[block_hdr_pos], block_size);block_hdr_pos = block_hdr_pos + block_size;}                      break;}}if (hdr_tmp_pos < RT_FOTA_BLOCK_HEADER_SIZE){                fw_raw_len = rt_fota_read_part(part, fw_raw_pos, aes_ctx, aes_iv, crypt_buf, RT_FOTA_ALGO_BUFF_SIZE);if (fw_raw_len < 0){LOG_D("AES256 algorithm failed.");fota_err = RT_FOTA_PART_READ_ERR;goto __exit_check_hash;}fw_raw_pos += fw_raw_len;block_hdr_pos = 0;while (hdr_tmp_pos < RT_FOTA_BLOCK_HEADER_SIZE){block_hdr_buf[hdr_tmp_pos++] = crypt_buf[block_hdr_pos++];}block_size = block_hdr_buf[0] * (1 << 24) + block_hdr_buf[1] * (1 << 16) + block_hdr_buf[2] * (1 << 8) + block_hdr_buf[3];rt_memset(cmprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE + padding_size);rt_memcpy(cmprs_buff, &crypt_buf[block_hdr_pos], block_size);block_hdr_pos = (block_hdr_pos + block_size) % RT_FOTA_ALGO_BUFF_SIZE;}}rt_memset(dcprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE);     if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_FASTLZ) {dcprs_size = fastlz_decompress((const void *)&cmprs_buff[0], block_size, &dcprs_buff[0], RT_FOTA_CMPRS_BUFFER_SIZE);}else if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_QUICKLZ) {dcprs_size = qlz_decompress((const char *)&cmprs_buff[0], &dcprs_buff[0], dcprs_state);}if (dcprs_size <= 0){LOG_D("Decompress failed: %d.", dcprs_size);fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}if(total_copy_size == 0){hash_value = calc(dcprs_buff, FNV_SEED, dcprs_size);}else{hash_value = calc(dcprs_buff, hash_value, dcprs_size);}total_copy_size += dcprs_size;rt_kprintf("#");}/* no compress option */else{fw_raw_len = rt_fota_read_part(part, fw_raw_pos, aes_ctx, aes_iv, crypt_buf, RT_FOTA_ALGO_BUFF_SIZE);if (fw_raw_len < 0){LOG_D("AES256 algorithm failed.");fota_err = RT_FOTA_PART_READ_ERR;goto __exit_check_hash;}     fw_raw_pos += fw_raw_len;if(total_copy_size == 0){hash_value = calc(crypt_buf, FNV_SEED, fw_raw_len);}else if((total_copy_size / 1024) == (part_head->raw_size / 1024)){hash_value = calc(crypt_buf, hash_value, (part_head->raw_size - total_copy_size));}else{hash_value = calc(crypt_buf, hash_value, fw_raw_len);}total_copy_size += fw_raw_len;rt_kprintf("#");}}/* it has compress option */if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) != RT_FOTA_CRYPT_ALGO_NONE){while (total_copy_size < part_head->raw_size){if ((block_hdr_pos < fw_raw_len) && ((fw_raw_len - block_hdr_pos) > RT_FOTA_BLOCK_HEADER_SIZE)){rt_memcpy(block_hdr_buf, &crypt_buf[block_hdr_pos], RT_FOTA_BLOCK_HEADER_SIZE);block_size = block_hdr_buf[0] * (1 << 24) + block_hdr_buf[1] * (1 << 16) + block_hdr_buf[2] * (1 << 8) + block_hdr_buf[3];if ((fw_raw_len - block_hdr_pos - RT_FOTA_BLOCK_HEADER_SIZE) >= block_size){rt_memset(cmprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE + padding_size);               rt_memcpy(cmprs_buff, &crypt_buf[block_hdr_pos + RT_FOTA_BLOCK_HEADER_SIZE], block_size);rt_memset(dcprs_buff, 0x0, RT_FOTA_CMPRS_BUFFER_SIZE);block_hdr_pos += (block_size + RT_FOTA_BLOCK_HEADER_SIZE);if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_FASTLZ) {dcprs_size = fastlz_decompress((const void *)&cmprs_buff[0], block_size, &dcprs_buff[0], RT_FOTA_CMPRS_BUFFER_SIZE);}else if ((part_head->fota_algo & RT_FOTA_CMPRS_STAT_MASK) == RT_FOTA_CMPRS_ALGO_QUICKLZ) {dcprs_size = qlz_decompress((const char *)&cmprs_buff[0], &dcprs_buff[0], dcprs_state);}if (dcprs_size <= 0){LOG_D("Decompress failed: %d.", dcprs_size);fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}hash_value = calc(dcprs_buff, hash_value, dcprs_size);total_copy_size += dcprs_size;rt_kprintf("#");}else{break;}                                }else{break;}}}rt_kprintf("\r\n");#ifdef RT_FOTA_USE_HASH/* add hash cal */  if(hash_value != part_head->hash_val){rt_kprintf("hash value check failed.");fota_err = RT_FOTA_GENERAL_ERR;goto __exit_check_hash;}rt_kprintf("hash value check sucess.\r\n");
#endifif (total_copy_size < part_head->raw_size){LOG_D("Decompress check failed.");fota_err = RT_FOTA_GENERAL_ERR;}__exit_check_hash:if (aes_ctx)rt_free(aes_ctx);if (aes_iv)rt_free(aes_iv);if (crypt_buf)rt_free(crypt_buf);if (cmprs_buff)rt_free(cmprs_buff);if (dcprs_buff)rt_free(dcprs_buff);if (dcprs_state)rt_free(dcprs_state);if (fota_err == RT_FOTA_NO_ERR){rt_kprintf("check success, total %d bytes.", total_copy_size);}return fota_err;
}
#endif

其它文件夹增删

见https://gitee.com/yangfei_addoil/rt-fota-gd32

GD32 RT-Thread OTA/Bootloader驱动函数相关推荐

  1. rt thread studio使用QBOOT和片外flash实现OTA升级

    我们这里要使用单片机外部flash作为OTA的下载分区,外部flash硬件连接关系 PB3-->SPI3_CLK PB4-->SPI3_MISO PB5-->SPI3_MOSI PE ...

  2. stm32f407单片机rt thread 片外spi flash OTA升级配置示例

    参考地址https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/ 第一步,生成Boot ...

  3. xpt 2046的触摸屏 rt thread设备驱动框架

    1 基于rtt 开发触摸屏驱动 准备使用rtt 框架 , 驱动xpt 2046的触摸屏, 翻阅大量资料发现, 大部分文章强调的是时序图, 而且很多代码要么直接操作寄存器, 要么是io 口模拟, 只能用 ...

  4. GD32 RT-Thread RTC驱动函数

    GD32 RTC驱动函数 驱动函数需要修改两个文件,drv_rtc.c,使用RT_USING_RTC进行开启关闭,移植注意事项参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于rtc ...

  5. 正点原子delay函数移植到rt thread操作系统(HAL库)

    正点原子教程中涉及到的操作系统只涉及了UCOS的教程,其中例程的system文件夹中的delay.c函数只是适配了UCOS. 下面将delay.c函数移植到rt thread中,使用的bsp是rt t ...

  6. RT Thread根据开发板制作BSP方法

    之前一直不懂怎么使用RT Thread的软件包,感谢网上的大神,看了你们的博客后大概了解一些,在此做下记录.用RT Thread软件包需要RT Thread的系统,但是RT Thread和RT Thr ...

  7. 基于rt thread smart构建EtherCAT主站

    我把源码开源到到了gitee,https://gitee.com/rathon/rt-thread-smart-soem 有兴趣的去可以下载下来跑一下 软件工程推荐用vscode 打开.rt thre ...

  8. 关于RT thread系统节拍时钟的配置

    关于RT thread系统节拍时钟的配置                  -----本文基于rt-thread-3.1.3版本编写 首先,使用RTthread OS时,要配置(或者明白)它的系统节拍 ...

  9. rt thread 使用FAL遇到fal_init() undefined reference

    rt thread FAL 0.5版,之前有没有不知道,遇到一个坑. 在main.cpp里面已经 #include <fal.h> fal_init() 编译报错,说 fal_init() ...

最新文章

  1. 双11大考 POLARDB分钟级弹性让企业轻松扩展
  2. Django基础——ORM字段和字段参数
  3. JVM调优总结(五)-调优方法(转载)
  4. aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列
  5. [Python学习] 专题四.文件基础知识
  6. linux学习总结--linux100day(day2)
  7. Linux系统编程(一)
  8. 查询每个用户最后一次登录信息
  9. leetcode 1160 python
  10. 华为+android+root权限获取root,华为emui5.0系统如何root?华为荣耀v8 emui5.0获取7.0系统的root权限方法...
  11. python中tab键表示为_python中的tab键表示什么意思
  12. Python 3的反驳
  13. 萨达撒 这篇 Java 基础,我吹不动了
  14. 在线微信公众号调查数据分析报告
  15. linux crontab不执行
  16. address localhost:8080 is already in use(端口被占用)Windows系统问题解决
  17. 智能电话机器人介绍(AI语音机器人)
  18. 【心情分享】联系博主
  19. 万石谷,粒粒积累;千丈布,根根织成 ——随笔第二弹
  20. Linux 超级终端 不显示,超级终端怎么设置,超级终端密码不显示

热门文章

  1. 程序员在 Github 上疯狂薅羊毛!
  2. 50部世界名著中最经典的那一句话
  3. 时针 分针 一天内重合问题
  4. 【华人学者风采】刘维民 中国科学院
  5. 北京小学几年级学计算机,北京小学入学信息采集系统2020年什么时候开始
  6. Matlab的曲线拟合工具箱CFtool的使用
  7. C++智能指针之——boost::intrusive_ptr<T>的内部实现
  8. 基于UGUI的Unity画线工具
  9. 利用Python爬取网页美女图片,哇太多了,我U盘装满了!
  10. JavaScript——DOM之节点操作