以前老是对ARM程序中(*(volatile unsigned long *))不理解,通过查阅资料,和看别人写的文章,今天对这个类型转换进行解析一下。这个用法不止在定义内部特殊寄存器有用,在用到外部总线时,定义外部器件的地址也会用。
对于嵌入式系统编程,要求程序员能够利用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 类型是这样的,其数据确实可能在未知的情况下发生变化。比如共享的内存地址,多个程序都对它操作的时候。你的程序并不知道,这个内存何时被改变了。如果不加这个volatile修饰,程序是利用cache当中的数据,那个可能是过时的了,加了 volatile,就在需要用的时候,程序重新去那个地址去提取,保证是最新的。归纳起来如下:
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)可看作是一个普通变量,这个变量有固定的地址,指向0x20。而0x20只是个常量,不是指针更不是变量。
关键字:ARM 特殊寄存器
引用地址:
ARM定义特殊寄存器*(volatile unsigned long *))的理解
推荐阅读最新更新时间:2024-03-16 14:59
ARM 平台上的Linux系统启动流程
开始学习嵌入式开发就一直在使用Linux系统作为学习的平台,到现在无论是PC机还是ARM开发板都已经能顺利地跑起了Linux系统,但是对Linux 的启动流程还是不甚了解。于是开始各种百度谷歌,当然看到了各路大神写的介绍。总的来说就是:bootloader - kernel- root filesystem,当然还介绍了哪个阶段完成了哪些工作。比如bootloader 是一上电就拿到cpu 的控制权的,而bootloader实现了硬件的初始化。bootloader俨然就成了power on 之后 第一个吃螃蟹 的代码。 谈到这就得想到硬件机制是如何满足这个功能的了。就拿S3C2440 这个芯片来说(我的硬件平台就是拿这个芯片
[单片机]
二、冯式结构与哈佛结构及ARM处理器状态和处理器模式
2.1 冯式结构与哈佛结构 2.1.1 两者的区别 如果是独立的存储架构和信号通道那就是哈佛结构,否则就是冯式结构 结构与是否统一编址没有关系,也与 CPU 没有关系,与计算机的整体设计有关 CACHE 的引入(CPU 内部哈佛结构) 总结:高性能单片机的为冯式结构,单片机为哈佛结构 8086 冯式结构 相同存储(RAM) 相同的通道 统一编址 STM32F103 哈佛结构 不同的存储(ROM/RAM) 不同的通道 统一编址 8051 改进型的哈佛结构 不同的存储(ROM/RAM) 相同的通道 独立编址 ARM9 改进型的冯式结构 相同的存储(RAM/ROM) 不同的通道 统一编址 2.
[单片机]
基于ARM9和USB摄像头的网络视频采集系统设计
0 引言 通信网络已经普及到人类生活的各个方面,布控区域广阔的网络视频采集系统也在迅速的发展,嵌入式视频采集系统的服务器直接连入已经建成的网络,既没有线缆长度的限制,也没有信号衰减的限制,通过没有距离概念的网络,彻底抛弃了地域的限制。系统具有几乎无限的无缝扩展能力,所有设备都以IP地址划分,增加设备只是意味着IP地址的增加,可组成非常复杂的视频采集系统,服务器输出的视频数据已完成模拟到数字的转换并压缩,采用TCP/IP协议在网络上传输,支持跨网关、跨路由器的远程视频信息传输。 本文根据网络视频采集的需要,将网络传输与视频采集相结合,设计了以S3C2440为核心的USB摄像头视频采集和嵌入式Linux系统下的视频服务器,从而实
[单片机]
专用于ARM的NI LabVIEW嵌入式模块进行嵌入式系统教学
通过一系列面向机器人开发的实验室实践课程与团队项目,吸引电子工程和计算机科学学院的同学们积极投入嵌入式系统设计。 The Solution: 采用专用于ARM单片机的NI LabVIEW嵌入式模块,对连接到iRobot Create移动机器人平台的Cortex-M3单片机编程,使得同学们可开发一个嵌入式系统,与具有实时约束的真实世界进行交流。 加州大学伯克利分校工程师采用专用于ARM单片机的NI LabVIEW嵌入式模块,对连接到iRobot Create移动机器人平台的Cortex-M3单片机编程,使得同学们可开发一个嵌入式系统。 通过使用LabVIEW,同学们可以更快地开发复杂的功能,使整个过程
[测试测量]
ARM-Linux自动创建设备结点
硬件平台:FL2440 内核版本:2.6.28 主机平台:Ubuntu 11.04 内核版本:2.6.39 1、首先配置busybox busybox Linux System Utilities --- mdev Support /etc/mdev.conf Support command execution at device addition/removal 2、配置内核 3、修改文件系统里的/etc/init.d/rcS #!/bin/sh /bin/mount -a /sbin/ifconfig eth0 192.168.0.3 up #exec /usr/etc/rc.mouse
[单片机]
国内首个ARM架构云平台发布 完善国产芯片生态产业链
中新网贵阳10月13日电 (记者 刘鹏)13日,国内首个完全基于ARM商业架构的云平台“ARM架构云平台”在贵阳发布。该平台的推出旨在吸引和集成ARM阵营在芯片、硬件、软件平台的上下游产业链,从而推动国产服务器芯片领域的应用开发,完善和融合产业生态系统。 据了解,“ARM架构云平台”的建立基于贵州华芯通半导体技术有限公司生产的ARM架构中央处理器,充分利用了该服务器CPU的高性能、低功耗和低成本的优势。同时,基于华芯通半导体的服务器参考评估设备(REP),并通过与云服务提供商——云上贵州大数据产业发展有限公司(以下简称:云上贵州)合作,实现了典型的云服务应用。 华芯通半导体由贵州省及美国高通公司共同出资成立,注册地为贵州贵安新区,
[网络通信]
基于ARM的嵌入式Linux移植真实体验(5)――应用实例
应用实例的编写实际上已经不属于Linux操作系统移植的范畴,但是为了保证本系列文章的完整性,这里提供一系列针对嵌入式Linux开发应用程序的实例。 编写Linux应用程序要用到如下工具: (1)编译器:GCC GCC是Linux平台下最重要的开发工具,它是GNU的C和C++编译器,其基本用法为:gcc 。 我们应该使用arm-linux-gcc。 (2)调试器:GDB gdb是一个用来调试C和C++程序的强力调试器,我们能通过它进行一系列调试工作,包括设置断点、观查变量、单步等。 我们应该使用arm-linux-gdb。 (3)Make GNU Make的主要工作是读进一个文本文件,称为makefile。这个文件记
[单片机]
uC/OS-II在ARM系统上的移植与实现
摘要:使用ARM公司提供的ADS 开发工具,将uC/ OS - II 移植到ARM 处理器上,并将移植结果应用在跑马灯和数码管的实现上,运行正常,表明移植成功.
关键词:uC/ OS - II ;ARM;移植
0 引言
在开发嵌入式系统时,一般选择基于ARM 和uC/ OS - II 的嵌入式开发平台,因为ARM 微处理器具有处理速度快、超低功耗、价格低廉、应用前景广泛等优点 . 将uC/ OS - II 移植到ARM 系统之后,可以充分结合两者的优势. 如果一个程序在一个环境里能工作,我们经常希望能将它移植到另一个编译系统、处理器或者操作系统上,这就是移植技术.移植技术可以使一种特定的技术在更加广泛的范围使用,使软件使用更
[应用]