• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

RTL871x BootLoader

pvvx

Активный участник сообщества
Но сегодня нет исходников BootLoader-а.
BootLoader загружается из ROM-BIOS и находится в начале Flash (см. RTL871x Flash Memory Map).
У BL существует несколько веток старта (см. RTL8710AF - загрузчик в ROM-BIOS).
Указатель на процедуру стандартной загрузки с Flash находится первым в таблице BL. Другие указатели обычно содержат на одну и ту-же ссылку на процедуру старта используемую для отладки запуска кода из RAM, минуя загрузку из Flash.

Какие ныне проблемы с BL:
Область загрузки BL в RAM используется некоторыми процедурами из ROM-BIOS.
К примеру, содержит в своем теле по фиксированным адресам данные для ROM-BIOS (хотя-бы громадную структуру _reent *rtl_impure_ptr + _reent impure_data от общей либы СИ) и если они затерты и не восстановлены, то получите крах системы SDK в lib_rtlstd.a (процедуры rtl_printf и т.д.).

Расстановку переменных, задействованных в ROM-BIOS и находящихся в теле BL уже составил. Но пока не нашел как сделать линковку в GCC с такими условиями:
Возьмем, в качестве примера, тот-же указатель rtl_impure_ptr на структуру impure_data. Макрос инициализации есть стандартных исходниках либ GCC.

#include <reent.h>
struct _reent __attribute__((section(".libc.reent"))) impure_data = _REENT_INIT(impure_data);

С помощью __attribute__((section(".libc.reent"))) мы задали область линковки для этого блока. Он может находится где угодно в RAM - ROM-BIOS лезет к нему через указатель и у нас с ним проблем нет.
Теперь нам надо создать указатель на эту структуру, но положить практически посередине (!) тела BootLoader-a, чтобы абсолютный адрес у него был 0x10001c60.

Как это указать линковщику и в кодах СИ, чтобы данные и коды в BL обходили его?

Делать дыру в несколько килобайт ради него в сегменте BL, как это делает Ameba нет никакого желания. Прилинковать все данные от ROM-BIOS мы тоже не можем - нету куска с новыми процедурами расположенными в хвосте ROM. rom.a - это только первая редакция маски ROM, за ней дописали ещё вторую версию и все чипы с ней.
См. отличия export-rom_v02.txt и export-rom_v03.txt. Часть раздробленных кусков обновления есть в rom_v01.nodbg.a (найдете сами). Исходников BL нет, т.к. нет правильного скрипта *.ld для GCC, а имеющиеся собираются в IAR с линковкой rom_v0x.a, а не указываются export-rom_v0x.txt в *.ld... Но и там выходят лишние килобайты, пропадает RAM из-за неиспользования (причуды линковки - на некоторые данные и процедуры есть ссылки из ROM-BIOS и других либ из которых собирался текущий BL, а ему они не требуются, т.к. вообще не используется. Далее стартует загрузчик SDK и дублирует эти данные и процедуры в новых местах RAM. Т.е. пропадает от 8-ми кило неиспользуемой RAM точно, хотя часть загрузчика затем затирается и используется как добавка к HEAP. В эти 8-мь кило влезет flasher по UART и т.д.).

 
Последнее редактирование:

pvvx

Активный участник сообщества
Вы зря думаете, что я этого не знаю.
Уже перепробовал более изощренные варианты... Не выходит "каменный цветок" - не задавал бы вопроса :)
Мне нужно (желательно) "обтекание" этого указателя в 4 байта, чтобы при смене большинства сегментов ничего не нарушалось и не лазать каждый раз в итого - линкера - переполнилось что там или нет. Пересечение глобальных секций указывается "."... да зачем дублировать Help по линкеру GCC? Для ARM есть свои спец. закорючки в коде СИ.
Вообще в boot-loader-е уже всё в закорючках, до "pragma ..."
__attribute__((at(адрес смещения в сегменте))) что-то не пашет.
struct _reent * __attribute__((at(0x1098))) __attribute__((section(".libc.reent"))) _rtl_impure_ptr = { &impure_data };
Толи затирается сверху наложением кода, то-ли в данной версии сборки не пашет...
У неё ещё и KEEP(*(.libc.reent*)), т.к. в проекте структура не задействуется, а надо её оставить для потомков бута :) Туда полезет ROM-BIOS, когда SDK вызовет rtl_printf и другие либы СИ. Если этот указатель имеет не верное значение, указывающее не на буфера sprintf-ов то вывалиться надпись с множеством "!!!!!" расставленных неуравновешенным челом в распечатке регистров по прерыванию протектеда и других сообщений SDK и ROM (замучался по всему SDK их стирать! Ещё бы CAPS LOCK-ом напечатал всё... а сообщения об ошибках когда надо не помечены "!". Какой-то выборочный психоз...) :)
 
Последнее редактирование:

sharikov

Active member
...но положить практически посередине (!) тела BootLoader-a, чтобы абсолютный адрес у него был 0x10001c60.
Как это указать линковщику и в кодах СИ, чтобы данные и коды в BL обходили его?

Никак.
LD не умеет автоматически обходить дыры. Вы не первый с таким вопросом (на работе у меня была такая же проблема - решения нет).

Делать дыру в несколько килобайт ради него в сегменте BL, как это делает Ameba нет никакого желания.
Это единственный практически реализуемый вариант.
не нравится - переписывайте LD.
 

pvvx

Активный участник сообщества
Никак.
LD не умеет автоматически обходить дыры. Вы не первый с таким вопросом (на работе у меня была такая же проблема - решения нет).
Полено упрямое, а я еще упрямей. (с) Кортик.
Это единственный практически реализуемый вариант.
не нравится - переписывайте LD.
Что не нравитьсяв LD?
Мне не нравиться, что текущий бут содержит кучу хлама. К примеру из-за указания __image2_entry_func__ = .; туда влинкована InfraStart() со всеми цепляемым ей сегментами и вызовами. Но она никогда не исполняется там, т.к. работает только в составе image2 :) В IAR не подсвечивается по умолчанию незадействованные ветки и #if.. но это их беда - у нас Eclipse и arm-none-eabi.
Во вторых уже один вариант проходит, но мне не нравиться - надо следить потом по Итого...
Есть ещё третий и самый простой - сразу перед запуском процедуры загруженного image2 тупо написать в СИ _rtl_impure_ptr = &impure_data; прямо в своё отработавшее тело, а кусок это процедуры объявить в начали линковки раздела сегментов, чтобы она никогда не попала сама в себя. :)
В Ld:
go_start_image2.o (.go_start_image2.text*)
Т.е. можно вообще все данные, которые фиксед и попадают в тело boot, не грузить изначально, а скопировать из области flash перед стартом InfraStart() в image2
 
Последнее редактирование:

sharikov

Active member
Полено упрямое, а я еще упрямей. (с) Кортик.
...
Мне не нравиться, что текущий бут содержит кучу хлама.
Можно хлам линковать в отдельную секцию.
Загруженный код можно перемещать на место занимаемое хламом. Как делается relocation смотрите в uboot. Минус: jtag отладка после relocation потребует знаний (в гугле все написано, но нужно прочитать и освоить openocd или что-то-там). Плюс: телепузики отвалятся.
 

pvvx

Активный участник сообщества
Можно хлам линковать в отдельную секцию.
Загруженный код можно перемещать на место занимаемое хламом. Как делается relocation смотрите в uboot. Минус: jtag отладка после relocation потребует знаний (в гугле все написано, но нужно прочитать и освоить openocd или что-то-там). Плюс: телепузики отвалятся.
Но вы забыли одно объявленное условие = жалко RAM (для RTL871xAF), а в попке у пчелки другое жалко :) Вот им и надо скомпоновать и укоротить разбросанные данные к ROM-BIOS, благо они все узаются по указателям. Вываливается из группы всего одни Импире указатель. На то он и Импире :) Сама структура может быть хоть в SDRAM.
Jtag-у ничего не будет, если запись не вперед. В данном случае в отработавший код.
 

pvvx

Активный участник сообщества
Хлам занять кучей.
Оно уже до нас так сделано - китайцем на форуме и вставлено в "оф. SDK" от версии 3.5+.
Методы увеличения памяти для собственных приложений в sdk-ameba1-v3.4b3_without_NDA.
Но не всё что было возможно, т.к. сборка ROM была (наверно в IAR) с кучкой хлама от ненужных процедур и данные от них выместили этот указатель.
Слинкуйте rom.a с доп *.o (от rom новой версии) в IAR и увидите, что у них вышло и почему :) Посмотрите обращения к данным торчащим полям и увидите, что вышли дырки из-за линковки в IAR ненужного хлама.

Дык какое решение? Патчим взад? А то до нормальной разметки Flash никогда не доберемся... Ещё не составил единый правильный *.ld для трансляции и SDK и boot и ROM (rom - для теста правильной линковки). Там каждую закорючку надо по десять раз проверять по десяткам ссылок на разные файлы в разных SDK и т.д. чтобы вышло "и нашим и вашим" - совместимое :)

И с регистрами Spiс разобрались? По теме какие команды Flash в неё закидывать для разных режимов SIO/DIO (spic берет команды специфичных функций из регистров с заранее записанных в них команд, специфичных для текущего типа flash и какие разрешить ей режимы работы?).

Бут ещё отвечает за запись калибровок SDRAM и SPIC в 9-й сектор.
Бут можно загрузить и в TCM - ROM-BIOS всё равно куда его кинуть и запустить :)
Так-же осталось неясно пару адресов
u32 Image2Addr = *(u32 *)(0x1006FFFC);
Такая инициализация по старту адреса загрузки image2 c flash (далее масса условий - пины всякие, разметки в Flash и т.д.) - к чему и от кого это? Остаток какой-то реалтековской отладки (берется значение самого конца SRAM)?
(мне надо пропилить тропинку рестарта для типа deep_sleep с быстрой перезагрузкой через RESET... а пока такой в SDK нет - иначе целый пин входа пропадает :) )
 
Последнее редактирование:

pvvx

Активный участник сообщества
Хлам занять кучей.
Всё решилось с областью бута - RTL871x ROM-BIOS все поля данных в RAM включу в boot и image2,3.. чтобы не дублировать их в RAM и не согласовывать с ROM-BIOS. Остается всего дцать лишних, пока неизвестных, байт... Делить "кучу" можно только если грузить image2 в память с дыркой между данными ROM-BIOS... В общем все хидеры собрал и проверил трансляцию на соответствие с IDA с бинарниками от ROM, а не с кривой бета версией от rom.a. Теперь надо пересобирать код всяких HAL, чтобы работали в единых буферах для boot-loader-а, SDK и ROM-BIOS. Нет смысла дублировать эти данные по RAM.
 
Последнее редактирование:

pvvx

Активный участник сообщества
@sharikov - нашел ещё проблемы. Если записаны какие-то кривые значения калибровки в 9-ом секторе для spic, то модуль не запускается с разными инициализациями. Если запись правильная, то работает если задать процу при старте и от 20 до 200 MHz.
В общем там зарыта ещё одна собака... от которой у многих разное не работает - например загрузка в RAM. Видимо записаны тайминги в позицию для высокой частоты данными для низкой и SPIC ку-ку - не пашет и всё вешается.

Крутой загрузчик:
При ветке загрузки в RAM [PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 )] Jlink: w4 0x40000210,0x04111157
Достаточно просто переадресовать на старт image2. Никакого кода в bootloader-е вообще не нужно. :)
Но условия - правильные данные в 9-ом секторе и загрузчик в image2 врубается что его ROM-BIOS пустила на 41 MHz и переключает хоть на 200. Не все загрузчики от SDK и Ameba, которые вписываются в image2 содержат корректный по данном делу код.
По ветке загрузки с Flash та-же история. ROM-BIOS уже инициализит по умолчанию spic, таймер и uart console (что по той-же ветке при загрузке в RAM Jlink: w4 0x40000210,0x04111157). Остается только выбрать image для загрузки по пинам, но каждый загрузчик в каждой image тоже выбирает кого грузить :)
Т.е. всё надо переписывать с нуля в них.
-------
В буте 5 веток, с первой и последней описал выше - там rom-bios сама всё инит.
В других 3-х дублируем иниты из ROM и немного меняем алго:
Код:
//----- RtlBootToSram
void BOOT_RAM_TEXT_SECTION RtlBootToSram(void) {
    JtagOn(); /* JTAG On */
    __asm__ __volatile__ ("cpsid f\n"); // rom-bios не проинила ничего!
    HalCpuClkConfig(2);
    SetDebugFlgs();
    VectorTableInitRtl8195A(STACK_TOP);
    HalInitPlatformLogUartV02();
    HalInitPlatformTimerV02();
    __asm__ __volatile__ ("cpsie f\n");
#if 1 // тут можно включить 50 МГц
    HalDelayUs(1000);
//    HalCpuClkConfig(2);
    HAL_SYS_CTRL_WRITE32(REG_SYS_SYSPLL_CTRL1, HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) | (1<<17));
    HalReInitPlatformLogUartV02();
    HalInitPlatformTimerV02();
#endif
    DiagPrintf("\rCPU CLK %d Hz\r\n", HalGetCpuClk()); // для отладки

   SpicInitRtl8195AV02(1, 0); // Работает только с параметрами: HalCpuClkConfig(2) и SpicInitRtl8195AV02(1, 0) ! Иначе будут беды у кривого кода инициализации в image2 ! Т.е. в диапазоне от 40 до 50 МГц.
    EnterImage15();
}
далее просто jmp - запуск в image2 (с распечаткой и проверкой - есть ли Image2):
Код:
void BOOT_RAM_TEXT_SECTION EnterImage15(void) {
    DBG_8195A("\r\n==*== Enter Image 1.5 ====\nImg2 Sign: %s, InfaStart @ 0x%08x\r\n",
            &__image2_validate_code__, __image2_entry_func__);
    if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) {
        DBG_MISC_ERR("Invalid Image2 Signature!\n");
        RtlConsolRam();
    }
    __image2_entry_func__();
}
//----- JtagOn
void BOOT_RAM_TEXT_SECTION JtagOn(void) {
    /* JTAG On */
    ACTCK_VENDOR_CCTRL(ON);
    SLPCK_VENDOR_CCTRL(ON);
    HalPinCtrlRtl8195A(JTAG, 0, 1);
}
void BOOT_RAM_TEXT_SECTION SetDebugFlgs(void) {
// ставим по настроению :)
    CfgSysDebugWarn = -1;
    CfgSysDebugInfo = -1;
    CfgSysDebugErr = -1;
    ConfigDebugWarn = -1;
    ConfigDebugInfo = -1;
    ConfigDebugErr = -1;
}
void BOOT_RAM_TEXT_SECTION RtlConsolRam(void) {
//    DiagPrintf("\r\nRTL Console ROM\r\n");
    pUartLogCtl->pTmpLogBuf->UARTLogBuf[0] = '?';
    pUartLogCtl->pTmpLogBuf->BufCount = 1;
    pUartLogCtl->ExecuteCmd = 1;
    RtlConsolTaskRom(pUartLogCtl);
}
В принципе это весь bootloder (с заполненным сегментом данных для rom-bios).
Влезает в буфер для теста SDRAM при калибровке (позиция AvaWds = 0x10000be8 .. 1024 байта)
 
Последнее редактирование:

pvvx

Активный участник сообщества
С такими параметрами для spic работает всё правильно (до 200 МГц):
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 0): BaudRate=0x2 RdDummyCyle=0x2 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 1): BaudRate=0x2 RdDummyCyle=0x0 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 2): BaudRate=0x2 RdDummyCyle=0x0 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 3): BaudRate=0x2 RdDummyCyle=0x0 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 4): BaudRate=0x2 RdDummyCyle=0x0 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 0, CPUClk 5): BaudRate=0x2 RdDummyCyle=0x0 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 0): BaudRate=0x1 RdDummyCyle=0x13 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 1): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 2): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 3): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 4): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 1, CPUClk 5): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 0): BaudRate=0x1 RdDummyCyle=0x13 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 1): BaudRate=0x1 RdDummyCyle=0x12 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 2): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 3): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 4): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31
[SPIF Inf]SpicNVMCalLoad: Calibration Loaded(BitMode 2, CPUClk 5): BaudRate=0x1 RdDummyCyle=0x11 DelayLine=0x31

Таблица SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]:
00: 01310202 011420C2 01310002 011420C2
10: 01310002 011420C2 01310002 011420C2
20: 01310002 011420C2 01310002 011420C2
30: 01311301 011420C2 01311201 011420C2
40: 01311101 011420C2 01311101 011420C2
50: 01311101 011420C2 01311101 011420C2
60: 01311301 011420C2 01311201 011420C2
70: 01311101 011420C2 01311101 011420C2
80: 01311101 011420C2 01311101 011420C2

Таблица то умолчанию с оптимальными параметрами сохранена в 9-ый сектор "прошивки для восстановления работоспособности модуля RTL00": RtlDuino/OTA_RTLDuino.bin at master · pvvx/RtlDuino · GitHub .
При включенных отладочных сообщениях получите простыню загрузки SpicNVMCalLoad: Calibration, указанную выше.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Посмотрел исходники EMW3081 (RTL8711AM). Там есть бут, способный грузить по UART (921600 baud) прошивки. Протокол YMODEM. По размеру влезает вместо загрузчика... Пересобрал для RTL00:
Снимок1315.gif
Но надо менять разбивку Flash на адаптирующуюся и по приемлемым условиям к RTL871xAF...
Программа прошивки c UART для компа по протоколу YMODEM на EWM3081 на китайском :)
 
Последнее редактирование:

sharikov

Active member
Программа прошивки c UART для компа по протоколу YMODEM на EWM3081 на китайском :)
Не очень понятно зачем нужна прошивка именно через ymodem.
Потребитель обновляет прошивки через http а у всех разработчиков есть jtag.
Зачем ???
Вот что-нибудь свое вставить в bootloader было бы полезно.
ymodem - стандартный протокол он есть во всех вменяемых терминалках. Для чего нужна "специальная программа на китайском" ?

Чего-то я недопонимаю.
 

pvvx

Активный участник сообщества
Не очень понятно зачем нужна прошивка именно через ymodem.
Потребитель обновляет прошивки через http а у всех разработчиков есть jtag.
Зачем ???
Вот что-нибудь свое вставить в bootloader было бы полезно.
ymodem - стандартный протокол он есть во всех вменяемых терминалках. Для чего нужна "специальная программа на китайском" ?
Чтобы не думать. Она у них для автомата - серийной прошивки, но имеет ошибки (при ошибке COM не закрывается и программа падает :)).
Снимок1316.jpgСнимок1317.gif
Вы тысячу шт модулей будете вручную в терминале шить? :)
Чего-то я недопонимаю.
Если сделать прошивку по UART, то её можно обновить и залить по WiFi OTA или Jtag на стадии продажи модуля (тот-же китайский продавец зальет). Пользователь получит модуль с возможностью работать без Jtag.
В своем изделии аналогично, можно будет сделать обновление с внешнего MCU или USB-COM порта. Т.е. вариантов много и в принципе поддержка заливка по UART модулю нужна, не обязательно в boot, но в boot не влезет OTA по WiFi.
 
Последнее редактирование:

sharikov

Active member
Чтобы не думать. Она у них для автомата - серийной прошивки, но имеет ошибки
UART загрузчик нужно сначала прошить и сделать это можно только по jtag.
Получается 2 операции тогда как через jtag все делается за одну.
2 операции через разные интерфейсы никак не получатся быстрее чем одна.
Если надо шить тысячи берем jflash и жмем кнопку "Auto". jflash шьет быстро, через uart быстрее не будет.

Пользователь получит модуль с возможностью работать без Jtag.
Кто является пользователем ?
Если это разработчик то у него уже есть jtag, да не один и не два вплоть до wiggler и потребности в загрузке по uart у него нет.
Если это конечный пользователь то он вообще не знает что такое uart, более того он даже ota сервер запустить не в состоянии. У конечного пользователя есть только веб страница в пальцетыке.

Не вижу никакой объективной надобности в загрузке по uart (т.к. "голый" чип без jtag не шьется и без него разработчику никак).
 

pvvx

Активный участник сообщества
Не вижу никакой объективной надобности в загрузке по uart (т.к. "голый" чип без jtag не шьется и без него разработчику никак).
А мои пришедшие модули с али RTL00 шьются по OTA через три команды по "AT". Маркировка B&T.
-------
Как убрать align(8) у uint64_t?
Не стыкуются структуры по полям в WiFi драйвере c описаниями. Невозможно обратиться к lib_wlan.a.
 

sharikov

Active member
Как убрать align(8) у uint64_t?
Не стыкуются структуры по полям в WiFi драйвере c описаниями. Невозможно обратиться к lib_wlan.a.
В keil тоже align 8 для 64-битных переменных. Compiler User Guide: Basic data types in ARM C and C++
Пишите подробнее, вопрос сложный и завязан на стек и ABI.
__attribute__((packed)) и ручное выравнивание пробовали ?

... for va_arg() to work with double and uint64_t on cortex and arm, the stack
needs to be aligned on a 8-byte boundary.


---

Eight byte stack alignment

The Application Binary Interface (ABI) for the ARM architecture requires that the stack must be eight-byte aligned on all external interfaces, such as calls between functions in different source files. However, code does not need to maintain eight-byte stack alignment internally, for example in leaf functions.

This means that when an interrupt or exception occurs the stack might not be correctly eight-byte aligned. Revision 1 and later of the Cortex-M3 silicon can automatically align the stack pointer when an exception occurs. This behavior must be enabled by setting STKALIGN (bit 9) in the Configuration Control Register at address 0xE000ED14.

If you are using revision 0 of the Cortex-M3, this adjustment cannot be performed in hardware. The compiler can generate code in your IRQ handlers that correctly aligns the stack. To do this you must prefix your IRQ handlers with __irq and use the --cpu=Cortex-M3-rev0 compiler switch, not --cpu=Cortex-M3.
 

pvvx

Активный участник сообщества
В keil тоже align 8 для 64-битных переменных. Compiler User Guide: Basic data types in ARM C and C++

__attribute__((packed)) и ручное выравнивание пробовали ?
__attribute__((packed)) не катит. Я чё буду думать куда и как слинковалась структура и каждый раз переписывать? :)
Обошел данный баг, через typedef. Это ЕГГОГ в текущем arm GCC c align(8)... плодит неопределенные ситуации. Лечится через зад. :)
У нас не Cortex-M3, хотя совместим (немного круче). И не в стеке надо, а в структурах, для совместимости со старыми версиями arm-none-eabi GCC...
ROM-BIOS что вам пишет?
Build ToolChain Version: gcc version 4.8.3 (Realtek ASDK-4.8.3p1 Build 2003)
__alignof(uint64_t) :)
Погадать хотите?
Код:
struct x1 {
uint64_t u1;
uint32_t u2;
};
struct x2 {
uint32_t u1;
uint64_t u2;
};
struct x3 {
struct x1 a1;
struct x2 a2;
};
Как разместит ? :)
Пишите подробнее, вопрос сложный и завязан на стек и ABI.
Нечего подробней писать - есть заголовки всех структур - они связываются в кучу более 6 килобайт из десятков отдельных описаний структур и при разном трансляторе на тот-же Cortex-M3 получаем разные варианты компановки этих структур. Изменить порядок и align мы не можем на свои, т.к. их использует и ROM и закрытые части WiFi библиотеки.
Все входы к ним в SDK закрыты на void *, а интерфейс с драйвером WiFi происходит через текстовые команды - через специфический ioctl со своими отдельными процессами в RTOS. Сначала переводиться в бинарные коды команд, потом в текст, потом обратно в бинарные коды и только тогда достигает драйвера :) Обратно тоже - текстовые сообщения декодируются в цифровые, потом обратно... Этим и занята большая часть памяти чипа...
Но уже всё - сделал, чтобы совмещалось в GNU_Tools_ARM_Embedded 5.4_2016q2 arm-none-eabi. Простыни заголовков всех внутренних функций драйвера WiFi, ROM-BIOS и используемых ими структур данных уже сидят в моем SDK на гит и линкуются. Описание, что они делают мне не требуется - есть IDA c подробным листингом и псевдо-авто-переводом в СИ (т.е. вполне читаемом, с возможность быстрой замены любой процедуры на свой исходник).
SDK придется весь вывернуть на изнанку. Но уже ясно, что новой оф. версии не будет. Realtek занят новыми чипами, а на эти RTL871xAx всё и так работает и отлажено в SDK выпущенном в конце 2015 года.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Первый вариант boot-loader-a сделан. Выявлена проблема - функции инициализации Spic в SDK имеют ошибки и не одну. При частоте 166 MHz инициализация Spic проходит неверно и на RTL8711AM. Требуется полное переписывание hal_spi_flash, а пока используется кривенький патч, не решающий всех проблем. Ошибки в hal_spi_flash приводят к зависанию при старте и неправильному определению типа Flash. Зависания и нестабильная работа происходит из-за неверного чтения параметров WiFi из 10-ого сектора установок и подобному...
 
Сверху Снизу