25. C语言版本LED驱动实验

一、C语言运行环境构建

1.1、设置处理器模式
设置6ULL处于SVC模式 下。设置CPSR寄存器的bit4-0,也就是M[4:0]为10011=0X13。读写状态寄存器需要用到MRS和MSR指令。MRS将CPSR寄存器数据读出到通用寄存器里面,MSR指令将通用寄存器的值写入到CPSR寄存器里面去。
在这里插入图片描述
在这里插入图片描述

MRS R0, CPSR @将特殊寄存器 CPSR 里面的数据传递给 R0,即 R0=CPSR
bic r0, r0, #0x1f /* 将 r0 的低 5 位清零,也就是 cpsr 的 M0~M4 */
orr r0, r0, #0x13 /* r0 或上 0x13,表示使用 SVC 模式 */
msr cpsr, r0 /* 将 r0 的数据写入到 cpsr_c 中 */

1.2、设置sp指针
Sp可以指向内部RAM,也可以指向DDR,我们将其指向DDR。Sp设置到哪里?512MB的范围0x80000000~0x9FFFFFFF。栈大小,0x200000=2MB。处理器栈增长方式,对于A7而言是向下增长的。设置sp指向0x80200000。

在这里插入图片描述

ldr sp, =0X80200000 /* 设置栈指针 */

1.3、跳转到C语言
使用b指令,跳转到C语言函数,比如main函数。
在这里插入图片描述

b main /* 跳转到 main 函数 *

/

二、软件编写

.global _start  		/* 全局标号 */

/*
 * 描述:	_start函数,程序从此函数开始执行,此函数主要功能是设置C
 *		 运行环境。
 */
_start:

	/* 进入SVC模式 */
	mrs r0, cpsr
	bic r0, r0, #0x1f 	/* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 	*/
	orr r0, r0, #0x13 	/* r0或上0x13,表示使用SVC模式					*/
	msr cpsr, r0		/* 将r0 的数据写入到cpsr_c中 					*/

	ldr sp, =0X80200000	/* 设置栈指针			 */
	b main				/* 跳转到main函数 		 */

三、链接脚本

链接脚本描述了要连接的文件,以及链接顺序,和链接首地址

//imx6ul.lds
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 = .;
}

四、Makefile

objs = start.o main.o

ledc.bin:$(objs)
	arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^
	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
	arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis
	
%.o:%.s
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
	
%.o:%.S
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
	
%.o:%.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
	
clean:
	rm -rf *.o ledc.bin ledc.elf ledc.dis

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lljss1980/article/details/114479133