终于完成了STM32的在线下载功能,下面把各个坑总结一下:
1,flash读写时死机
后来发现是数组下标溢出,由于keil中启动函数堆栈默认是0x400个字节,而stm32的flash读写每次要求读写1页,即2048个字节,所以在写入的时候局部变量数组直接溢出,造成内存泄漏。
2,主程序备份后,缓冲区数据被清空
主程序初始地址 0x8010000,缓冲区地址 0x803000,备份区地址 0x8020000,在备份时候,由于一次每次写入时擦除了32页,刚好把缓冲区的数据擦干净了。
3,程序跳转后重启
stm32的存储方式为小端存储,每四个字节的大小写在写入内存后刚好颠倒,在从缓冲区向应用程序区写入时,必须对数据进行顺序整理。
4,程序跳转后串口无数据接收
在bootloader程序中,跳转前要关掉所有中断,跳转后还有重新打开中断,并且在应用程序中要设置程序偏置向量,即函数:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0010000);
5,时钟不对
程序成功跳转后,发现原来的1秒计时函数变成了9秒,后面发现是函数:
RCC_DeInit();
将时钟改的不正确。由于我的板子时钟使用的是12M,不是默认的8M,不知道是不是这里影响,把这个初始化屏蔽后工作正常,暂时没有发现别的问题。
6,2018.09.18补充
时钟问题
在boot中,对系统时钟初始化(SystemInit()函数),使用外部晶振,倍频9倍。
由 bootloader 跳转到App后,一旦调用 SystemInit() 进行时钟初始化,串口能正常打印输出,但是SysTick停止工作。屏蔽掉后,造成串口时钟混乱,输出乱码,但是SysTick时钟缺是正确的。修改方法是屏蔽SystemInit()函数,但是在Option for Target ‘upload’–>Asm–>Define中添加外部晶振频率 HSE_VALUE=8000000
看起来好像是,STM32上电后,只允许进行一次外部时钟函数的初始化,后面跳转的程序就依照上电后的时钟执行。