Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

casting functions into function pointers in a c programme

Tags:

c

casting

I am trying to understand a software for a Tire Pressure Monitoring System but I know little about C language. In one of the header files there is these kind of definitions :

#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)))

I don´t really understand this trick of casting into other functions. Have you got any idea?

like image 554
roi_saumon Avatar asked Aug 07 '26 14:08

roi_saumon


1 Answers

Function pointer casting is a way to convert non-C firmware memory addresses into valid function declarations in C. This is normally done in embedded systems when you're accessing firmware functions (probably written in non-C languages / assembly) without the firmware's API exposed as a C API.

For example, in your case, the firmware provides a list of addresses to firmware functions in gu8Derivative (a jump-table in the firmware code). Using u16fnDALLinkFmw(gu8Derivative, X) you can get the jump-address of function X in firmware which is equivalent to a function pointer in C. Now, since the function declaration in firmware is not known directly in C, it is provided as a function pointer cast with an accompanying comment describing the API of the corresponding firmware function.

This NXP community post gives some more details about this exact firmware you're trying to use.

like image 88
iVoid Avatar answered Aug 10 '26 11:08

iVoid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!