2017-03-31 79 views
3

我想了解一个轮胎压力监测系统的软件,但我对C语言知之甚少。 在头文件中的一个有这几样定义:将函数强制转换为c程序中的函数指针

#define TPMS_RESET   gu16AddressToFn = u16fnDALLinkFmw(gu8Derivative, FN_RESET);\ 
         ((void(*)(void))(gu16AddressToFn)) 

/* UINT8 TPMS_READ_VOLTAGE(UINT16 *u16UUMA) */ 
#define TPMS_READ_VOLTAGE ((UINT8(*)(UINT16*))(u16fnDALLinkFmw(gu8Derivative, FN_READ_VOLT))) 

/* UINT8 TPMS_COMP_VOLTAGE(UINT8 *u8CompVoltage, *UINT16 u16UUMA) */ 
#define TPMS_COMP_VOLTAGE ((UINT8(*)(UINT8*, UINT16*))(u16fnDALLinkFmw(gu8Derivative, FN_COMP_V))) 

/* UINT8 TPMS_READ_TEMPERATURE(UINT16 *u16UUMA) */ 
#define TPMS_READ_TEMPERATURE ((UINT8(*)(UINT16*))(u16fnDALLinkFmw(gu8Derivative, FN_READ_T))) 

/* UINT8 TPMS_COMP_TEMPERATURE(UINT8 *u8Temp, UINT16 *u16UUMA) */ 
#define TPMS_COMP_TEMPERATURE ((UINT8(*)(UINT8*, UINT16*))(u16fnDALLinkFmw(gu8Derivative, FN_COMP_T))) 

/* UINT8 TPMS_READ_PRESSURE(UINT16 *u16UUMA, UINT8 u8Avg) */ 
#define TPMS_READ_PRESSURE ((UINT8(*)(UINT16*, UINT8))(u16fnDALLinkFmw(gu8Derivative, FN_READ_P))) 

/* UINT8 TPMS_COMP_PRESSURE(UINT16 *u16CompPressure, UINT16 *u16UUMA) */ 
#define TPMS_COMP_PRESSURE ((UINT8(*)(UINT16*, UINT16*))(u16fnDALLinkFmw(gu8Derivative, FN_COMP_P)))  

/* UINT8 TPMS_READ_ACCEL_X(UINT16 *u16UUMA, UINT8 u8Avg, UINT8 u8FiltSelect, UINT8 u8DynamicOffset) */ 
#define TPMS_READ_ACCEL_X ((UINT8(*)(UINT16*, UINT8, UINT8, UINT8))(u16fnDALLinkFmw(gu8Derivative, FN_READ_X))) 

/* UINT8 TPMS_READ_ACCEL_Z(UINT16 *u16UUMA, UINT8 u8Avg, UINT8 u8FiltSelect, UINT8 u8DynamicOffset) */ 
#define TPMS_READ_ACCEL_Z ((UINT8(*)(UINT16*, UINT8, UINT8, UINT8))(u16fnDALLinkFmw(gu8Derivative, FN_READ_Z))) 

我不真正了解铸造成其他功能的这一招。你有什么想法吗?

+0

什么是'u16fnDALLinkFmw'?什么是'gu8Derivative'? –

+0

这是一个很好的例子,使用'typedef'会导致更多可理解的代码。 –

回答

5

函数指针铸造是将非C固件内存地址转换成C.有效的函数声明这是在嵌入式系统中正常完成,当你访问固件功能的方法(可能是写在非C语言/汇编)没有将固件的API作为C API公开。

例如,在您的情况下,固件提供了gu8Derivative(固件代码中的跳转表)中固件功能的地址列表。使用u16fnDALLinkFmw(gu8Derivative, X)你可以得到跳地址固件的功能X这相当于在C函数指针现在,由于在固件的函数声明不是在C直接知道,它是作为一个函数指针投用提供描述相应固件功能的API的附带评论。

This NXP community post提供有关您正在尝试使用这个确切的固件的更多细节。

+0

在“gu16AddressToFn”中,gu8代表全局无符号8位? –

+0

'u16'和'u8'通常代表'unsigned' 16位或8位,但我不确定'g'在这里的含义是什么 - 'global'似乎是可能的,但是如果不仔细查看,码。 – iVoid

0

你现在都最终在功能方面(可能)或者是另一个宏(不太可能),u16fnDALLinkFmw()定义的宏。我会认为这是一个功能。然而,你并不完全明白这里发生了什么:宏代替文本中的代码并不是,它的功能是;相反,他们正在铸造它的返回值

什么似乎是这里发生了,因此,这是动态调度的变化。这些宏提供了通过offset/id在指定表中查找每个需要的函数,并且由于不同ID的查找函数可能具有不同的签名,所以宏将返回的函数指针转换为正确签名函数指针类型。

你可以使用这些东西是这样的:

uint16_t argument = 1; 
uint8_t result = TPMS_READ_VOLTAGE(&argument);