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

Освоение ARM контроллеров

А ещё можно соединить GPIO и RESET и дёргать этот сигнал :yeah:

Хех! Круче - соединить GPIO и ногу EN питающего LDO :beer:

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


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

Сейчас разбираюсь с юзерским бутлоадером. Почитал про систему прерываний Cortex, она кардинально от PIC отличается но в принципе все понятно. При старте мы сразу попадаем в прерывание Reset и из него уже выходим в нашу main().

Как все организовать я понял. Только не получается перенести вектор прерываний как в бутлоадере когда переходим к выполнению основной программы, так и в основной программе (ее ведь необходимо сместить выделив место под бутлоадер). Нашел пример бутлоадера, там для этих целей используется функция NVIC_SetVectorTable(). У меня в функциях NVIC файла core_cm4.h такой нет.

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

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


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

Только не получается перенести вектор прерываний как в бутлоадере когда переходим к выполнению основной программы, так и в основной программе (ее ведь необходимо сместить выделив место под бутлоадер).

Ну нельзя же так. Правильные пацаны читают мануал на процессор (Cortex-M4, как я понял). Там английским по белому написано, что есть регистр VTOR (в стандартных заголовках обозначается SCB->VTOR). Не нужна функция, чтобы записать значение в регистр, это моветон.

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


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

Вот два кода, первый бутлоадера, а второй моя программа. Так нужно делать?

 

//В проекте бутлоадера
int main(void)
{
//Здесь код бутлоадера



//здесь переопределение адреса таблицы векторов прерываний
//и переход к выполнению основной программы 
__disable_irq ();
__set_MSP( *(uint32_t*)(0x08001000) );
SCB->VTOR = 0x08001000;
(*(void(*)(void))( *(uint32_t*)(0x08001000+4) ))(); 
}

//В проекте с основной программой
int main(void)
{

SCB->VTOR = 0x08001000;//и в линкере проекта основной программы установить адресацию с 0x08001000

//Дальше код основной программы
}

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


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

Вот два кода, первый бутлоадера, а второй моя программа. Так нужно делать?

Кому нужно?

Делать можно по-разному. Мне нравится немного по-другому.

Адрес таблицы векторов не обязательно менять в загрузчике - основная программа сама это может сделать.

Переход на основную программу мне нравится делать вот так:

static const uint16_t jump2fw[] =
{
    0xF850, 0xDB04, /* LDR.W SP, [R0], #4   */
    0x6800,         /* LDR.W R0, [R0]       */
    0x4700,         /* BX R0                */
};
...
((void (*)(int))(1 + (int)jump2fw))(0x08010000);

Причём выполняю это действие сразу после сброса в самом начале Reset_Handler(), если установлен соответствующий флаг (запрос на переход в основную прошивку). При таком способе основная прошивка стартует со сброшенной периферией, что удобно.

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


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

Тогда не верно выразился, нужно так - "Так все правильно будет работать?" . Учитывайте тот факт, что я вообще только начал изучение STM32.

И еще один вопрос в нагрузку:

- когда я ставлю в линкере основного проекта адрес 0x08001000, то после компиляции при переходе в отладку, у меня все весит по адресу 0x00000000. Ну это и понятно, потому что там ничего нет. Тогда как отлаживать? Сначала делаем программу как обычную не под бутлоадер, то есть не меняя в ней адрес таблицы векторов и не трогая линкер. А после того как проект готов, ставим в начало main SCB->VTOR = 0x08001000; и корректируем линкер. Или нужно что то еще?

Изменено пользователем IgorKossak
бездумное цитирование

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


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

- когда я ставлю в линкере основного проекта адрес 0x08001000, то после компиляции при переходе в отладку, у меня все весит по адресу 0x00000000. Ну это и понятно, потому что там ничего нет. Тогда как отлаживать?

Я отлаживаю в кейле. Там можно подключить скрипт отладчика. В скрипте пишу

SP = *(int*)0x08001000;
PC = *(int*)0x08001004;

И всё.

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


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

//здесь переопределение адреса таблицы векторов прерываний

//и переход к выполнению основной программы

__disable_irq ();

__set_MSP( *(uint32_t*)(0x08001000) );

SCB->VTOR = 0x08001000;

(*(void(*)(void))( *(uint32_t *)(0x08001000+4) ))();

}

Как-то слишком кудряво и лишнее разименование. Надо быть проще:

((void(*)(void))*(void **)0x08001004)();

И, как тут уже сказали, основная программа должна выставлять VTOR какой ей надо (как и все прочие регистры периферии), а не бутлоадер.

И какое-то у Вас странное содержимое SP. Вы уверены, что по этим адресам у Вас находится ОЗУ? Обычно в МК с ядром Cortex-M по этим адресам находится Flash.

И насчёт __disable_irq () - не уверен, что это будет работать в Cortex-M. Обычно для Cortex-M используют __disable_interrupt().

А __disable_irq() и __disable_fiq() - это для ARM7/9 (и Cortex-A наверное).

 

Почитал про систему прерываний Cortex, она кардинально от PIC отличается но в принципе все понятно.

Кроме того: система прерываний Cortex-M кардинально отличается от системы прерываний Cortex-A.

 

- когда я ставлю в линкере основного проекта адрес 0x08001000, то после компиляции при переходе в отладку, у меня все весит по адресу 0x00000000. Ну это и понятно, потому что там ничего нет. Тогда как отлаживать? Сначала делаем программу как обычную не под бутлоадер, то есть не меняя в ней адрес таблицы векторов и не трогая линкер

Это то как раз и непонятно. Что-то у Вас неправильно компилится/линкуется.

Не надо делать "не под бутлоадер". Если правильная конфигурация командного файла линкёра, то после загрузки ПО JTAG-ом, PC устанавливается на точку входа (содержимое вектора сброса или начало функции main()). И это вне зависимости от того, на какие адреса линковали - хоть в FLASH хоть в SRAM хоть во внешнюю SDRAM.

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


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

Это то как раз и непонятно. Что-то у Вас неправильно компилится/линкуется.

Не надо делать "не под бутлоадер". Если правильная конфигурация командного файла линкёра, то после загрузки ПО JTAG-ом, PC устанавливается на точку входа (содержимое вектора сброса или начало функции main()). И это вне зависимости от того, на какие адреса линковали - хоть в FLASH хоть в SRAM хоть во внешнюю SDRAM.

При установке в настройка линкера CooCox старт адреса 0x08001000, после компиляции и запуска отладки у меня во втором слове памяти по адресу 0x00000004 почему весит значение с адресом 0x00010101. Да и вообще я вижу, что в памяти какая то бяка вместо моей программы.

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


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

При установке в настройка линкера CooCox старт адреса 0x08001000, после компиляции и запуска отладки у меня во втором слове памяти по адресу 0x00000004 почему весит значение с адресом 0x00010101. Да и вообще я вижу, что в памяти какая то бяка вместо моей программы.

Так если линкуете с адреса 0x08001000, то зачем смотрите на адрес 0x00000000???

И что такое старт адрес 0x08001000? У Вас там таблица векторов прерываний расположена?

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


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

Так если линкуете с адреса 0x08001000, то зачем смотрите на адрес 0x00000000???

И что такое старт адрес 0x08001000? У Вас там таблица векторов прерываний расположена?

 

Смотрю на адрес 0x00000004 потому что внем записано 0x00010101 и у меня отладчик висит на этом адресе после старта.

Хотя смотрел бинарник после компиляции, там вроде все верно. (по крайней мере код программы есть)

Наверное я что то делаю не так.

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

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


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

Хотя смотрел бинарник после компиляции, там вроде все верно. (по крайней мере код программы есть)

Наверное я что то делаю не так.

Как Вы смотрите бинарник? Как там видите адреса?

Смотреть надо map-файл. По нему проверяете куда у Вас скомпоновалась таблица векторов прерываний и прочие секции кода и данных.

Также там указана точка входа ПО (в IAR называется "Entry symbol"). Вот с этой точки входа отладчик и стартует.

Я не знаю кокос, пользуюсь IAR.

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


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

Как-то слишком кудряво и лишнее разименование. Надо быть проще:

 

((void(*)(void))*(void **)0x08001004)();

 

1. #define ADDR 0x08001004

2. ()ADDR .... Будем явно тип преобразовывать

3. (*)ADDR ....В указатель

4, ((*)())ADDR .................. на функцию

5. ((*)(void))ADDR ........................................без параметров

6. (void(*)(void))ADDR ...... ничего не возвращающую

 

8. Ну и вызываем:

 

((void(*)(void))ADDR)();

 

 

 

 

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


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

1. #define ADDR 0x08001004

...

((void(*)(void))ADDR)();

У ТС адрес 0x08001004 - не адрес функции, а адрес вектора reset в таблице прерываний, который указывает на функцию. Так что там ещё разыменование забыли.

А если-б это был адрес функции, бит0 был бы равен ==1, а не 0.

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


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

У ТС адрес 0x08001004 - не адрес функции, а адрес вектора reset в таблице прерываний, который указывает на функцию.

Поял.

А если-б это был адрес функции, бит0 был бы равен ==1, а не 0.

Это смотря какой режим - не только на кортексах свет клином сошелся.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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