1.实现将Boot和App下载到FLASH的不同地址上,我们需要对链接脚本进行配置
IAR默认的链接脚本在安装目录下
C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.0\stm8\config
找到对应芯片打开后可以看到的这样的字样:
/////////////////////////////////////////////////////////////////
// Example ILINK command file for
// STM8 IAR C/C++ Compiler and Assembler.
//
// Copyright 2014 IAR Systems AB.
//
/////////////////////////////////////////////////////////////////
define memory with size = 16M;
define region TinyData = [from 0x00 to 0xFF];
define region NearData = [from 0x0000 to 0x0FFF];
define region Eeprom = [from 0x1000 to 0x10FF];
define region BootROM = [from 0x6000 to 0x67FF];
define region NearFuncCode = [from 0x8000 to 0xFFFF];
define region FarFuncCode = [from 0x8000 to 0xFFFF]
| [from 0x10000 to 0x17FFF];
define region HugeFuncCode = [from 0x8000 to 0x17FFF];
这里定义了不同区域对应的地址,先将该文件拷贝到工程目录下,我们要对其做相应的修改,
我规划Boot的大小为5k,所以将三个FuncCode的范围改为如下:
define region NearFuncCode = [from 0x8000 to 0x93FF];
define region FarFuncCode = [from 0x8000 to 0x93FF];
define region HugeFuncCode = [from 0x8000 to 0x93FF];
相应的app的链接脚本我们也做了如下的修改:
define region NearFuncCode = [from 0x9400 to 0xFFFF];
define region FarFuncCode = [from 0x9400 to 0xFFFF]
| [from 0x10000 to 0x17FFF];
define region HugeFuncCode = [from 0x9400 to 0x17FFF];
最后我们对配置进行修改,右击工程->Options->Linker->Config->Linker configuration file->选中Override define,
并将链接脚本路径改为工程目录下:$PROJ_DIR$\lnkstm8l052r8.icf
至此Boot和App地址空间划分完毕
2.中断向量表的配置
在stm32中,有一个寄存器保存着中断向量表的起始地址,所以在Boot和App中可以有两个中断向量表,
当从Boot跳转到App时只需要设置一下这个寄存器里的值就行了。
但是STM8l的中断向量位置是固定的,从0x8000处开始。
当中断发生时都是跳转到0x8000开始的中断向量表。那么问题就来了,如果App中发生中断,要是跳到Boot中去了,
那不就GG了,所以我们要对Boot的中断向量表进行修改:
/**************************************************
*
* System initialization code for the STM8 IAR Compiler.
*
* Copyright 2010 IAR Systems AB.
*
* $Revision: 1413 $
*
***************************************************
*
* To add your own interrupt handler to the table,
* give it the label _interrupt_N, where N is the
* offset from the RESET vector. Your label will
* override the corresponding weak label declaration
* on the unhandled_exception function.
*
**************************************************/
MODULE ?interrupt
SECTION __DEFAULT_CODE_SECTION__:CODE
/*
* The interrupt vector table.
*/
SECTION `.intvec`:CONST
PUBLIC __intvec
EXTERN __iar_program_start
//app start at 0x9000
__intvec:
DC8 0x82
DC24 __iar_program_start ;; RESET 0x8000
DC8 0x82
DC24 0x9404
DC8 0x82
DC24 0x9408
DC8 0x82
DC24 0x940C
DC8 0x82
DC24 0x9410
DC8 0x82
DC24 0x9414
DC8 0x82
DC24 0x9418
DC8 0x82
DC24 0x941C
DC8 0x82
DC24 0x9420
DC8 0x82
DC24 0x9424
DC8 0x82
DC24 0x9428
DC8 0x82
DC24 0x942C
DC8 0x82
DC24 0x9430
DC8 0x82
DC24 0x9434
DC8 0x82
DC24 0x9438
DC8 0x82
DC24 0x943C
DC8 0x82
DC24 0x9440
DC8 0x82
DC24 0x9444
DC8 0x82
DC24 0x9448
DC8 0x82
DC24 0x944C
DC8 0x82
DC24 0x9450
DC8 0x82
DC24 0x9454
DC8 0x82
DC24 0x9458
DC8 0x82
DC24 0x945C
DC8 0x82
DC24 0x9460
DC8 0x82
DC24 0x9464
DC8 0x82
DC24 0x9468
DC8 0x82
DC24 0x946C
DC8 0x82
DC24 0x9470
DC8 0x82
DC24 0x9474
DC8 0x82
DC24 0x9478
DC8 0x82
DC24 0x947C
END
个人理解DCn是开辟一个n bit的汇编指令吧。0x82 为操作码,意思是跳转到后面的地址去执行。
0x94XX表示一个地址,我们会将这个地址里的数据赋值给PC指针。
那么这个中断向量表的意思就是,除了Reset,其他的中断发生时,都跳转到App的中断向量表去执行。
这么做的后果就是,Boot中不能使用中断了。不然就跳转到App中去执行了。
那有的同学头就很铁,我偏要两个地方都是用中断呢?
还真有办法,前面的流程都一样,但是用一个全局变量来表示当前程序是在在哪里运行的,
然后在中断函数里根据这个全局变量来选择执行哪段程序。大致思路就这样,具体没有去实现过。
这里还要说一句:既然写Boot就好好写一个功能专一点的Boot,干嘛非要用中断。这种花里胡哨的搞来搞去,没有用的!
3.执行Boot到App的跳转
比较常用的跳转方法有两种,在C语言里,我们一般使用函数指针的方式,还有一种就是使用汇编直接改变PC指针的值。
stm8l中用的是第二种:
asm("LDW X, SP ");
asm("LD A, $FF");
asm("LD XL, A ");
asm("LDW SP, X ");
asm("JPF $9400");
我只知道这些是C语言内嵌汇编的写法,对于stm8l的架构是一无所知,大概就是设置了堆栈,然后跳转吧$9400就是App的起始地址。
上一篇:STM8S与IAR程序常用错误
下一篇:STM32F02R8T6Nuceo板子Uart2串口问题
推荐阅读最新更新时间:2024-03-16 16:04