野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13700|回复: 9

关于__IO,__I,__O宏定义的用法的疑惑。

[复制链接]
发表于 2015-12-9 10:15:41 | 显示全部楼层 |阅读模式
看到core_cm3.h头文件内定义了下面几个宏。发现__IO,__I,__O都是定义为volatile这个关键字。而后面注释的都是要么是只读许可,要么是读写许可,可是后面其他地方使用这个宏进行定义变量的时候,都是被替换成一样的volatile?怎么会有不同的读写限制呢?   看后面的 NVIC_Type 结构体定义便知:
#ifdef __cplusplus
  #define     __I     volatile                /*!< defines 'read only' permissions     */   只读许可
#else
  #define     __I     volatile const          /*!< defines 'read only' permissions      */
#endif
#define     __O     volatile                  /*!< defines 'write only' permissions    */ 只写许可
#define     __IO    volatile                  /*!< defines 'read / write' permissions  */读写许可

-----------------------------------------注意下面的红色的宏定义,被替换后,都是清一色的volatile关键字,从哪里看出有读写访问限制了?
typedef struct
{
  __IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register        */  
       uint32_t RESERVED0[24];                                   
__IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register    */
       uint32_t RSERVED1[24];                                    
  __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register        */
       uint32_t RESERVED2[24];                                   
  __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register   */
       uint32_t RESERVED3[24];                                   
  __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register      */
       uint32_t RESERVED4[56];                                   
  __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide) */
       uint32_t RESERVED5[644];                                 
__O  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register  */  这个地方是只写访问许可,读也是可以的吧?
}  NVIC_Type;                       


typedef struct
{
  __I uint32_t CPUID;                        /*!< Offset: 0x00  CPU ID Base Register             CPUIDo&#197;                     */ 这个地方是只读访问许可,写也是可以的吧?
  __IO uint32_t ICSR;                         /*!< Offset: 0x04  Interrupt Control State Register &#214;D&#182;&#207;&#191;&#216;&#214;&#198;&#198;÷×′ì&#172;              */
  __IO uint32_t VTOR;                         /*!< Offset: 0x08  Vector Table Offset Register     &#207;òá&#191;±í&#198;&#171;ò&#198;                    */
  __IO uint32_t AIRCR;                        /*!< Offset: 0x0C  Application Interrupt / Reset Control Register ó|ó&#195;&#214;D&#182;&#207;&#184;′&#206;&#187;&#191;&#216;&#214;&#198;&#198;÷       */
  __IO uint32_t SCR;                          /*!< Offset: 0x10  System Control Register &#207;μí3&#191;&#216;&#214;&#198;&#188;&#196;′&#230;&#198;÷                     */
  __IO uint32_t CCR;                          /*!< Offset: 0x14  Configuration Control Register  &#197;&#228;&#214;&#195;&#191;&#216;&#214;&#198;&#188;&#196;′&#230;&#198;÷         */
  __IO uint8_t  SHP[12];                      /*!< Offset: 0x18  System Handlers Priority Registers (4-7, 8-11, 12-15) */
  __IO uint32_t SHCSR;                        /*!< Offset: 0x24  System Handler Control and State Register     &#207;μí3′|àí&#191;&#216;&#214;&#198;×′ì&#172;        */
  __IO uint32_t CFSR;                         /*!< Offset: 0x28  Configurable Fault Status Register   1ê&#213;&#207;×′ì&#172;&#188;&#196;′&#230;&#198;÷                 */
  __IO uint32_t HFSR;                         /*!< Offset: 0x2C  Hard Fault Status Register          ó2&#188;t1ê&#213;&#207;×′ì&#172;&#188;&#196;′&#230;&#198;÷      */
  __IO uint32_t DFSR;                         /*!< Offset: 0x30  Debug Fault Status Register         μ÷ê&#212;1ê&#213;&#207;×′ì&#172;&#188;&#196;′&#230;&#198;÷   */
  __IO uint32_t MMFAR;                        /*!< Offset: 0x34  Mem Manage Address Register         &#196;ú′&#230;1üàíμ&#216;&#214;·&#188;&#196;′&#230;&#198;÷*/
  __IO uint32_t BFAR;                         /*!< Offset: 0x38  Bus Fault Address Register         ×ü&#207;&#223;1ê&#213;&#207;μ&#216;&#214;·&#188;&#196;′&#230;&#198;÷*/
  __IO uint32_t AFSR;                         /*!< Offset: 0x3C  Auxiliary Fault Status Register     &#184;¨&#214;ú1ê&#213;&#207;&#188;&#196;′&#230;&#198;÷ */
  __I  uint32_t PFR[2];                       /*!< Offset: 0x40  Processor Feature Register          ′|àí&#198;÷ì&#216;D&#212;&#188;&#196;′&#230;&#198;÷    */
  __I  uint32_t DFR;                          /*!< Offset: 0x48  Debug Feature Register              μ÷ê&#212;ì&#216;D&#212;&#188;&#196;′&#230;&#198;÷  */
  __I  uint32_t ADR;                          /*!< Offset: 0x4C  Auxiliary Feature Register          &#184;¨&#214;úì&#216;D&#212;&#188;&#196;′&#230;&#198;÷    */
  __I  uint32_t MMFR[4];                      /*!< Offset: 0x50  Memory Model Feature Register        &#196;ú′&#230;&#196;£Díì&#216;D&#212;&#188;&#196;′&#230;&#198;÷    */
  __I  uint32_t ISAR[5];                      /*!< Offset: 0x60  ISA Feature Register                 ISAì&#216;D&#212;&#188;&#196;′&#230;&#198;÷*/
} SCB_Type;               


----------------------------------
恳求指导!!

多谢


回复

使用道具 举报

发表于 2015-12-10 08:32:07 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-10 12:00:54 | 显示全部楼层
亽亼 发表于 2015-12-10 08:32
http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html
先参考这篇博文

感谢。我也查询了很多资料关于这个volatile的。但是都是说一点,就是让编译器不要优化掉某些指令。都必须去原来位置读写变量值。不能偷工减料。

我的问题是,为什么__O,__IO,__I这几个宏名都是被定义成了相同的一个东西volatile。而且后面的注释明显说明带有访问限制的作用。就是要么只读,要么只写,要么可读可写。我怎么没有看出这几个限制功能体现在何处?
回复 支持 反对

使用道具 举报

发表于 2015-12-10 12:05:13 | 显示全部楼层
单独使用volatile没办法起到读写限制的
回复 支持 反对

使用道具 举报

发表于 2015-12-10 12:12:22 | 显示全部楼层
这里的__IO更多是与寄存器的读写限制挂钩
比如CPUID对应在寄存器的位就是只读属性,这里就使用__I
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-10 12:40:05 | 显示全部楼层
亽亼 发表于 2015-12-10 12:12
这里的__IO更多是与寄存器的读写限制挂钩
比如CPUID对应在寄存器的位就是只读属性,这里就使用__I

关键这不是定义了一个宏吗?经过替换后,不管__IO,__I,__O,最后都替换成了volatile了啊。怎么会起到限制作用?最后不都是清一色的volatile吗?
回复 支持 反对

使用道具 举报

发表于 2015-12-10 13:34:58 | 显示全部楼层
这里使用__IO,__I,__O只是指明对应寄存器的读写限制,字面含义跟volatile没关系
回复 支持 反对

使用道具 举报

发表于 2015-12-10 16:09:11 | 显示全部楼层
从程序上是起不了限制读写作用的
它是写给你看的,在你编程时候提醒你这个变量存在限制,让你别乱操作
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 03:01 , Processed in 0.029476 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表