本帖最后由 new_fresh 于 2015-10-6 17:04 编辑
各位好. 最近被一个问题堵了很久, 没有思路了, 网上也搜索不到解决方案. 所以来问问各位.
问题是这样的, 我有一个开发板, 芯片型号为STM32F105RB, 我想做一个在线升级功能, 写了一个bootloader, 使用串口(串口为中断方式获取数据)来对App部分进行升级. 代码使用ST官方的库函数, RB型号表示闪存容量为128K
我原先代码是这样的:
// A: 以下代码为接收到串口开始升级命令后执行
uint8_t PageIndex = 0;
uint8_t PageCnt = 0;
FLASH_Status status = FLASH_COMPLETE;
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
PageCnt = 32; //这里固定擦除32 * 2K = 64K Flash
for(PageIndex = 0; PageIndex < PageCnt; PageIndex++)
{
/* PAGE_SIZE定义为0x800, 即2K大小, ApplicationAddress定义为0x8010000 */
status = FLASH_ErasePage(ApplicationAddress + PageIndex * PAGE_SIZE);
if(FLASH_COMPLETE == status)
{
// do something here
}
}
FLASH_Lock();
// B: 以下代码为串口接收到一帧升级数据后开始写入FLASH
uint8_t index = 0;
uint32_t Ramsorce = (uint32_t)data; //这里的data为需要写入到Flash的数据
uint8_t writeCnt = len / 4; //len为数据长度, 为4的整数倍
FLASH_Status status = FLASH_COMPLETE;
FLASH_Unlock();
for(index = 0; index < writeCnt; index++)
{
/* FlashDestination 初始定义为0x8010000 */
status = FLASH_ProgramWord(FlashDestination, *(uint32_t*)Ramsorce);
if(status != FLASH_COMPLETE)
{
// do something here
}
FlashDestination += 4;
Ramsorce += 4;
}
FLASH_Lock();
测试发现, 在A: 中, 如果添加了FLASH_Unlock(), 那么串口接收就会出现问题, 如果不添加, 那么串口接收正常. 但是B: 中的对FLASH的写入就不会成功(奇怪的是status返回为FLASH_COMPLETE, 不是其他值). 为此, 我又特地做了一个测试, 就是在A: 中擦除的同时写入数据, 这样却又可以写入成功, 而且是64K内容全部写入成功了.
在这里, 我想问一下:
1. 擦除是不是一定要添加FLASH_Unlock()的?
2. 不加的时候通过工具查看内容没有写入, 为什么返回值还是完成?写入不成功也是完成吗?
3. 为什么会存在擦除的同时写就可以成功, 擦除后Lock(), 然后再Unlock()来写就不成功?
我是一个新手, 如有低级错误的地方, 还请轻拍.
这个问题困扰我很长时间了, 如果各位有什么见解, 恳请给点建议.
问题已经得到解决.
1. FLASH擦写确实是需要使用Unlock 和 Lock, 否则会出现不成功的问题(返回值没有错, 为FLASH_COMPLETE,但是实际上没有擦除). 2. 我的串口出现发送错误是因为在发送的时候没有USART_GetFlagStatus来判断状态就发送了. 导致可能以为发送了, 但是实际上没有发送. 附一个例子: if(RESET != USART_GetFlagStatus(USART1,USART_FLAG_TXE)) {//这里的USART1可以根据你的需要替换为别的串口 // send your data here }
我在本贴子中回复了一个帖子, 就被删除了, 说违规...我都不知道哪里违规了. 难道是不能另外回复帖子, 只能在自己发的帖子上回复???
那21ic也太...不接地气了吧.
|