前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >嵌入式Linux驱动开发——汇编点灯

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

作者头像
小点点
发布2024-04-10 08:58:35
1190
发布2024-04-10 08:58:35
举报
文章被收录于专栏:小点点小点点

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

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

代码编写

使能时钟

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

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

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
.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。
代码语言:javascript
复制
	/* 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
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
/* 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, =0X10B0
    str r1,[r0]
设置GPIO

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

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
/* 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文件中,这里是生成的反汇编文件。
代码语言:javascript
复制
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

代码语言:javascript
复制
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文件用于管理编译、链接、转换和清理操作,具体作用如下:

  • 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,比较简单

代码语言:javascript
复制
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 DDR3
    V1.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

结果

在这里插入图片描述
在这里插入图片描述
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 嵌入式Linux驱动开发——汇编点灯
    • 代码编写
      • 使能时钟
      • 设置复用
      • 设置IO
      • 设置GPIO
    • 编译
      • makefile
        • 代码烧录
          • 结果
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
          http://www.vxiaotou.com