Перейти к содержанию
    

LPC4337, свой загрузчик. Инициализация SDRAM

Если после приёма прошивки (и записи её во флешь с установленным флажком "имеется новая прошивка") выполняется Ваш программный сброс, загрузчик делает как Вы написали и переходит к пункту 2 вашего списка.... и в этот момент происходит случайный сброс (например - сработал супервизор питания из-за помехи по питанию). Что получится? Да - прошивка не обновится уже никогда. laughing.gif

Есть у меня bootloader-ы, которые выходят из коматоза в любом случае, главное подать питание. Там да, все сделано на энергонезависимом флаге. Я говорил о более-менее простых бутах, на основе которого можно делать хороший загрузчик.

 

пункт 2 замечаний:

Видимо Вы меня не совсем поняли. Из пользовательского ПО я перехожу в bootloader вызовом NVIC_SystemReset(). Поэтому мне не интересно, в каком режиме находится сейчас процессор и что он там выполняет.

 

Так что такой метод передачи управления загрузчику допустим разве что в настольно-наколенных поделках.

Теперь тоже так считаете? :rolleyes:

 

Вы писали о передаче управления бутлоадеру без сброса

Нет, я писал

Ровно как и ничего не мешает инициализировать указатель стека и перейти сразу на приложение явно.

что контекстно подразумевает, что мы находимся в загрузчике. Речь шла о передаче управления из загрузчика в основную программу.

 

Итого: из приложения в загрузчик - NVIC_SystemReset(), из загрузчика в приложение - как указал выше JumpToApplication().

Это просто как вариант. Я не говорю что у меня все такие загрузчики. Надежные летают щас даже :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

void HW_JumpToApplication(void)
{
unsigned int pFunction = *((volatile unsigned int *)(APPLICATION_BASE_ADDRESS + 4));
void (*UserApplication)(void) = (void (*)())pFunction;
__set_MSP(*(volatile unsigned int *)APPLICATION_BASE_ADDRESS);
UserApplication();
    
return;
}

Мне больше нравится вот так:

void jump_to_app(void)
{
    static const uint16_t code[] = {
       0x1d01, // adds r1, r0, #4
       0x6800, // ldr r0, [r0, #0]
       0x4685, // mov sp, r0
       0x6809, // ldr r1, [r1, #0]
       0x4708  // bx r1
    };
    ((void (*)(int))code)(APP_BASE);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне больше нравится вот так:

А какие плюшки от этого?

Вообще конечно из Си-кода менять MSP/PSP не есть комильфо, но с другой стороны не вижу криминала, если в функцию перехода на приложение не передавать никаких параметров.

0x1d01, // adds r1, r0, #4

0x6800, // ldr r0, [r0, #0]

0x4685, // mov sp, r0

0x6809, // ldr r1, [r1, #0]

0x4708 // bx r1

Страшно :biggrin: И не будь тут комментариев, показалось бы ужасным костылем :rolleyes: Ведь функцию по сути можно было написать чисто на ассемблере (хоть в отдельном .s файле, либо внутри Си-функции инлайн-ассемблером).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне больше нравится вот так:

.h:

#define PFLASH_BEGIN_C      0x08000000 //адрес начала внутренней флешь МК (кэшированная область)
#define FW_WORK_BEGIN       0x00020000 //смещение рабочего ПО (FIRMWARE_TARGET_WORK) относительно начала флешь
extern "C" void StartWorkFw();

.cpp (в бутлоадере):

//деинит/reset использованной в буте периферии и старт рабочего ПО
    IntCpuDis();
    FaultCpuDis();
    IntDisAll();
    //отключение тактирования периферии
    SCU.CCU.CGAT[0].SET = B0 | B1 | B2 | B3 | B4 | B7 | B8 | B9 | B10 | B11 | B16;
    SCU.CCU.CGAT[1].SET = B0 | B3 | B4 | B5 | B6 | B7 | B8;
    SCU.CCU.CGAT[2].SET = B1 | B2 | B4 | B5 | B6 | B7 | B10;
    SCU.CCU.CGAT[3].SET = B2;
    MPUoff();
    StartWorkFw();

.asm:

               SECTION  .text:CODE:NOROOT(2)
               THUMB
               PUBLIC   StartWorkFw
StartWorkFw:   LDR      R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN
               LDRD     R1, R2, [R0]
               MOV      SP, R1
               BX       R2
               LTORG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.asm:

               SECTION  .text:CODE:NOROOT(2)
               THUMB
               PUBLIC   StartWorkFw
StartWorkFw:   LDR      R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN
               LDRD     R1, R2, [R0]
               MOV      SP, R1
               BX       R2
               LTORG

Ну в общем на вкус и цвет, как говорится. А таблицу векторов где смещаете, кстати? Тоже где-то в boot-е или в основном приложении в начале?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

               SECTION  .text:CODE:NOROOT(2)
               THUMB
               PUBLIC   StartWorkFw
StartWorkFw:   LDR      R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN
               LDRD     R1, R2, [R0]
               MOV      SP, R1
               BX       R2
               LTORG

Точно!

void jump_to_app(void)
{
    static const uint16_t code[] = {
       0xc806, // ldmia r0!, {r1, r2}
       0x468d, // mov sp, r1
       0x4710  // bx r2
    };
    ((void (*)(int))code)(APP_BASE);
}

Этот код будет работать и на Cortex-M0, в отличие от.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну в общем на вкус и цвет, как говорится. А таблицу векторов где смещаете, кстати? Тоже где-то в boot-е или в основном приложении в начале?

само запускаемое приложение программирует всю периферию как ему надо. Бутлоадер только обеспечивает чтобы после него регистры периферии были в изначальном состоянии.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно!

...

Этот код будет работать и на Cortex-M0, в отличие от.

Поправлю сам себя. Последний штрих:

void jump_to_app(void)
{
    static const uint16_t code[] = {
        0xc806, // ldmia r0!, {r1, r2}
        0x468d, // mov sp, r1
        0x4710  // bx r2
    };
    ((void (*)(int))(1 + (int)code))(APP_BASE);
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поправлю сам себя. Последний штрих:

void jump_to_app(void)
{
    static const uint16_t code[] = {
        0xc806, // ldmia r0!, {r1, r2}
        0x468d, // mov sp, r1
        0x4710  // bx r2
    };
    ((void (*)(int))(1 + (int)code))(APP_BASE);
}

ИМХО, лишнее.

Компилятор вроде сам это контролирует (я про режим Thumb).

На ассемблере да, надо следить.

 

P.S. Может, ошибаюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ИМХО, лишнее.

Компилятор вроде сам это контролирует (я про режим Thumb).

На ассемблере да, надо следить.

 

P.S. Может, ошибаюсь.

Не лишнее. При тестировании вскрылось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не лишнее. При тестировании вскрылось.

Пардон. Я вычитывал слово по нужному адресу, а там было слово из таблицы векторов прерываний (вектор сброса) - а там уже в младшем бите установлена единица.

Интересно, а считается ли Ваш способ наглядным примером самомодифицирующегося кода?

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пардон. Я вычитывал слово по нужному адресу, а там было слово из таблицы векторов прерываний (вектор сброса) - а там уже в младшем бите установлена единица.

Интересно, а считается ли Ваш способ наглядным примером самомодифицирующегося кода?

Мне кажется, вы запутались :wacko:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да нет, не запутался.

Говорю же что ошибся насчёт лишней установки младшего бита. Признаю, что устанавливать нужно его.

А насчёт СМК - слышал, но не встречался, поэтому и подумал, а почему бы коду, копирующего самого себя и передающего управление функции в ОЗУ не называться СМК. Вот и все. Поправьте, если не прав.

А, у вас же static const... Все во Flash разместится...

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...