【发布时间】:2014-11-27 21:14:43
【问题描述】:
我正在做一个需要 USB 通信的项目。 我使用的是运行 ARM cortex M0 内核的 Nuvoton NUC123,速度为 48MHz、20kb RAM 和 64kb 闪存。 每当 USB 端点从主机接收到数据传输给它时,微控制器就会实现硬件中断,无论是 Ack、Nak 还是设置数据包。 制造商提供的示例代码相当脏,它涉及对中断所属的端点进行 switch-case,如果它是包含特定于类的请求的设置数据包,它会为每个接口或端点创建一个 switch-case这可能是请求的目标。
我想我可以通过定义一个结构数组来让事情变得更漂亮:
typedef void UsbEventCallback(uint32_t u32IntFlag, uint32_t u32EPSTS);
typedef uint32_t UsbClassReqCallback(void);
typedef struct
{
uint8_t ep_address;
uint32_t config;
uint32_t buff_offset;
UsbClassReqCallback *usb_classreq_cb;
UsbEventCallback *usb_event_cb;
} ATTR_PACKED EP_Config_Struct;
typedef struct
{
uint8_t interface_id;
UsbClassReqCallback *usb_classreq_cb;
} ATTR_PACKED Interface_Config_Struct;
extern const EP_Config_Struct EP_config_settings[TOTAL_NUM_ENDPOINTS];
extern const Interface_Config_Struct interfaces_config_settings[TOTAL_NUM_INTERFACES];
然后,在我做的中断回调中:
switch( req_destination )
{
case 1: //interface
for ( uint8_t interface_index = 0 ; interface_index < TOTAL_NUM_INTERFACES ; interface_index++ )
{
if ( interfaces_config_settings[interface_index].interface_id == UsbDev.Setup.wIndex )
{
if ( interfaces_config_settings[interface_index].usb_classreq_cb == NULL )
return FALSE;
else
return (*interfaces_config_settings[interface_index].usb_classreq_cb)();
}
}
break;
case 2: //endpoint
for ( uint8_t ep_index = 0 ; ep_index < TOTAL_NUM_ENDPOINTS ; ep_index++ )
{
if ( EP_config_settings[ep_index].ep_address == UsbDev.Setup.wIndex )
{
if ( EP_config_settings[ep_index].usb_classreq_cb == NULL )
return FALSE;
else
return (*EP_config_settings[ep_index].usb_classreq_cb)();
}
}
break;
}
return FALSE;
我的问题是: 不实际做出所有这些决定并在中断时间调用所有这些其他函数会更好吗?我最好只保存中断数据并打开一些标志,要求主线程处理中断吗? 尽快从回调中返回有多重要?
您认为这样一个程序的正确架构是什么?
谢谢
【问题讨论】:
-
您可以考虑缩进您的代码,使一行不超过 100 个字符,甚至更好的是 80 个字符;)