OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4814|回复: 13

FLASH写问题

[复制链接]

15

主题

59

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1400
金钱
1400
注册时间
2016-6-2
在线时间
166 小时
发表于 2016-9-13 12:12:39 | 显示全部楼层 |阅读模式
1金钱
用107VC进行IAP在线升级,上位机每次发1000个字节,直到把整个APP代码发送完成,我能够接收一次就写一次flash,然后下一次再接收1000个字节,再写一次flash么?void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)       
{
        u32 secpos;          
        u16 secoff;         
        u16 secremain;
        u16 i;   
        u32 offaddr;
       
        if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;
        FLASH_Unlock();                                               
        offaddr=WriteAddr-STM32_FLASH_BASE;               
        secpos=offaddr/STM_SECTOR_SIZE;                       
        secoff=(offaddr%STM_SECTOR_SIZE)/2;               
        secremain=STM_SECTOR_SIZE/2-secoff;               
        if(NumToWrite<=secremain)secremain=NumToWrite;
        while(1)
        {       
                STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
                for(i=0;i<secremain;i++)
                {
                        if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;
                }
                if(i<secremain)
                {
                        FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);
                        for(i=0;i<secremain;i++)
                        {
                                STMFLASH_BUF[i+secoff]=pBuffer[i];          
                        }
                        STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
                }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);          
                if(NumToWrite==secremain)break;
                else
                {
                        secpos++;                               
                        secoff=0;                               
                        pBuffer+=secremain;         
                        WriteAddr+=secremain*2;       
                        NumToWrite-=secremain;
                        if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;
                        else secremain=NumToWrite;
                }         
        };       
        FLASH_Lock();
}


我定义了一个u8 RX_BUF【1000】用来接收每次传过来的1000个字节,但每次发送完之后都无法运行APP程序。写地址是iap_write_appbin((FLASH_APP1_ADDR+(cishu*1000)),RX_BUF,recvlen);
cishu为接收次数,接收一次就加1,目测是写flash出错了,但是没找到原因。
请大神指点迷津。

最佳答案

查看完整内容[请看2#楼]

void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite) 看下这个函数的写入步骤, 首先确定写入地址所在的页,然后读取整页数据出来 ,判断数据是否全部是0xFF,是则写入数据,否则先檫除该页。 你第一次写入1000字节后,第二次写入地址还是和第一次写入的地址属于同一页, 所以第二次写入的时候,读取数据判断数据是否全部是0xFF,这步的结果是否,然后程序檫除该页, 你前面写入的数据会被全部檫除掉。 所以正确 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

108

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1137
金钱
1137
注册时间
2013-7-16
在线时间
81 小时
发表于 2016-9-13 12:12:40 | 显示全部楼层
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   看下这个函数的写入步骤, 首先确定写入地址所在的页,然后读取整页数据出来 ,判断数据是否全部是0xFF,是则写入数据,否则先檫除该页。  你第一次写入1000字节后,第二次写入地址还是和第一次写入的地址属于同一页, 所以第二次写入的时候,读取数据判断数据是否全部是0xFF,这步的结果是否,然后程序檫除该页, 你前面写入的数据会被全部檫除掉。   所以正确的做法是一次写1K的整数倍。
回复

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2016-9-13 13:09:35 | 显示全部楼层
RX_BUF【1024】
shop60994719.taobao.com
回复

使用道具 举报

15

主题

59

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1400
金钱
1400
注册时间
2016-6-2
在线时间
166 小时
 楼主| 发表于 2016-9-13 13:33:18 | 显示全部楼层

一定要1024么。。。
回复

使用道具 举报

0

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
191
金钱
191
注册时间
2013-8-14
在线时间
46 小时
发表于 2016-9-13 15:08:38 | 显示全部楼层
关于Flash读写的问题我觉得你可以先写个小程序验证一下。另外,FLASH写之前要进行擦除操作。
回复

使用道具 举报

70

主题

6769

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13197
金钱
13197
注册时间
2012-11-26
在线时间
3820 小时
发表于 2016-9-13 15:21:34 | 显示全部楼层
你两边协议定好啊,第一次接收正确并写入,再开始第二次的发送接收,循环这个步骤
回复

使用道具 举报

15

主题

59

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1400
金钱
1400
注册时间
2016-6-2
在线时间
166 小时
 楼主| 发表于 2016-9-13 16:49:44 | 显示全部楼层
jermy_z 发表于 2016-9-13 15:21
你两边协议定好啊,第一次接收正确并写入,再开始第二次的发送接收,循环这个步骤

嗯嗯,我就是这个思路。
就是怀疑第二次开始写入的那个地址是不是不正确。
FLASH_APP1_ADDR+(cishu*1000)
回复

使用道具 举报

15

主题

59

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1400
金钱
1400
注册时间
2016-6-2
在线时间
166 小时
 楼主| 发表于 2016-9-13 16:50:20 | 显示全部楼层
62021732 发表于 2016-9-13 15:08
关于Flash读写的问题我觉得你可以先写个小程序验证一下。另外,FLASH写之前要进行擦除操作。

可以只擦除我需要写的那一部分还是全部都要擦?
回复

使用道具 举报

70

主题

6769

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13197
金钱
13197
注册时间
2012-11-26
在线时间
3820 小时
发表于 2016-9-14 09:11:10 | 显示全部楼层
hyarcher25 发表于 2016-9-13 16:49
嗯嗯,我就是这个思路。
就是怀疑第二次开始写入的那个地址是不是不正确。
FLASH_APP1_ADDR+(cishu*100 ...

给你我以前写的IAP上下位机,有兴趣的话,可以参考看看
学无止境
回复

使用道具 举报

70

主题

6769

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13197
金钱
13197
注册时间
2012-11-26
在线时间
3820 小时
发表于 2016-9-14 09:12:55 | 显示全部楼层
见附件

bootloader.rar

882.76 KB, 阅读权限: 20, 下载次数: 2

售价: 10 金钱  [记录]  [购买]

下位

IAP_Blue.rar

138.89 KB, 阅读权限: 20, 下载次数: 2

售价: 10 金钱  [记录]  [购买]

上位

回复

使用道具 举报

70

主题

6769

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13197
金钱
13197
注册时间
2012-11-26
在线时间
3820 小时
发表于 2016-9-14 09:14:56 | 显示全部楼层
注释有的地方有问题,如果参照的话,自己对照着代码理解理解吧
学无止境
回复

使用道具 举报

15

主题

59

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1400
金钱
1400
注册时间
2016-6-2
在线时间
166 小时
 楼主| 发表于 2016-9-14 11:16:45 | 显示全部楼层
jermy_z 发表于 2016-9-14 09:14
注释有的地方有问题,如果参照的话,自己对照着代码理解理解吧

谢谢。
回复

使用道具 举报

3

主题

23

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2015-8-14
在线时间
92 小时
发表于 2017-5-18 11:02:13 | 显示全部楼层
cookles 发表于 2016-9-13 12:12
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   看下这个函数的写入步骤, 首先确定写 ...

你好 我遇到了 和他 差不多的问题,  但是我用GPRS做的iap,  GPRS我测试了一下,他每次最多发送的是1010个字节, 1k数据不到,我如果也是和楼主这样的 就收一次写一次的话,我要怎么解决这个接收不做1k字节的问题呢
回复

使用道具 举报

9

主题

108

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1137
金钱
1137
注册时间
2013-7-16
在线时间
81 小时
发表于 2017-6-21 14:16:26 | 显示全部楼层
tismily 发表于 2017-5-18 11:02
你好 我遇到了 和他 差不多的问题,  但是我用GPRS做的iap,  GPRS我测试了一下,他每次最多发送的是1010 ...

那就每次发送512字节,接收两次就启动一次写操作。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-17 21:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表