打印
[STM32F0]

Flash连接写操作,跑死,求解

[复制链接]
3045|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
viseng|  楼主 | 2017-6-15 02:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是Flash写N个半字的函数:
ErrorStatus Flash_User_WriteNHalfWord(uint16_t offAddress, uint16_t *buffer,uint16_t len_halfword)
{
        FLASH_Status status = FLASH_COMPLETE;
        uint16_t i;
        EMPTYStatus Empty=EMPTY;
        uint16_t pageaddr,pageoffset_half;
        uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];

        assert_param(IS_FLASH_PROGRAM_ADDRESS(offAddress+len_halfword*2-1));

        offAddress &= FLASH_ADDR_ALIGN;                            //half word align
        pageaddr = offAddress & FLASH_PAGE_ADDR_MSK;
        pageoffset_half = (offAddress & (~FLASH_PAGE_ADDR_MSK))/2;
   
    if((offAddress+len_halfword*2-2)>=FLASH_OFFSET_END)
        {
                printf("\n\rFlash space is not enough!\n\r");
                return ERROR;
        }
        
        Empty = Flash_Check_Empty(offAddress,len_halfword);           //查要写的部分是否全为空,如果为空,后续不用擦除,否则进行整页擦除
        
//        Flash_ReadNHalfWord(offAddress,flash_buf,len_halfword);            //这里有个问题,我用这个注释掉的部分代码,而不用Flash_Check_Empty(),写操作OK
//        for (i=0;i<len_halfword;i++)                                                                //用上面那个替代就会跑死
//        {
//                if(flash_buf[i] !=0xFFFF)
//                {
//                        Empty = NOTEMPTY;
//                        break;
//                }
//        }
        status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
        if(status == FLASH_COMPLETE)
                FLASH_Unlock();
        if(Empty == EMPTY)
        {
                for(i=0;i<len_halfword;i++)
                        FLASH_ProgramHalfWord((FLASH_BASE+offAddress+2*i),buffer[i]);
        }
        else
        {
                Flash_ReadNHalfWord(pageaddr,flash_buf,FLASH_PAGE_HALF_SIZE);            //read program area data
                for (i=0;i<len_halfword;i++)
                        flash_buf[pageoffset_half+i] = buffer[i];
                FLASH_ErasePage(FLASH_BASE+pageaddr);
                for (i=0;i<FLASH_PAGE_HALF_SIZE;i++)
                        FLASH_ProgramHalfWord((FLASH_BASE+pageaddr+2*i),flash_buf[i]);
        }
        
        status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
        if(status == FLASH_COMPLETE)
                FLASH_Lock();
        return SUCCESS;
}
沙发
viseng|  楼主 | 2017-6-15 02:03 | 只看该作者
查空操作的函数定义如下:
EMPTYStatus Flash_Check_Empty(uint16_t offAddress,uint16_t len_halfword)
{
                uint16_t i;
                uint16_t tflash_buf[FLASH_PAGE_HALF_SIZE];
       
                offAddress &= FLASH_ADDR_ALIGN;                                                        //half word align
       
                Flash_ReadNHalfWord(offAddress,tflash_buf,len_halfword);      //进入这个函数开始就死
                for (i=0;i<len_halfword;i++)
                {
                                if(tflash_buf[i] !=0xFFFF)
                                                return NOTEMPTY;
                }
                return EMPTY;
}

使用特权

评论回复
板凳
viseng|  楼主 | 2017-6-15 02:05 | 只看该作者
问题如1楼中注释部分所说,用注释掉的代码就可以写成功,用查空函就跑死,用单步调试跟了一下,
具体死的位置在查空函数的Flash_ReadNHalfWord(offAddress,tflash_buf,len_halfword);这里
进入函数就死

使用特权

评论回复
地板
viseng|  楼主 | 2017-6-15 02:08 | 只看该作者
但如果将查空函数改为:
EMPTYStatus Flash_Check_Empty(uint16_t offAddress,uint16_t *buffer,uint16_t len_halfword)
{
                uint16_t i;
                uint16_t tflash_buf[FLASH_PAGE_HALF_SIZE];
       
                offAddress &= FLASH_ADDR_ALIGN;                                                        //half word align
       
                Flash_ReadNHalfWord(offAddress,tflash_buf,len_halfword);
                for (i=0;i<len_halfword;i++)
                {
                                if(tflash_buf[i] !=0xFFFF)
                                                return NOTEMPTY;
                }
                return EMPTY;
}
然后调用用Empty = Flash_Check_Empty(offAddress,flash_buf,len_halfword);
就没问题了,想不通问题在哪

使用特权

评论回复
5
viseng|  楼主 | 2017-6-15 02:16 | 只看该作者
这里主要的差别就是一个加没加指针形参uint16_t *buffer,跑不通的是没加的,也就是在查空函数中去声明暂存读出的数组,另一种是把外部已申请好的,共用一个

如果我在Flash_User_WriteNHalfWord函数中不使用2楼的查空函数,而使用注释掉的部分代码,写半字数据是OK的,然后再用单独使用查空函数去查某一段空间是否全空,
也是正确的返回的,就是要把2楼的查空函数嵌到Flash_User_WriteNHalfWord函数中就不行,跑死。

新手求教!

使用特权

评论回复
6
viseng|  楼主 | 2017-6-15 02:18 | 只看该作者
主要是1楼的函数还没考虑跨页写情况,可能会多次用到查空(只写操作页一部分的时候才去查空),所以想做成函数,结构好点

使用特权

评论回复
7
whtwhtw| | 2017-6-15 08:34 | 只看该作者
对flash读写操作都会影响flash内代码的执行,正确做法是对flash的读写操作函数需要放到RAM中

使用特权

评论回复
8
feelhyq| | 2017-6-15 08:59 | 只看该作者
看汇编

使用特权

评论回复
9
viseng|  楼主 | 2017-6-15 09:56 | 只看该作者

还看不懂汇编,能帮忙解析下吗?谢谢

使用特权

评论回复
10
feelhyq| | 2017-6-15 10:43 | 只看该作者
看看传入的参数对不对,特别是指针。单步调试的时候,已进入这个函数就挂掉了吗?

使用特权

评论回复
11
feelhyq| | 2017-6-15 10:46 | 只看该作者
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可能把栈给击穿了,你将这个uint16_t flash_buf[FLASH_PAGE_HALF_SIZE]定义成全局变量数组试试

使用特权

评论回复
12
feelhyq| | 2017-6-15 10:53 | 只看该作者
另外,你很多函数里面都申请了局部内存,要考虑栈开辟的空间是否足够大

使用特权

评论回复
13
viseng|  楼主 | 2017-6-15 14:08 | 只看该作者
feelhyq 发表于 2017-6-15 10:46
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可 ...

谢谢,问题就要这里,解决了~~~~

使用特权

评论回复
14
viseng|  楼主 | 2017-6-15 15:24 | 只看该作者
feelhyq 发表于 2017-6-15 10:53
另外,你很多函数里面都申请了局部内存,要考虑栈开辟的空间是否足够大

我是改全变量来解决的,不过这样还是费内存,我想这应该是栈初击穿的原因,有办法增加栈的空间分配吗?谢谢

使用特权

评论回复
15
viseng|  楼主 | 2017-6-15 15:27 | 只看该作者
feelhyq 发表于 2017-6-15 10:46
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可 ...

默认的栈空间大小是多少?

使用特权

评论回复
16
feelhyq| | 2017-6-15 15:43 | 只看该作者
有个 startup_stm32fxxx.s 汇编文件,当然根据你使用的芯片去找到这个汇编的启动文件,文件其中有一行 Stack_Size      EQU     0x00000400,这个就是用来设置栈空间的。 EQU  means  equal

使用特权

评论回复
17
feelhyq| | 2017-6-15 15:45 | 只看该作者
记得结帖后把分给我啦

使用特权

评论回复
18
viseng|  楼主 | 2017-6-15 17:39 | 只看该作者
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

呵呵,可以,谢谢

使用特权

评论回复
19
viseng|  楼主 | 2017-6-15 17:51 | 只看该作者
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

谢谢,问题解决,可以推荐个STM32的栈配置这块的资料吗?这个配置太大会有什么不良后果?

使用特权

评论回复
20
viseng|  楼主 | 2017-6-15 17:54 | 只看该作者
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

栈的配置有什么讲究,给推荐个资料看看,谢谢

使用特权

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

本版积分规则

44

主题

410

帖子

1

粉丝