a707083746 发表于 2018-8-17 17:59:47

STM32将函数定位于flash指定位置,导致后续6K空间被清零

芯片:STM32F103C8
我使用 #pragma arm section code=".ARM.__at_0x0800E400" 定位了3个函数到flash开始的地方:

一直清零到,约6KB

有数据要保存在0x0800EC00开始的地方,但每次在KEIL上进入调试状态时,数据都被清零了:


有大神知道这是什么原因么?

a707083746 发表于 2018-8-17 19:48:56

额 我发现把一个常量定义到 了,去掉了就不清零了~~~
const u8 NbComsOb /*__attribute__((at(0x0800FC00)))*/ = 65;
:L:L:L:L

toofree 发表于 2018-8-17 20:04:37

本帖最后由 toofree 于 2018-8-17 20:06 编辑

有毛病吗?不觉得呀。
从.map来看,这段空间又没用,爱是啥是啥呗。
工程编译出的目标程序里面是什么?BIN或HEX文件都看看。

有些IDE会把没用的空间置00的,也有的是没用的空间置ff。
BIN和HEX不会骗人

(请自觉附上工程及源代码,不能耍流氓)

feixiang20 发表于 2018-8-17 23:08:24

定义错误,把函数定位在FLASH高端的指定位置,以后更新,只更新那小块地方就可以了。

a707083746 发表于 2018-8-18 10:09:51

toofree 发表于 2018-8-17 20:04
有毛病吗?不觉得呀。
从.map来看,这段空间又没用,爱是啥是啥呗。
工程编译出的目标程序里面是什么?BIN ...

这段空间我用来保存参数的,每次上电都被清零。
下面是几个主要的函数


main.c:
/*
本工程用于测试把函数定位到flash指定的位置,并通过地址调用
KEIL版本:4.23
芯片:STM32F103C8
功能:通过按键交替点亮/熄灭LED
问题:当常量NbComsOb定位到0x0800FC00时,函数之后的空间会被清零 (清零后擦除芯片才变FF)
*/
u8 Type = 1;//非0 -- 通过地址调用,0 -- 通过函数名调用
main(void)
{
RCC_Configuration();
Pro_Key_LED_Init();
//Type = NbComsOb;//0;//NbComsOb;
while (1)          
{
        if(Type == 0)
        {//通过函数名调用
       ProKey_Scan();
       ProLED_Display();
        }
        else
        {//通过地址调用
       ((void (*)(void))0x0800e43f)();//ProKey_Scan()的地址
       ((void (*)(void))0x0800e48b)();//ProLED_Display()的地址
        }
}
}


Fun.c:
const u8 NbComsOb __attribute__((at(0x0800FC00))) = 65;       //指定位置,随便定义一个常量
//const u8 NbComsOb= 65;       //不指定位置,随便定义一个常量
u8 Device_ProStatus;

#pragma arm section code=".ARM.__at_0x0800E400"
/*
初始化按键和灯
*/
void Pro_Key_LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(ProKey_RCC | ProLED_RCC , ENABLE);
//按键
GPIO_InitStructure.GPIO_Pin = ProKey_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(ProKey_Port, &GPIO_InitStructure);
//灯
GPIO_InitStructure.GPIO_Pin = ProLED_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ProLED_Port, &GPIO_InitStructure);
}

/*
扫描按键
*/
void ProKey_Scan(void)
{
static u32 T = 0;
if(Pro_Key_Read == 0)
{
if(T < 128)
{
   T ++;
}
else
{
   if(T != 10086)
   {
    Device_ProStatus ^= 0x01;
    T = 10086;
   }
}
}
else
{
T = 0;
}
}

/*
灯处理
*/
void ProLED_Display(void)
{
if(Device_ProStatus & 0x01)
{
Pro_LED_ON;
}
else
{
Pro_LED_OFF;
}
}

#pragma arm section        code

a707083746 发表于 2018-8-18 10:12:16

feixiang20 发表于 2018-8-17 23:08
定义错误,把函数定位在FLASH高端的指定位置,以后更新,只更新那小块地方就可以了。 ...

我这芯片是64K的,已经比较靠后了。。。

发表于 2018-8-18 10:44:58

楼主,从你传的工程中的Project.hex中可以查到,数据是存在的。如果仿真不存在的话,考虑查看一下使用芯的容量是否正确。

a707083746 发表于 2018-8-18 14:02:20

安 发表于 2018-8-18 10:44
楼主,从你传的工程中的Project.hex中可以查到,数据是存在的。如果仿真不存在的话,考虑查看一下使用芯的 ...

实际的芯片是64K的,定义的函数和常量没超范围。现在就是给常量指定到后,函数后面的flash空间会清零;常量不指定地址就不会清零。因为我要在被清零的地方保存参数,所以看看有没有办法解决。

liu553824989 发表于 2018-8-20 09:41:36

这是个好问题,支持一下,会不会常量制定地址,编译器识别充函数定位到常量地址初始化了,你可以把常量地址定义在函数地址的地方前几个字节。

发表于 2018-8-20 15:28:54

a707083746 发表于 2018-8-18 14:02
实际的芯片是64K的,定义的函数和常量没超范围。现在就是给常量指定到后,函数后面的flash空 ...

楼主看一下生成的文件HEX,如果这段空间是存在的代码,而仿真的时候却不存在,那么看一下仿真器配置的芯片容量。
页: [1] 2
查看完整版本: STM32将函数定位于flash指定位置,导致后续6K空间被清零