正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-9.1-LED灯(模仿STM32驱动开发实验)

 前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第9.1讲” 的读书笔记。第9.1 介绍了

0.  SMT32 格式的LED驱动程序示例

对于STM32而言,使用一个结构体将一个外设的所有寄存器都放在一起,这样就相当于寄存器抽象为外设了。

1. 设计C语言 LED 灯程序,模仿STM32 LED灯驱动程序

在结构体中添加寄存器的时候,一定要注意寄存器的连续性,如果不连续的话要添加寄存器占位。

2. 模仿STM32驱动程序进行源码编写

2.1 创建 imx6u.h 文件,把寄存器组织为结构体

创建 imx6u.h 文件,并模仿STM32驱动程序把寄存器组织为结构体,我们先根据《IMX6ULL参考手册.pdf》中寄存器的地址,在 imx6u.h 文件中的寄存器基地址 BASE。

查找 《IMX6ULL参考手册.pdf》中CCM寄存器的起始基地址,并定义为宏 '#typedef CCM_BASE':

查找 《IMX6ULL参考手册.pdf》中CCM_ANALOG 寄存器的起始基地址,并定义为宏 '#typedef CCM_ANALOG_BASE':

查找 《IMX6ULL参考手册.pdf》中 IOMUXC_SW_MUX  寄存器的起始基地址,并定义为宏 '#typedef IOMUXC_SW_MUX_BASE':

查找 《IMX6ULL参考手册.pdf》中 IOMUXC_SW_PAD  寄存器的起始基地址,并定义为宏 '#typedef IOMUXC_SW_PAD_BASE': 

同样方法,查找 《IMX6ULL参考手册.pdf》中GPIO1~GPIO5的寄存器起始基地址,并 定义为宏 '#define GPIOx_BASE' :

参考正点原子提供的第“9.1讲”视频教程的附带源码目录中的 'imx6u.h' 文件和STM32 LED驱动程序文件中,把寄存器组织成 C语言结构体的方法,在 mx6u.h 文件中定义 I.MX6U 的寄存器C语言结构体定义。

定义C语言结构体的时候,有一些细节需要注意:

  1. 把 I.MX6U 外设寄存器地址组成C语言结构体,利用了C语言结构体中结构体成员地址依次递增的特性。
  2. 所以需要注意《IMX6ULL参考手册.pdf》文档中,I.MX6U 的外设寄存器地址是不是连续的,特别需要注意的是,I.MX6U 的外设寄存器从 base 基地址开始大部分是连续的但也有几个寄存器的地址中间有不连续的,寄存器地址跳过了几个地址,对于这种情况需要再C语言结构体定义以留下占位成员。

例如, CCM 寄存器其里的如下两个寄存器之间是不连续了,两个寄存器之间间隔了 8个byte的空间。

按照 《IMX6ULL参考手册.pdf》中 “18.6 CCM Memory Map/Register Definition” 中 CCM 寄存器的地址顺序,在 imx6u.h 中定义CCM 寄存器结构体。每个CCM寄存器的名字作为结构体中的一个成员,结构体体总成员的名字按照手册中寄存器地址的顺序排序。

2.2 编写 start.s 汇编文件

同上一讲中的“C语言LED灯驱动程序”中准备C语言运行环境的 start.s 汇编文件,本节中的 start.s 汇编文件通上一讲中的汇编文件内容一样,需要做如下两步:

  1. 设置CPSR寄存器,让处理器运行在SVC模式
  2. 设置SP寄存器,准备C语言运行环境
	/* 进入svn模式 */mrs r0, cpsrbic r0, 0x1f	@清零 cpsr M[4:0]orr r0, 0x13	@cpsr或上0x13,也就是svc模式msr cpsr, r0	@写cpsr/* 准备C环境 */ldr sp, =0x80200000b main

在本节中,新增加了清零最终链接文件中 .bss 段的内容。使用ARM汇编语言来清零最终文件加载到内存后指定起始位置和结束位置之间的地址区间,这里我们会用到 ARM 汇编的如下指令: 

  • cmp 指令,比较两个寄存器的值大小
  • ble 指令,当状态寄存器CPSR 也就是上一步 CMP 指令比较结果为LE(Less Equal)小于等于时跳转到指定位置。
  • stmia 指令,写寄存器内容到内存地址中,ia 后缀的含义是 increse -after ,即先将寄存器写到指定地址,然后在让地址+4 (也就是 incrase after,执行后地址增长)

使用ARM汇编清零内存中 .bss 段的时候,我们也需要用到定义在描述文件链接方式的链接文件 .lds 里的两个符号 '__bss_strart', '__bss_end'。这两个符号是定义在链接脚本里的两个变量,我们在 start.s 汇编文件中使用这两个变量,__bss_start 的值等于 .bss 段的起始地址,__bss_end 的值等于 .bss 段的结束地址。

.global _bss_start.world __bss_start		@使用连接脚本 imx6u.lds 中定义的符号 __bss_start.global _bss_end.world __bss_end		@使用连接脚本 imx6u.lds 中定义的符号 __bss_end/* 清零 .bss */ldr r0, _bss_start	ldr r1, _bss_endmov r2, #0
bss_loop:stmia r0!, {r2}cmp r0, r1	ble bss_loop

 最终的 start.s 链接文件的完整内容如下


.global _start
.global _bss_start.world __bss_start		@使用连接脚本 imx6u.lds 中定义的符号 __bss_start.global _bss_end.world __bss_end		@使用连接脚本 imx6u.lds 中定义的符号 __bss_end_start:/* 进入svn模式 */mrs r0, cpsrbic r0, 0x1f	@清零 cpsr M[4:0]orr r0, 0x13	@cpsr或上0x13,也就是svc模式msr cpsr, r0	@写cpsr/* 清零 .bss */@ldr r0, =_bss_start	@语法错误ldr r0, _bss_start		@正确的语法就是直接使用_bss_start符号,@不是像之前写立即数到寄存器一样需要在立即数前面加上符号'='@ldr r1, =_bss_end		@语法错误ldr r1, _bss_end//ldr r2, =0x0			@ldr指令传送立即数到寄存器r0,立即数前面加上符号'='mov r2, #0				@mov指令传送立即数到寄存器r0,立即数前面加上符号'#'bss_loop://ldmia r0!, {r2}	@语法错误,正确应该是 stmia,因为目的是写寄存器的值到内存中,所以应该是汇编 stm (store)stmia r0!, {r2}		@ia:Increase Aftercmp r0, r1			@比较r0, r1ble bss_loop		@如果r0小于等于r1,继续执行循环/* 准备C环境 */ldr sp, =0x80200000b main
2.3 编写 .lds 链接脚本

编写链接脚本文件,链接脚本.lds 和上一节内容完全一样,没有差异。

SECTION {. = 0x87800000;.text : {start.o*(.text)}.data : { *(.data) }.rodata : { *(.rodata*) }__bss_start = .;.bss : { *(.bss) *(COMMON) }__bss_end = .;
}
2.4 编写 man.c 文件

编写 man.c 文件,使用定义的I.MX6ULL寄存器结构体,在这一讲中我们已经参考STM32驱动程序中寄存器的组织方式,讲 I.MX6ULL 处理器手册中的寄存器根据寄存器的用途组织为了C语言结构体,利用C语言结构体提内成员变量地址一次递增的特性,在给出了寄存器组的起始基地址之后,使用C语言指针访问结构体的成员,就访问到 ‘基地址+偏移’ 位置上的I.MX6ULL 寄存器的地址。我们在 imx6u.h 头文件中把 I.MXULL 的我们用到的寄存器组,定义为一下几个寄存器集合组:

  • CCM 寄存器组
  • CCM_ANALOG 寄存器组
  • IOMUX_SW_MUX 寄存器组
  • IOMUX_SW_PAD 寄存器组
  • GPIO 寄存器组

我们在 main.c C语言源文件中使用 'CCM->CCGR0 = 0xFFFF_FFFF' 就可以写I.MX6ULL 的 CCM_CCGR0 外设时钟寄存器的值。使用C语言结构体来操作寄存器,修改之后的main.c源码如下:

#include "imx6u.h"void clk_init(void)
{CCM->CCGR0 = 0xFFFFFFFF;CCM->CCGR1 = 0xFFFFFFFF;CCM->CCGR2 = 0xFFFFFFFF;CCM->CCGR3 = 0xFFFFFFFF;CCM->CCGR4 = 0xFFFFFFFF;CCM->CCGR5 = 0xFFFFFFFF;CCM->CCGR6 = 0xFFFFFFFF;
}void led_init(void)
{IOMUX_SW_MUX->GPIO1_IO03 = 0x5;     /*服用GPIO1_IO03为GPIO模式*/IOMUX_SW_PAD->GPIO1_IO03 = 0x10B0;  /*设置GPIO1_IO03电气特性*/GPIO1->GDIR = 0x08;                 /*bit3设置为1,GPIO为输出OUTPUT*/GPIO1->DR = 0x0;                    /*GPIO输出第电平*/
}void led_on(void)
{GPIO1->DR &= ~(1<<3);                    /*bit3清零*/
}void led_off(void)
{GPIO1->DR |= (1<<3);                    /*bit3设置*/
}void short_delay(unsigned int n)
{while(n--){;}
}/* sleep 1ms */
void delay(unsigned int m){while(m--){short_delay(0x7ff);}
}int main(void)
{clk_init();led_init();while(1){led_on();delay(50);led_off();delay(50);}return 0;
}

3. 编译

修改Makefile,之间我们总是输入ARM交叉编译工具链的完整路径来编译源码,例如,'arm-linux-gnueabifh-gcc', 'arm-linux-gnueabihf-ld' 来进行编译,每一次输入完整的路径名比较麻烦,我么可可以在Makefile中定义变量的方式来减少每次输入的路径名长度。

CROSS=arm-linux-gnueabihf-
CC=$(CROSS)gcc
LD=$(CROSS)ld
OBJCOPY=$(CROSS)objcopy
OBJDUMP=$(CROSS)objdumpobjs :=  start.o main.oledc.bin : $(objs)arm-linux-gnueabihf-ld -Timx6u.lds -o ledc.elf $^arm-linux-gnueabihf-objcopy -O binary -S ledc.elf ledc.binarm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis%.o : %.c#arm-linux-gnueabihf-gcc -nostdlib -c -o $@ $<$(CC) -nostdlib -c -o $@ $<%.o : %.s #arm-linux-gnueabihf-gcc -nostdlib -c -o $@ $<$(CC) -nostdlib -c -o $@ $<clean:rm -rf *.o ledc.bin ledc.elf imxdownloadrm -rf ledc.dis

在Makefile里,我们定义了变量 'CROSS=arm-linux-gnueabihf-',然后定义了变量 'LD=$(CROSS)LD', 'OBJCOPY=$(CROSS)objcoy', 'CC=$(CROSS)cc',然后使用定义的变量 '$(LD)', '$(CC)’,这样就不用输入完整的交叉编译工具名了。

4.烧录SD卡验证

执行'make' 编译出来 ledc.bin之后,使用 imxdownload 烧录编译出来的 .bin 文件到SD卡中,把SD卡插到正点原子 I.MX6U APLHA/Mini 开发板验证 LED 灯否正产闪烁。

我验证的结果是,LED灯使用模仿STM32的方式使用C语言结构体来组织I.MX6U 寄存器后,LED灯可以正常的闪烁。

5. 总结:

5.1 VSCode Compare插件

使用 VSCode的 compare 插件来比较两个文本文件的差异,使用方法步骤如下:

  1. 在VSCode中按下 "F1" 键
  2. 在出现的搜索框里输入 "compare" 进行搜索,vscode会自动进行补全。
  3. 选择 "Compare With",打开需要比较的文件,进行比较两个文本文件的差异。

5.2 VSCode TabNine AI 自动代码补全

使用 VSCode 插件 TabNine AI 智能补全工具,实现自动代码 AI 人工智能补全。TabNine 分为收费版和免费版,收费版提供基本代码AI补全功能,收费版提供高级的AI功能。TabNine 会分析你写的源码文件自动提供AI代码补全,也就是你写的源码越多 TabNine AI 代码补全就越精准。实际使用了一些 TabNine AI 代码补全超级好用,一用一个不吱声,推荐。

5.3 发现正点原子示例源码 imx6u.h 的一点小错误

发现了正点原子"9.1讲 模仿STM32驱动程序”视频教程提供示例源码 imx6u.h 里的一点小错误:在 《IMX6ULL参考手册.pdf》手册中章节“18.7 CCM Analog Memory Map/Register Definition”里面,手册定义了 6 个和 AUTO 相关的寄存器,但是在正点原子提供的示例源码 “ imx6u.h” 只有5个AUTO寄存器,丢失了一个 "AUDO_NUM" 寄存器。

哈哈,也算本人发现的一点小错误。正点原子的示例源码和视频教程还是质量很高的,根正点原子哥点赞。

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

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

相关文章

MySQL技能树学习——数据库组成

数据库组成&#xff1a; 数据库是一个组织和存储数据的系统&#xff0c;它由多个组件组成&#xff0c;这些组件共同工作以确保数据的安全、可靠和高效的存储和访问。数据库的主要组成部分包括&#xff1a; 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a; 数据库管理系…

eNSP-抓包解析HTTP、FTP、DNS协议

一、环境搭建 1.http服务器搭建 2.FTP服务器搭建 3.DNS服务器搭建 二、抓包 三、http协议 1.HTTP协议&#xff0c;建立在TCP协议之上 2.http请求 3.http响应 请求响应报文参考&#xff1a;https://it-chengzi.blog.csdn.net/article/details/113809803 4.浏览器开发者工具抓包…

爬虫自动化之drissionpage实现随时切换代理ip

目录 一、视频二、dp首次启动设置代理三、dp利用插件随时切换代理一、视频 视频直接点击学习SwitchyOmega插件使用其它二、dp首次启动设置代理 from DrissionPage import ChromiumPage, ChromiumOptions from loguru

Flask教程1:flask框架基础入门,路由、模板、装饰器

文章目录 一、 简介二、 概要 一、 简介 Flask是一个非常小的Python Web框架&#xff0c;被称为微型框架&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&#xff0c;也意味着我们需要学习各…

C++设计模式-创建型设计模式

设计模式 设计模式是什么 设计模式是指在软件开发中&#xff0c;经过验证的&#xff0c;用于解决在特定环境下&#xff0c;重复出现的&#xff0c;特定问题的解决方案&#xff1b;其实就是解决问题的固定套路。但是要慎用设计模式&#xff0c;有一定的工程代码量之后用它比较…

[每日AI·0501]GitHub 版 Devin,Transformer的强力挑战者 Mamba,Sora 制作细节与踩坑,OpenAI 记忆功能

AI 资讯 国资委&#xff1a;加快人工智能等新技术与制造全过程、全要素深度融合GitHub版 Devin 上线&#xff0c;会打字就能开发应用&#xff0c;微软 CEO&#xff1a;重新定义 IDE在12个视频理解任务中&#xff0c;Mamba 先打败了 TransformerSora 会颠覆电影制作吗&#xff…

信息泄露.

一&#xff0c;遍历目录 目录遍历&#xff1a;没有过滤目录相关的跳转符号&#xff08;例如&#xff1a;../&#xff09;&#xff0c;我们可以利用这个目录找到服务器中的每一个文件&#xff0c;也就是遍历。 tipe&#xff1a;依次点击文件就可以找到flag 二&#xff0c;phpi…

LNMP部署及应用(Linux+Nginx+MySQL+PHP)

LNMP 我们为什么采用LNMP这种架构? 采用Linux、PHP、MySQL的优点我们不必多说。 Nginx是一个小巧而高效的Linux下的Web服务器软件&#xff0c;是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的&#xff0c;已经在一些俄罗斯的大型网站上运行多年&#xff0c;目…

服务器被攻击,为什么后台任务管理器无法打开?

在服务器遭受DDoS攻击后&#xff0c;当后台任务管理器由于系统资源耗尽无法打开时&#xff0c;管理员需要依赖间接手段来进行攻击类型的判断和解决措施的实施。由于涉及真实代码可能涉及到敏感操作&#xff0c;这里将以概念性伪代码和示例指令的方式来说明。 判断攻击类型 步…

18、ESP32 ESP-NOW 点对点通信

ESP-NOW 是乐鑫自主研发的无连接通信协议&#xff0c;具有短数据包传输功能。该协议使多个设备能够以简单的方式相互通信。 ESP-NOW 功能 ESP-NOW 支持以下功能&#xff1a; 加密和未加密的单播通信;混合加密和未加密的对等设备;最多可携带 250 字节 的有效载荷;发送回调功能…

Python | Leetcode Python题解之第66题加一

题目&#xff1a; 题解&#xff1a; class Solution:def plusOne(self, digits: List[int]) -> List[int]:n len(digits)for i in range(n - 1, -1, -1):if digits[i] ! 9:digits[i] 1for j in range(i 1, n):digits[j] 0return digits# digits 中所有的元素均为 9retu…

阿里云API网关 产品的使用笔记

阿里云的产品虽多&#xff0c;还是一如既往的一用一个看不懂&#xff0c;该模块的文档依旧保持“稳定”发挥&#xff0c;磕了半天才全部跑通。 用阿里云API网关的原因是&#xff0c;在Agent中写插件调用API的时候&#xff0c;需要使用Https协议&#xff0c;又嫌搞备案、证书等事…

ASV1000视频监控平台:通过SDK接入海康网络摄像机IPC

目录 一、为何要通过SDK接入海康网络摄像机 &#xff08;一&#xff09;海康网络摄像机的SDK的功能 1、视频采集和显示 2、视频存储 3、视频回放 4、报警事件处理 5、PTZ控制 6、自定义设置 7、扩展功能 &#xff08;二&#xff09;通过SDK接入的好处&#xff08;相对…

ARP欺骗使局域网内设备断网

一、实验准备 kali系统&#xff1a;可使用虚拟机软件模拟 kali虚拟机镜像链接&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 注意虚拟机网络适配器采用桥接模式 局域网内存在指定断网的设备 二、实验步骤 打开kali系统命令行&#xff1a;ctrlaltt可快…

nginx--配置文件

组成 主配置文件&#xff1a;nginx.conf 子配置文件&#xff1a;include conf.d/*.conf 协议相关的配置文件&#xff1a;fastcgi uwsgi scgi等 mime.types&#xff1a;⽀持的mime类型&#xff0c;MIME(Multipurpose Internet Mail Extensions)多用途互联⽹网邮件扩展类型&…

Linux服务器常用命令总结

view查找日志关键词 注意日志级别&#xff0c;回车后等一会儿&#xff0c;因为文件可能比较大加载完需要时间 当内容显示出来后&#xff0c;使用“/关键词”搜索 回车就能搜到&#xff0c;n表示查找下一个&#xff0c;N表示查找上一个 find 查找 find Family -name book …

CBCGPStatic 显示图片

初始化代码&#xff1a; // 1、 m_DataPic.SetPicture(IDB_BITMAP1, TRUE, TRUE); //2、 CString strPath L"C:\\Users\\14713\\Desktop\\Example\\Example\\res\\pic.png"; m_DataPic.SetPicture(strPath, TRUE, TRUE); 资源中&#xff1a; / // //…

MVP+敏捷开发

MVP敏捷开发 1. 什么是敏捷开发&#xff1f; 敏捷开发是一种软件开发方法论&#xff0c;旨在通过迭代、自组织的团队和持续反馈&#xff0c;快速响应需求变化并交付高质量的软件。相较于传统的瀑布模型&#xff0c;敏捷开发强调灵活性、适应性和与客户的紧密合作。敏捷开发方…

深入 Django 模型层:数据库设计与 ORM 实践指南

title: 深入 Django 模型层&#xff1a;数据库设计与 ORM 实践指南 date: 2024/5/3 18:25:33 updated: 2024/5/3 18:25:33 categories: 后端开发 tags: Django ORM模型设计数据库关系性能优化数据安全查询操作模型继承 第一章&#xff1a;引言 Django是一个基于Python的开源…

chrome和drive安装包路径

Chrome for Testing availability (googlechromelabs.github.io) 下载Stable下面的包哈