设置6ULL处于SVC模式,设置CPSR的[4:0],也就是10011=0x13.读写状态的寄存器需要用到MRS与MSR指令,分别是“获取当前系统运行状态”与“设置当前运行状态”。见下图
SP可以指向iRAM,也可以指向DDR,我们要将其指向DDR。由于开发版是512M的。范围在0x80000000-0x9FFFFFFF。栈内存大小0x200000=2M。因此将sp指向0x80200000的地址。
.global _start
_start:
/*设置SVC模式*/
mrs r0 ,cpsr
bic r0 , r0, #0x1f /*清除cpsr的bit [4:0]*/
orr r0 , r0, #0x13 /*设置为SVC模式 10011*/
msr cpsr , r0 /*将cpsr写入r */
/*设置SP指针 */
ldr sp , =0x80200000
b main /*跳转到C语言main函数 */
/*
定义使用的寄存
*/
#define CCM_CCGR1 *((volatile unsigned int *) 0x020c406c)
/*
IOMUX相关寄存器地址
*/
#define SW_MUX_GPIO1_IO04 *((volatile unsigned int *) 0x020e006c)
#define SW_PAD_GPIO1_IO04 *((volatile unsigned int *) 0x020e02f8)
/*
GPIO相关寄存器地址
*/
#define GPIO1_DR *((volatile unsigned int *) 0x0209c000)
#define GPIO1_GDIR *((volatile unsigned int *) 0x0209c004)
void led_init(void);
void clk_init(void);
int main(int argc, char const *argv[])
{
/*初始化led*/
clk_init();
led_init();
/*LED闪烁*/
while(1){}
return 0;
}
/*使能外设时钟*/
void clk_init(void){
CCM_CCGR1 = 0xFFFFFFFF;
}
/*初始化led*/
void led_init(void){
SW_MUX_GPIO1_IO04 = 0x5; /*复用为GPIO*/
SW_PAD_GPIO1_IO04 = 0x10B0; /*设置电气属性*/
/*GPIO初始化*/
GPIO1_GDIR = 0x10; /*设置为输出*/
GPIO1_DR = 0x0; /*打开LED*/
}
目标文件生辰ledc.bin依赖于OBJC的目标文件。当发现路径中没有目标文件以后,会去执行,8-11行的程序去生成目标文件。
通过预编译文件,执行4-5行的,分别进行链接,转换成二进制文件。如果有问题可以进行反汇编查看问题出在了哪里。
OBJC := start.o main.o
ledc.bin : $(OBJC)
arm-linux-gnueabihf-ld -Ttext 0x87800000 $^ -o ledc.elf
arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
#arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis
%.o : %.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o : %.s
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
clean:
rm -rf *.o *.bin *.elf *.dis
将程序烧入SD卡就可以点亮了。
链接脚本可以将程序的不同的文本段,进行定义到你想要放到的位置。其中,如下程序首先定位到0x87800000的地址上,然后确定text的代码就在0x87800000的位置上,我们将text中放入start.o , main.o的文件以及其他的所有代码。
在在后面的能以4字节整除的地址接上.rodate的代码;.data的代码。以及.bss的代码。其中.bss的代码需要确定它的地址,因为它是未初始化的变量。
SECTIONS{
. = 0x87800000;
.text :
{
start.o
main.o
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : {*(.data)}
__bss_start = .;
.bss ALIGN(4) : {*(.bss) *(COMMON)}
__bss_end = .;
}
说先要选择IO复用模式MUX,和IO电气特性设置PAD。
翻阅手册GPIO模块的寄存器很少。对于点灯只需要配置GPIO_DR与GPIO_GDIR两个寄存器。其他的寄存是是关于中断有关的寄存器。在后面的部分会写到。