I have a struct with 10 function pointers. A global instance of the struct is initialized wit function pointers pointing to local functions. In my application, using any one or more of the function references causes linker to include all 10 functions in the map file.
In order to save memory, I need linker to include onle those functions that used in the application. Not all the functions referenced in the struct.
Struct in file r_adc_api.h (from Manufacturer)
typedef struct st_adc_api
{
ssp_err_t (* open)(adc_ctrl_t * const p_ctrl, adc_cfg_t const * const p_cfg);
ssp_err_t (* scanCfg)(adc_ctrl_t * const p_ctrl, adc_channel_cfg_t const * const p_channel_cfg);
ssp_err_t (* scanStart)(adc_ctrl_t * const p_ctrl);
ssp_err_t (* scanStop)(adc_ctrl_t * const p_ctrl);
ssp_err_t (* scanStatusGet)(adc_ctrl_t * const p_ctrl);
ssp_err_t (* read)(adc_ctrl_t * const p_ctrl, adc_register_t const reg_id, adc_data_size_t * const p_data);
ssp_err_t (* sampleStateCountSet)(adc_ctrl_t * const p_ctrl, adc_sample_state_t * p_sample);
ssp_err_t (* close)(adc_ctrl_t * const p_ctrl);
ssp_err_t (* infoGet) (adc_ctrl_t * const p_ctrl, adc_info_t * const p_adc_info);
ssp_err_t (* versionGet)(ssp_version_t * const p_version);
} adc_api_t;
**Header r_adc.h ** (from Manufacturer)
extern const adc_api_t g_adc_on_adc;
Assignment and function definitions is in file r_adc.c (from Manufacturer)
const adc_api_t g_adc_on_adc =
{
.open = R_ADC_Open,
.scanCfg = R_ADC_ScanConfigure,
.infoGet = R_ADC_InfoGet,
.scanStart = R_ADC_ScanStart,
.scanStop = R_ADC_ScanStop,
.scanStatusGet = R_ADC_CheckScanDone,
.sampleStateCountSet = R_ADC_SetSampleStateCount,
.read = R_ADC_Read,
.close = R_ADC_Close,
.versionGet = R_ADC_VersionGet
};
and ## Function Definitions ##
** MAP File ** MAP file
In my Application, if i use adc_on_g_adc.open(...); linker pulls all 10 symbols to the map file instead of just pulling R_ADC_Open();
What might be causing .map file to pull all the functions from the struct even if one function is called?
Edit: Putting all these together in one single file gives map file I need. IAR compiler omits unused functions. Just doesn't work when I use multiple header and source.
If you fill up the structure with function pointers, the functions have been "used" so far as the linker is concerned.
Think about it in terms of what the linker is supposed to replace R_ADC_ScanConfigure
with. It can't choose to set g_adc_on_adc.scanCfg
to NULL, can it? It doesn't know that the object code doesn't actually call g_adc_on_adc.scanCfg
.
Basically, it's only option is to include R_ADC_ScanConfigure
in the output.
However, if instead of assigning R_ADC_ScanConfigure
in the structure you set g_adc_on_adc.scanCfg
to NULL, the linker would then be able omit R_ADC_ScanConfigure
from the output.
const adc_api_t g_adc_on_adc =
{
.open = R_ADC_Open,
.scanCfg = NULL,
.infoGet = R_ADC_InfoGet,
.scanStart = R_ADC_ScanStart,
.scanStop = R_ADC_ScanStop,
.scanStatusGet = R_ADC_CheckScanDone,
.sampleStateCountSet = R_ADC_SetSampleStateCount,
.read = R_ADC_Read,
.close = R_ADC_Close,
.versionGet = R_ADC_VersionGet
};
Of course, if your code then did end up calling g_adc_on_adc.scanCfg
you'd be trying to run code at address 0 (probably), which would be a very bad thing indeed. You could make .scanCfg
point to a function that simply prints up a nasty error message on your console / down your serial port / whatever so that at least you know something has gone wrong.