И я не придумал ничего лучшего, как в скрипте линкера написать
Код
/*выше - секция .data */
/* конец данных во флеш - кладём сюда контрольную сумму */
.CheckSum :
/*AT ( _sidata + SIZEOF ( .data ) )*/
AT ( _sidata + (_edata - _sdata) )
{
. = ALIGN(4);
KEEP(*(.CheckSum))
} > FLASH
/*ниже - секция .bss*/
/* конец данных во флеш - кладём сюда контрольную сумму */
.CheckSum :
/*AT ( _sidata + SIZEOF ( .data ) )*/
AT ( _sidata + (_edata - _sdata) )
{
. = ALIGN(4);
KEEP(*(.CheckSum))
} > FLASH
/*ниже - секция .bss*/
(пробовал оба варианта AT(), работает одинаково)
Код
__attribute__ ((section(".CheckSum")))
const uint32_t gCoreChksum = 0xAABBCCDD;
const uint32_t gCoreChksum = 0xAABBCCDD;
И получил следующее:
- в map-файле моя переменная имеет тот же адрес, что и начало .data
- в программе взятие адреса также возвращает адрес начала .data
- в скомпилированном бинарнике переменную явно видно в самом конце, как я и хотел. Адрес её при этом с не совпадает с тем, что написано в map'е.
Собственно, вопросы:
- я правильно понимаю, что нашёл баг в линкере?
Код
C:\Program Files\GNU Tools ARM Embedded\4.9 2015q1\bin>arm-none-eabi-ld.exe --version
GNU ld (GNU Tools for ARM Embedded Processors) 2.24.0.20150304
GNU ld (GNU Tools for ARM Embedded Processors) 2.24.0.20150304
По хорошему, он должен работать единообразно. Или же единообразно не работать :-)
- (более насущный) как по-человечески сделать?
UPDATE
Вот так работает:
Код
/* конец данных во флеш - кладём сюда контрольную сумму */
.CheckSum (_sidata + SIZEOF(.data)) :
{
. = ALIGN(4);
KEEP(*(.CheckSum))
} > FLASH
.CheckSum (_sidata + SIZEOF(.data)) :
{
. = ALIGN(4);
KEEP(*(.CheckSum))
} > FLASH
Плохо, что я никак концепцию этого странного скрипта не пойму...