首页 > 解决方案 > 从北欧半导体库了解编写预处理器指令的方法

问题描述

我正在努力了解 Nordic 的嵌入式系统计时器库。我发现他们以一种我不理解且以前从未见过的方式定义预处理器指令:

/** @brief The configuration structure of the timer driver instance. */
typedef struct
{
    nrf_timer_frequency_t frequency;          ///< Frequency. 
    nrf_timer_mode_t      mode;               ///< Mode of operation.
    nrf_timer_bit_width_t bit_width;          ///< Bit width.
    uint8_t               interrupt_priority; ///< Interrupt priority.
    void *                p_context;          ///< Context passed to interrupt handler.
} nrfx_timer_config_t; 

/** @brief Timer driver instance default configuration. */
#define NRFX_TIMER_DEFAULT_CONFIG                                                    \
{                                                                                    \
    .frequency          = (nrf_timer_frequency_t)NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY,\ 
    .mode               = (nrf_timer_mode_t)NRFX_TIMER_DEFAULT_CONFIG_MODE,          \
    .bit_width          = (nrf_timer_bit_width_t)NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH,\
    .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,                    \
    .p_context          = NULL                                                       \
}

我不明白的是他们的预处理指令中的符号#define NRFX_TIMER_DEFAULT_CONFIG。点运算符用于访问结构成员,但点的左侧没有任何内容,那么编译器如何知道要访问哪个结构?我本来期望像这样的:

nrfx_timer_config_t.frequency = NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY, \

但没有对nrfx_timer_config_t结构的引用。我猜这(nrf_timer_frequency_t)是以某种方式表示成员资格,但我不明白它是如何做到这一点的,.interrupt_priority而且.p_context似乎根本没有对nrfx_timer_config_t结构的任何引用。编译器如何知道这些值来自哪里以及如何分配它们?

此外,我不确定是否需要此上下文,但nrf_timer_frequency_t,nrf_timer_mode_tnrf_timer_bit_width_t都是枚举。

任何帮助理解这里发生的事情将不胜感激,谢谢!

标签: cembeddedpreprocessor-directive

解决方案


它与宏语法或预处理器指令无关。它是一个指定的初始化器,并且自 ISO C99 以来一直是 C 语言的一部分。

在这种情况下,用例将实例化一个类型的对象nrfx_timer_config_t并使用以下方法对其进行初始化NRFX_TIMER_DEFAULT_CONFIG

nrfx_timer_config_t timer1 = NRFX_TIMER_DEFAULT_CONFIG ;

扩展为:

nrfx_timer_config_t timer1 = {
    .frequency          = (nrf_timer_frequency_t)NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY,
    .mode               = (nrf_timer_mode_t)NRFX_TIMER_DEFAULT_CONFIG_MODE,
    .bit_width          = (nrf_timer_bit_width_t)NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH,
    .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
    .p_context          = NULL
};

(忽略 theNULL和任何其他宏也会被扩展的事实)。

关于:

我本来期望像这样的:

nrfx_timer_config_t.frequency = NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY, \ 

...点运算符 ( ) 的左侧.不能是类型名称,它必须是对象。宏用于初始化这样的对象(在 的 lhs 上=

关于:

我猜 ( nrf_timer_frequency_t) 以某种方式表示成员资格,

不,这正是它的样子,一个常规的类型转换。如果NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY如果枚举的枚举符号(或扩展为一个的宏),则强制转换nrf_timer_frequency_t是不必要的。


推荐阅读