ARM定义特殊寄存器(*(volatile unsigned long *))的理解

2023-11-01

以前老是对ARM程序中(*(volatile unsigned long *))不理解,今天看了两篇文章,觉得对理解这个很有用,当然这个不止在定义内部特殊寄存器有用,在用到外部总线时,根据具体情况,定义外部器件的地址也可以用。

  下面是文章一

终于理解了#define SREG (*(volatile unsigned  CHAR  *)0x5F)
以前看到#define SREG     (*(volatile unsigned 
CHAR  *)0x5F)
这样的定义,总是感觉很奇怪,不知道为什么,今天终于有了一点点心得,请大虾们多多批砖~~~

    嵌入式系统编程,要求程序员能够利用C语言访问固定的内存地址。既然是个地址,那么按照C语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,比如0x5F,
    第一步是要把它强制转换为指针类型
(unsigned 
CHAR  *)0x5F,AVR的SREG是八位寄存器,所以0x5F强制转换为指向
unsigned 
CHAR 类型。
    volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变——意想不到。
    第二步,对指针变量解引用,就能操作指针所指向的地址的内容了
    *(volatile unsigned 
CHAR  *)0x5F
    第三步,小心地把#define宏中的参数用括号括起来,这是一个很好的习惯,所以#define SREG     (*(volatile unsigned 
CHAR  *)0x5F)

     类似的,如果使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义#define RAM_ADDR      (*(volatile unsigned 
LONG    *)0x0000555F)
     然后就可以用C语言对这个内存地址进行读写操作了
     读:tmp = RAM_ADDR;
     写:RAM_ADDR = 0x55;

已下是文章二

对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方便的多了。

         以 #define IOPIN   (*((volatile unsigned long *) 0xE0028000))   为例:作为一个宏定义语句,define是定义一个变量或常量的伪指令。首先( volatile unsigned long * )的意思是将后面的那个地址强制转换成 volatile unsigned long * ,unsigned long * 是无符号长整形,volatile 是一个类型限定符,如const一样,当使用volatile限定时,表示这个变量是依赖系统实现的,以为着这个变量会被其他程序或者计算机硬件修改,由于地址依赖于硬件,volatile就表示他的值会依赖于硬件。

        volatile 类型是这样的,其数据确实可能在未知的情况下发生变化。比如,硬件设备的终端更改了它,现在硬件设备往往也有自己的私有内存地址,比如显存,他们一般是通过映象的方式,反映到一段特定的内存地址当中,这样,在某些条件下,程序就可以直接访问这些私有内存了。另外,比如共享的内存地址,多个程序都对它操作的时候。你的程序并不知道,这个内存何时被改变了。如果不加这个voliatile修饰,程序是利用catch当中的数据,那个可能是过时的了,加了 voliatile,就在需要用的时候,程序重新去那个地址去提取,保证是最新的。归纳起来如下:

1. volatile变量可变允许除了程序之外的比如硬件来修改他的内容   
2. 访问该数据任何时候都会直接访问该地址处内容,即通过cache提高访问速度的优化被取消  

       对于((volatile unsigned long *) 0xE0028000)为随硬件需要定义的一种地址,前面加上“*”指针,为直接指向该地址,整个定义约定符号IOPIN代替,调用的时候直接对指向的地址寄存器写内容既可。这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。上述表达式拆开来分析,首先(volatile unsigned long *) 0xE0028000的意思是把0xE0028000强制转换成volatile unsigned long类型的指针,暂记为p,那么就是#define A *p,即A为P指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作。

对于(volatile unsigned char *)0x20我们再分析一下,它是由两部分组成:
1)(unsigned char *)0x20,0x20只是个值,前面加(unsigned char *)表示0x20是个地址,而且这个地址类型是unsigned char ,意思是说读写这个地址时,要写进unsigned char 的值,读出也是unsigned char 。
2)volatile,关键字volatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值。例如用while((unsigned char *)0x20)时,有时系统可能不真正去读0x20的值,而是用第一次读出的值,如果这样,那这个循环可能是个死循环。用了volatile 则要求每次都去读0x20的实际值。

那么(volatile unsigned char *)0x20是一个固定的指针,是不可变的,不是变量。而char   *u则是个指针变量。
再在前面加"*":*(volatile unsigned char *)0x20则变成了变量(普通的unsigned char变量,不是指针变量),如果#define i (*(volatile unsigned char *)0x20),那么与unsigned char i是一样了,只不过前面的i的地址是固定的。

那么你的问题就可解答了,(*(volatile unsigned char *)0x20)可看作是一个普通变量,这个变量有固定的地址,指向0x20。而0x20只是个常量,不是指针更不是变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARM定义特殊寄存器(*(volatile unsigned long *))的理解 的相关文章

  • AD采样出来的数值与实际值之间的关系

    当刚接触AD采样时 一直对于AD采集出来的数值与实际的值之间的关系有些模糊 现在闲暇下来打算记录一下 这里以采集量为电压量来记录 当采集温度 电流等模拟量时 都是通过一个电路把模拟量转化为一个电压量输入进AD采样引脚 就不一一叙述 AD采样
  • x86寄存器

    通用寄存器 GPR寄存器 AX Accumulator 累加寄存器 也叫累加器 BX Base 基地址寄存器 CX Count 计数器寄存器 DX Data 数据寄存器 指针寄存器 SP Stack Pointer 堆栈指针寄存器 BP B
  • stm32USB之模拟U盘

    STMF0 W25Q32模拟U盘 1 第一次写博客 如有错误 请及时指正 如有表达不通顺的地方 敬请谅解 2 本篇文章主要描述如何使用STM32cube配置USB 使用的主控为STM32F072 Flash为W25Q32 使用的主控RAM只
  • 新唐NUC980使用记录(5.10.y内核):u-boot & linux & rootfs 编译与烧录测试(基于SD1位置SD卡)

    文章目录 目的 基础准备 烧录环境 开发编译环境 SD卡分区 制作和设置编译工具链 制作toolchain和rootfs 拷贝rootfs内容到SD卡 设置编译工具链 u boot编译与测试 下载 配置与编译 烧录u boot与环境变量 l
  • main.c(31): warning: #223-D: function “uart_init“ declared implicitly

    Keil5编程之warning 223 D function xxx declared implicitly 1 函数没有头文件中进行声明 在头文件中添加声明 2 定义错误 字母大小可能不一致 仔细看一下出现问题的函数是否在声明和调用时使用
  • 粤嵌GEC6818开发板-入门感慨篇(续一)

    触摸屏的事件 include
  • verilog奇数分频器的问题讲解(7分频为例)

    先不多哔哔 直接上代码 verilogHDL 代码的后面讲原理 module fenpin3 clk clk7 rst input clk rst 设置rst的目的是当rst 1的时候给cnt0和cnt1赋初值 output clk7 re
  • LWIP在STM32上的移植

    本文做记录摘抄 加上自己的体会 文章标题 STM32使用LWIP实现DHCP客户端 http www cnblogs com dengxiaojun p 4379545 html 该文章介绍了几点 LWIP源码的内容 关键点 1 inclu
  • 模板类成员函数特化写法

    昨天有对模板类的函数成员特化需求 目的是为了对不同模板参数实现不同的操作 结果在写过程中碰到already defined的问题 貌似是模板新手最容易碰到的问题了 类外的成员函数和同在类外的特化版本成员函数冲突了 因为对模板用法不是很熟悉
  • STM32 IAP 在线升级详解

    扩展 IAP主要用于产品出厂后应用程序的更新作用 考虑到出厂时要先烧写IAP 再烧写APP应用程序要烧写2次增加工人劳动力基础上写了 STM32 IAP APP gt 双剑合一 链接稍后发 一 在进入主题之前我们先了解一些必要的基础知识 s
  • 步进电机基础(5.6)-步进电机的驱动与控制-闭环控制

    步进电机基础 5 6 步进电机的驱动与控制 闭环控制 前言 基本信息 前言说明 5 6 闭环控制 前言 基本信息 名称 描述说明 教材名称 步进电机应用技术 作者 坂本正文 译者 王自强 前言说明 根据我读的 步进电机应用技术 这本书 进行
  • [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL s...

    Err 1064 You have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the rig
  • 毕业设计 STM32人体红外测温枪温度采集系统 - 单片机

    文章目录 1 前言 2 主要器件 3 实现效果 4 设计原理 MLX90614 红外温度传感器 5 部分实现代码 6 最后 1 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求
  • 9.用python写网络爬虫,完结

    前言 这是python网络爬虫的最后一篇给大家做个总结 且看且珍惜把 截止到目前 前几章本书介绍的爬虫技术都应用于一个定制网站 这样可以帮助我们更加专注于学习特定技巧 而在本章中 我们将分析几个真实网站 来看看这些技巧是如何应用的 首先我们
  • C#写的34401A串口232数据读取程序

    首先呢 请先设置惠普表为Talk only模式 也就是31 还不明白的自己查手册去 另外 各个表设置不一样 比如我这里2块表就不一样 一块是7位数据位 even校验 另一块是8位数据位 none校验 具体的可以看看表里的i o那里的设置 数
  • STM32F103C8t6程序下载

    一 下载程序之前了解的内容 STM32英文手册下载 https www stmcu org cn document list index category 158 STM32的芯片上有两个管脚BOOT0和BOOT1 这两个管脚在芯片复位时的
  • 面经——小米面经(2021春招)

    摘自 小米面经 2021春招 感谢小米 感谢雷总 感谢上官可编程 作者 阿波罗啦啦啦啦 发布时间 2021 05 01 11 08 41 网址 https blog csdn net weixin 44933419 article deta
  • 32位的Ubuntu16.04安装QT5.8,并编译实现window环境下的代码

    开始 这是本人的第一篇博客 自己经常在网上找问题的解决方法 发现有些问题很难找到合适的解决方法 所以自己也写写 希望能帮助到大家 有错的地方大家指出 安装环境 linux环境 Ubuntu16 04 32位系统 使用apt get命令进行安
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 【go语言】AST抽象语法树详解&实践之扫描代码生成错误码文档

    背景 为了能识别出代码中抛出错误码的地址和具体的错误码值 再根据错误码文件获取到错误码的具体值和注释 方便后续的排错 这里使用AST进行语法分析获取到代码中的目标对象 一 编译过程 在开始解析代码之前先补充了解一下编译过程 编译过程是将高级

随机推荐

  • 变长模板:模板参数包和函数参数包

    模板参数包 我们先看看变长模板的语法 以tuple为例 template
  • Qt 菜单背景设置颜色 菜单设置颜色

    菜单红色 菜单栏紫色 this gt setStyleSheet QMenu item selected background color ff0000 QMenuBar background color ee00ff 紫色 看效果 菜单背
  • 什么是vue生命周期?

    vue生命周期是指vue实例对象从创建之初到销毁的过程 vue所有功能的实现都是围绕其生命周期进行的 在生命周期的不同阶段调用对应的钩子函数实现组件数据管理和DOM渲染两大重要功能 vue生命周期的这八个阶段 1 创建前 beforeCre
  • ut本地系统服务器,mysql本地服务器地址

    mysql本地服务器地址 内容精选 换一换 云数据库RDS服务提供使用内网 公网和数据管理服务 Data Admin Service 简称DAS 的连接方式 VPC 虚拟私有云 Virtual Private Cloud 简称VPC ECS
  • R语言中向量和矩阵简单运算

    一 向量运算 向量是有相同基本类型的元素序列 一维数组 定义向量的最常用办法是使用函数c 它把若干个数值或字符串组合为一个向量 1 R语言向量的产生方法 gt x lt c 1 2 3 gt x 1 1 2 3 2 向量加减乘除都是对其对应
  • IDEA默认Maven设置

    IDEA是自带Maven的 但版本有点低 故自己下了新版的Maven 但每次使用创建或者导入Maven项目的时候 IDEA都会使用系统默认的Maven 如下图所示 此时 如果想默认使用自定义安装的Maven 需要点击Maven home d
  • CentOS7 安装MySQL 图文详细教程

    目录 一 检查是否已经安装过MySQL 方法一 方法二 二 安装MySQL 1 将压缩包传到服务器 2 解压文件 3 重命名解压后的文件 4 检查是否有mysql用户组和mysql用户 5 进入mysql目录 更新权限
  • Unity无限列表插件-EnhancedScroller 简单操作步骤

    1 导包 将EnhancedScroller v2 15 6 unitypackage导入到场景中 2 创建画布 创建一个canvas画布 3 创建Scroll 在画布下创建一个UI gt Scroll View 将组建内Scrollbar
  • 厦门PX项目迁址:意义有限的进步

    朱金灿 在新浪网上看到这样一则消息 来自厦门消息称 福建省政府和厦门市政府上周末决定顺从民意 停止在厦门海沧区兴建台资翔鹭集团对二甲苯 paraxylene 简称 PX 工厂 将该项目迁往漳州古雷半岛兴建 厦门市将赔偿翔鹭集团 并在发改委批
  • 计算机视觉:窥探数字世界的眼睛

    目录 简介 一 计算机视觉的起源与发展 二 计算机视觉的应用领域 三 计算机视觉的挑战与未来发展 结论 简介 计算机视觉 Computer Vision 是人工智能 AI 领域中的一个重要分支 专注于研究如何使计算机系统能够 看见 理解和解
  • 学术界到底能不能用 ChatGPT?

    全民在日常工作 学习 测试过程中使用 ChatGPT 已经不是什么秘密了 但是光明正大地在学术论文中使用 还把 ChatGPT 的 Regenerate response 按钮标签文字复制到论文中 尚未在方法或致谢一栏提及任何有关 Chat
  • Windows下搭建PHP调试环境(phpstudy+VScode)

    Windows下搭建PHP调试环境 phpstudy VScode 0x00 问题背景 0x01 配套环境 0x02 php Xdebug简介 官方介绍 Xdebug扩展启用 0x03 php ini配置 0x04 vscode配置 VSc
  • k8s dashboard安装

    安装 wget https raw githubusercontent com kubernetes dashboard v2 5 1 aio deploy recommended yaml kubectl apply f recommen
  • springboot集成log4j2

    一 前言 1 为什么要使用log4j2作为我们的日志记录管理框架呢 答 springboot默认使用logback作为日志记录框架 常见的日志记录框架有log4j logback log4j2 2 我们在项目中经常使用一个叫SLF4J的依赖
  • 十分钟学会写shell脚本

    大家好 我是handsomecui 下面我为大家讲解一下shell脚本的写法 讲的不好的地方 欢迎大家留言拍砖 1 在linux下会写shell脚本是非常重要的 下面我参照例子给大家展示几个脚本 顺带这学习shell 的语法 什么时候hel
  • 汇编语言(1)——从机器到汇编

    汇编语言 王爽 著 读书笔记 1 汇编语言的出现 最早期出现的计算机 是名副其实的 计算 机 这个机器可以执行一系列特定的指令 即机器指令 而由机器指令构成的集合被称为指令集 也就是我们说的机器语言 机器指令是由一系列的二进制数字0和1构成
  • EMC整改流程及常见问题

    电磁兼容EMC整改专题 目录 EMC整改流程及常见问题 1EMC整改意见 2EMC整改流程 3EMC整改的一些小建议 4总结 电磁兼容 EMC EMC小结之时钟辐射问题 一前言 二测试数据分析 三辐射超标的原因 四结语 EMC整改流程及常见
  • 人机交互期末复习要点

    文章pdf下载 点击下载pdf 注 我们网上的作业 老师说的考试题目 可能会考的重点 无 可能会考选择题 也可能会考大题 比如 人机交互设备 我们这次期末考试就考了 绪论 什么是人机交互技术 是指关于设计 评价和实现供人们使用的交互式计算机
  • matlab中float类型的_数据类型(一)——数值类型

    数值类型包括两种 整数类型和浮点数类型 整数类型 uint8 分别表示有 不带u 无 带u 符号和对应的数值范围 或者说是整数的位数 浮点数类型 单精度 single 和双精度 float 或者直接输入小数 因为matlab默认即为双精度
  • ARM定义特殊寄存器(*(volatile unsigned long *))的理解

    以前老是对ARM程序中 volatile unsigned long 不理解 今天看了两篇文章 觉得对理解这个很有用 当然这个不止在定义内部特殊寄存器有用 在用到外部总线时 根据具体情况 定义外部器件的地址也可以用 下面是文章一 终于理解了