IMX6ULL仿STM32寄存器格式编写LED程序

博客介绍
硬件:正点原子linux开发板IM6ULL
开发环境:Ubuntu下的VSCode
功能:仿照STM32寄存器格式进行对IMX6ULL的内存地址进行映射对应的寄存器。
参考:正点原子linux
声明:以下仅为个人学习认知。如有错误,希望提出建议。

学习步骤简介
文件编写步骤:
1.编写连接脚本文件
2.编写汇编初始化内存及跳转
3.编写寄存器映射内存头文件
4.编写初始化
5.编写Makefil


编写连接脚本文件

在这里插入图片描述

  1. 第2行为初始化定位计数器为0x87800000;
  2. 第3行为设置一个.test段名,在花括号内start.o必须写在前面,不然在连接的时候程序的启动顺序将会被改变,导致程序不能正常启动;
  3. 第8行中的.rodata 表示只读数据段名;ALIGN(4) 表示数据段以4字节对齐方式;
  4. 第9和12行表示为分别获取.bss段的起始地址和终止地址。__bss_start 和 __bss_end错不多就是给段地址起了个别名。在连接汇编的时候可以使用这两个名字进行对bss段内的数据进行初始化。

编写汇编初始化内存及跳转

start.S

.global _start			/*定义全局标号*/
.global _bss_start		/*定义全局标号 指向bss段的起始地址*/
_bss_start:
    .word __bss_start	/*__bss_start 在链接脚本文件中定义*/

.global _bss_end		/*定义全局标号 指向bss段的终止地址*/
_bss_end:
    .word __bss_end		/*__bss_end 在链接脚本文件中定义*/

_start:
/*设置处理器进入VSC模式*/
/*-------------------------------------------------------------------------------------------------------------------------*/
    MRS R0, CPSR        /*读取CPSR到R0 */
    BIC R0, R0, #0x1F   /*清除CPSR的bit0-4 */
    ORR R0, R0, #0x13   /*写CPSR的bit0-4 */
    MSR CPSR, R0        /*将RO写入CPSR */

/*清除BSS段 */
/*-------------------------------------------------------------------------------------------------------------------------*/
    LDR R0, _bss_start  /*将bss段起始地址送入R0 */
    LDR R1, _bss_end   	/*将bss段结束地址送入R1 */
    MOV R2, #0          /*设置R2初始值 */
bss_loop:               /*bss段数据初始化循环 */
    STMIA R0!, {R2}     /*将R2的值送如R0所在地址,并更新R0 */
    CMP R0, R1          /*比较R0与R1,并设置CPSR的状态标志位 */
    BLE bss_loop        /*BLE=B+LE; LE:如果R0 <= R1 执行B:跳转命令 */

/*设置SP指针并跳转C语言main函数 */
/*-------------------------------------------------------------------------------------------------------------------------*/
    LDR SP, =0x80200000
    B main      /*跳转到C语言main函数 */

编写寄存器映射内存头文件

以CCM寄存器为例:

#ifndef __IMX6ULL_H
#define __IMX6ULL_H

/*先进行初始化 CCM寄存器的基地址 */
#define CCM_BASE            (0x020C4000)         /*CCM的基地址*/

typedef struct
{
    volatile unsigned int CCR;
    volatile unsigned int CCDR;
    volatile unsigned int CSR;
    volatile unsigned int CCSR;
    volatile unsigned int CACRR;
    volatile unsigned int CBCDR;
    volatile unsigned int CBCMR;
    volatile unsigned int CBCMR1;
    volatile unsigned int CBCMR2;
    volatile unsigned int CSCDR1;
    volatile unsigned int CS1CDR;
    volatile unsigned int CS2CDR;
    volatile unsigned int CDCDR;
    volatile unsigned int CHSCCDR;
    volatile unsigned int CSCDR2;
    volatile unsigned int CSCDR3;
    volatile unsigned int RESERVEC_1[2];	//中间出现跳跃地址,也就是不连续的内存地址,使用地址占位变量来填充
    volatile unsigned int CDHIPR;
    volatile unsigned int RESERVEC_2[2];
    volatile unsigned int CLPCR;
    volatile unsigned int CISR;
    volatile unsigned int CIMR;
    volatile unsigned int CCOSR;
    volatile unsigned int CGPR;
    volatile unsigned int CCGR0;
    volatile unsigned int CCGR1;
    volatile unsigned int CCGR2;
    volatile unsigned int CCGR3;
    volatile unsigned int CCGR4;
    volatile unsigned int CCGR5;
    volatile unsigned int CCGR6;
    volatile unsigned int RESERVEC_3[1];
    volatile unsigned int CMEOR;
}CCM_Type;

/*将CCM_BASE对应的地址设置为CCM_Type结构体类型*/
#define CCM					((CCM_Type*) CCM_BASE)

#endif


编写初始化

以CCM寄存器为例:

//使能外设时钟
void clock_init(void)
{
    CCM->CCGR0 = 0xFFFFFFFF;	//使用结构体指针方式对CCM_CCGR寄存器进行操作,就相当于与对0x020C4068H地址进行操作
    CCM->CCGR1 = 0xFFFFFFFF;
    CCM->CCGR2 = 0xFFFFFFFF;
    CCM->CCGR3 = 0xFFFFFFFF;
    CCM->CCGR4 = 0xFFFFFFFF;
    CCM->CCGR5 = 0xFFFFFFFF;
    CCM->CCGR6 = 0xFFFFFFFF;
}

编写Makefil

Makefile文件

objs 	:= start.o main.o
gcc		:= arm-linux-gnueabihf-gcc
ld		:= arm-linux-gnueabihf-ld
objcopy	:= arm-linux-gnueabihf-objcopy
objdump	:= arm-linux-gnueabihf-objdump

ledc.bin	: $(objs)
	$(ld) 	-Timx6u.lds -o ledc.elf $^
	$(objcopy)	-O binary -S ledc.elf ledc.bin
	$(objdump)	-D -m arm ledc.elf > ledc.dis

%.o:%.c
	$(gcc) -Wall -nostdlib -c -O2 $^ -o $@
%.o:%.s
	$(gcc) -Wall -nostdlib -c -O2 $^ -o $@
%.o:%.S
	$(gcc) -Wall -nostdlib -c -O2 $^ -o $@

clean:
	rm -rf *.o ledc.bin ledc.elf ledc.dis

收获:

  1. 使用变量名赋值 := 代替 较长的编译命令
  2. 使用依赖集合符号: $^
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值