LV.12 D13 C工程与寄存器封装 学习笔记
一、C语言工程简介
![]()
把模板在linux解压出来

代码写在interface.c就可以了。
map.lds是链接脚本文件(负责代码的排布)

include中是头文件,src中是写好的源代码

start.s是启动代码,在interface.c之前运行,把cpu和栈做一个初始化
二、启动代码分析
.text
.global _start
_start:/** Vector table * 异常向量表(占32个字节)*/ b resetb .b .b .b .b .b .b .reset:/** Set vector address in CP15 VBAR register*/ ldr r0, =_start @把异常向量表的值给r0mcr p15, 0, r0, c12, c0, 0 @Set VBAR (把r0寄存器的值放到p15协处理器中的c12寄存器)/** Set the cpu to SVC32 mode, Disable FIQ/IRQ* 把cpu模式改成SVC模式,改成ARM状态,关闭FIQ/IRQ中断*/ mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr ,r0/** Defines access permissions for each coprocessor*/ mov r0, #0xfffffffmcr p15, 0, r0, c1, c0, 2 /** Invalidate L1 I/D */mov r0, #0 @Set up for MCRmcr p15, 0, r0, c8, c7, 0 @Invalidate TLBsmcr p15, 0, r0, c7, c5, 0 @Invalidate icache/** Set the FPEXC EN bit to enable the FPU*/ mov r3, #0x40000000fmxr FPEXC, r3/** Disable MMU stuff and caches* MMU:负责物理地址和虚拟地址间的转换*/mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002000 @Clear bits 13 (--V-)bic r0, r0, #0x00000007 @Clear bits 2:0 (-CAM)orr r0, r0, #0x00001000 @Set bit 12 (---I) Icacheorr r0, r0, #0x00000002 @Set bit 1 (--A-) Alignorr r0, r0, #0x00000800 @Set bit 11 (Z---) BTBmcr p15, 0, r0, c1, c0, 0/** Initialize stacks * 初始化栈 */
init_stack: /*svc mode stack*/msr cpsr, #0xd3 @把cpu的模式改为svc模式ldr sp, _stack_svc_end @把svc模式下的栈的最高地址给了svc模式下的sp/*undef mode stack*/msr cpsr, #0xdb ldr sp, _stack_und_end/*abort mode stack*/ msr cpsr,#0xd7ldr sp,_stack_abt_end/*irq mode stack*/ msr cpsr,#0xd2ldr sp, _stack_irq_end/*fiq mode stack*/msr cpsr,#0xd1ldr sp, _stack_fiq_end/*user mode stack, enable FIQ/IRQ*//*把cpu的模式改为user模式,并打开FIO/IRQ中断msr cpsr,#0x10ldr sp, _stack_usr_end/*Call main*/b main/** 把各个栈最高的地址算出来,作为起始地址*/
_stack_svc_end: .word stack_svc + 512
_stack_und_end: .word stack_und + 512
_stack_abt_end: .word stack_abt + 512
_stack_irq_end: .word stack_irq + 512
_stack_fiq_end:.word stack_fiq + 512
_stack_usr_end: .word stack_usr + 512/** 给各个模式都申请了512个字节空间,作为栈*/
.data
stack_svc: .space 512
stack_und:.space 512
stack_abt: .space 512
stack_irq: .space 512
stack_fiq: .space 512
stack_usr: .space 512
三、C语言实现LED实验
/** 一、汇编语言访问存储器* 1.读存储器* LDR R1, [R2]* 2.写存储器* STR R1, [R2]** 二、C语言访问存储器* 1.读存储器* data = *ADDR* 2.写存储器* *ADDR = data* */void Delay(unsigned int Time)
{while(Time--);
}int main()
{/*通过设置GPX2CON寄存器来将GPX2_7引脚设置成输出功能*/*(unsigned int *)0x11000c40 = 0x10000000;while(1){/*点亮LED2*/*(unsigned int *)0x11000c44 = 0x00000080;/*延时*/Delay(1000000);/*熄灭LED2*/*(unsigned int *)0x11000c44 = 0x00000000;/*延时*/Delay(1000000);}return 0;
}
四、寄存器的封装方式
1、把单个的寄存器封装成一个宏
#define GPX2CON (*(unsigned int *)0x11000c40)
#define GPX2DAT (*(unsigned int *)0x11000c44)int main()
{GPX2CON = 0x10000000;while(1){/*点亮LED2*/GPX2DAT = 0x00000080;/*延时*/Delay(1000000);/*熄灭LED2*/GPX2DAT = 0x00000000;/*延时*/Delay(1000000);}return 0;
}
2、把相关的几个寄存器封装成一个结构体,其地址空间必须是连续的
typedef struct
{unsigned int CON;unsigned int DAT;unsigned int PUD;unsigned int DRV;
}gpx2;#define GPX2 (*(gpx2 *)0x11000c40)int main()
{GPX2.CON = 0x10000000;while(1){/*点亮LED2*/GPX2.DAT = 0x00000080;/*延时*/Delay(1000000);/*熄灭LED2*/GPX2.DAT = 0x00000000;/*延时*/Delay(1000000);}return 0;
}
3、把整个芯片里的寄存器封装好,引用头文件
#include "exynos_4412.h"int main()
{GPX2.CON = 0x10000000;while(1){/*点亮LED2*/GPX2.DAT = 0x00000080;/*延时*/Delay(1000000);/*熄灭LED2*/GPX2.DAT = 0x00000000;/*延时*/Delay(1000000);}return 0;
}
五、寄存器操作的标准化
只改寄存器的某几位,其他位保持不变
#include "exynos_4412.h"int main()
{GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);while(1){/*点亮LED2*/GPX2.DAT = GPX2.DAT | (1 << 7);/*延时*/Delay(1000000);/*熄灭LED2*/GPX2.DAT = GPX2.DAT & (~(1 << 7));/*延时*/Delay(1000000);}return 0;
}/** 1.unsigned int a; 将a的第3位置1,其他位保持不变* ******** ******** ******** ********* ******** ******** ******** ****1**** 00000000 00000000 00000000 00001000** a = a | (1 << 3);** 2.unsigned int a; 将a的第3位置0,其他位保持不变* ******** ******** ******** ********* ******** ******** ******** ****0**** 11111111 11111111 11111111 11110111** a = a & (~(1 << 3));** 3.unsigned int a; 将a的第[7:4]位置为0101,其他位保持不变* ******** ******** ******** ********* ******** ******** ******** 0101****** 1).先清零* 11111111 11111111 11111111 00001111* 00000000 00000000 00000000 11110000* 00000000 00000000 00000000 00001111** a = a & (~(0xF << 4));** 2).再置位* 00000000 00000000 00000000 01010000* 00000000 00000000 00000000 00000101** a = a | (0x5 << 4);** => a = a & (~(0xF << 4)) | (0x5 << 4);*/
我没并不只能控制LED,一切可以通过高低电频控制的东西,都可以通过GPIO来控制。
相关文章:
LV.12 D13 C工程与寄存器封装 学习笔记
一、C语言工程简介 把模板在linux解压出来 代码写在interface.c就可以了。 map.lds是链接脚本文件(负责代码的排布) include中是头文件,src中是写好的源代码 start.s是启动代码,在interface.c之前运行,把cpu和栈做一…...
Java SE 学习笔记(十九)—— XML、设计模式
目录 1 XML1.1 XML 概述1.2 XML 语法规则1.3 XML 文档约束(了解)1.3.1 DTD 约束1.3.2 schema 约束 2 XML 解析2.1 XML 解析概述2.2 Dom4J 解析 XML 文件2.3 XML 解析案例 3 XML 检索4 设计模式4.1 工厂模式4.2 装饰模式 1 XML 在有些业务场景下ÿ…...
grafana InfluxDB returned error: error reading influxDB 400错误解决
问题: 如图提示错误解决 确认自己的docker容器是否配置了以下3个字段 DOCKER_INFLUXDB_INIT_USERNAMExxx DOCKER_INFLUXDB_INIT_PASSWORDyyy DOCKER_INFLUXDB_INIT_ADMIN_TOKENzzz 如果有,在grafana中需要添加header配置Header: Authorization , Value…...
【LeetCode:150. 逆波兰表达式求值 | 栈】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
什么是神经网络,它的原理是啥?(2)
参考:https://www.youtube.com/watch?vmlk0rddP3L4&listPLuhqtP7jdD8CftMk831qdE8BlIteSaNzD 视频3:什么是激活函数?为什么我们需要激活函数?它的类型有哪些? 为什么需要激活函数?如果没有激活函数&…...
leetcode做题笔记206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3: 输入&am…...
2023/10/31 JAVA学习
idea一般会自动帮我们导包 new string创建出的字符串是空的,可以对其进行新赋值 s[i]在Java字符串中是没有这个东西的,想要遍历字符串只能用下面这种方式 但是可以把字符串,转换为字符数组然后那样输出 java中是无法s1 s2这样比较字符串的,因为这样比较的是地址,如果是new创建…...
SurfaceFliger绘制流程
前景提要: 当HWComposer接收到Vsync信号时,唤醒DisSync线程,在其中唤醒EventThread线程,调用DisplayEventReceiver的sendObjects像BitTub发送消息,由于在SurfaceFlinger的init过程中创建了EventThread线程,…...
系统架构设计师-第14章-云原生架构设计理论与实践-
云原生架构产生背景 云原生与商业场景的深度融合 ( 1 )从为企业带来的价值来看,云原生架构有着以下优势通过对多元算力的支持,满足不同应用场景的个性化算力需求,井基于软硬协同架构,为应用提供极致性能的云原生算力 (2) 通过最…...
conda 实践
1. 环境部署 1.1. 下载 anaconda 安装包 下面这个网址查找自己需要的版本 https://repo.anaconda.com/archive/ 或者手动下载。 wget https://repo.anaconda.com/archive/Anaconda3-5.3.0-Linux-x86_64.sh 1.2. 执行安装程序 #安装依赖: sudo yum install bzip2…...
行业追踪,2023-10-31
自动复盘 2023-10-31 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
springboot 配置多个Redis数据源详解
实现原理 需要配置好两个数据源,创建两个RedisTemplate在配置类中注入两个RedisConnectionFactory,分别创建对应的RedisTemplate进行操作 详解 配置数据源 我这里是在之前已有一个配置下面另外加了一个 spring:redis:# 地址host: localh…...
【数据结构】排序算法总结
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈数据结构 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 总结 1. 归并排序2. 计数排序3. 排序…...
作为20年老程序员,我如何使用GPT4来帮我写代码
如果你还在用google寻找解决代码bug的方案,那你真的out了,试试gpt4, save my life. 不是小编危言耸听,最近用gpt4来写代码极大地提高了代码生产力和运行效率,今天特地跟大家分享一下。 https://www.promptspower.comhttps://www.…...
【机器学习合集】模型设计之残差网络 ->(个人学习记录笔记)
文章目录 模型设计之残差网络1. 什么是残差结构1.1 网络加深遇到的优化问题1.2 short connect技术 2. 残差网络及有效性理解2.1 残差网络 3. 残差网络的发展3.1 密集残差网络3.2 更宽的残差网络(wide resnet)3.3 分组残差网络3.4 Dual Path Network3.5 加权残差网络3.6 预激活残…...
GoLong的学习之路(十六)基础工具之Gin框架
Gin框架介绍及使用,这张不用看内容就知道非常重要,重要到什么地步呢?重要到开发java不会Spring全家桶这种概念。 上几篇文章写的是如何构建骨架,经脉。这一章是将血肉注入。 文章目录 Gin框架RESTful API Gin渲染HTML渲染静态文件…...
VMware打开centos黑屏解决方法汇总
VMware打开centos黑屏解决方法汇总 前言:一. VMware打开centos黑屏解决方法汇总一 .情况情况一:情况二情况三 二. 解决方法最简单的方法:一. 以管理员权限在命令行执行1. 管理员身份运行cmd2. 输入“netsh winsock reset”,回车3. 重启电脑即…...
5G物联网关相较有线网关有哪些独特优势
5G为产业物联网应用带来了质的飞跃,5G技术实现更高速率、更低延迟和更大带宽,使得物联网能够接入更多数量的设备,实现更稳定、高效的连接和数据传输,在提高生产效率的同时,也进一步促进了物联网的应用发展和升级。 针对…...
【数据结构】顺序表的学习
前言:在之前我们学习了C语言的各种各样的语法,因此我们今天开始学习数据结构这一个模块,因此我们就从第一个部分来开始学习"顺序表"。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:C程序设计谭浩强版本…...
在NISQ小型计算机上执行大型并行量子计算的可能性
简介 Steve White提出了密度矩阵重整化群(DMRG)的基本思想,即纠缠是一种有价值的资源,可以用来精确或近似地描述大量子系统。后来,这一思想被理解为优化矩阵积状态(MPS)的算法,支持…...
Thorium浏览器:重新定义Chromium性能的颠覆性优化方案
Thorium浏览器:重新定义Chromium性能的颠覆性优化方案 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Windows and MacOS/Raspi/Android/Special builds are in different repositories, links are towards the top of the READM…...
vLLM-v0.17.1保姆级教程:vLLM + Weights Biases 实验跟踪实践
vLLM-v0.17.1保姆级教程:vLLM Weights & Biases 实验跟踪实践 1. vLLM框架简介 vLLM是一个专注于大语言模型推理和服务的开源库,以其出色的性能和易用性在开发者社区中广受欢迎。这个项目最初由加州大学伯克利分校的天空计算实验室发起࿰…...
【算法实战】分支限界法解电路布线:从理论到代码实现
1. 电路布线问题与分支限界法初探 电路布线问题就像是在一个布满障碍物的迷宫中寻找最短路径。想象一下,你手里拿着一根电线,需要在布满元件的电路板上找到一条最短的路径连接两个点,而且电线只能走直线或者直角转弯。这就是电路布线问题的现…...
如何用Captum实现多任务学习解释:复杂模型的归因策略终极指南
如何用Captum实现多任务学习解释:复杂模型的归因策略终极指南 【免费下载链接】captum Model interpretability and understanding for PyTorch 项目地址: https://gitcode.com/gh_mirrors/ca/captum Captum是一个基于PyTorch的模型可解释性库,专…...
打造沉浸式音乐体验:Apple Music-Like Lyrics 全栈技术指南
打造沉浸式音乐体验:Apple Music-Like Lyrics 全栈技术指南 【免费下载链接】applemusic-like-lyrics 一个基于 Web 技术制作的类 Apple Music 歌词显示组件库,同时支持 DOM 原生、React 和 Vue 绑定。 项目地址: https://gitcode.com/gh_mirrors/ap/a…...
保姆级教程:用UniApp+佳博打印机实现小票与条形码打印(含完整TSC/ESC指令封装)
UniApp佳博打印机实战:从蓝牙连接到小票打印的全流程解析 在移动零售和仓储管理场景中,蓝牙小票打印是提升工作效率的关键环节。本文将手把手带您实现UniApp与佳博打印机的深度整合,涵盖蓝牙连接管理、TSC/ESC指令封装、40mm50mm小票排版等核…...
告别手动截图!用Python脚本从ROS bag文件里精准提取带时间戳的图片(附完整代码)
告别手动截图!用Python脚本从ROS bag文件里精准提取带时间戳的图片(附完整代码) 在计算机视觉和机器人研究中,从ROS bag文件中高效提取带时间戳的图像数据是构建数据集的关键步骤。传统方法依赖ROS自带工具,但常面临提…...
这个网站,我愿称之为生信云平台天花板
刚入门生信的你,是否也曾被这些问题折磨得想摔键盘?• Linux 环境配置:conda install 报错到怀疑人生,环境冲突让你原地崩溃。• 硬件瓶颈: 实验室服务器要排队,自己的轻薄本跑个比对就能当暖气片。• 代码…...
研发物料管理新思路:巧用SAP预留功能实现打样耗材精准管控
研发物料管理新思路:巧用SAP预留功能实现打样耗材精准管控 在制造业研发部门,物料管理一直是令人头疼的难题。不同于生产线的标准化流程,研发活动往往伴随着频繁的设计变更、小批量试制和突发性物料需求。传统的手工台账或Excel表格管理方式&…...
nRF54L15实现更快的处理速度
Nordic的nRF54L15系统级芯片相比前代nRF52系列,不仅速度更快、功耗更低,还配备了更丰富的外设,” 刘佳杭继续说道,“基于Arm Cortex-M33处理器的HJ-N54L_SIP不仅能处理更复杂的应用程序,同时显著提升了处理速度。系统级…...
