今天在新的设备上,使用XMODEM协议下载升级问题,之前用了很多年都没出问题,突然在这个F4上面出问题了,单独调用都是好的,最后通过不断的调试发现原因,以前写入FLASH都是调用单字节或者单字烧写,最近修改了一个底层函数,批量写入多个字,由于写入的数据如果不是32bit对齐,就会出现异常,刚好xmodem协议前面有3个字节头,刚好不是4字节对齐。
//128B数据包格式
typedef struct
{
u8 X_Start;
u8 X_PackNum;
u8 X_bPackNum;
u8 X_PackData[128];
u8 X_CRC16H;
u8 X_CRC16L;
}XMODEM_128B_PACK;
//1024B数据包格式
typedef struct
{
u8 X_Start;
u8 X_PackNum;
u8 X_bPackNum;
u8 X_PackData[1024];
u8 X_CRC16H;
u8 X_CRC16L;
}XMODEM_1KB_PACK;
最终修改方法是,通过判断输入的内存是否32bit对齐,如果是的,直接访问,如果不是的,则转换为BYTE数组后手动组装为32bit。
/*************************************************************************************************************************
* 函数 : STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
* 功能 : 在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)
* 参数 : faddr:指定地址(此地址必须为4的倍数);data:要写入的数据
* 返回 : STM32FLASH_STATUS
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2020-02-08
* 最后修改时间 : 2020-02-08
* 说明 : 警告,地址必须为4的倍数
2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
不会判断是否能写入
2020-06-29修复如果data[]没有32bit对齐崩溃问题
*************************************************************************************************************************/
STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
{
STM32FLASH_STATUS status;
u8 *p = (u8*)data;
u32 offset = 0;
vu32 temp;
bool is32bit = (((u32)data)%4)?FALSE:TRUE;
status=STM32FLASH_WaitDone(200); //判断状态
if(status==STM32FLASH_OK) //没有错误
{
FLASH->CR&=~(3<<8); //清除PSIZE原来的设置
FLASH->CR|=2<<8; //设置为32bit宽,确保VCC=2.7~3.6V之间!!
FLASH->CR|=1<<0; //编程使能,测试发现使能编程后不延时会出现编程顺序错误
nop;nop;nop;nop; //2020-02-08 此处必须增加延时,否则可能出现顺序错误
while(dWordCount --)
{
if(is32bit == TRUE) //32bit对齐的
{
*(vu32*)faddr=*data++; //写入数据
}
else //没有32bit对齐
{
temp = p[offset++];
temp |= (u32)p[offset++]<<8;
temp |= (u32)p[offset++]<<16;
temp |= (u32)p[offset++]<<24;
*(vu32*)faddr=temp; //使用临时变量存储要写入的数据,防止data[]不是32bit对齐,如果写入vu32变量将会导致异常
}
faddr +=4; //地址自增+4
status=STM32FLASH_WaitDone(200); //等待操作完成,一个字编程,最多100us.
if(status!=STM32FLASH_OK) //有错误
{
break;
}
}
if(status!=STM32FLASH_BUSY) //非忙
{
FLASH->CR&=~(1<<0); //清除PG位
}
}
if(status != STM32FLASH_OK)
{
DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
}
return status;
}
————————————————
版权声明:本文为CSDN博主「cp1300」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cp1300/article/details/107022751
|