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

news2024/11/17 21:45:12

 前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]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, cpsr
	bic r0, 0x1f	@清零 cpsr M[4:0]
	orr r0, 0x13	@cpsr或上0x13,也就是svc模式
	msr cpsr, r0	@写cpsr


	/* 准备C环境 */
	ldr sp, =0x80200000
	b 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_end
	mov 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, cpsr
	bic 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 After
	cmp r0, r1			@比较r0, r1
	ble bss_loop		@如果r0小于等于r1,继续执行循环


	/* 准备C环境 */
	ldr sp, =0x80200000
	b 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 外设时钟寄存器的值。

 

3. 编译

4.烧录SD卡验证

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.coloradmin.cn/o/1637457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云开源大模型开发环境搭建

ModelScope是阿里云通义千问开源的大模型开发者社区,本文主要描述AI大模型开发环境的搭建。 如上所示,安装ModelScope大模型基础库开发框架的命令行参数,使用清华大学提供的镜像地址 如上所示,在JetBrains PyCharm的项目工程终端控…

【IDEA】IDEA自带Maven/JDK,不需要下载

IDEA是由Java编写的,为了保证其运行,内部是自带JDK的。IDEA 2021 及 之后的版本是自带Maven的: 视频连接: https://www.bilibili.com/video/BV1Cs4y1b7JC?p4&spm_id_frompageDriver&vd_source5534adbd427e3b01c725714cd…

3-4STM32C8T6按键控制LED开与关

实物接线如下: 为了代码的简洁性,这里需要对LED与KEY进行封装如下: #include "stm32f10x.h" // Device headervoid LED_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GP…

粤嵌gec6818开发板-播放视频、音频文件(管道文件控制)

前段时间做了一个项目,用到了linux环境下gec6818开发板播放视频、音频文件,在这里给大家分享一下。 这里使用的方法是利用mplayer播放器进行播放,首先先给开发板装上mplayer播放器,这里就不详细说明了。 我用的是管道文件来控制视…

如何解决DA14531编译工程出现大量报错的问题

在编译DA14531某个工程时,在这台电脑可以编译,另外一台电脑就编译不过,出现很多错误问题。那要怎样处理呢? 建议安装新MDK版本 可能是MDK版本问题,在不同的电脑安装不同的MDK版本,用新的版本可以编译通过&…

ZABAPGIT问题,导入github上的程序包时报 DBSQL_DUPLICATE_KEY_ERROR

跟踪程序发现在94050行 INSERT seocompotx FROM TABLE it_descriptions 报的错 刚开始,不想着改动他,把seocompotx 表的数据做下指定清楚,但是5次清楚后,果断注释掉 改成 MODIFY seocompotx FROM TABLE it_descriptions。 在用…

Winfrom —— 计算阶乘

首先搭建一个界面 创建listBox输入框进行输入内容 界面图如下 计算按钮的事件 private void button1_Click(object sender, EventArgs e) {if (textBox1.Text.Length 0){textBox1.Text "";}else{int n 1;int sum 1;n Convert.ToInt32(textBox1.Text);for (; n…

成像测井基础-1

一、成像测井系统简介 成像测井是一种能探测地层的某个特性(如岩石成分、孔隙度、渗透率)在以井轴为垂直坐标(z)、以井径为径向坐标、以方位角为方向坐标(θ)的柱状坐标系(r,θ,z )中分布的测井方法,且可以按井壁的展开平面或沿某个方位的剖面进行图像显…

Hi3519AV100 处理器⾼速全局快⻔相机

⾼速全局快⻔相机采⽤ 1英⼨全局快⻔ Sensor,⽀持 H.264/H.265 编码,8 百万 分辨率模式下最⾼帧率可达 50 帧/秒,1080P 模式下最⾼帧率可达 120 帧/秒。主控采⽤ Hi3519AV100 处理器,集成 2 Tops AI 算⼒ NPU ,⽀持⼤…

必应广告投放怎么做?怎么开户推广?

今天搜索引擎广告依旧是企业提升品牌知名度、吸引潜在客户的关键渠道之一,必应Bing,作为全球第二大搜索引擎,不仅拥有庞大的用户基础,更以其精准的定向能力和高效的转化效率,成为众多企业拓展市场的优选平台。 一、必…

Mysql_数据库事务

文章目录 😊 作者:Lion J 💖 主页: https://blog.csdn.net/weixin_69252724 🎉 主题: MySQL__事务) ⏱️ 创作时间:2024年04月26日 ———————————————— 这里写目…

基于python的舞蹈经验分享交流网站django+vue

1.运行环境:python3.7/python3.8。 2.IDE环境:pycharmmysql5.7/8.0; 3.数据库工具:Navicat11 4.硬件环境:windows11/10 8G内存以上 5.数据库:MySql 5.7/8.0版本; 运行成功后,在浏览器中输入&am…

Nginx负载均衡主备模式

1. 背景 使用Nginx代理后端服务,有时候某些服务是不能使用多台负载均衡,但又想保障高可用,所以采用主备模式,记录如下: 2. 参考 nginx 负载均衡Nginx-负载均衡-后端状态max_conns、down、backup、max_fails、fail_t…

Docker: 如何不新建容器 修改运行容器的端口

目录 一、修改容器的映射端口 二、解决方案 三、方案 一、修改容器的映射端口 项目需求修改容器的映射端口 二、解决方案 停止需要修改的容器 修改hostconfig.json文件 重启docker 服务 启动修改容器 三、方案 目前正在运行的容器 宿主机的3000 端口 映射 容器…

修改Docker容器内文件的三种方式

说明:本文介绍修改Docker容器内文件的三种方式 方式一:直接修改 敲下面的命令,进入Docker容器,如mysql docker exec -it mysql /bin/bash修改mysql的配置文件,/etc/my.cnf vim /etc/my.cnf如下,如果vim…

【机器学习】基于扩散模型的文本到音频生成:突破数据局限,优化音频概念与实践顺序

基于扩散模型的文本到音频生成:突破数据局限,优化音频概念与时间顺序 一、现有模型的局限与挑战二、偏好数据集的构建与利用三、Diffusion-DPO损失的应用与模型微调四、实例与代码展示五、总结与展望 随着数字化技术的迅猛发展,音乐和电影行业…

霍纳法则与多项式求值问题

目录 多项式求值问题引入 什么是霍尔法则 多项式求值问题引入 题目链接:多项式求值 对于多项式求值问题,例如多项式: 常规的计算方法是每一项单独计算,即先计算,再接着计算,以此类推,最后求和即可&…

排序-八大排序FollowUp

FollowUp 1.插入排序 (1).直接插入排序 时间复杂度:最坏情况下:0(n^2) 最好情况下:0(n)当数据越有序 排序越快 适用于: 待排序序列 已经基本上趋于有序了! 空间复杂度:0(1) 稳定性:稳定的 public static void insertSort(int[] array){for (int i 1; i < array.length; i…

鸿蒙学习1概况

鸿蒙学习1相关概念 前言相关概念Stage 模型1. AbilityStage2. UIAbility组件和ExtensionAbility组3. WindowStage4. Context 事件传递UIAbility组件与UI的数据同步UIAbility组件间交互&#xff08;设备内&#xff09; 进程模型线程模型 前言 有时间多看官网&#xff0c;官网的…

Android项目中添加Dobby(inline hook)

2024技术交流群 ​ 课程地址 鸿蒙(HarmonyOS)APP开发实战课程(入门到精通) https://edu.csdn.net/course/detail/39448 1.Ubuntu编译Dobby 2.Dobby框架的介绍 Dobby是一个轻量级、多平台、多架构的inline hook框架&#xff0c;它使用起来轻快便捷&#xff0c;支持Windows/ma…