реклама на сайте
подробности

 
 
> LPC1768 uart bootloader, не получается
Cosmojam
сообщение Dec 8 2011, 21:00
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



Всем привет!
Помогите победить проблему.
Пробую сделать загрузчик по юарту. Позже планируется usb, но пока с этим ничего не получается.
За основу взят usb bootloader от NXP AN10866 http://www.nxp.com/documents/other/LPC1700..._bootloader.zip
В аттаче архив с 2 проектами для LPCXpresso. UART_bootloader - собственно бутлодырь, точнее только его скелет с самым самым минимумом. test - светодиодная моргалка, которую надо загружать для теста.
Проблема такова:
Загрузчик работает верно, бинарный файл с прошивкой тестового проекта сохраняет как нужно (файл не выравнен по 512байт, то чего не хватает для записи последнего блока дописываю ручками, временно так). Проверки при записи проходят т.е. неверно залитый файл исключается.
При старте он проверяет контрольную сумму прошивки в секторе 4 (туда по умолчанию загружаем). Сумма есть в бинарнике.
Сумма сошлась, надо переходить к исполнению программы с 4 сектора.
Указываем новое местоположение таблицы векторов прерываний, смещаем программный счётчик и верхушку стека (всё как в NXP-шном примере, только там для Keil, а у меня gcc с другим синтаксисом ассемблера):
Код
void boot(uint32_t a)
{
    asm(
    "LDR SP, [R0]\n"
    "LDR PC, [R0, #4]\n"
    );
}

void execute_user_code(void)
{
    uint32_t addr=(uint32_t)sector_start_adress[USERCODE_SECTOR_START];
    SCB->VTOR = (addr & 0x1FFFFF80);
    boot(addr);
}

Успешно попадаем в ResetISR загруженной программы (смотрю пошагово в отладчике и сверяю адреса инструкций с адресами в .map файле)
Дальше самое интересное:
Тестовая программа:
Код
volatile uint32_t del;
void _delay(uint32_t delay)
{
    uint32_t i;
    for(i = 0; i < delay; i++ )
        del = i; // do this so that the compiler does not optimize away the loop.
}


int main(void)
{
//    SystemInit();

//    init_uart(57600);

    LPC_SC->PCONP |= ( 1 << 15 ); // power up GPIO
    LPC_GPIO0->FIODIR |= 1 << 1;
    LPC_GPIO0->FIOPIN = 1<<1;

//    uart_sendstring("YES\n");

    uint32_t i;
    const uint32_t delay=1<<22;
    while(1)
    {
    //    _delay(1<<22);
        for(i = 0; i < delay; i++ )
            del = i;
        LPC_GPIO0->FIOPIN ^= 1 << 1;
    }
    return 0;
}

В таком виде работает, светодиод на P1.1 моргает. Но стоит раскомментировать задержку в вечном цикле и закомментировать "инлайновую" задержку (так она в теле цикла, а станет функцией) - всё, получаем HardFault Precise Error (скачок на адрес 0x40F6 где лежит обработчик HardFault-ов). Тоже самое и с юартом и системинитом. Можно предположить косяк со стеком при вызове функции, но фактически стек работает верно. Например, если убрать системинит, но оставить юарт, то хардфолтов не будет, он исправно пробежит uart_sendstring("YES\n"); но ничего не отправит. Та же программа зашитая в 0 сектор как обычно (с соответсвующей правкой скрипта линкера) работает абсолютно верно.
Оно мне уже мозг вынесло. Подскажите плз, что я делаю не так?

Прикрепленные файлы
Прикрепленный файл  uart_boot.zip ( 183.5 килобайт ) Кол-во скачиваний: 26
 


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Cosmojam
сообщение Dec 9 2011, 13:04
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



Поступило предложение использовать барьеры памяти и сбросить конвейер перед "прыжком в другую реальность". Почитал что это и как, не особо хорошо понял этот механизм, но всё же добавил:
Код
   __asm (
            "dmb\n"
            "dsb\n"
            "isb\n"
        );

Прямо перед вызовом функции, изменяющей PC в загрузчике. А так же в моей программе в ResetISR прямо в самом начале.
Вот что происходит в этом случае:
Загрузчик всё так же успешно отрабатывает, обновляет SP и PC, прыгаем в ResetISR моей программы и на этапе инициализации data/bss происходит сразу 3 пакости: Access Violation, Stack Error, Precise Error. Но что интересно они происходят не без причины. SP внезапно изменяется на 3FE т.е. какой-то код в загрузчике, поскольку в моей программе эта область не отмечена вообще никак - происходит Access Violation. Но кто мог так надругаться над стеком?? Затрейсить выполнение нечем, но в отладчике отображаются красным цветом с градиентом последние 4 команды и это всё тот же цикл в инициализации секторов data/bss, т.е. дальше этого места она никак не могла выпрыгнуть. Есть вариант что кончается память и "куча" дорастает до стека, но этого не может быть т.к. у меня нет столько глобальных переменных, есть парочка статических буферов, один на 4k, другой на 256 и ещё по мелочи, но это никак не переползёт до 32k если только не произойдёт какой-то бяки и цикл инициализации не "взбесится". Но какого лешего тогда оно работает из 0 сектора?
Вот что интересно, если не добавлять барьеры и сброс конвейера в начале ResetISR, то поведение будет другое. SP уже так не изменяется, остаётся на 10007ED8 (начальная верхушка 10008000) во время хардфолта, и ошибка - Bus Error. Тут не удаётся увидеть что было перед этим (видимо отладчик глючит), но судя по такому отрастанию стека там уже какие-то функции успели вызваться. Если же убрать барьеры и из загрузчика, то будет примерно также, но ошибка Imprecise Error и тот же хардфолт.
Кошмар sm.gif


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Cosmojam   LPC1768 uart bootloader   Dec 8 2011, 21:00
- - Dron_Gus   А приложение точно собрано для того адреса, по кот...   Dec 9 2011, 07:01
- - Cosmojam   Точно-точно. По крайней мере скрипты линкера верны...   Dec 9 2011, 07:30
- - toweroff   стартовый адрес точно __main ? упс.. прошу прощен...   Dec 9 2011, 10:05
- - toweroff   прямо несколько минут назад поднимали одну мою вет...   Dec 9 2011, 13:17
- - Cosmojam   Всё намного проще Ну почему люди такие идиоты? ...   Dec 9 2011, 20:26
- - Cosmojam   В догонку ещё вопрос по теме бутлодырей. Что если...   Dec 9 2011, 22:05
|- - Сергей Борщ   QUOTE (Cosmojam @ Dec 10 2011, 00:05) На ...   Dec 10 2011, 10:45
- - toweroff   Жестко прописанная переменная в Non-ZI сегменте   Dec 10 2011, 08:25
- - Dron_Gus   SVC? Можно сдвинуть таблицу векторов обратно на бу...   Dec 10 2011, 09:45
- - Cosmojam   Цитата(toweroff @ Dec 10 2011, 11:25) Жес...   Dec 10 2011, 17:54
|- - toweroff   Цитата(Cosmojam @ Dec 10 2011, 21:54) Так...   Dec 10 2011, 23:27
||- - Cosmojam   Цитата(toweroff @ Dec 11 2011, 02:27) а В...   Dec 11 2011, 12:17
||- - toweroff   Цитата(Cosmojam @ Dec 11 2011, 16:17) В с...   Dec 11 2011, 13:07
|- - Сергей Борщ   QUOTE (Cosmojam @ Dec 10 2011, 19:54) Вы ...   Dec 11 2011, 00:47
||- - toweroff   Цитата(Сергей Борщ @ Dec 11 2011, 04:47) ...   Dec 11 2011, 07:59
|- - Dron_Gus   Цитата(Cosmojam @ Dec 10 2011, 20:54) Да,...   Dec 12 2011, 20:22
|- - Cosmojam   Цитата(Dron_Gus @ Dec 12 2011, 23:22) При...   Dec 13 2011, 09:17
- - Dron_Gus   Я Вам предлагаю вызвать SWI. Для него свой вектор.   Dec 13 2011, 10:38
- - Cosmojam   Оно вроде для других целей. Плохо понимаю как можн...   Dec 13 2011, 19:00
- - Dron_Gus   При вызове SWI процессор переходит в привелигирова...   Dec 14 2011, 10:28


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th July 2025 - 02:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01462 секунд с 7
ELECTRONIX ©2004-2016