0

这是交易:我正在研究一个 C 函数,它配置一个包含许多成员的结构,作为 *BASE(指向结构的指针),ID,MODE;但是 BASE 是一个结构,可以定义为(比如)“struct a”、“struct b”、“...”,具体取决于接口。这是结构(和一些示例)声明:

typedef unsigned int u32_t;
typedef unsigned char u8_t;
typedef struct _interface_t{
    u32_t *BASE;
    u8_t ID;
    u32_t MODE;
} interface_t;

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0}; // <-- Here we have a AT91C_BASE_US0 struct as *BASE
interface_t USART1_DEV  = {AT91C_BASE_US1, AT91C_ID_US1, 0};
interface_t TC0_DEV     = {AT91C_BASE_TC0, AT91C_ID_TC0, 0}; // <-- Here we have a AT91C_BASE_TC0 struct as *BASE
interface_t TC1_DEV     = {AT91C_BASE_TC1, AT91C_ID_TC1, 0};
interface_t TC2_DEV     = {AT91C_BASE_TC2, AT91C_ID_TC2, 0};
interface_t TWI_DEV     = {AT91C_BASE_TWI, AT91C_ID_TWI, 0}; // <-- Here we have a AT91C_BASE_TWI struct as *BASE

如您所见,我使用u32_t而不是结构,因为我声明了指向该结构的指针。后来我将我的功能定义为:

unsigned char ConfigureDevice(interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, void (*Interface_irq_handler)(void)){
    ...
    Interface->BASE->US_IER = IRQ_Trigger; //Note: US_IER Must receive a vector to a function
    ...
}

但我收到错误“无法解决 US_IER”。所以我尝试了AT91S_USART InterfaceBASE = Interface->BASE; InterfaceBASE->US_IER = IRQ_Trigger;而不是Interface->BASE->US_IER = IRQ_Trigger;没有错误。但我不能使用它,因为我并不总是知道我正在处理什么样的接口(直到我阅读 ID 成员)。

更糟糕的是:当我尝试编译时,我不断在typedef中收到conflicting type qualifiers for 'u32_t'错误,并在每个定义中收到警告。u32_tinitialization from incompatible pointer typenear initialization for USART0_DEV.BASEinterface_t

我在论坛中搜索,但我无法弄清楚我的错误。这些有点帮助:

我的代码有什么问题?我能做些什么来使用类似的东西Interface->BASE->US_IER

编辑:嗨!,所以现在这就是我得到的:

typedef struct _Interface_t{
    struct PERIPH_BASE * BASE;
    u32_t ID;
    u32_t MODE;
Interface_t;

Interface_t USART0_DEV  = {(struct PERIPH_BASE *)AT91C_BASE_US0, AT91C_ID_US0, 0};
...
unsigned char ConfigureDevice(Interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger,...
...
((AT91S_SYS)Interface->BASE)->AIC_IECR = IRQ_Trigger; //No problems marked by Eclipse Code Editor
....

}

看起来不错,但是编译时出现cast to union type from type not present in union错误...

4

3 回答 3

1

如果您想保持“开放”,您应该将您的定义BASE

void *BASE;

或者,为了表明/记录它是一个特殊的指针,您可以使用不完整的类型:

struct hwbase * BASE;

并将其定义为

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0};

如果你使用过void *或者更确切地说

interface_t USART0_DEV  = {(struct hwbase *)AT91C_BASE_US0, AT91C_ID_US0, 0};

对于第二个选项。

然后,在使用它时,确保在正确类型的硬件(例如 TWI、USART)上进行操作后,您就可以进行投射了。

将指针从上方投射到正确的类型,例如

unsigned char ConfigureDevice(interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, void (*Interface_irq_handler)(void)){
    ...
    ((AT91S_USART *)Interface->BASE)->US_IER = IRQ_Trigger; //Note: US_IER Must receive a vector to a function
    ...
}

(这里我不确定是否AT91S_USART已经是指针类型 - 在这种情况下,你省略了*.)

另一种选择可能是添加一些函数指针以获得一种“穷人的 OOP”:

typedef void config_func(struct _interface_t *, whateveryouneed...)

config_func config_usart; // forward declaration, does as well ensire you have no typo in the function
typedef struct _interface_t{
    void *BASE;
    u8_t ID;
    u32_t MODE;
    config_func * configure; // function pointer
} interface_t;

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0, config_usart };

void config_usart(struct _interface_t * iface, whateveryouneed...)
{
    AT91S_USART * my_base = iface->BASE;
    ...
    my_base->US_IER = ...
    ...
}
于 2013-08-07T06:05:58.233 回答
0

您已将基本成员定义为 u32_t 上的指针,因此编译器认为它指向的是 u32_t,而 u32_t 没有名为 US_IER 的成员。当您使用代码的“工作”版本时会发生什么是从 uint_32* 到 AT91S_USART* 的指针的隐式转换,其中包含所需的成员。

于 2013-08-07T04:09:07.150 回答
0

BASE 是一个类型的变量,u32_t pointer它试图访问一个US_IERu32_t pointer. u32_t pointer但是您希望将其定义为 a 的期望structure pointer可能是不可能的,因为如果通过结构指针访问它,编译器将期望应该已经定义了一个成员。

但是对于您的情况(即,具有 128 个不同的接口类型),使用这 3 个必需成员(在所有 128 个接口中通用)定义一个结构类型,US_IER, US_IAM, US_IDM并在该结构中定义一个具有所需可能成员的联合,并尝试使用 switch 案例访问这些项目否则。

于 2013-08-07T05:51:59.253 回答