У меня есть те же предварительные условия, что и Дейв Дурбин в Как я могу реализовать таблицу динамической рассылки в C... кроме моей цели является AVR. Вот мои ограничения:
- Модули
- должны быть выбраны в списке, подобно Linux-компилированным модулям ядра
- количество модулей C (может быть С++) известно во время компиляции
- модули должны быть статически связаны (очевидно)
- Я хочу, чтобы таблица в программной памяти не была в SRAM.
Обычно таблица должна содержать элементы этого типа:
typedef struct jump_item {
uint16_t function_id;
void (*callback)(void);
} jump_item_t;
Я попытался использовать пользовательские разделы, как было предложено в ответе, но затем компоновщик выдает ошибку для неизвестного символа __start_myownsection
(любое имя раздела, которое я использую). Конечно, поскольку код нацелен на Linux/GCC. Но я думаю, что я близок, потому что avr-gcc
действительно может использовать sections, просто я еще не смог выяснить как складывать символы в пользовательский раздел и фактически указывать на начало таблицы, а также определять длину таблицы во время выполнения.
Как Ответ искусства" был адаптирован к AVR?
* РЕДАКТИРОВАТЬ *
Я вижу по крайней мере два способа достижения того, что я хочу, используя разделы, либо с функциями, "прикрепленными" к определенному пользователем разделу, либо таблицам структур (как определено выше), которые все будут складываться в пользовательском разделе, Мои текущие проблемы:
- неиспользуемые переменные оптимизируются во время компиляции!
- неиспользуемые функции оптимизируются во время связи из-за аргумента linker
-gc-sections
, который мне нужно очистить неиспользуемые функции.
Я предпочитаю второй вариант, что-то похожее на это:
module1.c:
const jump_item_t module1_table[] __attribute__((__progmem__, section("tbl_dispatch"))) =
{
{ 0x02, func11 },
{ 0x03, func12 },
...
};
module2.c:
const jump_item_t module2_table[] __attribute__((__progmem__, section("tbl_dispatch"))) =
{
{ 0x12, func21 },
{ 0x13, func22 },
...
};
Примечание: индексы не должны считаться релевантными.
Когда все модули определяют такие переменные, они оптимизируются, как нигде никакой ссылки на них. Они должны складываться в разделе tbl_dispatch
. Поэтому мой вопрос возвращается к:
Как я могу сказать компилятору об удалении переменных, которые он "думает" не используется, но только с определенными модулями C/С++?
Глобальная командная строка, которую я использую до сих пор, выглядит следующим образом:
avr-gcc -g -Wall -mcall-prologues -fshort-enums -Os \
-DF_CPU=8000000 -Wl,-relax -mmcu=... \
*.cpp *.c -o main
* РЕДАКТИРОВАТЬ *
К моему разочарованию, PROGMEM и пользовательские разделы не совпадают. Я попытался объединить их, но я получаю распространенные таблицы прыжка в памяти программ... когда я вообще их включаю. Факт, что даже не все таблицы отображаются в памяти программы.
Отказаться.
Любая идея приветствуется.