当前位置:网站首页>Gd32 RT thread ota/bootloader driver function
Gd32 RT thread ota/bootloader driver function
2022-06-30 10:33:00 【Sky_ Lannister】
GD32 OTA/Bootloader Driving functions
The driver function needs to modify a file rt_fota.c, Add interior flash Operation related documents , Delete external flash Operation related documents , Please refer to for precautions during migration and other peripheral migration details Migrate full version RT-Thread To GD32F4XX( detailed ) About China bootloader And flash Migration related content , The use and verification methods after transplantation are the same as stm32
The original open source project is located in https://gitee.com/spunky_973/rt-fota, It only suits stm32f4 series , Unrealized hash check ; The changes made in this blog are only for adaptation GD32F4XX series , And added hash check ( Has been submitted PR), At the same time, modify the off chip upgrade to the on-chip upgrade , Further reduce bootloader size , The open source address is https://gitee.com/yangfei_addoil/rt-fota-gd32
rt_fota.c
// add to hash check adopt RT_FOTA_USE_HASH Open and close
//hash fnv1a
#define FNV_SEED 0x811c9dc5
#define DATA_LEN 355232
int 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");
#endif
if (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
Addition and deletion of other folders
see https://gitee.com/yangfei_addoil/rt-fota-gd32
边栏推荐
- Robot system dynamics - inertia parameters
- Who should the newly admitted miners bow to in front of the chip machine and the graphics card machine
- Foster design method
- Node environment configuration
- June training (day 30) - topology sorting
- 【Rust日报】2021-01-22 首份Rust月刊杂志邀请大家一起参与
- After recording 7000 IELTS words in 100 sentences, there are only 1043 words (including simple words such as I and you)
- OSError: [Errno 28] No space left on device
- MySQL advanced SQL statement of database (2)
- Ant s19xp appeared in 140t, why is it called the computing power ceiling by the world
猜你喜欢

“昆明城市咖啡地图”活动再度开启

打通供应链 深圳礼品展助跨境电商寻破局之道

苹果5G芯片被曝研发失败,QQ密码bug引热议,蔚来回应做空传闻,今日更多大新闻在此...

“昆明城市咖啡地图”活动再度开启

MySQL advanced SQL statement of database (1)

长城数艺数字藏品平台发布创世徽章

‘Failed to fetch current robot state‘ when using the ‘plan_ kinematic_ path‘ service #868

South China Industrial Group launched digital economy and successfully held the city chain technology conference

L'activité "Kunming City coffee map" a rouvert
[email protected]體感機械臂"/>技能梳理[email protected]體感機械臂
随机推荐
安徽《合肥市装配式建筑施工图审查设计深度要求》印发;河北衡水市调整装配式建筑预售许可标准
Compare the maximum computing power of the Cenozoic top ant s19xp and the existing s19pro in bitland
The latest SCI impact factor release: the highest score of domestic journals is 46! Netizen: I understand if
机器学习面试准备(一)KNN
"Kunming City coffee map" was opened again, and coffee brought the city closer
Notes on numerical calculation - iterative solution of linear equations
“昆明城市咖啡地图”活动再度开启
Who should the newly admitted miners bow to in front of the chip machine and the graphics card machine
Eth is not connected to the ore pool
“昆明城市咖啡地圖”活動再度開啟
The preliminary round of the sixth season of 2022 perfect children's model Hefei competition area was successfully concluded
移植完整版RT-Thread到GD32F4XX(详细)
半钢同轴射频线的史密斯圆图查看和网络分析仪E5071C的射频线匹配校准
The programmer was beaten.
R language plot visualization: use plot to visualize the prediction confidence of the multi classification model, the prediction confidence of each data point of the model in the 2D grid, and the conf
Skill combing [email protected] voice module +stm32+nfc
Go -- standard library sort package
Getting started with X86 - take over bare metal control
mysql数据库基础:约束、标识列
The rising star of Goldshell STC box