MDK中函数绝对地址定位

合集下载

STC单片机Keil中C语言函数定位的方法

STC单片机Keil中C语言函数定位的方法

STC单片机Keil中C语言函数定位的方法
下面以演示程序进行说明
演示程序中有ReadIAP、ProgramIAP和EraseIAP三个函数
最终目的是将这三个函数都定位到0x8000之后
第一步:新建一个项目“Demo”,并将源文件“Demo.C”添加到项目中
第二步:直接编译,并打开编译后生成的“Demo.M51”文件
从M51文件的“CODE MEMORY”信息中,可以看到3个函数的链接名称、链接地址和函数长度ReadIAP的链接名称为“?PR?_READIAP?DEMO”,链接地址为“0003H”,长度为16H字节ProgramIAP的链接名称为“?PR?_PROGRAMIAP?DEMO”,链接地址为“0019H”,长度为16H字节EraseIAP的链接名称为“?PR?_ERASEIAP?DEMO”,链接地址为“0044H”,长度为14H字节
第三步:根据M51中函数的长度信息计算出各个函数重定位的地址,ReadIAP的重定位的地址为0x8000
ProgramIAP的重定位的地址为0x8016
EraseIAP的重定位的地址为0x802C
第四步:打开项目选项中的“BL51 Locate”属性页
在上图的“Code”域中输入下列语句
“?PR?_READIAP?DEMO(0x8000), ?PR?_PROGRAMIAP?DEMO(0x8016), ?PR?_ERASEIAP?DEMO(0x802C)”
第五步:点击确定按钮,并重新编译即可,此时可以重新打开“Demo.M51”文件,便可发现3个函数已被重定位到我们所指定的地址了,如下图。

如何将函数和变量定义到指定位置

如何将函数和变量定义到指定位置

嵌入式编程第一篇:51单片机如何将函数定义到指定程序地址在单片机编程使用中,会涉及到将某些函数定义到指定的code区。

此时需要对工程文件进行配置修改才可完成。

本期针对单片机平台做出说明介绍1、测试目标将函数testaddr定义到0x6000地址2、测试环境LKT4106加密芯片算法工程、KEIL-C51编译软件、3、实现步骤3.1 使用KEIL软件导入LKT4106算法工程(KEIL软件基本操作不再敷述,如不清楚请自行百度)3.2 在App_Main.c文件中声明测试函数testaddr:extern void testaddr(u8 xdata *in,u8 xdata *out,u8 len);3.3 在App_fun.c文件中实现测试函数testaddr:void testaddr(u8 xdata *in,u8 xdata *out,u8 len){u8 i;for(i=0;i < len;i++)out[i]= in[i]+1;}3.4 在App_Main.c文件中调用测试函数testaddr,此处省略3.5 编译算法工程后,在\LKT4106_AppDemo\Out\Bin\路径下找到LKT4106_AppDemo.M51,打开该文件。

3.6 找到* * C O D E M E M O R Y * * 部分,寻找到testaddr编译后存储的地址,注意:根据编译规则,testaddr函数会转换为大写格式,并加上函数所在文件的名称。

本例中,编译后的默认地址如图1所示。

图1. 默认编译链接地址3.7 回到算法工程,选择Project->Options for Target ...->BL51 Misc,点击Edit按钮调出lin文件,如图2所示图2. 打开lin文件3.8 在LKT4106_App.lin文件中,按照下图所示,将testaddr函数指定到程序区的目标地址,本例将其由默认的0x48B0地址更改到0x6000地址,如图3所示。

MDK(KEIL)中设定变量或数组到指定的位置

MDK(KEIL)中设定变量或数组到指定的位置

MDK(KEIL)中设定变量或数组到指定的位置MDK(KEIL)中设定变量或数组到指定的位置分类:【嵌入式开发】2013-05-20 14:51 239人阅读评论(0) 收藏举报转自zyboy2000定位变量到指定的位置使用定义在头文件absacc.h中的 __at宏,可以将变量以如下方式定位到绝对地址处:C 例子:#include <absacc.h>const char MyText[] __at (0x1F00) = "TEXT AT ADDRESS 0x1F00";int x __at (0x40003000); // variable at address 0x40003000unsigned char xArray[128] __at (0x68000000); // Array start at address 0x68000000汇编例子:在汇编文件中可以使用段名,由|.ARM.__AT_<addr>|组成来定义位置。

下面的例子是将一个段定义到地址0xFFE0处:AREA |.ARM.__AT_0xFFE0|, CODE, READONLYu8 a[10] __attribute__ ((at(0x2000002c)));编译说..\List\ALL.axf: Error: L6971E: Section .data from objectusart.o with type RW incompatible withSection .ARM.__AT_0x2000002C from object hal.o with type ZI in er RW_IRAM1.似乎是定位了这个绝对地址后,其他变量不会为它让位~NONO,这个方法不行的,因为编译器并没有真正开辟一个变量,你仅仅是强行操作某个地址而已,但这个地址是否被其他数据利用了,你管不到也不知道~(0字)电子白菜[8次]2009-9-5 2:08:47编译器里面应该有设置,比如系统总共有多少内存,你可以故意设置的少一些,这样在编译的时候他就会避开你没有指定的了。

stm32分段管理代码

stm32分段管理代码

编译大型的程序时,可能某一段代码固定之后不再改变(比如BSP),而应用部分经常修改。

在这种情况下,如果使用在线升级或是Bootloader的方式升级程序时,你就觉得每次升级的代码有一部分是重复的(BSP),如果把这部分代码固定在一个区里面,升级的时候只选择APP区的代码升级,这样提高效率,也节省时间。

MDK或是早前的ADS提供的分散加载方式对代码分区提供了较好的支持,但是我总觉得代码之外再管理一个文件,会比较费劲。

所以一直在寻找更好的方式。

今天仔细研究了MDK的帮助文档,同时简单尝试了一下,有一点体会。

先和大家一起分享:///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MDK下有两种方式给函数定位(均在代码中控制):1. 给函数声明__attribute__比如声明函数:void task(void) __attribute((section(".ARM.__at_0x8100000")));这样函数task 会被连接到0x8100000 地址处.不同的函数可以使用同一个地址,链接的时候会自动处理.每个函数都需要声明一次.2. 使用#pagaram 控制如下定义:#pragma arm section code=".ARM.__at_0x8100000"void task(void){}#pragma arm section这样函数task 会被链接到0x8100000 地址.这样做的优点是声明区内的函数都会包含在指定的地址范围内.以上两种方式均在代码文件中实现, 不需要修改分散加载文件, 对代码的分区比较方便.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////特别注意的是:比如你选择BSP代码固化,一定要保证你的代码的稳定性, 如果经常修改的话,该方法不实用!。

keil中函数变量定位方法

keil中函数变量定位方法

keil中函数变量定位⽅法keil中函数变量定位⽅法(2010-09-14 16:02:58)转载标签:杂谈分类:技术函数绝对定位⽅法:将链接⽅式从LX51改回BL51,然后再BL51 Locate中的Code框中写⼊:PR?_DELAY?DELAY(0x8000)其中,前⾯那个_DELAY是指函数名叫做delay,前⾯为什么要加_还不清楚,⽽且原来⽆论是什么这⾥都是⼤写;后⾯那个DELAY是指⽂件名叫做delay,也就是说这个函数要到delay.c中去找;括号⾥⾯的当然就是要定位到的地址了。

如果不强制定位,连接器⼀般都会把程序从0开始安排,有多⼤安排多⼤。

ouravr⽹友总结(⽐较全):使⽤KeilC51软件,可以很⽅便地将代码或者数据绝对定位到某个地址。

1、代码定位:⽅法1:使⽤伪指令CSEG。

⽐如要将MyFunc1定位到代码区C:0x1000,则新建⼀个A51⽂件,添加以下内容:PUBLIC MYFUNC1CSEG AT 1000HMYFUNC1:;其它代码RET在其它源⽂件中,就可以调⽤MyFunc()函数了。

需要注意的是,编译器不检测传递参数的数⽬,仅检测函数是否有返回值。

⽅法2:使⽤BL51 Locate选项。

⽐如在main.c中定义了⼀个MyFunc2函数,并且要将该函数定位到代码区C:0x2000,则从菜单中选择Project->Options for Target 'Target1',在弹出的对话框中选择BL51 Locate页,在下⾯的code栏中写上?PR?MYFUNC2?MAIN(0x2000)即可。

如果想定位多个函数,也可以使⽤*通配符。

2、变量定位:只有全局变量可以绝对定位,局部变量⽆法实现绝对定位。

⽅法1:使⽤_at_关键字。

声明⼀个全局变量unsigned char data MyBuf1[8] _at_ 0x20;⽅法2:使⽤BL51 Locate选项。

KEIL C51之绝对地址定位详解

KEIL C51之绝对地址定位详解
然后在:
Project->Options for Target ...->BL51 Locate:Xdata
中填入:
?XD?INITVARS(0x200)
再次编译即可。相应地,若定义的是data/idata等变量,则相应处理即可。
3、若有多个变量或函数要进行绝对地址定位,则应按地址从低到高的顺序
使用KeilC51软件,可以很方便地将代码或者数据绝对定位到某个地址。
相应地,如为xdata变量,则InitVars.c中写:
char xdata myVer = {COPYRIGHT 2001-11};
然后将该文件加入工程,编译,打开M51文件,在
* * * X D A T A M E M O R Y * * *
下可找到:
XDATA xxxxH xxxxH UNIT ?XD?INITVARS
KEIL C51之绝对地址定位详解
单片机空间分配看*.M51文件,ARM,DSP空间分配看*.map文件
1、函数定位:
假如要把C源文件tools.c中的函数
int X(int xx)
{
...
}
放在CODEMEMORY的0x1000处,先编译该工程,然后打开该工程的
M51文件,在
* * * C O D E M E M O R Y * * *
行下找出要定位的函数的名称,应该形如:
CODE xxxxH xxxxH UNIT ?PR?_BCD2HEX?TOOLS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填写如下内容:
?PR?_BCD2HEX?TOOLS(0x1000)

c语言相对路径转绝对路径 -回复

c语言相对路径转绝对路径 -回复

c语言相对路径转绝对路径-回复C语言是一种通用的编程语言,被广泛应用于系统软件开发和嵌入式系统的编程。

在C语言编程中,文件路径是一个重要的概念。

相对路径和绝对路径都可以用来指定文件的位置。

本文将探讨相对路径与绝对路径之间的转换,并提供一步一步的指南。

一、什么是相对路径和绝对路径?在计算机中,文件路径是指文件在文件系统中的位置。

相对路径是从当前工作目录开始寻找文件的路径。

当前工作目录是指执行程序时所在的目录。

相对路径的路径不包含完整的文件系统路径,而是基于当前工作目录的相对位置。

相对路径通常以"../" 或"./"开头,以指示上级目录或当前目录。

例如,假设当前工作目录是一个名为"myproject"的文件夹。

要访问该文件夹中的另一个文件夹中的文件,我们可以使用相对路径"../anotherfolder/file.txt"。

这个路径中的".."表示上级目录。

绝对路径是一个完整的文件系统路径,从根目录开始到文件的路径。

绝对路径可以唯一地指定一个文件的位置,不依赖于当前工作目录。

绝对路径通常以根目录(如"/"或"C:\")开头。

例如,要访问Windows系统中C盘下的文件,可以使用绝对路径"C:\folder\file.txt"。

这个路径中的"C:\"表示C盘根目录。

二、相对路径转绝对路径的方法在C语言中,我们可以使用函数来处理路径,以实现相对路径转绝对路径的功能。

下面是一种实现相对路径转绝对路径的方法:1. 获取当前工作目录C语言提供了函数`getcwd(char *buffer, size_t size)`来获取当前工作目录。

这个函数将当前工作目录的路径存储在`buffer`中,最多存储`size`个字符。

2. 连接相对路径和当前工作目录将相对路径与当前工作目录连接起来,形成一个完整的路径。

C语言绝对地址跳转

C语言绝对地址跳转

C语言使用函数指针跳转到程序固定地址(0x8000)执行程序的方法使用函数指针,把一个纯数据强制转换为函数指针类型。

int main(void){void (* my_function)(void);//int *my_address = 0x8000;my_function = (void (*)()) (0x8000);my_function();}其实更简单,不适用中间变量,直接一步到位:(*(void(*)())0x8000)();转成汇编就占两条指令.在IAP的bootloader中经常使用到地址跳转,指定程序跳转到某一地址运行,例如强制跳转到0x2c去执行,则可使用(*((void(*)(void))0x2c)))();实际上这是运用的函数指针,可以这样分解:1,函数指针的定义为void (* fd) (void); 省略参数的函数原型为void (*)(void).2,0x2c, 这里的0x2c为地址,可以认为是变量(个人理解),可以理解为将变量0x2c进行强制类型转换,转换成函数指针类型,即( void(*)(void) )0x2c.3,调用函数。

(* (func) ) (); func 为函数指针(void(*)(void) )0x2c,合起来就是(* ((void(*)(void) )0x2c) )();嵌入式笔试题:想让程序跳转到绝对地址0x100000处执行,该如何做?网上看到有如下答案:*((void(*)(void))0x100000)();经过在VC++6.0和Linux gcc4.4.3下测试,均不能通过编译。

VC++6.0报错:error C2100: illegal indirectionGCC报错:error: void value not ignored as it ought to be应该是怎么写呢?经过测试,有两种方法:答案1. (*(void(*)(void))0x100000)();答案2. ((void(*)(void))0x100000)();仔细观察,第一种写法只是第一个*的位置不同,第二种写法少了一个*,但是都能正确编译通过,且正确执行。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档