1),首先f2812上电之后,cpu处理boot ROM中的内容(地址是:0x3F F000,大小4k*16)。头3k*16是存放数学函数表,不需要处理。接下来存放的是bootloader函数和一些芯片版本的校对信息。最后是cpu 向量表,cpu只处理第一条:复位向量。复位后(上电,手动等),程序先从复位向量执行(0x3F FFC0)
2),执行完复位向量后执行initBoot函数,这个函数文档中没有找到具体干些什么。
3),接着call select bootmode function.这一步主要是根据外部引脚(gpiof4,f12,f3,f2)来确定程序接下来执行的位置。具体如下图:
如果是跳到flash执行代码,由于制定的跳转位置是0x3F 7FF6,这正是csm密码代码的前一个位置,所以不能从这里开始程序,必须在这个地址安排一条跳转指令,跳到flash别的地方执行,当然代码是存在哪个地方的了。跳到H0就没什么问题了。这里不研究bootloader了,没看懂。
好了,这样,处理器顺利的跑到了我们想要的地方(sram或者flash),接下来就是我们要做在这里安排一个代码了。也就是把代码放在sram或者flash中。怎么来安排代码呢?当然是cmd文件了,通过cmd文件你可以随便把你的代码安排在哪个地方(当然,随便放是运行不了的),所以把代码安排在H0中或者flash中。下面贴个cmd文件的例子。
-stack 400
MEMORY
{
PAGE 0:
RAMM0 : origin = 0x000000, length = 0x000400
BEGIN : origin = 0x3F8000, length = 0x000002
PRAMH0 : origin = 0x3F8002, length = 0x000FFE
RESET : origin = 0x3FFFC0, length = 0x000002
PAGE 1:
RAMM1 : origin = 0x000400, length = 0x000400
DRAMH0 : origin = 0x3F9000, length = 0x001000
DEV_EMU : origin = 0x000880, length = 0x000180
PIE_VECT : origin = 0x000D00, length = 0x000100
FLASH_REGS : origin = 0x000A80, length = 0x000060
CSM : origin = 0x000AE0, length = 0x000010
XINTF : origin = 0x000B20, length = 0x000020
CPU_TIMER0 : origin = 0x000C00, length = 0x000008
CPU_TIMER1 : origin = 0x000C08, length = 0x000008
CPU_TIMER2 : origin = 0x000C10, length = 0x000008
PIE_CTRL : origin = 0x000CE0, length = 0x000020
ECANA : origin = 0x006000, length = 0x000040
ECANA_LAM : origin = 0x006040, length = 0x000040
ECANA_MOTS : origin = 0x006080, length = 0x000040
ECANA_MOTO : origin = 0x0060C0, length = 0x000040
ECANA_MBOX : origin = 0x006100, length = 0x000100
SYSTEM : origin = 0x007010, length = 0x000020
SPIA : origin = 0x007040, length = 0x000010
SCIA : origin = 0x007050, length = 0x000010
XINTRUPT : origin = 0x007070, length = 0x000010
GPIOMUX : origin = 0x0070C0, length = 0x000020
GPIODAT : origin = 0x0070E0, length = 0x000020
ADC : origin = 0x007100, length = 0x000020
EVA : origin = 0x007400, length = 0x000040
EVB : origin = 0x007500, length = 0x000040
SCIB : origin = 0x007750, length = 0x000010
MCBSPA : origin = 0x007800, length = 0x000040
CSM_PWL : origin = 0x3F7FF8, length = 0x000008
}
SECTIONS
{
PieVectTableFile : > PIE_VECT, PAGE = 1
DevEmuRegsFile : > DEV_EMU, PAGE = 1
FlashRegsFile : > FLASH_REGS, PAGE = 1
CsmRegsFile : > CSM, PAGE = 1
XintfRegsFile : > XINTF, PAGE = 1
CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1
CpuTimer1RegsFile : > CPU_TIMER1, PAGE = 1
CpuTimer2RegsFile : > CPU_TIMER2, PAGE = 1
PieCtrlRegsFile : > PIE_CTRL, PAGE = 1
ECanaRegsFile : > ECANA, PAGE = 1
ECanaLAMRegsFile : > ECANA_LAM PAGE = 1
ECanaMboxesFile : > ECANA_MBOX PAGE = 1
ECanaMOTSRegsFile : > ECANA_MOTS PAGE = 1
ECanaMOTORegsFile : > ECANA_MOTO PAGE = 1
SysCtrlRegsFile : > SYSTEM, PAGE = 1
SpiaRegsFile : > SPIA, PAGE = 1
SciaRegsFile : > SCIA, PAGE = 1
XIntruptRegsFile : > XINTRUPT, PAGE = 1
GpioMuxRegsFile : > GPIOMUX, PAGE = 1
GpioDataRegsFile : > GPIODAT PAGE = 1
AdcRegsFile : > ADC, PAGE = 1
EvaRegsFile : > EVA, PAGE = 1
EvbRegsFile : > EVB, PAGE = 1
ScibRegsFile : > SCIB, PAGE = 1
McbspaRegsFile : > MCBSPA, PAGE = 1
CsmPwlFile : > CSM_PWL, PAGE = 1
codestart : > BEGIN, PAGE = 0
ramfuncs : > PRAMH0 PAGE = 0
.text : > PRAMH0, PAGE = 0
.cinit : > PRAMH0, PAGE = 0
.pinit : > PRAMH0, PAGE = 0
.switch : > RAMM0, PAGE = 0
.reset : > RESET, PAGE = 0, TYPE = DSECT
.stack : > RAMM1, PAGE = 1
.ebss : > DRAMH0, PAGE = 1
.econst : > DRAMH0, PAGE = 1
.esysmem : > DRAMH0, PAGE = 1
这是在ram中运行的cmd文件。在flash中也差不多了。
现在来分析下程序运行的顺序。
1),安排在H0首地址的是一个codestart文件,我查了下,主要是选择禁止看门狗,然后跳到_c_int00函数
2),执行_c_int00函数,主要是执行一些初始化操作,然后跳到main()函数。
程序顺利执行到了main()中,接下来就是我们编写的运用程序了。
第一次写技术博客,一方面是想理理自己的思维,理一下学的东西,另一方面也是想和csdn上的一些技术达人们探讨技术,互相学习,共同进步。希望xdjm没不要留情面,尽情拍砖!