打印
[STM32F4]

STM32F4 flash写入偶尔出现的异常调试

[复制链接]
121|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-10-18 16:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天在新的设备上,使用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

使用特权

评论回复
沙发
两只袜子| | 2023-10-18 16:37 | 只看该作者
使用专门的工具(例如STM32CubeProgrammer、OpenOCD等)进行编程和调试试试

使用特权

评论回复
板凳
jcky001| | 2023-10-18 16:38 | 只看该作者
是否遵循了正确的擦除和编程序列?

使用特权

评论回复
地板
Jacquetry| | 2023-10-18 19:30 | 只看该作者
他们两个库函数是不是不同啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1364

主题

13994

帖子

8

粉丝