Linux操作系统-汇编LED驱动程序基础

一、汇编LED原理分析

        IMX6ULL-LED灯硬件原理分析:

        1、使能时钟,CCGR0-CCGR6这7个寄存器控制着IMX6ULL所有外设时钟的使能。为了简单,设置CCGR0-CCGR6这7个寄存器全部为0XFFFFFFFF,相当于使能全部外设时钟。(在IMX6ULL芯片参考手册CCM篇章介绍)

        2.IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit-0设置为0101,这样GPIO1_IO03就复用为GPIO。

​编辑

              3.寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO1_IO03的电器属性。

        4.Pin配置GPIO功能:设置输入输出功能,设置GPIOx_GDIR寄存器bit3为1,也就是输出寄存器。设置GPIOx_DR寄存器bit3为1,表示输出高电平,为0表示输出低电平。

 三、GNU汇编简介

        1.GNU汇编常用伪操作

        label:标号,表示地址位置,有些指令前面可以会有标号,这样可以通过这个标号得到指令的地址,标号也可以用来表示数据地址。注意label后面的“ :”,任何一 " : "结尾的标识符都会被认为是一个标号。

        instruction:指令,也就是汇编指令或伪代码

        @:注释符号

        comment:注释内容

        .section:伪操作用来定义一个段,使用 .section来定义一个段,每个段以段名开始,以下一段名或者文件结尾结束,汇编系统定义了一些段名:

                      .text:表示代码段

                      .data:初始化的数据段

                      .bss: 未初始化到数据段

                      .ridata: 只读数据段

        _start:汇编程序的默认入口标号是

        .byte:定义一个单字节数据

        .short:定义双字节数据

        .long:定义一个4字节数据

        .equ:赋值语句,例如.equ num,0x12 表示num=0x12

        .align:数据字节对齐

        .end:表示源文件结束

        .global:定义一个全局符号

        注意! ARM中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用
小写,但是不能大小写混用。

        2.GNU汇编函数

        GNU汇编同样也支持函数,函数格式如下:

函数名:函数体返回语句   @返回语句不是必须的

        3.常用汇编指令

           3.1处理器内部数据传输指令

           ①、将数据从一个寄存器传递到另外一个寄存器。②、将数据从一个寄存器传递到特殊寄存器,如 CPSR SPSR 寄存器。③、将立即数传递到寄存器。

           MOV指令:MOV指令用于将数据从一个寄存器拷贝到另外一个寄存器,或者将一个立即数传递到寄存器里面,使用示例如下:

MOV R0,R1 @表示将寄存器R1中的数据传递给R0即:R0=R1
MOV R0,#0X12 @表示将立即数0x12传递给R0寄存器即:R0=0x12 

         MRS指令:指令用于将特殊寄存器 (如 CPSR和 SPSR)中的数据传递给通用寄存器,要读取特殊寄存器的数据只能使用 MRS指令!使用示例如下:

MRS R0,CPSR @将特殊寄存器CPSR里面的数据传递给R0即R0=CPSR

         MSR指令:MSR指令和 MRS刚好相反, MSR指令用来将普通寄存器的数据传递给特殊寄存器,也就是写特殊寄存器,写特殊寄存器只能使用 MSR,使用示例如下:

MSR CPSR,R0 @将R0中的数据复制到CPSR中即CPSR=R0

        3.2存储器访问指令

         ARM不能直接方位寄存器,一般要先将需要配置的值写入Rx(x=0~12),然后借助存储器访问指令将Rx中的数据写入到寄存器中,读取数据反过来就行。

       LDR指令:主要用于从存储器加载数据到计算器Rx中,LDR也可以将一个立即数加载到寄存器Rx中,LDR加载立即数的时候要使用“ = ”,而不是" # "使用示例如下

LDR R0,=0X0209C004 @将寄存地址0X0209C004加载到R0中即:R0=0X0209C004
LDR R1,[R0]  @读取地址0X0209C004中的数据到R1寄存器中

       STR指令:DR是从存储器读取数据, STR就是将数据写入到存储器中使用示例如下。

LDR R0, =0X0209C004 @将寄存器地址0X0209C004加载到R0中,即R0=0X0209C004
LDR R1, =0X20000002 @R1保存要写入到寄存器的值,即R1=0X20000002
STR R1, [R0] @将R1中的值写入到R0中所保存的地址中

       3.3压栈操作和岀栈操作指令

        我们通常会在A函数中调用B函数,当B函数执行完以后再回到A函数继续执行。要想再跳回A函数以后代码能够接着正常运行,那就必须在跳到B函数之前将当前处理器状态保存起来 (就是保存R0~R15这些寄存器值 ),当B函数执行完成以后再用前面保存的寄存器值恢复R0~R15即可。保存 R0~R15寄存器的操作就叫做现场保护,恢复R0~R15寄存器的操作就叫做恢复现场。在进行现场保护的时候需要进行压栈操作,恢复现场就要进行岀栈操作

        假如我们现在要将 R0~R3和 R12这 5个寄存器压栈,当前的 SP指针指向 0X80000000,处理器的堆栈是向下增长的,使用的汇编代码如下:

PUSH {R0~R3, R12} @将R0~R3和R12压栈

          此时sp指针指向了0X7FFFFFEC,再次对LR进行压栈:

PUSH {LR}  @将LR进行压栈

         接下来我们来进行岀栈演示使用以下代码:

POP {LR} @先恢复LR
POP {R0~R3,R12} @在恢复R0~R3,R12

       出栈的就是从栈顶,也就是SP当前执行的位置开始,地址依次减小来提取堆栈中的数据
到要恢复的寄存器列表中。

        3.4跳转指令

        ①、直接使用跳转指令 B、 BL、 BX 

        ②、直接向 PC寄存器里面写入数据。

        B指令:这是最简单的跳转指令, B指令会将 PC寄存器的值设置为跳转目标地址, 一旦执行 B指令, ARM处理器就会立即跳转到指定的目标地址。如果要调用的函数不会再返回到原来的执行处,那就可以用 B指令,如下示例:

_start:ldr sp,=0X80200000 @设置栈指针
b main @跳转到main函数

   上述代码就是典型的在汇编中初始化 C运行环境,然后跳转到 C文件的 main函数中运行,上述代码只是初始化了SP指针,有些处理器还需要做其他的初始化,比如初始化 DDR等等。因为跳转到 C文件以后再也不会回到汇编了,所以在第 4行使用了 B指令来完成跳转。

        BL指令:BL指令相比 B指令,在跳转之前会在寄存器 LR(R14)中保存当前 PC寄存器值,所以可以通过将 LR寄存器中的值重新加载到 PC中来继续从跳转之前的代码处运行,这是子程序调用一个基本但常用的手段。

push {r0, r1} @保存r0,r1
cps #0x13 @进入SVC模式,允许其他中断再次进去bl system_irqhandler @加载C语言中断处理函数到r2寄存器中
cps #0x12 @进入IRQ模式
pop {r0, r1}
str r0, [r1, #0X10] @中断执行完成,写EOIR

         3.5 算术运算符

         3.6 逻辑运算指令

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

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

相关文章

学习数据结构和算法的第16天

单链表的实现 链表的基本结构 #pragma once #include<stdio.h> #include<stlib.h> typedf int SLTDataType; typedy struct SListNode {SLTDataType data;struct SListNode*next; }SLTNode;void Slisprint(SLTNode*phead); void SListPushBack(SLTNode**pphead,S…

SQLiteC/C++接口详细介绍之sqlite3类(十三)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十二&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十四&#xff09;&#xff08;未发表&#xff09; 40.sqlite3…

相机拍照与摄影学基础

1.相机拍照 相机可能形状和大小不同&#xff0c;但基本功能相同&#xff0c;包括快门速度、光圈和感光度&#xff0c;这些是摄影的通用概念。即使是一次性相机也是基于这三个理念工作的。不同类型相机在这三个概念上的唯一区别是你可以控制这些功能的程度。这三个参数被称为相…

HCIP—OSPF课后练习一

本实验模拟了一个企业网络场景&#xff0c;R1、R2、R3为公司总部网络的路由器&#xff0c;R4、R5分别为企业分支机构1和分支机构2的路由器&#xff0c;并且都采用双上行方式与企业总部相连。整个网络都运行OSPF协议&#xff0c;R1、R2、R3之间的链路位于区域0&#xff0c;R4与R…

计算机设计大赛 题目:基于大数据的用户画像分析系统 数据分析 开题

文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

波奇学Linux:线程安全和自选锁和读写锁

STL不是线程安全的 单例模式的线程安全 自选锁&#xff1a;当线程申请锁失败时&#xff0c;不是挂起&#xff0c;而是一直申请 挂起等待锁 &#xff1a;当线程申请锁失败时&#xff0c;把锁挂起 一般临界区时间短的适合自选锁&#xff0c;长的适合挂起等待锁

Linux系统——Session ID(负载均衡如何保持会话)

目录 一、实验环境搭建 二、部署Nginx代理服务器配置 三、部署后端真是服务器Tomcat配置 四、配置Tomcat的Session ID会话保持 五、测试 此次实验是Tomcat后端服务器如何做Session ID会话保持 一、实验环境搭建 [rootlocalhost ~]#systemctl stop firewalld [rootlocalho…

Qt QTableWidget 实现行选中及行悬浮高亮

表格整行的 selected、hover 高亮需求很常见&#xff0c;但使用 Qt 提供的开箱即用的方法根本无法实现这个需求&#xff08;至少在当前的时间节点是不行的&#xff09;&#xff1b;想要实现这个效果必须要费一点点力气&#xff0c;我们尽量选择较为简单的方法。 话不多说&…

“import ... =“ 只能在 TypeScript 文件中使用

当你遇到这个问题很苦恼。 可以按照以下解决办法 使用ctrlshiftP 修改"javascript.validate.enable": false

从大模型到Agentscope——分布式Multi-Agent应用开发与部署

目录 Why需要分布式 案例 多进程的分布书版本能快速提升速度 分布式的挑战 AgentScope分布式解决 方案 实现RPC Agent 基于Actor模式的并行调度缺点&#xff1a;需要Agent内部决定消息传递目标 被调用的Agent立即返回占位符placeholder to_dist: 开启自动将单机进行扩展…

android中单例模式为什么会引起内存泄漏?

单例模式使用不恰当会造成内存泄漏。因为单例的静态特性使得单例的生命周期和应用的生命周期一样长&#xff0c; 如果一个对象已经不需要使用了&#xff0c;但是单例对象还持有该对象的引用&#xff0c;那么这个对象就不能被正常回收&#xff0c;因此会导致内存泄漏。 举个例子…

<Linux> 线程的同步与互斥

目录 前言&#xff1a; 一、资源共享问题 &#xff08;一&#xff09;多线程并发访问 &#xff08;二&#xff09;临界资源与临界区 &#xff08;三&#xff09;“锁” 是什么 二、多线程抢票场景 &#xff08;一&#xff09;并发抢票 &#xff08;二&#xff09;并发访…

学习笔记--强化学习(1)

参考&#xff1a;https://blog.csdn.net/koulongxin123/article/details/122676149 1.什么是强化学习&#xff1f; (1)定义 基于环境的反馈而行动&#xff0c;通过不断与环境的交互、试错&#xff0c;最终完成特定目的或者使得整体行动收益最大化&#xff08;是一种通过与环境…

YOLOv9改进策略:注意力机制 | SimAM(无参Attention),效果秒杀CBAM、SE

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;SimAM是一种轻量级的自注意力机制&#xff0c;其网络结构与Transformer类似&#xff0c;但是在计算注意力权重时使用的是线性层而不是点积 yolov9-c-CoordAtt summary: 972 layers, 51024476 parameters, 510…

L4 级自动驾驶汽车发展综述

摘要:为了减小交通事故概率、降低运营成本、提高运营效率,实现安全、环保的出行,自动驾驶 技术的发展已成为大势所趋,而搭配有L4 级自动驾驶系统的车辆是将车辆驾驶全部交给系统。据此,介绍了自动驾驶汽车的主流技术解决方案;分析了国内外L4 级自动驾驶汽车的已发布车型、…

学点Java打小工_Day4_Homework

1 统计数字 1 int[] scores{0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,1,2,3,9}; 求出上面数组中0-9分别出现的次数 &#xff08;双重for循环&#xff09; Testpublic void solveProblem1() {int[] scores {0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,…

JavaWeb笔记 --- 三、MyBatis

三、MyBatis 概述 MyBatis是一个持久层框架&#xff0c;用于简化JDBC Mapper代理开发 在resources配置文件包中创建多级目录用 / MyBatis核心配置文件 enviroments&#xff1a;配置数据库连接环境信息。 可以配置多个enviroment&#xff0c;通过default属性切换不同的envir…

大衍数列-蓝桥杯?-Lua 中文代码解题第2题

大衍数列-蓝桥杯&#xff1f;-Lua 中文代码解题第2题 中国古代文献中&#xff0c;曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。 它的前几项是&#xff1a;0、2、4、8、12、18、24、32、40、50 … 其规律是&#xff1a;对偶数项&#xff0c;是序号平方再除…

数据可视化-ECharts Html项目实战(1)

在之前的文章中&#xff0c;我们学习了如何安装Visual Studio Code并下载插件&#xff0c;想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 安装 Visual Studio…

MATLAB环境下基于稀疏方法的基线校正

以光谱信号为例进行说明&#xff0c;光谱信号中基线的存在会降低样品定性和定量分析的准确性&#xff0c;因此在光谱分析前对光谱进行基线校正具有重要意义。光谱数据在采集过程中易受温度、湿度等环境因素影响&#xff0c;发生基线偏移现象。该现象不仅会导致纯谱的谱峰发生形…