5.IMX6ULL点灯

一、C语言环境运行构建

1.设置处理器模式

5.IMX6ULL点灯_第1张图片
​ 设置6ULL处于SVC模式,设置CPSR的[4:0],也就是10011=0x13.读写状态的寄存器需要用到MRS与MSR指令,分别是“获取当前系统运行状态”与“设置当前运行状态”。见下图

5.IMX6ULL点灯_第2张图片

2.设置SP指针

​ SP可以指向iRAM,也可以指向DDR,我们要将其指向DDR。由于开发版是512M的。范围在0x80000000-0x9FFFFFFF。栈内存大小0x200000=2M。因此将sp指向0x80200000的地址。

3.跳转到C语言的汇编程序

.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函数 */

4.点亮LED的C程序

/*
	定义使用的寄存
*/
#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*/
}

5.Makefile编写

​ 目标文件生辰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卡就可以点亮了。

6.链接脚本的编写

​ 链接脚本可以将程序的不同的文本段,进行定义到你想要放到的位置。其中,如下程序首先定位到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 = .;
}

二、GPIO输出总结

​ 说先要选择IO复用模式MUX,和IO电气特性设置PAD。

​ 翻阅手册GPIO模块的寄存器很少。对于点灯只需要配置GPIO_DR与GPIO_GDIR两个寄存器。其他的寄存是是关于中断有关的寄存器。在后面的部分会写到。

你可能感兴趣的:(IMX6ULL学习手册)