打印

IAR编译器如何设定某个源文件的某个函数编译在起始地址

[复制链接]
9321|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bigfacecat|  楼主 | 2009-11-25 11:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
IAR编译器如何设定某个源文件的某个函数编译在起始地址

我是用的STM32 M3的片子
例如
我想把main.c的main函数编译在起始地址
IAR编译器应当如何设置?
我不想用编译器提供的一堆初始化代码的。
沙发
lxyppc| | 2009-11-25 13:18 | 只看该作者
我用的是IAR4.42A 30K限制版
有个叫stm32f10x_vector.c的文件
里面有个结构体

#pragma language=extended
#pragma segment="CSTACK"

void __program_start( void );

#pragma location = "INTVEC"
/* STM32F10x Vector Table entries */
const intvec_elem __vector_table[] =
{
  { .__ptr = __sfe( "CSTACK" ) },
  __program_start, // 把这个改成你想要的函数
  NMIException,
  HardFaultException,
  MemManageException,
  BusFaultException,
  UsageFaultException,

把里面的__program_start改成你自己的应该就可以了

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
bigfacecat + 1
板凳
desert_hawk| | 2009-11-25 18:24 | 只看该作者
本帖最后由 desert_hawk 于 2009-11-25 18:26 编辑

楼主的这个要求会使数据段得不到初始化,包括初始值为0的数据段 (DATA_Z)和初始值非0的数据段(DATA_I)。除非你在main函数中把所有的全局变量都初始化一遍。

使用特权

评论回复
地板
bigfacecat|  楼主 | 2009-11-26 09:33 | 只看该作者
我就是不想用全局变量,做到模块化。

使用特权

评论回复
5
desert_hawk| | 2009-11-26 09:57 | 只看该作者
模块化跟使用全局变量没必然联系吧。
各模块间通讯或测试以及模块和ISR之间的通讯或测试不可避免地要使用全局变量。

使用特权

评论回复
6
bigfacecat|  楼主 | 2009-11-26 11:43 | 只看该作者
有关系的,我想做成动态链接的模式,主程序不需要编译,只更新模块。
所以受到编译器的限制,不能使用全局变量,因为无法重定位地址。

使用特权

评论回复
7
desert_hawk| | 2009-11-26 12:15 | 只看该作者
晕了,主程序不需要编译?还有不需要编译就能使用的程序?理解不了。

使用特权

评论回复
8
bigfacecat|  楼主 | 2009-11-26 16:19 | 只看该作者
可以呀,现在就是要做成这样的,只更新模块,就可以实现升级。

使用特权

评论回复
9
vigia| | 2009-11-26 17:42 | 只看该作者
本帖最后由 vigia 于 2009-11-26 17:43 编辑

IAR5.x版本:
改下icf文件:
place at address MEM:0x40000 { section .text object myfile.o };
/* 把myfile.c中的代码放在0x40000 */

如果要定义函数的首地址,估计大概要每个.c文件放一个函数了。。。

使用特权

评论回复
10
bigfacecat|  楼主 | 2009-11-26 18:15 | 只看该作者
我现在用的是4.5版本的
不知道要怎么改

使用特权

评论回复
11
desert_hawk| | 2009-11-26 18:35 | 只看该作者
2楼的方法是可行的,只是对楼主这么做的目的仍迷惑中。

使用特权

评论回复
12
bigfacecat|  楼主 | 2009-11-26 18:53 | 只看该作者
其实想法和动态库的思想是一样的
我把程序拆分为主程序和模块
模块可以单独编译升级
模块的接口函数的入口地址必须在固定的地址,也就是起始地址
这样主程序才可以访问到该入口函数
所以必须把这个函数编译到起始地址

使用特权

评论回复
13
mohanwei| | 2009-11-26 19:15 | 只看该作者
约定个地址就行了,放到起始地址则是不行的……

典型的应用就是像例程那样,bootloader放在起始地址(某种意义上的主函数);用户程序放到2000(某种意义上的模块),bootloader运行完直接跳转到该地址。

使用特权

评论回复
14
bigfacecat|  楼主 | 2009-11-26 19:49 | 只看该作者
约定个地址,那也需要保证那个入口函数就是编译到那个地址
是吧

使用特权

评论回复
15
mohanwei| | 2009-11-26 20:29 | 只看该作者
你看一下那个IAP的例程就知道了。bootloader和用户程序是分成两个项目的。入口地址通过指定ROM的起始地址来实现:
options->linker->config->edit->memory regions->ROM  看到这个值没有,修改成你需要的地址就可以了。
当然直接编辑*.icf文件更快。

使用特权

评论回复
16
arm_fan168| | 2009-11-26 21:26 | 只看该作者
把应用程序放在起始地址肯定是不行的,cortex-M3内核的起始地址存放的是中断向量表,程序并不是从0x00000000开始运行的,而是从0x00000004这个地址的内容所指向的位置开始运行的。如果你把应用程序硬是烧写到起始地址,程序肯定是运行不了的,因为连堆栈指针都没定位。
用C编程,想把某个函数编译在一个确定的地址太难了,还是用汇编,伪指令定位吧。

使用特权

评论回复
17
bigfacecat|  楼主 | 2009-11-26 21:39 | 只看该作者
我可以使用汇编ASEG ORG来定位,可是要是C能够实现就更好了

使用特权

评论回复
18
vigia| | 2009-11-27 09:28 | 只看该作者
IAR4.X版本:

在workspace中,选择某个.c文件的option,选中option中的override inherited settings,然后到extra options页中,添加:
--segment code = MYCODE

这样,这个.c文件中的所有函数都位于MYCODE段。

然后在xcl文件中指定MYCODE段的位置:
-Z(CODE)MYCODE=xxxx-xxxx

使用特权

评论回复
19
bigfacecat|  楼主 | 2009-11-27 15:35 | 只看该作者
这就是我要的效果
等我验证下

使用特权

评论回复
20
xiaocheng_zjc| | 2014-1-17 17:59 | 只看该作者
这个解决了吗,我怎么打了--segment code = MYCODE,编译错呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

46

帖子

0

粉丝