言归正传,飞思卡尔在新推出的官方例程包中对启动代码部分做了较大的结构改动(主要体现在Keil下的工程),由原来的crt.s现在统一改成了startup_MKxxxx.s或者startup_MKxxxx.s,当然不只是文件名字的改变,整个启动结构都因此有了较大的改变,个人感觉这种新风格更好一些也更好理解一些,具体的区别我下面简单列出几项:
1. 新的启动文件把原来的Vectors.c和.h文件中的中断向量表也包含进去了,即在文件里面直接定义了中断向量表;
2. 预定义了中断向量表中各个中断服务函数的默认名称,以弱函数的形式体现,这部分我在下篇文章会具体解释一下;
3. 把堆和栈的地址和空间大小定义也都包含在此文件中;
4. 在启动文件里添加了复位函数实现,将程序最后跳转到main函数中去。
上面简单介绍了新版启动文件中的一些新的特色和区别,下面具体以一个实例来说明新版启动文件带来的一个需要注意的问题,即在不同flash大小芯片之间代码移植时需要注意的堆栈地址的问题,下图为新版启动代码定义的相应128k flash的Kinetis KL26的堆栈地址和空间定义,可以看到其定义的堆栈地址为该芯片最大SRAM空间地址-8(128K flash的KL26其SRAM为16k,地址范围为0x1FFFF000~0x20002ff8)
在这个启动代码中定义堆栈地址会带来一个问题,那就是如果我们想要在此工程基础上直接修改成64k flash芯片的工程,除了需要在工程配置选项中选择好修改后的芯片型号,这部分堆栈地址也要进行相应的改动,很简单的道理,因为RAM物理空间变小了,而如果这个地址仍然没有相应的修改的话,那如果程序中做中断,定义局部变量或者子函数调用等需要堆栈空间分配的时候则会出现跳转错误,因为由于RAM空间变小了,原来的地址是无效的空间,所以在我们代码移植的时候这个堆栈地址也要根据实际开发的芯片型号做相应修改才行。
上述这个问题,是用户在进行代码平台移植的时候经常会遇到的问题,这里写出来就是给大家提个醒,小心使得万年船啊,呵呵。未完待续~
PS:
问:_initial_sp 这个在很多的启动文件中对他进行赋值。。你这边对他进行了 赋值。。。。如果不赋值的话。他的值会是多少?怎么算呢
答:原来你也发现了,哈哈,我发现有些启动文件中不对它赋值,应该是编译 器自动给他分配了,我看了map文件,地址也是对的。
问:编译器自动赋值的话。那么可能就不是在SRAM 的最高地址了吧,
我看到栈指针是 SRAM 的基地址 +RW+RO +栈大小。。是这样吧
答:是的。