FC游戏站:为您提供一个绿色免费的下载空间! 首页| 电脑软件| 安卓 | 手机网站
当前位置:首页 > FC游戏动态 > 周立功lpc21xx/lpc22xx系列ARM7启动代码分析

周立功lpc21xx/lpc22xx系列ARM7启动代码分析

来源:FC游戏站 更新:2020-12-03

用手机看

扫描二维码随时看1.在手机上浏览
2.分享给你的微信好友或朋友圈

第一,MSR CPSR_c, #0xdf, 这一句把ARM的工作模式设置为系统模式,或者也可以说是用户模式, 因为系统模式与用户模式是共享相同的寄存器组. 用0xdf对CPSR寄存器赋值,就把IRQ中断关闭了(可以查一下CRSR的详细说明), 代码正常执行时处理器是处在用户模式的,所以IRQ中断是不会执行的. 所以,如果用周立功的这个启动代码,当你的程序中需要中断时,要把0xdf改成0x5f. 之前看到很多人在网上说用周立功的ADS工程模板,FC,进不了中断,很多情况下是这个原因.

第二, 并不是每一种模式下的堆栈都用设置的, 比如说如果你的程序中不会用到FIQ,FC,就可以不用设置快速中断下的堆栈.

第三, 注意LDR SP, =StackUsr这个语句, 其它都是没有=号的, 为什么这个要用等号呢? 这就是LDR伪指令与LDR指令的区别了,LDR SP, =StackUsr是把StackUsr表示的地址装载到sp,LDR SP, StackUnd是把StackUnd表示地址的内容装载到sp,注意下面几句

StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4

StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4

StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4

StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4

StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

可以看到,没有”=”的标号都已经用DCD初始化了, 而StackUsr到底是什么呢, 它是由下面的语句决定的

(startup.s文件)

AREA Stacks, DATA, NOINIT

StackUsr

(分散加载文件)

STACKS 0x40002000 UNINIT

{

Startup.o (Stacks)

}

这样就明白了, StackUsr肯定是0x40000000~0x400020000之间的某个数. 用户模式下的堆栈空间就是它了.

ResetInit

BL InitStack

BL TargetResetInit

B __main

处理器上电复位后通过中断向量表进入该函数,__main函数主要工作是初始化C的库函数, 并由它进入C的main函数.

__user_initial_stackheap

LDR r0,=bottom_of_heap

; LDR r1,=StackUsr

MOV pc,lr

__user_initial_stackheap函数是ADS的一个库函数, 如果程序中用到的分散加载文件, 这个函数必须要被实现. 应用程序的栈和heap是在C库函数初始化过程中建立起来的。可以通过重定向对应的子程序来改变堆栈和heap的位置. 堆栈的地址在分散加载文件里已经指定好,本函数不应该修改它们的值. 用r0,r1分别返回heap和stack的基址. 关于ADS的存储器机制大家可以去网上查更详细的资料.

StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4

StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4

StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4

StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4

StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

AREA MyStacks, DATA, NOINIT, ALIGN=2

SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;Stack spaces for Administration Mode

IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode

FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode

AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode

UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode

上面几行代码是为各个模式下的堆栈分配空间. 其中MyStacksA的位置会在分散加载文件中指定.

IF :DEF: EN_CRP

IF . >= 0x1fc

INFO 1,"nThe data at 0x000001fc must be 0x87654321.nPlease delete some source before this line."

ENDIF

CrpData

WHILE . < 0x1fc

NOP

WEND

CrpData1

DCD 0x87654321 ;/*When the Data is 为0x87654321,user code be protected. 当此数为0x87654321时,用户程序被保护 */

ENDIF

上面这几行其实是加密芯片用的, lpc21xx和lpc22xx系列的ARM7,当你的工程选择RelInFlash时, 代码写进flash,芯片也同时被加密, 加密状态下JTAG也读不到芯片, 也不能单步调试, 要解密的话必须要用ISP完全擦除一下. 上面的代码的意思就是在地址0x1fc处放数据0x87654321, 从而实现加密的功能, 但前提是IF :DEF: EN_CRP, 也就是定义了EN_CPP这个宏. 而这个宏是在当选择了RelInFlash时ADS自动定义的. 然后,再说一下0x87654321的问题. LPC2100 系列ARM7微控制器是世界首款可加密的ARM芯片,对其加密的方法是通过用户程序在指定地址上设置规定的数据。PHILIPS公司规定,,对于 LPC2100芯片(除LPC2106/2105/2104外),当片内FLASH地址0x000001FC处的数据为0x87654321时,芯片即被加密. 所以问题搞定.

猜你感兴趣