Linux之ARM(IMX6U)裸机汇编LED驱动实验--编译驱动

发布者:tanjunhui最新更新时间:2021-10-29 来源: eefocus关键字:Linux  ARM  编译驱动 手机看文章 扫描二维码
随时随地手机看文章

前言

我们是要编译出在 ARM 开发板上运行的可执行文件,所以要使用交叉编译器 arm-linux-gnueabihf-gcc 来编译。


交叉编译链的安装参考另外一篇博文:交叉编译链的安装


编译代码

本试验就一个 leds.s 源文件,所以编译比较简单。


源文件代码(leds.s):


.global _start @全局标号


_start:

    /*使能所有外设时钟 */

    LDR R0 , =0x020c4068  @CCGR0 

    LDR R1 , =0xffffffff  @要想CCGR0写入的数据

    STR R1 , [R0]         @将R1的值写入到R0中

    

    LDR R0 , =0x020c406c  @CCGR1

    STR R1 ,[R0]


    LDR R0 , =0x020c4070  @CCGR1

    STR R1 ,[R0]


    LDR R0 , =0x020c4074  @CCGR1

    STR R1 ,[R0]


    LDR R0 , =0x020c4078  @CCGR1

    STR R1 ,[R0]


    LDR R0 , =0x020c407c  @CCGR1

    STR R1 ,[R0]


    LDR R0 , =0x020c4080  @CCGR1

    STR R1 ,[R0]


    /*配置 GPIO_I003  PIN的复用为GPIO

    * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0101 =5

    * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器的地址为0x020E_0068

    */

    LDR R0 , =0x020E0068  @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03

    LDR R1 , =0x5          @要写入的数据

    STR R1 , [R0]          @将5写入IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03


    /*配置 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的电器属性

    * IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址时0x020E_02F4

    * bit0 :    0 低速率

    * bit5-3:   110 R0/6  驱动能力

    * bit7-6:   10 100MHz速度

    * bit11:    0 关闭开路输出

    * bit12:    1 使能pull/keeper

    * bit15-14: 00 100K下拉

    * bit16:    0 关闭hys    

    * 向寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03写入 0x10b0

    */


    LDR R0 , = 0x020E02F4

    LDR R1 , = 0x10b0

    STR R1 ,[R0]


    /*设置GPIO功能

     *设置GPIO1_GDIR寄存器  设置GPIO1_GPIO03为输出

     *寄存器GPIO_GDIR的地址是  0x0209C004

     * 设置GPIO1_GDIR寄存器bit3为1也就是GPIO1_GPIO03为输出

     */

    LDR R0 , = 0x0209C004

    LDR R1 , = 0x8

    STR R1 ,[R0]


    /*打开LED,也就是设置GPIO1_GPIO03为0 

     *GPIO1_DR 寄存器地址为0x0209C000

    */


    LDR R0 , = 0x0209C000

    LDR R1 , =0

    STR R1 ,[R0]


loop:

    b loop


1.把 .s 文件编译成 .o文件

在这里插入图片描述

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

在这里插入图片描述

其中“-g”选项是产生调试信息,GDB 能够使用这些调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文件名字,这里我们指定 led.s 编译完成以后的文件名字为 leds.o。执行上述命令以后就会编译生成一个 leds.o 文件


2.把 .o文件编译成连接文件 .elf

arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置。


代码要运行,那就必须处于运行地址处,否则代码肯定运行出错。比如 I.MX6U 支持 SD 卡、EMMC、NAND 启动,因此代码可以存储到 SD 卡、EMMC 或者 NAND 中,但是要运行的话就必须将代码从 SD 卡、EMMC 或者NAND 中拷贝到其运行地址(链接地址)处,“存储地址”和“运行地址”可以一样


裸机例程都是烧写到 SD 卡中,上电以后 I.MX6U 的内部 boot rom 程序会将可执行文件拷贝到链接地址处,这个链接地址可以在 I.MX6U 的内部 128KB RAM 中(0X900000~0X91FFFF),也可以在外部的 DDR 中。


我们把链接地址都放在 DDR中,链接起始地址为 0X87800000。I.MX6U-ALPHA 开发板的DDR 容量有两种:512MB 和256MB,起始地址都为 0X80000000,只不过 512MB 的终止地址为 0X9FFFFFFF,而 256MB 容量的终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 其链接地址就是 0X87800000,这样我们统一使0X87800000 这个链接地址,不容易记混。


确定了链接地址以后就可以使用 arm-linux-gnueabihf-ld 来将前面编译出来的 led.o 文件链接到 0X87800000 这个地址,使用如下命令:



arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf


上述命令中-Ttext 就是指定链接地址,“-o”选项指定链接生成的 elf 文件名,这里我们命名为 led.elf。上述命令执行完以后就会在工程目录下多一个 led.elf 文件

在这里插入图片描述

led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还需要将 led.elf 文件转换为.bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具了。


3.arm-linux-gnueabihf-objcopy 格式转换生成bin文件

arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为

led.bin 文件,命令如下:


arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin


上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出,选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息。上述命令执行完成以后,工程目录如图

在这里插入图片描述

至此我们终于等到了想要的东西—led.bin 文件。


4.arm-linux-gnueabihf-objdump 反汇编

大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:


arm-linux-gnueabihf-objdump -D led.elf > led.dis


上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一个名为 led.dis 文件

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

可以看出 led.dis 里面是汇编代码,而且还可以看到内存分配情况。在0X87800000 处就是全局标号_start,也就是程序开始的地方。通过 led.dis 这个反汇编文件可以明显的看出到我们的代码已经链接到了以 0X87800000 为起始地址的区域。


这些命令一条条的敲太麻烦了,我们把它整理成一个Makefile文件


5.整理成makefile文件

是用“touch”命令在工程根目录下创建一个名为“Makefile”的文件,如图

在这里插入图片描述

创建好 Makefile 文件以后就需要根据 Makefile 语法编写 Makefile 文件了:


led.bin:led.s

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

arm-linux-gnueabihf-objdump -D led.elf > led.dis

clean:

rm -rf *.o led.bin led.elf led.dis


注意: Makefile 命令前一定要是tab键形成的四个空格


创建好 Makefile 以后我们就只需要执行一次“make”命令即可完成编译

在这里插入图片描述

关键字:Linux  ARM  编译驱动 引用地址:Linux之ARM(IMX6U)裸机汇编LED驱动实验--编译驱动

上一篇:Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin文件到SD卡运行
下一篇:Linux之ARM(IMX6U)裸机汇编LED驱动实验--驱动编写

推荐阅读最新更新时间:2024-11-12 17:34

arm:c语言和汇编混合编程
仅作演示。 1.C和汇编可相互调用,汇编子函数格式参考 汇编:普通的函数调用的汇编代码解析 http://www.cnblogs.com/mylinux/p/4139972.html   本文演示了 : 汇编嵌入到c语言;         汇编调用c语言,c语言调用汇编。 2.C函数参数从左到右是放到r0-r3, ;push stack用stmfd ldmfd,右边的参数会先入栈。 ;//call_asm.s PRESERVE8 AREA C$$code, CODE, READONLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IMPORT cfunc
[单片机]
快速学Arm(29)--存储器寻址2
ARM芯片中的片内和片外存储器在芯片中的地址是由芯片厂家或用户分配的.给物理存储器分配逻辑地址的过程称为存储器映射.通过这些逻辑地址,就可以访问到相应存储器的物理存储单元.我们再来看一下下面的lpc2300的物理地址的分布: 从上面图中可以看出,AHB,APB两个内存区域都是分配给外设使用了.每个外设空间大小为16KB,最多可以分配128个外设,总共各2MB左右. 接下来,我们要理解一下存储器重映射的问题,所谓的存储器重映射是指部分存储器单元出现在与之前不同的逻辑地址上,也就是说同一物理地址在用户看来可能有多个不同的逻辑地址.逻辑地址是用户所看到的地址,而物理地址是在存储器中的实际地址.看下面的两个图例:
[单片机]
快速学<font color='red'>Arm</font>(29)--存储器寻址2
ARM嵌入式应用调试之自制系统调用
一、原理 要想自制系统调用,当然首相要做的就是明白系统调用的过程: 我们拿open函数来举个例子:当用户空间执行open函数时,会通过glibc函数库的作用最终去调用sys_open函数,sys_open函数最终又会调用我们具体注册的open函数!那么这里最主要的就是glibc函数库干了些什么呢?其实它的作用就是当用户空间执行open函数时,会去执行一条swi #val指令,这条指令会使cpu发生异常,并跳转到异常向量入口:vector_swi处去执行,之后的代码会根据引发异常的指令取出其中的参数,并根据这个参数调用对应的处理函数!sys_open、sys_read、sys_write这些函数是放在一个数组里面的,就是根据取出的这
[单片机]
Arm推出全新显示解决方案,提升用户体验新境界
Arm今日宣布推出全新 显示 解决方案,其中包含Mali-D71显示处理器、CoreLink MMU-600和Assertive Display 5。新显示解决方案以Arm IP为开发基础,提升设备效能,并采用智能解决方案应对所有来自显示技术的挑战。   Arm计算产品事业群营销总监Ian Hutchinson表示,“Arm在显示技术领域有着丰富的发展历史。2013年,Arm通过并购成立了现在的显示IP产品线,随后,第一代显示处理器IP接踵而至。2016年,我们发布了Mali-DP650并完成了Apical的并购,将Assertive Display纳入产品阵营。为了应对显示技术在虚拟现实, 高动态范围, 多窗口模式以及众多面板与
[嵌入式]
ARM的开发步骤
1.做个最小系统板:如果你从没有做过ARM的开发,建议你一开始不要贪大求全,把所有的应用都做好,因为ARM的启动方式和dsp或单片机有所不同,往往会遇到各种问题,所以建议先布一个仅有Flash,SRAM或SDRAM、CPU、JTAG、和复位信号的小系统板,留出扩展接口。使最小系统能够正常运行,你的任务就完成了一半,好在ARM的外围接口基本都是标准接口,如果你已有这些硬件的布线经验,这对你来讲是一件很容易的事情。 2.写启动代码,根据硬件地址先写一个能够启动的小代码,包括以下部分:初始化端口,屏蔽中断,把程序拷贝到SRAM中;完成代码的重映射;配置中断句柄,连接到C语言入口。也许你看到给你的一些示例程序当中, bootloader
[单片机]
[ARM裸机程序][1]ARM裸机程序开发环境搭建
环境搭建 安装交叉编译工具链(arm-linux-gcc4.4.3) 详见Bolg。 交叉编译基础 arm-linux-gcc常用命令 1.查看头文件和库文件的搜索路径: arm-linux-gcc -print-libgcc-file-name 2.arm-linux-gcc常用命令 arm-linux-gcc -g -c led.S //-c为仅汇编操作 -g添加调试信息 arm-linux-ld -Tled.lds -o led.elf led.o //执行链接操作 arm-linux-readelf -a led.elf //查看elf文件头信息 arm-linux-objdump -D -S led.el
[单片机]
Arm与合肥高新技术产业开发区签署合作协议
2017年12月7日,中国 合肥 ——Arm今日宣布与合肥高新技术产业开发区签署两项合作协议,共同建设Arm物联网协同创新中心并设立Arm中国研究生院项目。双方将携手打造物联网 集成电路 产业的聚合效应,为产业今后的蓬勃发展培养人才,积极推进合肥电子产业创新生态圈的建设。   Arm全球执行副总裁兼大中华区总裁吴雄昂表示:“一直以来,Arm积极响应国家推动产业创新与升级的政策,持续加大在中国的战略部署和投入,紧跟双创人才与新工科等教育改革步伐,促进本地产业核心竞争力的形成。此次Arm与合肥高新技术产业开发区签署两项合作协议,以创新中心汇聚智慧方案,以研究生院培养领军人才的实践,是我们在国内积极建设本土产业生态的又一个具体举措。”
[嵌入式]
Linux 蓝牙系列 -- ARM-Linux蓝牙工具的移植
一 内核修改 ------------------------------------------------------------ 将内核的蓝牙做成模块形式。 并配置如下, Bluetooth subsystem support --- L2CAP protocol support SCO links support RFCOMM protocol support RFCOMM TTY support BNEP protocol support HIDP protocol support (NEW) Bluetooth d
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved