2020-01-01 17:41发布
memory1_擦除后.jpg (160.98 KB, 下载次数: 0)
下载附件
擦除后
2017-1-7 20:43 上传
落叶随风 发表于 2017-1-7 20:44 楼主,我不知道你擦除的那个程序有多复杂,我自己做了个简单的测试,擦除后重启也没问题的,不知道是不是太 ...
最多设置5个标签!
MDK编译的时候会在固件结尾处添加一些有用的信息,这些信息丢失的话程序就不能执行了,所以如果你要在指定位置通过编译的方式存储数据的话,必须是完整一页的并且不能是最后一页,这样即使擦除这页也不会把编译器添加的有用信息擦除掉。
下面是简单的测试程序
- #include <stm32f10x.h>
- void func_test(void) __attribute__((section("test")));
- void delay(void)
- {
- int time = 0xfffff;
- while(time-- > 0);
- }
- int main(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- while(1)
- {
- GPIO_SetBits(GPIOC, GPIO_Pin_12);
- delay();
- GPIO_ResetBits(GPIOC, GPIO_Pin_12);
- delay();
- if((*(uint32_t *)func_test) != 0xffffffff)
- {
- func_test();
- RCC_HSICmd(ENABLE);
- FLASH_Unlock();
- FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
- FLASH_ErasePage((uint32_t)func_test);
- FLASH_Lock();
- }
- }
- }
- void func_test(void)
- {
- GPIO_SetBits(GPIOD, GPIO_Pin_2);
- delay();
- GPIO_ResetBits(GPIOD, GPIO_Pin_2);
- delay();
- }
复制代码scatter文件
- ; *************************************************************
- ; *** Scatter-Loading Description File generated by uVision ***
- ; *************************************************************
- LR_IROM1 0x08000000 { ; load region size_region
- ER_IROM1 AlignExpr(+0, 0x0800) { ; load address = execution address
- *.o (RESET, +First)
- *(InRoot$Sections)
- .ANY (+RO)
- }
- RW_IRAM1 0x20000000 0x00010000 { ; RW data
- .ANY (+RW +ZI)
- }
- }
- LR_IROM2 AlignExpr(+0, 0x0800) 0x0800
- {
- ER_IROM2 +0
- {
- *(test)
- }
- }
复制代码看具体的FLASH数据
memory1_擦除后.jpg (160.98 KB, 下载次数: 0)
下载附件
擦除后
2017-1-7 20:43 上传
.sct文件的语法,一直不太懂,假如以你的文件为例,希望将func_test编译到0x0803E000处,应该如何修改;
附我的sct(绝对定位成功,就是删除这段flash后,会进入hardfalut中断)
绝对定位的函数:void sec01(void)__attribute__((section("sec01")));
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00040000 { ; load region size_region
ER_IROM1 0x08000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
sec01 0x0803E000 FIXED 0xffff
{
sec01.o (sec01)
}
RW_IRAM1 0x20000000 0x0000C000 { ; RW data
.ANY (+RW +ZI)
}
}
你的sct文件中这一段
- sec01 0x0803E000 FIXED 0xffff
- {
- sec01.o (sec01)
- }
- RW_IRAM1 0x20000000 0x0000C000 { ; RW data
- .ANY (+RW +ZI)
- }
复制代码sec01确实在0x0803E000处了,单紧接着就是RW_IRAM1的数据了,
虽然这段数据运行时是在0x20000000处的,但存储地址是紧接着你
自己写的sec01后面,第一次上电后擦除了一页,同时也把RW_RAM1段
也擦除了,所以就进HardFault了。
sct文件应该这么写:
- ; *************************************************************
- ; *** Scatter-Loading Description File generated by uVision ***
- ; *************************************************************
- LR_IROM1 0x08000000 { ; load region size_region
- ER_IROM1 AlignExpr(+0, 0x0800) { ; load address = execution address
- *.o (RESET, +First)
- *(InRoot$Sections)
- .ANY (+RO)
- }
- RW_IRAM1 0x20000000 0x00010000 { ; RW data
- .ANY (+RW +ZI)
- }
- }
- LR_IROM2 AlignExpr(0x0803E000, 0x0800) 0x0800
- {
- ER_IROM2 AlignExpr(+0, 0x0800)
- {
- *(test)
- }
- }
复制代码LR_IROM1就不去动它了,另起一段LR_IROM2,当然这个名字可以自己定。
AlignExpr(0x0803E000, 0x0800) 表示:起始地址0x0803E000,按0x0800字节对齐
紧接着的0x0800 表示: 该区最大空间0x0800字节
里面的ER_IROM2 AlignExpr(+0, 0x0800) 这样写表示 execution address = load address,
就是那个+0,指偏移,相对与LR_IROM1指定的 load address,我们指定了0x0803E000。
*(test):这个section名字叫 test,* 表示任意的内容,也可以指定xxx.o什么的,不详述。
然后函数指定到这个section
- void func_test(void) __attribute__((section("test")));
复制代码编译好后看map文件
- ==============================================================================
- Memory Map of the image
- Image Entry point : 0x08000131
- Load Region LR_IROM1 (Base: 0x08000000, Size: 0x0000067c, Max: 0xffffffff, ABSOLUTE)
- Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x0000067c, Max: 0xffffffff, ABSOLUTE)
- Base Addr Size Type Attr Idx E Section Name Object
- (略...)
- Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00000660, Max: 0x00010000, ABSOLUTE)
- Base Addr Size Type Attr Idx E Section Name Object
- (略...)
- Load Region LR_IROM2 (Base: 0x0803e000, Size: 0x00000020, Max: 0x00000800, ABSOLUTE)
- Execution Region ER_IROM2 (Base: 0x0803e000, Size: 0x00000020, Max: 0xffffffff, ABSOLUTE)
- Base Addr Size Type Attr Idx E Section Name Object
- 0x0803e000 0x00000020 Code RO 3 test main.o
复制代码可以看到 LR_IROM2 位置在Base: 0x0803e000,大小Size: 0x00000020,最大 Max: 0x00000800
我自己理解也不是很充分,可能还有不少疏漏的地方,还烦请指出。
一周热门 更多>