嵌入式Linux驱动开发——汇编点灯

嵌入式Linux驱动开发——汇编点灯

本文章开始记录学习嵌入式Linux的过程,使用的开发板是正点原子的阿尔法,以及左老师的书籍和视频。然后这个系列不会介绍基础知识(书上都有),主要是记录思考过程以及需要注意的点。

代码编写

使能时钟

🚀🚀这个地方的代码还是很简单的,主要就是去哪找CCM的地址,不过也不算难找,比如CCGR0,就是0x020c4068。

🚀🚀然后找到GPIO1的时钟由CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即可

在这里插入图片描述

.global _start  /* 全局标号 */
/** 描述:	_start函数,程序从此函数开始执行此函数完成时钟使能、*		  GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。*/
_start:/* 1、使能GPIO1时钟 */ldr r1, =0xFFFFFFFF 	ldr r0, =0X020C406C  	/* CCGR1 */str r1, [r0]
  1. .global _start: 这是一个全局标签,标记了程序的起始位置。
  2. _start: 这是程序的入口点,程序将从这里开始执行。
  3. ldr r1, =0xFFFFFFFF: 这一行使能CCGR1。
  4. ldr r0, =0X020C406C: 这一行将立即数 0X020C406C 加载到寄存器 r0 中,这个值是GPIO1的时钟寄存器的地址。
  5. str r1, [r0]: 这一行将寄存器 r1 中的值写入到地址为 r0 的内存位置,即将生成的掩码写入到GPIO1的时钟寄存器,从而启用GPIO1时钟。

设置复用

  1. ldr r0, =0X020E0068: 这一行将立即数 0X020E0068 加载到寄存器 r0 中,这个值是SW_MUX_GPIO1_IO03_BASE寄存器的地址,也是像上面那样找。这个寄存器用于控制GPIO1_IO03引脚的复用功能。
  2. ldr r1, =0X5: 这一行将立即数 0X5 加载到寄存器 r1 中。在i.MX系列处理器中,设置为5的MUX_MODE表示该引脚被设置为GPIO模式,即将该引脚设置为普通GPIO引脚功能。
  3. str r1, [r0]: 这一行将寄存器 r1 中的值写入到地址为 r0 的内存位置,即将MUX_MODE设置为5,从而将GPIO1_IO03引脚的复用功能设置为GPIO1_IO03。
	/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */ldr r0, =0X020E0068	/* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */ldr r1, =0X5		/* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */str r1,[r0]

在这里插入图片描述

设置IO

在这里插入图片描述

/* 3、配置GPIO1_IO03的IO属性	*bit 16:0 HYS关闭*bit [15:14]: 00 默认下拉*bit [13]: 0 kepper功能*bit [12]: 1 pull/keeper使能,开启上下拉*bit [11]: 0 关闭开路输出*bit [7:6]: 10 速度100Mhz*bit [5:3]: 110 R0/6驱动能力*bit [0]: 0 低转换率*/ldr r0, =0X020E02F4	/*寄存器SW_PAD_GPIO1_IO03_BASE */ldr r1, =0X10B0str r1,[r0]

设置GPIO

🚀🚀这个的地址有一点点不一样,在GPIO Memory Map/Register Definition里面。

在这里插入图片描述

/* 4、设置GPIO1_IO03为输出 */ldr r0, =0X0209C004	/*寄存器GPIO1_GDIR */ldr r1, =0X0000008		str r1,[r0]/* 5、打开LED0
* 设置GPIO1_IO03输出低电平
*/ldr r0, =0X0209C000	/*寄存器GPIO1_DR */ldr r1, =0		str r1,[r0]/** 描述:	loop死循环*/
loop:b loop 			

编译

🚀🚀这四条命令用于将汇编代码编译、链接、转换为二进制文件,并生成反汇编文件,具体作用如下:

  1. arm-linux-gnueabihf-gcc -g -c led.s -o led.o
    • arm-linux-gnueabihf-gcc:使用arm-linux-gnueabihf工具链中的gcc编译器。
    • -g:生成带有调试信息的目标文件。
    • -c:表示只编译,不链接。
    • led.s:源文件名,这里是汇编代码文件。
    • -o led.o:指定输出的目标文件名为led.o,这里是编译后的目标文件。
  2. arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
    • arm-linux-gnueabihf-ld:使用arm-linux-gnueabihf工具链中的ld链接器。
    • -Ttext 0X87800000:指定链接地址,这里设置程序的起始地址为0X87800000。
    • led.o:输入的目标文件名,即刚刚生成的目标文件。
    • -o led.elf:指定输出的可执行文件名为led.elf,这里是链接后的可执行文件。
  3. arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
    • arm-linux-gnueabihf-objcopy:使用arm-linux-gnueabihf工具链中的objcopy工具。
    • -O binary:指定目标文件的格式为二进制。
    • -S:去除调试符号和调试信息。
    • -g:保留全局符号信息。
    • led.elf:输入的可执行文件名,即刚刚生成的可执行文件。
    • led.bin:指定输出的二进制文件名为led.bin,这里是转换后的二进制文件。
  4. arm-linux-gnueabihf-objdump -D led.elf > led.dis
    • arm-linux-gnueabihf-objdump:使用arm-linux-gnueabihf工具链中的objdump工具。
    • -D:显示反汇编代码。
    • led.elf:输入的可执行文件名,即刚刚生成的可执行文件。
    • > led.dis:将反汇编的结果输出到led.dis文件中,这里是生成的反汇编文件。
kali@ubuntu:~/linux/driver/01_leds$ arm-linux-gnueabihf-gcc -g -c led.s -o led.o
kali@ubuntu:~/linux/driver/01_leds$ arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
kali@ubuntu:~/linux/driver/01_leds$ arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
kali@ubuntu:~/linux/driver/01_leds$ arm-linux-gnueabihf-objdump -D led.elf > led.dis

makefile

led.bin:led.sarm-linux-gnueabihf-gcc -g -c led.s -o led.oarm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elfarm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.binarm-linux-gnueabihf-objdump -D led.elf > led.dis
clean:rm -rf *.o led.bin led.elf led.dis

🚀🚀这个Makefile文件用于管理编译、链接、转换和清理操作,具体作用如下:

  • led.bin: led.s:定义了一个目标文件led.bin,它依赖于led.s文件。也就是说,当led.s文件被修改时,会触发后续的编译、链接、转换操作。

  • arm-linux-gnueabihf-gcc -g -c led.s -o led.o:编译led.s文件为目标文件led.o,这里使用了arm-linux-gnueabihf工具链中的gcc编译器,并且指定生成带有调试信息的目标文件。

  • arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf:链接led.o文件为可执行文件led.elf,这里使用了arm-linux-gnueabihf工具链中的ld链接器,并且指定了链接地址为0X87800000。

  • arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin:将led.elf文件转换为二进制文件led.bin,这里使用了arm-linux-gnueabihf工具链中的objcopy工具,并且指定了输出的文件格式为二进制。

  • arm-linux-gnueabihf-objdump -D led.elf > led.dis:生成反汇编文件led.dis,这里使用了arm-linux-gnueabihf工具链中的objdump工具,并且指定了显示反汇编代码。

  • clean::定义了一个伪目标clean,用于清理生成的目标文件和中间文件。

  • rm -rf *.o led.bin led.elf led.dis:删除所有的目标文件和生成的二进制文件,以及反汇编文件。

代码烧录

🚀🚀这个就是使用imxdownload,比较简单

kali@ubuntu:~/linux/driver/01_leds$ ./imxdownload led.bin /dev/sdb
I.MX6ULL bin download software
Edit by:zuozhongkai
Date:2019/6/10
Version:V1.1
log:V1.0 initial version,just support 512MB DDR3V1.1 and support 256MB DDR3
file led.bin size = 88Bytes
Board DDR SIZE: 512MB
Delete Old load.imx
Create New load.imx
Download load.imx to /dev/sdb  ......
6+1 records in
6+1 records out
3160 bytes (3.2 kB, 3.1 KiB) copied, 0.0569602 s, 55.5 kB/s

结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/599824.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】继承总结

一、前言 我们众所周知的C三大特性分别为:封装、继承、多态。 封装就是将接口实现统一化,隐藏那些不同的地方,在上层函数调用体现的方式一样,如各种容器的迭代器iterator,尽管底层实现的方式不同,但是在使用…

rsync 远程同步 基础介绍

目录 一 Rsync 简介 1,rsync 是什么 2,rsync 中的发起端 同步源 3,同步方式 4,备份的方式 5,常用Rsync命令 6, 配置源的两种表达方法 7,rsync做本地复制时与cp 对比 二&#xff…

递归学习第一个课

一、递归定义 基本定义 函数自己调用自己(通俗第一印象)大问题可以拆分小问题(拆分,边界)大问题与小问题的关系(递归关系) 为什么拆分小问题? 小问题更容易求解大问题与小问题内部…

qt自定义窗口在拖动过程中出现抖动且拖动后位置看上去不对

自定义窗口拖动 引言开发环境关键性代码运行结果原因分析改进代码运行结果globalPos()globalPosition()再次修改代码运行结果区别 引言 本文旨在一个问题的记录:自定义窗口拖动的过程中,窗口不能很好的跟随鼠标移动,此外会出现窗口拖动时抖动…

day03 51单片机

51单片机学习 1 模块化编程 1.1 什么是模块化编程 随着我们的代码越来越复杂,我们的main.c越来越长,阅读性也越来越差。如果将来开始做项目,我们可能要同时操作好几个模块,这种情况下我们无法再把代码写到同一个文件,而是要分模块管理代码。 具体实现方法,就是将源码…

在linux服务器上安装anaconda

遇到问题: 在linux服务器中查看当前有哪些虚拟环境,conda环境用不了,anaconda没有安装,所以要在linux服务器中安装虚拟环境 解决步骤如下: 1.首先下载anaconda的Linux版本的安装包 方法1:官网下载&#…

爬虫逆向非对称加密和对称加密案例

注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!! 案例--aHR0cHM6Ly9jcmVkaXQuaGxqLmdvdi5jbi94eWdzL3l6d2ZzeHF5bWQv 第一步:分析页面、请求…

C#学习笔记9:winform上位机与西门子PLC网口通信_上篇

今日继续我的C#学习笔记,今日开始学习打开使用千兆网口来进行与西门子PLC的通信: 文章提供整体代码、解释、测试效果截图、整体测试工程下载: 主要包含的知识有:下载NuGet程序包、西门子PLC及通信协议、搭建虚拟的S7通信仿真环境…

【游戏分析】某游戏 无敌+代码

0x1 线索: 血量 1,开启DXF 2. OD附加 3. ce搜索 我们要实现无敌的思路是,把减去血量的逻辑给移除,这样就达到了无敌的效果 我们先找到血量的地址 535,改变一次血量,前面2个绿色的都是GameRpcs.dll中的地址,我们忽略掉。.. 这2个&#xff…

【服务器uwsgi + flask + nginx的搭建】

目录 服务器uwsgi flask nginx的搭建1. 安装必要的软件2. 启动nginx服务3. 测试Nginx4. 配置uwsgi和flask5. 配置nginx 服务器uwsgi flask nginx的搭建 1. 安装必要的软件 安装Python、uWSGI、Flask 和 Nginx。 # Ubuntu 安装命令 sudo apt-get update sudo apt-get ins…

MySQL-主从复制:概述、原理、同步数据一致性问题、搭建流程

主从复制 1. 主从复制概述 1.1 如何提升数据库并发能力 一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是采用数据库集群的方案,做主从架构、进行读写分离,这样同样可以提升数据库的并…

【引子】C++从介绍到HelloWorld

C从介绍到HelloWorld 一、C的介绍1. 简介2. 应用场景3. C的标准![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e3efb0f207f647729b92c0b5bcd4b330.png)4. C的运行过程 二、Visual Studio的安装1. 什么是Visual Studio2. Visual Studio的安装 三、完成HelloWorld1.…