查看: 595|回复: 27
打印 上一主题 下一主题
收起左侧

[STM32F0] Flash连接写操作,跑死,求解

[复制链接]   已结帖(20)
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
跳转到指定楼层
楼主
下面是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;
}

满意回复

+20
feelhyq 查看完整内容
有个 startup_stm32fxxx.s 汇编文件,当然根据你使用的芯片去找到这个汇编的启动文件,文件其中有一行 Stack_Size EQU 0x00000400,这个就是用来设置栈 ...
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
沙发
 楼主| 发表于 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;
}
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
板凳
 楼主| 发表于 2017-6-15 02:05 | 只看该作者 |返回版面
问题如1楼中注释部分所说,用注释掉的代码就可以写成功,用查空函就跑死,用单步调试跟了一下,
具体死的位置在查空函数的Flash_ReadNHalfWord(offAddress,tflash_buf,len_halfword);这里
进入函数就死
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
地板
 楼主| 发表于 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);
就没问题了,想不通问题在哪
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
5
 楼主| 发表于 2017-6-15 02:16 | 只看该作者 |返回版面
这里主要的差别就是一个加没加指针形参uint16_t *buffer,跑不通的是没加的,也就是在查空函数中去声明暂存读出的数组,另一种是把外部已申请好的,共用一个

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

新手求教!

21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
6
 楼主| 发表于 2017-6-15 02:18 | 只看该作者 |返回版面
主要是1楼的函数还没考虑跨页写情况,可能会多次用到查空(只写操作页一部分的时候才去查空),所以想做成函数,结构好点
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
12主题920帖子2816积分
初级工程师 专家等级:结帖率:66%打赏:9.88受赏:11.88
7
发表于 2017-6-15 08:34 | 只看该作者 |返回版面
对flash读写操作都会影响flash内代码的执行,正确做法是对flash的读写操作函数需要放到RAM中
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
8
发表于 2017-6-15 08:59 | 只看该作者 |返回版面
看汇编
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
9
 楼主| 发表于 2017-6-15 09:56 | 只看该作者 |返回版面

还看不懂汇编,能帮忙解析下吗?谢谢
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
10
发表于 2017-6-15 10:43 | 只看该作者 |返回版面
看看传入的参数对不对,特别是指针。单步调试的时候,已进入这个函数就挂掉了吗?
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
11
发表于 2017-6-15 10:46 | 只看该作者 |返回版面
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可能把栈给击穿了,你将这个uint16_t flash_buf[FLASH_PAGE_HALF_SIZE]定义成全局变量数组试试
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
12
发表于 2017-6-15 10:53 | 只看该作者 |返回版面
另外,你很多函数里面都申请了局部内存,要考虑栈开辟的空间是否足够大
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
13
 楼主| 发表于 2017-6-15 14:08 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 10:46
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可 ...

谢谢,问题就要这里,解决了~~~~
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
14
 楼主| 发表于 2017-6-15 15:24 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 10:53
另外,你很多函数里面都申请了局部内存,要考虑栈开辟的空间是否足够大

我是改全变量来解决的,不过这样还是费内存,我想这应该是栈初击穿的原因,有办法增加栈的空间分配吗?谢谢
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
15
 楼主| 发表于 2017-6-15 15:27 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 10:46
很有可能栈被击穿了,你申请了一段局部内存空间  uint16_t flash_buf[FLASH_PAGE_HALF_SIZE];  这个很有可 ...

默认的栈空间大小是多少?
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
16
发表于 2017-6-15 15:43 | 只看该作者 |返回版面
有个 startup_stm32fxxx.s 汇编文件,当然根据你使用的芯片去找到这个汇编的启动文件,文件其中有一行 Stack_Size      EQU     0x00000400,这个就是用来设置栈空间的。 EQU  means  equal
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
2主题245帖子741积分
高级技术员 专家等级:结帖率:100%
17
发表于 2017-6-15 15:45 | 只看该作者 |返回版面
记得结帖后把分给我啦
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
18
 楼主| 发表于 2017-6-15 17:39 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

呵呵,可以,谢谢
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
19
 楼主| 发表于 2017-6-15 17:51 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

谢谢,问题解决,可以推荐个STM32的栈配置这块的资料吗?这个配置太大会有什么不良后果?
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
     
19主题137帖子412积分
资深技术员 专家等级:结帖率:100%
20
 楼主| 发表于 2017-6-15 17:54 | 只看该作者 |返回版面
feelhyq 发表于 2017-6-15 15:45
记得结帖后把分给我啦

栈的配置有什么讲究,给推荐个资料看看,谢谢
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
您需要登录后才可以回帖 登录 | 注册
本版积分规则
分享 快速回复 返回顶部 返回列表