嵌入式Linux开发 Day1

本开发学习笔记以正点原子ALPHA开发板作为学习开发板,i.MX6ULL为其CPU。
主要学习步骤跟随https://beta.yuanzige.com/course/detail/50090中的视频进行学习,其中前期工作已经学习并准备完成,包括了学习视频的【第一期】手把手教你学Linux之Ubuntu入门篇全部内容和【第二期】手把手教你学Linux之ARM(MX6U)裸机篇中的前5讲内容,之后的笔记将从第二期视频的第6讲开始学习。

1. LED点亮实验(GPIO驱动)

1.1 汇编实现LED

1、使能函数的时钟寄存器:CCGR0对应的IO时钟 (CCM Clock Gating Register 1 (CCM_CCGR1)、27–26(CG13)表示gpio1 clock gpio1_clk_enable));
2、映射IO口功能:将寄存器(IOMUXC_SW_MUX _ CTL_PAD_GPIO1_IO03)的0-3bit设置为下图
嵌入式Linux开发 Day1_第1张图片
3、配置IO的电气属性:(IOMUXC_SW
_ PAD_CTL_PAD_GPIO1_IO03),在配置时需参考下图设置:
嵌入式Linux开发 Day1_第2张图片
主要包括压摆率(SRE)、速度(SPEED)、驱动能力(DSE)、开漏输出(ODE)、上下拉(PUS)等
压摆率表示为从0到1的变化快慢、快为高压摆率、低为低压摆率;
速度为输出时的速度;
驱动能力用所带的负载的大小表示;

4、配置GPIO的功能(数据位、输入输出、中断触发方式、中断使能、中断状态)
在本节中需设置GPIO1_GDIR的Bit3为输出模式,即置为1;
设置GPIO1_DR的Bit3的输出电平,0为低电平、1为高电平;

1.2 汇编简单回顾

常用指令:
1、处理寄存器内部寄存器: MOV 等
2、处理CPU RAM中的寄存器操作:
LDR Rd, [Rn , #offset] 表示 从存储器Rn+offset的位置读取数据存放到 Rd中。
STR Rd, [Rn, #offset] 表示 将Rd中的数据写入到存储器中的 Rn+offset位置。

**LDR:从存储器中读取数据到内部寄存器Rx中**
***LDR R0, =0X0209C004*** @将寄存器地址0X0209C004加载到R0中,即R0=0X0209C004 
***LDR R1, [R0]*** @读取地址0X0209C004中的数据到R1寄存器中

**STR:将内部寄存器Rx的数据写到存储器中**
***LDR R0, =0x0209c004*** @将寄存器地址0X0209C004加载到R0中,即R0=0X0209C004
***LDR R1, =0x20000002*** @R1保存要写入到寄存器的值,即R1=0X20000002
***STR R1, [R0]***		          @将R1中的值写入到R0中所保存的地址中

3、跳转操作: B(跳转到某一段代码之后不会再回来)、BL(跳转到某一段代码之后仍可再回来)

1.3 代码编写

编写出来代码如下,相关内容已在注释中说明清楚

/**
* Copyright @ JianshuZhao Co., Ltd. 2019-2049. All rights reserved.
* Name:led.s
* Description:学习Linux开发的实验程序
* Function: 点亮开发板上的LED灯
* Author:JianshuZhao
* Version:V1.0.0
* Date:2020.2.16
*/

.global _start @全局标号

_start:
    /* Enable Clock; */ 
    ldr r0, =0x020c4068  @CCGR0
    ldr r1, =0xffffffff
    str r1, [r0]    @write 0x020c406c to r1

    ldr r0, =0x020c406c  @CCGR1
    str r1, [r0]    

    ldr r0, =0x020c4070  @CCGR2
    str r1, [r0]    

    ldr r0, =0x020c4074  @CCGR3
    str r1, [r0]    

    ldr r0, =0x020c4078  @CCGR4
    str r1, [r0]    

    ldr r0, =0x020c407c  @CCGR5
    str r1, [r0]    

    ldr r0, =0x020c4080  @CCGR6
    str r1, [r0] 


    /* Config PIN MUX */
    ldr r0, =0x020e0068  @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
    ldr r1, =0x5
    str r1, [r0]    @write 0x020c406c to r1


    /* Config PIN PAD 
    * bit0: 0 低速率
    * bit5-3: 110 R0/6驱动能力
    * bit7-6: 10 100MHz速度
    * bit11: 0 关闭开路输出
    * bit12: 0 使能上下拉/保持
    * bit13: 0 保持
    * bit15-14: 00 100K下拉
    * bit16: 0 关闭hys
    */
    ldr r0, =0x020e02f4  @IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
    ldr r1, =0x10b0
    str r1, [r0]    @write 0x020e02f4 to r1


    /* Config GPIO  bit3 to 1, means output*/
    ldr r0, =0x0209c004  @GPIO direction register (GPIO1_GDIR)
    ldr r1, =0x8
    str r1, [r0]    @write 0x0209c004 to r1


    /* Open led , set GPIO1_IO03_DR to 0*/
    ldr r0, =0x0209c000  @GPIO data register (GPIO1_DR)
    ldr r1, =0x0
    str r1, [r0]    @write 0x0209c000 to r1

loop:
    b loop

1.4 编译程序

1、arm-linux-gnueabihf-gcc -g -c led.s -o led.o
其中-g表示产生调试信息、-c表示编译源文件,但是不链接,-o表示生成的文件名称

2、arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf
其中,链接时需指定起始地址,即代码运行的起始地址;
链接起始地址应指向RAM地址,分为内部RAM(0x900000—0x91FFFF)和外部RAM(DDR,在正点原子开发板中(512M,范围为0x800000—0x9FFFFFFF)),在之后的开发,使用0x87800000作为链接的起始地址。
在I.MX中,Bin文件除非使用jlink下载至内部RAM中运行,否则不能直接运行,必须使用头部文件。I.MX系列SOC内部有提供BootLoader,从外部存储中读取内部信息,然后初始化DDR,并将.bin文件拷贝到指定的地方。bin的运行地址一定要和链接地址一致。

3、arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
将led.elf文件转换成led.bin,其中 -O表示以什么格式(binary)输出,-S表示不要复制源文件中的重定位和符号信息,-g表示不复制源文件中的调试信息

4、arm-linux-gnueabihf-objdump -D led.elf > led.s
反汇编

最终三条命令执行完成之后输出如下内容
嵌入式Linux开发 Day1_第3张图片

下载程序、
因暂时没有SD卡,明天再说。

你可能感兴趣的:(Linux)