I'm trying to optimize access to some jump tables I have made, they are as follows:
int (*const usart_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[USART_READ_WRITE_CLEAR])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
As you can see, the functions are for accessing a usart peripheral on a hardware level and are arranged in the table in the order of read/write/clear.
What I am attempting to do is have another jump table of jump tables, this way I can either run through initializing all the usart's registers in startup or simply change a single register later if desired.
i.e.
<datatype> (*usart_peripheral_table[<number of jump tables>])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
This way I can expose that table to my middleware layer, which will help maintain a standard across changing HALs, and also I can use a define to index this table i.e.
fn_ptr = usart_peripheral_table[CTRL_TABLE]
fn_ptr[WRITE](bitmask);
fn_ptr[READ](buffer);
As you may have already guessed, I am struggling to figure out how to construct this table. I figured it is one of two things:
Another simple array of pointers, as even a jump table itself is just an array of pointers. Hence my initialization would be:
const int* (*usart_peripheral_table[<number of jump tables])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
However this doesn't seem to be working. Then I thought:
An array of pointers to pointers. So I tried all kinds of combos:
const int**(*usart_perip...
const int**(usart_perip...
const int** (*usart_peripheral_table[<number of jump tables])() =
{&usart_ctrl_table, &usart_frame_table[0], usart_trig_ctrl_table};
Nothing seems to work. Do I need to store the address of the lower jump tables in yet another pointer before assigning that variable to a pointer-to-pointer array? i.e.
int* fn_ptr = usart_ctrl_table;
<dataytype>(*const usart_periph[<number>])() = {fn_ptr};
Thanks in advance, any help would be greatly appreciated.
MM25
EDIT:
const int** (*const peripheral_table[1])() =
{&usart_ctrl_table[0]};
const int** (*const peripheral_table[1])() =
{usart_ctrl_table};
The above both give the error "initialization from incomaptible pointer type", as do all other combinations I have tried
Just add a *
like you added []
when defining an array.
int zg_usartCtrlRead();
int zg_usartCtrlWrite();
int zg_usartCtrlClr();
int zg_usartFrameRead();
int zg_usartFrameWrite();
int zg_usartFrameClr();
int zg_usartTrigctrlRead();
int zg_usartTrigctrlWrite();
int zg_usartTrigctrlClr();
int (*const usart_ctrl_table[])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
int (* const * const usart_peripheral_table[])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
Usage:
usart_peripheral_table[1][2](5, 1, 3, 5, 6);
Btw, an empty parameter list on function declaration ()
means unspecified number and type of arguments. Do (void)
if you want no arguments passed to your function.
This:
const int* (*usart_peripheral_table[<number of jump tables])();
Is an array of functions pointers that take unspecified number of arguments and return a pointer to constant integer.
This:
const int** (*usart_peripheral_table[<number of jump tables])()
Is an array of function pointers that take unspecified number of arguments and return a pointer to a pointer to a constant integer.
You can also go with a 2D array:
int (* const usart_peripheral_table_2d[][3])() = {
{
zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr,
}, {
zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr,
}, {
zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr,
},
};
But maybe you want to write accessor functions that will return a pointer to an array of functions. Nothing simpler!
#include <stddef.h>
int (*usart_ctrl_table_get(size_t idx))() {
return usart_ctrl_table[idx];
}
int (*usart_frame_table_get(size_t idx))() {
return usart_frame_table[idx];
}
int (*usart_trig_ctrl_table_get(size_t idx))() {
return usart_trig_ctrl_table[idx];
}
int (* const (* const usart_peripheral_table_indirect[])(size_t))() = {
usart_ctrl_table_get,
usart_frame_table_get,
usart_trig_ctrl_table_get,
};
Usage sample:
int main() {
usart_peripheral_table_indirect[2](1)();
}