IAR编译器如何设定某个源文件的某个函数编译在起始地址
IAR编译器如何设定某个源文件的某个函数编译在起始地址
我是用的STM32 M3的片子
例如
我想把main.c的main函数编译在起始地址
IAR编译器应当如何设置?
我不想用编译器提供的一堆初始化代码的。
我用的是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改成你自己的应该就可以了
模块化跟使用全局变量没必然联系吧。
各模块间通讯或测试以及模块和ISR之间的通讯或测试不可避免地要使用全局变量。
有关系的,我想做成动态链接的模式,主程序不需要编译,只更新模块。
所以受到编译器的限制,不能使用全局变量,因为无法重定位地址。
晕了,主程序不需要编译?还有不需要编译就能使用的程序?理解不了。
可以呀,现在就是要做成这样的,只更新模块,就可以实现升级。
IAR5.x版本:
改下icf文件:
place at address MEM:0x40000 { section .text object myfile.o };
/* 把myfile.c中的代码放在0x40000 */
如果要定义函数的首地址,估计大概要每个.c文件放一个函数了。。。
2楼的方法是可行的,只是对楼主这么做的目的仍迷惑中。
其实想法和动态库的思想是一样的
我把程序拆分为主程序和模块
模块可以单独编译升级
模块的接口函数的入口地址必须在固定的地址,也就是起始地址
这样主程序才可以访问到该入口函数
所以必须把这个函数编译到起始地址
约定个地址就行了,放到起始地址则是不行的……
典型的应用就是像例程那样,bootloader放在起始地址(某种意义上的主函数);用户程序放到2000(某种意义上的模块),bootloader运行完直接跳转到该地址。
约定个地址,那也需要保证那个入口函数就是编译到那个地址
是吧
你看一下那个IAP的例程就知道了。bootloader和用户程序是分成两个项目的。入口地址通过指定ROM的起始地址来实现:
options->linker->config->edit->memory regions->ROM 看到这个值没有,修改成你需要的地址就可以了。
当然直接编辑*.icf文件更快。
把应用程序放在起始地址肯定是不行的,cortex-M3内核的起始地址存放的是中断向量表,程序并不是从0x00000000开始运行的,而是从0x00000004这个地址的内容所指向的位置开始运行的。如果你把应用程序硬是烧写到起始地址,程序肯定是运行不了的,因为连堆栈指针都没定位。
用C编程,想把某个函数编译在一个确定的地址太难了,还是用汇编,伪指令定位吧。
我可以使用汇编ASEG ORG来定位,可是要是C能够实现就更好了
IAR4.X版本:
在workspace中,选择某个.c文件的option,选中option中的override inherited settings,然后到extra options页中,添加:
--segment code = MYCODE
这样,这个.c文件中的所有函数都位于MYCODE段。
然后在xcl文件中指定MYCODE段的位置:
-Z(CODE)MYCODE=xxxx-xxxx