FSL_TICS_ZJJ 发表于 2014-8-19 14:07:13

【经验分享】KL25在MDK中将函数指定到flash地址

【经验分享】KL25在MDK中将函数指定到flash地址
一,        经验分享描述
          在之前的经验分享中写了些在KE02下,CW,IAR以及keil的编译环境中,如何定义constant到指定的flash地址。但是实际上,大家在使用我们kinetis的过程中,可能也希望能够灵活的将某个函数直接定义到指定的flash地址,这样,如果改变这个函数,实际上,只需要改变函数所在的flash,而不需要更新所有的flash。所以,为了方便大家操作,我们论坛里已经推出了在CW以及IAR下,如何指定函数到具体的flash地址,本文就讲解下,在MDK的环境下如何实现指定函数到具体的flash地址。
二,        经验分享在MDK环境下实现
         该经验分享要在MDK中实现函数的绝对地址指定,一共有两点需要注意:scatter文件中函数绝对地址的开辟以及程序中将函数定义到定义的绝对地址处。
下面来仔细讲解这两点
1.在.sct文件中定义函数要存放的地址
.sct文件可以在工程的UV4Build文件夹中找到,找到后可以拖进MDK界面中即可以打开,可以使用如下格式定义这个地址:
ER_IROM2 绝对地址 FIXED
{
        *.o (段地址名)
               }
例如,在本次试验中,希望将函数定义到flash地址:0x0001E000这个地址,靠近flash空间的尾部。实际我们的定义如下图:

另外,每次编译之后,编译器都会重新生成.sct文件,所以为了避免写的代码被刷掉,需要做一些配置,禁止使用编译器每次生成的.sct文件,而是使用指定的.sct文件。修改方法:project->options for target->linker, 不勾选 use memory layout from target dialog. 如下图所示:

这样,你每次修改后的platinum_flash.sct在编译之后就不会被改变掉了。
2.    在主函数中定义函数
接下来要做的就是将所定义的函数放到1里面所定义的flash地址段中。
举例定义如下:
char funcInROM(int flag)__attribute__((section("funflash")));
char funcInROM(int flag)
{
        if (flag > 0)
        {
          return 1;
        }
        return 0;
}
此时,这个函数就直接放到了0x001e000地址。
3,测试结果
      本次试验的平台是FRDM_KL25,所使用的MDK平台版本为:V5.10.0.2。代码修改是基于KL25_SC的platinum工程上修改的。
测试结果分两部分进行,第一部分是在进入debug的状态下,查看memory。
第二部分是在生成的hex文件中查看。
      在测试之前,首先讲一下MDK hex文件生成配置,以及hex文件格式。
(1) MDK环境下hex生成配置
         在工程中选择project->options for target->output,勾选Create HEX file,点击ok。如下图:

(2)hex文件格式
文件格式为:
起始符“:”        数据长度(1B)        存储地址(2B)        数据类型(1B)        数据(16B)        校验码(1B)

这里举个例子:
      :1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
::表示一行的开始
10:表示这一行包含的数据长度,一个字节
00C0:表示存储的地址,两个字节,这里是在flash的地址0x000000c0.
00:表示数据类型,一个字节,00为数据记录;01文件结束记录;02扩展段地址记录;04扩展线性地址记录。
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:代表具体的数据,这里数据都是FF,16个字节。数据的存储是高位地址在前,低位地址在后。
40:表示校验码,一个字节。校验码是0x100-这一行数据总和的低字节,然后取低一个字节。
(3)debug 的memory查看测试
编译后,进入debug,调出memory窗口,方法为:view->memory windows->memory 1, 然后在address中输入要查询的flash地址:0x0001e000,然后按下enter键。结果如下:

   可以看到在0x0001e000这个地址的数据为:
29004601 2001DD01 20004770 0000E7FC

(4)查看对应的hex文件。
编译工程之后,Hex文件在工程的build\keil\platinum\UV4Build中,打开后可以看到具体的hex内容,找到地址为E000的地方,可以看到结果如下:

即结果为:
01460029 01DD0120 70470020 FCE70000
和窗口memory中的数据:
29004601 2001DD01 20004770 0000E7FC
相比hex的数据正好是高位地址在前,低位地址在后。
其实这一串数据就是上面定义的char funcInROM(int flag)的十六进制码,可以看到确实是在我们指定的flash地址中,实现了IAR环境下,函数的flash地址指定。
如果屏蔽掉主函数的地址指定:
char funcInROM(int flag)__attribute__((section("funflash")));
会发现,实际上这个函数会被编译器分配到hex的0x0424处,而0XE000处没有相关的函数代码。

三,        附件
附件提供了本文的PDF,以及测试代码。





FSL_TICS_ZJJ 发表于 2014-8-19 14:10:26

本帖与【经验分享】KL25在IAR中将函数指定到flash地址
以及CW 10.5的KL25Z中把代码放到指定位置的小例子 合为姐妹贴。

浪里白条 发表于 2014-8-19 14:12:59

感谢版主的分享,不过这个功能一般用处是什么呢?减少烧录FLASH的时间?

FSL_TICS_ZJJ 发表于 2014-8-19 14:22:19

浪里白条 发表于 2014-8-19 14:12
感谢版主的分享,不过这个功能一般用处是什么呢?减少烧录FLASH的时间?

如果你这个函数自己经常修改的话,如果地址指定,可以到时候直接更新你函数所在的Flash区域就可以了。

DiaoMao_Huang 发表于 2014-8-19 14:36:55

学习了      

abszy 发表于 2014-8-19 14:47:24

这个功能实现很实用先感谢版主分享~~~~~~~~~~

FSL_TICS_ZJJ 发表于 2014-8-19 14:53:38

abszy 发表于 2014-8-19 14:47
这个功能实现很实用先感谢版主分享~~~~~~~~~~

是的,加上2楼的两个编译器环境下的函数绝对地址指定,目前常用的编译器对于这个功能实现的经验分享就都全了。
如果你们在实际使用中遇到问题,欢迎发帖交流。

liliuqun 发表于 2014-8-19 16:05:32


学习了 感谢版主分享

yanpenghao 发表于 2014-8-19 17:10:36

谢谢楼主分享了
想请问一下楼主飞思卡尔是不是有一块游戏手柄类的板子呀?

wxfje 发表于 2014-8-19 23:03:52

这个有时间要好好钻研下,谢谢分享

FSL_TICS_ZJJ 发表于 2014-8-20 09:43:57

yanpenghao 发表于 2014-8-19 17:10
谢谢楼主分享了
想请问一下楼主飞思卡尔是不是有一块游戏手柄类的板子呀? ...

有,蓝牙无线飞鼠,用KL系列的芯片做的,而且之前我们在展会上也有展出,
在我们坛子中,已经发布出详细情况了:http://www.amobbs.com/thread-5558927-1-1.html

FSL_TICS_ZJJ 发表于 2014-8-20 09:45:06

wxfje 发表于 2014-8-19 23:03
这个有时间要好好钻研下,谢谢分享

不客气,如果在学习的过程中遇到任何问题,都欢迎你发帖交流。

yanpenghao 发表于 2014-8-22 17:36:35

FSL_TICS_ZJJ 发表于 2014-8-20 09:43
有,蓝牙无线飞鼠,用KL系列的芯片做的,而且之前我们在展会上也有展出,
在我们坛子中,已经发布出详细 ...

恩恩,谢谢
看了那块板子,好像不是我要找的那块,我忘记上次我在哪儿见了一块飞思卡尔的板子,上面有游戏手柄的那种操控杆
不知道还可以请您再帮我找找么?

wangpengcheng 发表于 2014-8-22 17:43:24

顶一个,ARM的分散加载,呵呵,想当年玩ARM7的时候可被这东西玩死了!资料又少!不过现在网上资料已经非常多了!

zndz410 发表于 2014-8-22 17:45:03

感谢版主的分享.

qwert1213131 发表于 2014-8-24 16:52:27

对于其他的mcu应该也差不多,谢谢分享

rootxie 发表于 2014-8-24 17:55:59

感谢分享,好像很高端的样子

FSL_TICS_ZJJ 发表于 2014-8-25 10:13:42

yanpenghao 发表于 2014-8-22 17:36
恩恩,谢谢
看了那块板子,好像不是我要找的那块,我忘记上次我在哪儿见了一块飞思卡尔的板子,上面有游 ...

这块板子,正面是遥控器,反面就是游戏手柄,我有的就是这款哦。

qerty2008 发表于 2014-8-25 11:52:37

楼主把函数定义到flash地址:0x0001E000

这样做,试想一下,其他的函数也是定义在以0x0001E000为地址的同一个扇区(或者页)里面

另外,擦除flash,不支持逐个字节擦除,而是整个扇区一起被擦除,甚至是整个页被擦除,那么其他的函数也不就是也被擦除了么???

是否有必要这么做,就还要研究过了!!!!

sdlibin007 发表于 2014-8-25 12:00:52

收藏资料,谢谢楼主@@!!

laotui 发表于 2014-8-25 12:30:24

谢谢楼主的资料。

dongyanbo 发表于 2014-8-25 12:40:36

这么多字,楼主敲得一定很辛苦,谢谢分享了

FSL_TICS_ZJJ 发表于 2014-8-25 12:49:07

qerty2008 发表于 2014-8-25 11:52
楼主把函数定义到flash地址:0x0001E000

这样做,试想一下,其他的函数也是定义在以0x0001E000为地址的同一 ...

我这里只是举个例子,如果你函数指定具体位置,自己肯定要考虑扇区擦除的问题,最好空出自己的需要用的扇区。

yanpenghao 发表于 2014-8-25 12:53:13

FSL_TICS_ZJJ 发表于 2014-8-25 10:13
这块板子,正面是遥控器,反面就是游戏手柄,我有的就是这款哦。

好哒
我再去看看,谢谢

fengyunyu 发表于 2014-9-5 17:06:59

分散加载,学习

yaxiaoyu 发表于 2014-11-21 18:25:58

收藏 慢慢看{:lol:}

chengsong 发表于 2014-11-21 20:54:08

好资料,加密用的吧

szy494468597 发表于 2014-11-21 21:35:47

学习下   还没用到过

hongbo3636 发表于 2014-11-27 09:56:55

学习下,谢谢楼主分享

jsszdfdn 发表于 2015-1-8 11:48:27

一直听说分散加载,今天总算看到了。谢谢楼主。

yy918 发表于 2015-1-8 12:31:18

收藏,学习中。。。

Juggernaut 发表于 2015-1-8 12:41:32

支持楼主~

jsszdfdn 发表于 2015-4-20 21:19:34

你好楼主 最近写了一段BOOT程序 并用到了分散加载,我用的是STM32F4芯片 ,我将加密程序指定到了一个分区,然后运行BOOT,一切正常,包扩这段加密程序,然后我将这个分区的程序删除了,然后重新运行,但是串口波特率不对了,发现是时钟配置不对了,然后我有恢复到之前,然后有正常了,不知楼主遇到过这样的问题么?

vaneno 发表于 2016-4-27 08:51:39

如何把这个代码的起始地址重新定义,譬如说我本来是0x00开始的 我需要让他从0x1000开始

jiki119 发表于 2016-4-27 11:15:15

将这个函数,单独列为一个独立的文件,单独编译并指定位置就不会出现
19楼担心的问题了。

单飞 发表于 2016-6-30 16:25:56

没有调试通过。。。在0x08007200留几个字节,函数指定到0x08008000地址,然后0x08007200被修改成了0。不指定函数的位置,0x08007200地址的数据都是1(下载时全擦,未使用,所以为1),怀疑函数指定的地址不对,影响的。

Magicfjpg 发表于 2016-7-12 10:38:25

很少用分散加载,
但有必要mark。

张彬 发表于 2022-12-7 14:07:53

本帖最后由 张彬 于 2022-12-7 14:09 编辑

请问可以直接按.c和.h分配固定地址吗,方便做升级
页: [1]
查看完整版本: 【经验分享】KL25在MDK中将函数指定到flash地址