Все функции загрузчика объявлены в классе, размещаются в .ramfunc секции:
Код
void erasePage(const uint32_t * const page_addr) __attribute__ ((section(".ramfunc")));
void writePage(const uint32_t * const page_addr, const uint8_t * const pagebuf) __attribute__ ((section(".ramfunc")));
uint8_t read(const uint8_t * const addr) __attribute__ ((section(".ramfunc")));
void writePage(const uint32_t * const page_addr, const uint8_t * const pagebuf) __attribute__ ((section(".ramfunc")));
uint8_t read(const uint8_t * const addr) __attribute__ ((section(".ramfunc")));
Соответственно, секция в линковщике определяется перед .data:
Код
.text.align :
{
. = ALIGN(8);
_etext = .;
_sidata = _etext; /* start of initialized data label */
} > FLASH
/* RAM functions section */
.ramfunc :
{
. = ALIGN(8);
_sdata = .; /* start of .data label */
KEEP( *(.ramfunc) )
KEEP( *(.ramfunc.*) )
} > RAM AT > FLASH
.data : /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = .; /* end of .data label */
} > RAM AT > FLASH
...
{
. = ALIGN(8);
_etext = .;
_sidata = _etext; /* start of initialized data label */
} > FLASH
/* RAM functions section */
.ramfunc :
{
. = ALIGN(8);
_sdata = .; /* start of .data label */
KEEP( *(.ramfunc) )
KEEP( *(.ramfunc.*) )
} > RAM AT > FLASH
.data : /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = .; /* end of .data label */
} > RAM AT > FLASH
...
Вопрос 1: Что надо сделать, чтобы загрузчик мог обновлять помимо пользовательской прошивки в том числе и себя.
Предположение: для этого необходимо все функции ОС выделить в отдельную секцию, например .scmRTOS, и секцию поместить в RAM по аналогии с .ramfunc.
Насколько это легко осуществимо? Или мне надо оставить всё в секции .text и её целиком в RAM пихать, т.к. есть ещё глобальные объекты со своими функциями? Ни разу так не пробовал ещё...
Вопрос 2: возможно ли использовать какую-то #pragma, чтобы пихать содержимое всего файла или части файла в отдельную секцию? Сейчас каждый раз перед телом функции пишу атрибут:
Код
__attribute__ ((section(".ramfunc"))) void flashdrv_t::erase (void) { ... }
Предположение: я неверно понимаю использование атрибута section и его достаточно 1 раз написать в начале файла.Вопрос 3: возможно ли как-нибудь остановить выполнение ОС и продолжить нормальное выполнение кода, находящегося после строчки OS::run(); ?
Предположение: запретить pensv, systick, и осуществить переход goto label по прямой ссылке.