新手上路
- 积分
- 45
- 金钱
- 45
- 注册时间
- 2020-2-16
- 在线时间
- 21 小时
|
最近读到一段代码,想移植到自己的工程中使用。源码是LPC1764平台的,我想移植到STM32F4之中。代码如下头文件中:
/**
* @brief Macro to implement unique IPMI handler functions
*
* This macro declares a IPMI handler function with a specific name (based on Netfn and CMD).
* The handler is placed in a spefic memory region with all handlers, so we have all of them stored sequentially.
*
* @warning In order to use IPMI_HANDLER macro the user is required to have .ipmi_handlers section defined in the linker script, like the following example:
* @code
* .ipmi_handlers : ALIGN(4)
* {
* _ipmi_handlers = .;
* KEEP(*(.ipmi_handlers))
* _eipmi_handlers = .;
* } >FLASHAREA
* @endcode
*/
#define IPMI_HANDLER(name, netfn_id, cmd_id, args...) \
void ipmi_handler_##netfn_id##__##cmd_id##_f(args); \
const t_req_handler_record __attribute__ ((section (".ipmi_handlers"))) ipmi_handler_##netfn_id##__##cmd_id##_s = { .req_handler = ipmi_handler_##netfn_id##__##cmd_id##_f , .netfn = netfn_id, .cmd = cmd_id }; \
void ipmi_handler_##netfn_id##__##cmd_id##_f(args)
后面.c文件中使用:
IPMI_HANDLER(ipmi_storage_get_fru_info, NETFN_STORAGE, IPMI_GET_FRU_INVENTORY_AREA_INFO_CMD, ipmi_msg * req, ipmi_msg * rsp )
{
uint8_t len = rsp->data_len = 0;
uint8_t id = req->data[0];
if ( id < FRU_COUNT ) {
rsp->data[len++] = fru[id].fru_size & 0xFF;
rsp->data[len++] = (fru[id].fru_size & 0xFF00) >> 8;
rsp->data[len++] = 0x00; /* Device accessed by bytes */
rsp->completion_code = IPMI_CC_OK;
} else {
rsp->completion_code = IPMI_CC_INV_DATA_FIELD_IN_REQ;
}
rsp->data_len = len;
}
这个代码我理解的是动态定义函数。首先声明了一个函数ipmi_handler_netfn_id__cmd_id_f,入口参数是args... ,然后定义了一个t_req_handler_record类型的结构体,名字是ipmi_handler_netfn_id__cmd_id_s,最后一行的void是添加函数ipmi_handler_netfn_id__cmd_id_f的具体定义吧,不知道理解的是否正确。__attribute__ ((section (".ipmi_handlers")))应该是吧结构体定义到.ipmi_handlers段吧。
我不太清楚用这个宏定义定义出来的函数应该如何使用,而且头文件中注释中写道要想使用ipmi_handler,需要在链接脚本中插入一段代码,这个涉及到我的知识盲区了。
希望有人能够告知一下,这个是什么类型的一个编程应用,应该学习那些资料来了解。
这个是属于构建初始化函数表吗?
|
|