你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
a707083746 提问时间:2018-8-17 17:59 /
芯片:STM32F103C8
我使用 #pragma arm section code=".ARM.__at_0x0800E400" 定位了3个函数到flash[0x0800E400]开始的地方:
函数定位的地址.png 清零结尾.png
一直清零到[0x0800FBFF],约6KB

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

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

收藏 1 评论11 发布时间:2018-8-17 17:59

举报

11个回答
a707083746 回答时间:2018-8-17 19:48:56
额 我发现把一个常量定义到 [0x0800FC00]了,去掉了就不清零了~~~
const u8 NbComsOb /*__attribute__((at(0x0800FC00)))*/ = 65;
七哥 回答时间:2018-8-17 20:04:37
本帖最后由 toofree 于 2018-8-17 20:06 编辑

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

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

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

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

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

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

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

STM32F103C8_函数定位测试.rar

下载

378.4 KB, 下载次数: 24, 下载积分: ST金币 -1

KEIL工程文件

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

我这芯片是64K的,已经比较靠后了。。。
废鱼 回答时间:2018-8-18 10:44:58
楼主,从你传的工程中的Project.hex中可以查到,数据是存在的。如果仿真不存在的话,考虑查看一下使用芯的容量是否正确。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

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

实际的芯片是64K的,定义的函数和常量没超范围。现在就是给常量指定到[0x0800FC00]后,函数后面的flash空间会清零;常量不指定地址就不会清零。因为我要在被清零的地方保存参数,所以看看有没有办法解决。
仙景 回答时间:2018-8-20 09:41:36
这是个好问题,支持一下,会不会常量制定地址,编译器识别充函数定位到常量地址初始化了,你可以把常量地址定义在函数地址的地方前几个字节。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

废鱼 回答时间:2018-8-20 15:28:54
a707083746 发表于 2018-8-18 14:02
实际的芯片是64K的,定义的函数和常量没超范围。现在就是给常量指定到[0x0800FC00]后,函数后面的flash空 ...

楼主看一下生成的文件HEX,如果这段空间是存在的代码,而仿真的时候却不存在,那么看一下仿真器配置的芯片容量。
a707083746 回答时间:2018-8-21 14:05:47
liu553824989 发表于 2018-8-20 09:41
这是个好问题,支持一下,会不会常量制定地址,编译器识别充函数定位到常量地址初始化了,你可以把常量地址 ...

可以了,谢谢。先常量后函数。
a707083746 回答时间:2018-8-21 14:08:49
安 发表于 2018-8-20 15:28
楼主看一下生成的文件HEX,如果这段空间是存在的代码,而仿真的时候却不存在,那么看一下仿真器配置的芯 ...

我按9楼的思路试了一下可以了

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 结帖奖励

查看全部评分

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版