奇怪的寄存器定义,声明和用法

时间:2017-06-24 15:56:43

标签: c struct unions cpu-registers

我正在研究GTM模块并且很难理解MCAL代码, 这是代码示例:

/* Here the definition of the register */
/** \brief  CMU Global Clock Control Numerator Register */
typedef struct _Ifx_GTM_CMU_GCLK_NUM_Bits
{
    Ifx_Strict_32Bit GCLK_NUM:24;           /**< \brief [23:0] Numerator for global clock divider (rw) */
    Ifx_Strict_32Bit reserved_24:8;         /**< \brief \internal Reserved */
} Ifx_GTM_CMU_GCLK_NUM_Bits;

/**
\brief  CMU Global Clock Control Numerator Register */
typedef union
{
    unsigned int U;                         /**< \brief Unsigned access */
    signed int I;                           /**< \brief Signed access */
    Ifx_GTM_CMU_GCLK_NUM_Bits B;            /**< \brief Bitfield access */
} Ifx_GTM_CMU_GCLK_NUM;

/*CMU Global Clock Control Numerator Register */
 #define GTM_CMU_GCLK_NUM /*lint --e(923)*/ (*(volatile fx_GTM_CMU_GCLK_NUM*)0xF0100304u)

/* Here we are using the register */
  /* The content of Numerator and Denominator are temporarily taken in local
     variables and used in the if statement below for Misra reasons. */
  RegTemp3 = GTM_CMU_GCLK_NUM.U;

那么为什么在联合中存在文件U和I以及为什么使用U的位域ifx_GTM_CMU_GCLK_NUM_Bits B

执行此代码时遇到问题,因为执行时会出现算术溢出异常:

RegTemp3 = GTM_CMU_GCLK_NUM.U;

2 个答案:

答案 0 :(得分:2)

GTM_CMU_GCLK_NUM是特定于目标系统的硬编码硬件寄存器。

将其作为无符号值读入RegTemp3是必要的,以确保以32位的形式对硬件进行单次访问。

您是否在目标系统上执行此代码?

您确定支持arithmetic overflow exception吗?

如果您在主机系统上运行代码,则很可能会导致分段错误。

答案 1 :(得分:0)

代码正在target system上运行。 是的,支持overflow arithmetic exception

为了读取寄存器值,为什么代码没有使用:

RegTemp3 = GTM_CMU_GCLK_NUM.B;

而不是

RegTemp3 = GTM_CMU_GCLK_NUM.U;