从这个问题:“Accessing a member of a pointer (variable) struct within a struct”。我们可以使用(undefined?)结构来接受一些(未知类型?)参数:配置包含许多成员的结构的C函数,作为* BASE(指向结构的指针),ID,MODE;但BASE是一个结构,可能被定义为(例如)“struct a”,“struct b”,“...”,具体取决于接口。在前一个问题的讨论之后,我们终于得到了这个结构声明:
typedef struct _Interface_t{
struct PERIPH_BASE * BASE;
u32_t ID;
u32_t MODE;
} Interface_t; //Typo edit
interface_t USART0_DEV = {(struct PERIPH_BASE *)AT91C_BASE_US0, AT91C_ID_US0, 0}; // <-- AT91C_BASE_US0 struct as *BASE
interface_t TC0_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TC0, AT91C_ID_TC0, 0}; // <-- AT91C_BASE_TC0 struct as *BASE
interface_t TWI_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TWI, AT91C_ID_TWI, 0}; // <-- AT91C_BASE_TWI struct as *BASE
...
unsigned char ConfigureDevice(Interface_t Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, u32_t IRQ_Mode, void (*Interface_irq_handler)(void)){
...
USART_Configure(Interface, config, Speed, PERIPHERALS_CLOCK); //ERROR0
if (*Interface_irq_handler != NULL){
((AT91S_USART)Interface->BASE)->US_IER = IRQ_Trigger; //ERROR1
}
USART_SetTransmitterEnabled(Interface->BASE, 1); //ERROR1
USART_SetReceiverEnabled(Interface->BASE, 1); //ERROR1
}
以这种方式Eclipse代码编辑器没有抛出任何警告或错误,但是I Builded所有项目和Compiler Complained:
incompatible type for argument 1 of 'USART_Configure'
(ERROR0)
invalid type argument of '->' (have 'Interface_t')
(ERROR1)
在我收到以下错误之前:"cast to union type from type not present in union"
;
所以,我认为也许我知道BASE
结构的类型我是“接收”(AT91S_PWMC,AT91S_USART,AT91S_AIC,......:请阅读Accessing a member of a pointer (variable) struct within a struct)我可以(重新)将PERIPH_BASE Struct定义为Recieved Struct。如果我错了,请纠正我......
最诚挚的问候!,提前感谢您的答案!
编辑:添加USART_Configure代码:
void USART_Configure(AT91S_USART *usart,
unsigned int mode,
unsigned int baudrate,
unsigned int masterClock)
{
// Reset and disable receiver & transmitter
usart->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX
| AT91C_US_RXDIS | AT91C_US_TXDIS;
// Configure mode
usart->US_MR = mode;
// Configure baudrate
// Asynchronous, no oversampling
if (((mode & AT91C_US_SYNC) == 0)
&& ((mode & AT91C_US_OVER) == 0)) {
usart->US_BRGR = (masterClock / baudrate) / 16;
}
}
编辑2:完整代码
#include "Config_file.h"
#include "board.h"
#include "aic/aic.h"
#include "pmc/pmc.h"
#include "twi/twi.h"
#include "usart/usart.h"
typedef volatile unsigned int u32_t;
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};
Interface_t USART1_DEV = {(struct PERIPH_BASE *)AT91C_BASE_US1, AT91C_ID_US1, 0};
Interface_t TC0_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TC0, AT91C_ID_TC0, 0};
Interface_t TC1_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TC1, AT91C_ID_TC1, 0};
Interface_t TC2_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TC2, AT91C_ID_TC2, 0};
Interface_t TWI_DEV = {(struct PERIPH_BASE *)AT91C_BASE_TWI, AT91C_ID_TWI, 0};
...
unsigned char ConfigureDevice(Interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, u32_t IRQ_Mode, void (*Interface_irq_handler)(void)){
PMC_EnablePeripheral(Interface->ID);
switch(Interface->ID){
case AT91C_ID_FIQ: // Interface is FIQ!
TRACE_ERROR("Attempt to Configure an FIQ as System Peripheral!");
break;
case AT91C_ID_SYS: // Interface is SYS!
if (*Interface_irq_handler != NULL){
((AT91S_SYS)Interface->BASE)->AIC_IECR = IRQ_Trigger;
}
break;
case AT91C_ID_PIOA|AT91C_ID_PIOB: // Interface is PIO!
// PIO_Configure(); ///XXX: PIO_Configure To Be Modified
if (*Interface_irq_handler != NULL){
((AT91S_PIO)Interface->BASE)->PIO_IER= IRQ_Trigger;
}
break;
case AT91C_ID_SPI0|AT91C_ID_SPI1: // Interface is SPI!
// SPI_Configure(Interface, config, Speed, PERIPHERALS_CLOCK); //XXX: SPI_Configure To Be Written
if (*Interface_irq_handler != NULL){
((AT91S_SPI)Interface->BASE)->SPI_IER = IRQ_Trigger;
}
break;
case AT91C_ID_US0|AT91C_ID_US1: // Interface is USART!
(AT91S_USART)Interface->BASE;
USART_Configure(Interface->BASE, config, Speed, PERIPHERALS_CLOCK);
if (*Interface_irq_handler != NULL){
((AT91S_USART)Interface->BASE)->US_IER = IRQ_Trigger;
}
USART_SetTransmitterEnabled(Interface->BASE, 1);
USART_SetReceiverEnabled(Interface->BASE, 1);
break;
case AT91C_ID_SSC: // Interface is SSC!
if (*Interface_irq_handler != NULL){
((AT91S_SSC)Interface->BASE)->SSC_IER = IRQ_Trigger;
}
break;
case AT91C_ID_TWI: // Interface is TWI!
if (*Interface_irq_handler != NULL){
((AT91S_TWI)Interface->BASE)->TWI_IER = IRQ_Trigger;
TWI_ConfigureMaster(Interface->BASE, Speed, PERIPHERALS_CLOCK);
}
break;
case AT91C_ID_PWMC: // Interface is PWM!
if (*Interface_irq_handler != NULL){
((AT91S_PWMC)Interface->BASE)->PWMC_IER = IRQ_Trigger;
}
break;
case AT91C_ID_UDP: // Interface is USB!
if (*Interface_irq_handler != NULL){
((AT91S_UDP)Interface->BASE)->UDP_IER = IRQ_Trigger;
}
break;
case AT91C_ID_TC0|AT91C_ID_TC1|AT91C_ID_TC2: // Interface is TC!
unsigned int div, tcclks;
PMC_EnablePeripheral(Interface->ID); // Enable TC0 peripheral clock
TC_FindMckDivisor(Speed, PERIPHERALS_CLOCK, &div, &tcclks); // Configure TC for a (u32_t Speed) In Hertz
TC_Configure(Interface->BASE, tcclks | config); // interrupt configuration
((AT91S_TC)Interface->BASE)->TC_RC = (PERIPHERALS_CLOCK / (2 * div));
if (*Interface_irq_handler != NULL){
((AT91S_TC)Interface->BASE)->TC_IER = IRQ_Trigger;
}
break;
case AT91C_ID_CAN: // Interface is CAN!
if (*Interface_irq_handler != NULL){
((AT91S_CAN)Interface->BASE)->CAN_IER = IRQ_Trigger;
}
break;
case AT91C_ID_EMAC: // Interface is EMAC!
if (*Interface_irq_handler != NULL){
((AT91S_EMAC)Interface->BASE)->EMAC_IER = IRQ_Trigger;
}
break;
case AT91C_ID_ADC: // Interface is ADC!
if (*Interface_irq_handler != NULL){
((AT91S_ADC)Interface->BASE)->ADC_IER = IRQ_Trigger;
}
break;
case AT91C_ID_IRQ0|AT91C_ID_IRQ1: // Interface is IRQ!
TRACE_ERROR("Attempt to Configure an IRQ as System Peripheral!");
break;
default:
TRACE_ERROR("Attempt to Configure an Undefined IRQ!"); // Unknown Interface!
break;
}
return 0;
}
void ConfigureAIC(Interface_t *Interface, u32_t IRQ_Mode, void (*Interface_irq_handler)(void)){
AIC_ConfigureIT(Interface->ID, IRQ_Mode, *Interface_irq_handler);
AIC_EnableIT(Interface->ID);
}
答案 0 :(得分:2)
您在一个地方拼写了interface_t
小写i
,而在另一个地方拼写了大写i
。 C是区分大小写的语言,因此您需要与案例保持一致(对于类型使用大写首字母并不罕见。)
答案 1 :(得分:1)
最初你的问题说这个功能花了
Interface_t * Interface
作为第一个参数。现在您已将其更改为
Interface_t Interface
如果确实是代码,请使用
更改所有行Interface->
到
Interface.
在黑暗中狂野刺伤,USART_Configure
可能需要基指针:
USART_Configure(Interface.BASE, config, Speed, PERIPHERALS_CLOCK);