Размещение памяти в C-функции
Я хотел бы создать программное обеспечение, где некоторые функции (или блоки) могут быть запрограммированы позже на моем микроконтроллере без необходимости перепрошивки всего программного обеспечения снова (флэш-память будет выполняться через интерфейс связи, например, SPI). Все новые блоки будут иметь один и тот же API (например, 5 байтов в качестве аргументов, 1 байт возвращается).
Архитектура памяти будет организована так, как показано на этом рисунке: архитектура памяти
Подводя итог, блоки FBL и APPL будут запрограммированы только один раз на MCU. Позже я хочу иметь возможность программировать или изменять некоторые функции в созданных блоках (БЛОК 1, БЛОК 2 ...)
Для каждого блока у меня есть:
- 2 раздела flash (один для функции init и один для функции "task").
- 1 раздел оперативной памяти, куда я могу поместить свои статические переменные.
В настоящее время моя проблема заключается в том, что я не могу создать один блок памяти со всем содержимым моей функции. Например, если я хочу использовать функцию из math.h в моем новом блоке, компоновщик поместит функции math.h в мой сектор APPL, а не в выделенный сектор памяти, выделенный для этого блока. Но, как я уже сказал, мой сектор APPL не должен меняться, потому что он будет запрограммирован только 1 раз. Итак, я хотел бы знать, как я могу написать некоторые "независимые" блоки...
Большое спасибо!
1 ответ
Вы должны убедиться, что все функции стандартной библиотеки, которые вам когда-либо понадобятся, будут вызваны хотя бы один раз и будут включены в ваш двоичный базовый код.
Для вашего "переменного" кода у вас должна быть своего рода таблица переходов в начале блока. Ваш базовый код вызывает функцию в коде переменной, и таблица переходов переходит к фактической точке входа функции (или вы можете иметь функции-оболочки), например:
char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}
char _f1(int a, int b) { return 0;} /* function not yet developed */
char _f2(int a, int b) { return 0;} /* function not yet developed */
и в коде, когда-то разработанном:
char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}
char _f1(int a, int b) {
/* lots of complex stuff */
return result;
}
char _f2(int a, int b) {
/* lots of complex stuff */
return result;
}
Здесь функции f1
, f2
etc будет находиться в фиксированном месте кода переменной и может вызываться из базового кода. После того, как окончательная версия блока кода мигает, они называют свою окончательную версию.
Примечание: я не уверен, как обращаться с функциями вызова кода переменной из стандартной библиотеки, которые размещены в вашей базовой области кода. Компоновщик для блока переменных должен либо дублировать загрузку функции в коде переменной, либо знать его абсолютное местоположение в области базового кода. Вы должны проверить документацию компоновщика / загрузчика для этого.