I'm doing some code for microcontrollers where I need to look up data based on function pointers (this data and the functions will be in ROM).
I'd like to be able to do this relatively quickly, and without using RAM for a lookup table. The easiest way I can think to do this would be to do a binary search.
I just hacked this up as an example, so it might be broken but hopefully you get the idea:
void myFunction1() {}
void myFunction2() {}
void myFunction3() {}
void myFunction4() {}
// ...
typedef struct {
void *functionPtr;
int myData[10];
} SearchData;
const SearchData mySearchData[] = {
{ &myFunction1, ... },
{ &myFunction2, ... },
{ &myFunction3, ... },
{ &myFunction4, ... },
// ...
};
void doBinarySearch(void *func, int min, int max) {
if (max<min) return;
int mid = (min+max)/2;
if (func < mySearchData[mid].functionPtr)
doBinarySearch(func, min, mid-1);
else if (func > mySearchData[mid].functionPtr)
doBinarySearch(func, mid+1, max);
else {
// we found it!
}
}
void realBinarySearch(void *func) {
doBinarySearch(func, 0, (sizeof(mySearchData)/sizeof(SearchData))-1);
}
However for this to work, myFunction1
, myFunction2
, etc need to be laid out one after the other in memory (although not necessarily right next to each other). I need to compile everything with -Os
to fit it in available ROM, so how do I ensure that the functions actually stay in the correct order?
...or failing that, how could I re-order mySearchData
such that it matches the order of the functions?
About the only things I can think of right now are:
- build the whole thing and then have a post-processing step that sorts the array inside the binary - very un-portable though.
- build once, look at the list file to figure out the real order of functions, re-write
mySearchData
and compile again - but there's no guarantee the compiler is deterministic
Neither of those sound great though.