文章目录
- 启动代码分析
- 使用C语言点灯
- 封装代码
- 寄存器操作的标准化
启动代码分析
.text
.global _start
_start:
/*
* Vector table:占用异常向量表空间,让它不再能被其它代码占用
*/
b reset
b . @跳转到程序自身
b .
b .
b .
b .
b .
b .
reset:
/*
* Set vector address in CP15 VBAR register
*/
ldr r0, =_start @把异常向量表首地址给r0
mcr p15, 0, r0, c12, c0, 0 @Set VBAR,通过设置协处理器把r0设为异常向量表首地址
/*
* Set the cpu to SVC32 mode, Disable FIQ/IRQ
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr ,r0
/*
* Defines access permissions for each coprocessor
*/
mov r0, #0xfffffff
mcr p15, 0, r0, c1, c0, 2
/*
* Invalidate L1 I/D
*/
mov r0, #0 @Set up for MCR
mcr p15, 0, r0, c8, c7, 0 @Invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @Invalidate icache
/*
* Set the FPEXC EN bit to enable the FPU
*/
mov r3, #0x40000000
fmxr FPEXC, r3
/*
* Disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @Clear bits 13 (--V-)
bic r0, r0, #0x00000007 @Clear bits 2:0 (-CAM)
orr r0, r0, #0x00001000 @Set bit 12 (---I) Icache
orr r0, r0, #0x00000002 @Set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @Set bit 11 (Z---) BTB
mcr p15, 0, r0, c1, c0, 0
/*
* Initialize stacks
*/
init_stack:
/*svc mode stack*/
msr cpsr, #0xd3 @切换模式
ldr sp, _stack_svc_end @sp栈指针指向栈底
/*undef mode stack*/
msr cpsr, #0xdb
ldr sp, _stack_und_end
/*abort mode stack*/
msr cpsr,#0xd7
ldr sp,_stack_abt_end
/*irq mode stack*/
msr cpsr,#0xd2
ldr sp, _stack_irq_end
/*fiq mode stack*/
msr cpsr,#0xd1
ldr sp, _stack_fiq_end
/*user mode stack, enable FIQ/IRQ*/
msr cpsr,#0x10
ldr sp, _stack_usr_end
/*Call main*/
b main @跳转到C语言中的main函数
_stack_svc_end: @由于ARM采用的是满减栈,因此栈指针要指向栈底
.word stack_svc + 512@栈底
_stack_und_end:
.word stack_und + 512
_stack_abt_end:
.word stack_abt + 512
_stack_irq_end:
.word stack_irq + 512
_stack_fiq_end:
.word stack_fiq + 512
_stack_usr_end:
.word stack_usr + 512
.data@由于每个工作模式用的栈寄存器都不一样,因此要给每个模式申请512字节的栈空间
stack_svc:
.space 512 @占用512字节空间,不让其它指令占用,用作栈存储
stack_und:
.space 512
stack_abt:
.space 512
stack_irq:
.space 512
stack_fiq:
.space 512
stack_usr:
.space 512
使用C语言点灯
void Delay(unsigned int Time)
{
while(Time --);
}
#if 0
int main()
{
*(unsigned int *)0x11000c40 = 0x10000000;
while(1)
{
*(unsigned int *)0x11000c44 = 0x00000080;
Delay(1000000);
*(unsigned int *)0x11000c44 = 0x00000000;
Delay(1000000);
}
return 0;
}
#endif
封装代码
#if 0
#define GPX2CON (*(unsigned int *)0x11000c40)
#define GPX2DAT (*(unsigned int *)0x11000c44)
int main()
{
GPX2CON = 0x10000000;
while(1)
{
GPX2DAT = 0x00000080;
Delay(1000000);
GPX2DAT = 0x00000000;
Delay(1000000);
}
return 0;
}
#endif
#if 0
typedef struct
{
unsigned int CON;
unsigned int DAT;
unsigned int PUD;
unsigned int DRV;
}gpx2;
#define GPX2 (*(gpx2 *)0x11000c40)
int main()
{
GPX2.CON = 0x10000000;
while(1)
{
GPX2.DAT = 0x00000080;
Delay(1000000);
GPX2.DAT = 0x00000000;
Delay(1000000);
}
return 0;
}
#endif
#if 0
#include "exynos_4412.h"
int main()
{
GPX2.CON = 0x10000000;
while(1)
{
GPX2.DAT = 0x00000080;
Delay(1000000);
GPX2.DAT = 0x00000000;
Delay(1000000);
}
return 0;
}
#endif
#include "exynos_4412.h"
int main()
{
GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
while(1)
{
GPX2.DAT = GPX2.DAT | (1 << 7);
Delay(1000000);
GPX2.DAT = GPX2.DAT & (~(1 << 7));
Delay(1000000);
}
return 0;
}
寄存器操作的标准化
在不破坏其它位的值的情况下,只修改某一位的值。
#include "exynos_4412.h"
int main()
{
GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
while(1)
{
GPX2.DAT = GPX2.DAT | (1 << 7);
Delay(1000000);
GPX2.DAT = GPX2.DAT & (~(1 << 7));
Delay(1000000);
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)