【问题标题】:Writing to hardware register using void *使用 void * 写入硬件寄存器
【发布时间】:2013-12-04 20:43:23
【问题描述】:

我正在编写一个基于 Altera 软处理器的应用程序。 API 提供对 VHDL 中定义的寄存器的访问,如下所示。

#define __IO_CALC_ADDRESS_DYNAMIC(BASE, OFFSET) \
((void *)(((alt_u8*)BASE) + (OFFSET)))

#define IOWR_32DIRECT(BASE, OFFSET, DATA) \
__builtin_stwio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET)), (DATA))

根据我在编写与硬件或寄存器直接接口的代码方面所学到的一切,我编写了这样的代码,

typedef uint8_t volatile reg;    /* special type to access registers */

typedef struct reg_one           /* access to base and offsets */
{
    reg data_0;    /* first 8 bits */
    reg data_1;    /* second 8 bits */
    .
    .
} reg_one;

static reg_one *const reg_ptr = (reg_one *)SOME_BASE_ADDRESS;

uint32_t data;

data = 0;

__builtin_stwio(&(reg_ptr->data_0), data);

但是,地址被转换为 void * 并且 volatile 和 const 限定符被立即丢弃。有没有办法解决这个问题,还是我只是缺少一些简单的东西?

我了解使用宏定义指针是一种选择,

#define reg_ptr ((reg_one *)SOME_ADDRESS)

但我更喜欢使用常量对象作为范围和类型。

提前感谢您的帮助!

【问题讨论】:

    标签: c embedded


    【解决方案1】:

    我认为使用结构来定义设备寄存器接口的更合适的方法是用普通类型声明结构,然后用关键字@987654322限定结构的类型@ 在定义指向寄存器基地址的指针时,因此:

    typedef struct reg_one  /* access to base and offsets */
    {
        uint8_t data_0;     /* first 8 bits */
        uint8_t data_1;     /* second 8 bits */
        /* ... */
    } reg_one;
    
    /*   key addition: volatile applied to the struct's type, reg_one   */
    static volatile reg_one* const reg_ptr = (reg_one*)SOME_BASE_ADDRESS;
    

    这会将通过指针reg_ptr 对该结构的成员进行的所有访问标记为volatile。这对于确保诸如

    之类的语句很有用
    reg_ptr->data_0 = (uint8_t)data;
    /* reg_ptr         has type volatile reg_one*, so 
       reg_ptr->data_0 has type volatile uint8_t      */
    

    不会被优化编译器删除或重新排序。

    但您似乎没有通过 C 语言赋值、递增/递减或其他方式访问这些成员。相反,您使用看起来像 GCC 内置的东西,__builtin_stwio。根据http://www.johnloomis.org/altera/nios2/gnutools/binutils/gcc/Altera-Nios-II-Built-in-Functions.html,内置的__builtin_stwio定义为

    void __builtin_stwio (volatile void *, int)
    

    当您参与编译器内置函数时,所有关于它们的真实行为的赌注都将落空,因为编译器会给它们任何它想要的特殊处理。也就是说,我敢打赌,您的 GCC 变体将尊重原型所暗示的内容。您的编译器很可能既不会删除也不会重新排序对此内置函数的调用,因此它的使用将遵循volatile 语义。

    【讨论】:

      猜你喜欢
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 2013-01-09
      • 2022-08-30
      • 1970-01-01
      相关资源
      最近更新 更多