查看: 8305|回复: 4

[CodeWarrior] Kinetis系列 在CodeWarrior环境下函数绝对地址(已解决)

[复制链接]

该用户从未签到

13

主题

86

帖子

0

新手上路

Rank: 1

积分
130
最后登录
1970-1-1
发表于 2013-3-22 19:25:07 | 显示全部楼层 |阅读模式
 求助大侠们:
第一个问题
(1)如何在CodeWarrior环境下,实现定位函数绝对地址。主要实现bootloader定位到某个地址,然后绝对地址调用?
 
第二个问题
(2)假设函数绝对地址在0x0001F000处,那么它是否对应flash映像地址就是在该处?如果我需要给PC赋值访问该函数,PC值应该是多少?
 
下面这段话是内核手册里说的,但还是没理解第二个问题。
读PC 时返回的值是当前指令的地址+4。如果向PC 中写数据,就会引起一次程序的分支(但是不更新LR 寄存器)。CM3 中的指令至少是半字对齐的,所以PC 的LSB 总是读回0。然而,在分支时,无论是直接写PC 的值还是使用分支指令,都必须保证加载到PC 的数值是奇数(即LSB=1),用以表明这是在Thumb 状态下执行。倘若写了0,则视为企图转入ARM 模式,CM3 将产生一个fault 异常。
 https://www.nxpic.org.cn/file:///D:qqUsers448352261ImageFYBJ4]6~S@VEK8)73T(S%E8.jpg
 
 
我知道答案 目前已有3人回答
回复

使用道具 举报

该用户从未签到

13

主题

86

帖子

0

新手上路

Rank: 1

积分
130
最后登录
1970-1-1
 楼主| 发表于 2013-3-22 19:34:47 | 显示全部楼层

回复:Kinetis系列 在CodeWarrior环境下函数绝对地址

在线等大侠~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

11

主题

288

帖子

0

版主

Rank: 7Rank: 7Rank: 7

积分
610
最后登录
1970-1-1
发表于 2013-3-23 08:55:48 | 显示全部楼层

RE:Kinetis系列 在CodeWarrior环境下函数绝对地址

通过#pragma CODE_SEG DEFAULT来将代码定义到指定的空间。
回复 支持 反对

使用道具 举报

该用户从未签到

35

主题

508

帖子

0

金牌会员

Rank: 6Rank: 6

积分
2167
最后登录
1970-1-1
发表于 2013-3-25 11:06:50 | 显示全部楼层

RE:Kinetis系列 在CodeWarrior环境下函数绝对地址(正解)

CodeWarrior项目中要将函数放在特定位置,需要在链接配置文件(.lcf)定义特定存储空间,指定其起始地址和存储空间大小。然后在链接配置文件(.lcf)中定义存储区块section。
例如在下面的链接配置文件(.lcf)中定义了m_paraconfig存储空间,并且在m_paraconfig存储空间中定义了.paraconfig 的存储区块。
MEMORY {
interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001BC
code (RX) : ORIGIN = 0x00000410, LENGTH = 0x0003FBF0
data (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00010000
cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_paraconfig (RX) : ORIGIN = 0x10000000, LENGTH = 0x00008000
}
SECTIONS {
.paraconfig :
{
*(.paraconfig)
. = ALIGN (0x4);
} > m_paraconfig
...
}
代码中使用#progma 为编译器指定所调用存储区块section,使用__declspec()函数设定函数放置在这个区域中。
例如:
#pragma define_section mySectionInROM ".romsymbols" far_abs RX
__declspec(section "mySectionInROM") void funcInROM(int flag); //Fcn Prototype
void funcInROM(int flag){
if (flag > 0)
{
printf("Option 1 selected \n\r");
printf("Executing funcInROM() \n\r");
printf("This function is executed from section myROM \n\r");
}
}
可以参看应用手册AN4498获得更多信息。
http://cache.freescale.com/files/soft_dev_tools/doc/app_note/AN4498.pdf
下面的代码是Kinetis串行bootloader的客户代码引导程序(AN2295):
//-----------------------------------------------------------------------------
// FUNCTION: JumpToUserApplication
// SCOPE: Bootloader application system function
// DESCRIPTION: The function startup user application
//
// PARAMETERS: pointer on user vector table
//
// RETURNS: function never go back
//-----------------------------------------------------------------------------
static void JumpToUserApplication(LWord userStartup)
{
/* set up stack pointer */
asm("LDR r13, [r0]");

/* jump to application reset vector */
asm("ADD r0,r0,#0x04 ");
asm("LDR r0, [r0]");
asm("BX r0");
}
调用方法:
// Jump to user application
JumpToUserApplication(RELOCATED_VECTORS);

可以看到,bootloader需要加载客户代码中断服务向量表,Kinetis中断服务向量表的vector 0为初始栈指针,vector 1为PC指针。
所以需要将中断服务向量表地址+0x4获得PC指针,然后再跳转运行客户代码。
假设函数绝对地址在0x0001F000处,那么它是否对应flash映像地址就是在该处?如果我需要给PC赋值访问该函数,PC值应该是多少?
您的问题与Bootloader运行还是有些区别,0x0001F000应该是函数入口地址,位于Flash内存区域。要给PC指针赋值,那应该是放上0x0001F000地址即可。
祝顺利。
回复 支持 反对

使用道具 举报

该用户从未签到

13

主题

86

帖子

0

新手上路

Rank: 1

积分
130
最后登录
1970-1-1
 楼主| 发表于 2013-4-1 10:27:44 | 显示全部楼层

回复:Kinetis系列 在CodeWarrior环境下函数绝对地址(已解决)

回复第 4 楼 于2013-03-25 11:06:50发表:
CodeWarrior项目中要将函数放在特定位置,需要在链接配置文件(.lcf)定义特定存储空间,指定其起始地址和存储空间大小。然后在链接配置文件(.lcf)中定义存储区块section。
例如在下面的链接配置文件(.lcf)中定义了m_paraconfig存储空间,并且在m_paraconfig存储空间中定义了.paraconfig 的存储区块。
MEMORY {
interrupts  (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001BC
code        (RX) : ORIGIN = 0x00000410, LENGTH = 0x0003FBF0
data        (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00010000
cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_paraconfig  (RX) : ORIGIN = 0x10000000, LENGTH = 0x00008000
}
SECTIONS {
.paraconfig :
{
*(.paraconfig)
. = ALIGN (0x4);
} > m_paraconfig
...
}
代码中使用#progma 为编译器指定所调用存储区块section,使用__declspec()函数设定函数放置在这个区域中。
例如:
#pragma define_section mySectionInROM ".romsymbols" far_abs RX
__declspec(section "mySectionInROM") void funcInROM(int flag); //Fcn Prototype
void funcInROM(int flag){
if (flag > 0)
{
printf("Option 1 selected \n\r");
printf("Executing funcInROM() \n\r");
printf("This function is executed from section myROM \n\r");
}
}
可以参看应用手册AN4498获得更多信息。
http://cache.freescale.com/files/soft_dev_tools/doc/app_note/AN4498.pdf
下面的代码是Kinetis串行bootloader的客户代码引导程序(AN2295):
//-----------------------------------------------------------------------------
// FUNCTION:    JumpToUserApplication
// SCOPE:       Bootloader application system function
// DESCRIPTION: The function startup user application
//              
// PARAMETERS:  pointer on user vector table
//              
// RETURNS:     function never go back
//-----------------------------------------------------------------------------  
static void JumpToUserApplication(LWord userStartup)
{
/* set up stack pointer */  
asm("LDR      r13, [r0]");

/* jump to application reset vector */
asm("ADD      r0,r0,#0x04 ");
asm("LDR      r0, [r0]");
asm("BX       r0");
}
调用方法:
// Jump to user application
JumpToUserApplication(RELOCATED_VECTORS);

可以看到,bootloader需要加载客户代码中断服务向量表,Kinetis中断服务向量表的vector 0为初始栈指针,vector 1为PC指针。
所以需要将中断服务向量表地址+0x4获得PC指针,然后再跳转运行客户代码。
假设函数绝对地址在0x0001F000处,那么它是否对应flash映像地址就是在该处?如果我需要给PC赋值访问该函数,PC值应该是多少?
您的问题与Bootloader运行还是有些区别,0x0001F000应该是函数入口地址,位于Flash内存区域。要给PC指针赋值,那应该是放上0x0001F000地址即可。
祝顺利。 
===================================================================
 
 
  非常感谢版主的回答。LZ好人!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-7-20 23:24 , Processed in 0.095006 second(s), 25 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表