jcxz 234 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба А ещё можно соединить GPIO и RESET и дёргать этот сигнал :yeah: Хех! Круче - соединить GPIO и ногу EN питающего LDO :beer: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxntf 0 5 апреля, 2016 Опубликовано 5 апреля, 2016 (изменено) · Жалоба Сейчас разбираюсь с юзерским бутлоадером. Почитал про систему прерываний Cortex, она кардинально от PIC отличается но в принципе все понятно. При старте мы сразу попадаем в прерывание Reset и из него уже выходим в нашу main(). Как все организовать я понял. Только не получается перенести вектор прерываний как в бутлоадере когда переходим к выполнению основной программы, так и в основной программе (ее ведь необходимо сместить выделив место под бутлоадер). Нашел пример бутлоадера, там для этих целей используется функция NVIC_SetVectorTable(). У меня в функциях NVIC файла core_cm4.h такой нет. Изменено 5 апреля, 2016 пользователем maxntf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Только не получается перенести вектор прерываний как в бутлоадере когда переходим к выполнению основной программы, так и в основной программе (ее ведь необходимо сместить выделив место под бутлоадер). Ну нельзя же так. Правильные пацаны читают мануал на процессор (Cortex-M4, как я понял). Там английским по белому написано, что есть регистр VTOR (в стандартных заголовках обозначается SCB->VTOR). Не нужна функция, чтобы записать значение в регистр, это моветон. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxntf 0 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Вот два кода, первый бутлоадера, а второй моя программа. Так нужно делать? //В проекте бутлоадера 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 //Дальше код основной программы } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Вот два кода, первый бутлоадера, а второй моя программа. Так нужно делать? Кому нужно? Делать можно по-разному. Мне нравится немного по-другому. Адрес таблицы векторов не обязательно менять в загрузчике - основная программа сама это может сделать. Переход на основную программу мне нравится делать вот так: 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(), если установлен соответствующий флаг (запрос на переход в основную прошивку). При таком способе основная прошивка стартует со сброшенной периферией, что удобно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxntf 0 5 апреля, 2016 Опубликовано 5 апреля, 2016 (изменено) · Жалоба Тогда не верно выразился, нужно так - "Так все правильно будет работать?" . Учитывайте тот факт, что я вообще только начал изучение STM32. И еще один вопрос в нагрузку: - когда я ставлю в линкере основного проекта адрес 0x08001000, то после компиляции при переходе в отладку, у меня все весит по адресу 0x00000000. Ну это и понятно, потому что там ничего нет. Тогда как отлаживать? Сначала делаем программу как обычную не под бутлоадер, то есть не меняя в ней адрес таблицы векторов и не трогая линкер. А после того как проект готов, ставим в начало main SCB->VTOR = 0x08001000; и корректируем линкер. Или нужно что то еще? Изменено 5 апреля, 2016 пользователем IgorKossak бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба - когда я ставлю в линкере основного проекта адрес 0x08001000, то после компиляции при переходе в отладку, у меня все весит по адресу 0x00000000. Ну это и понятно, потому что там ничего нет. Тогда как отлаживать? Я отлаживаю в кейле. Там можно подключить скрипт отладчика. В скрипте пишу SP = *(int*)0x08001000; PC = *(int*)0x08001004; И всё. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба //здесь переопределение адреса таблицы векторов прерываний //и переход к выполнению основной программы __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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxntf 0 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Это то как раз и непонятно. Что-то у Вас неправильно компилится/линкуется. Не надо делать "не под бутлоадер". Если правильная конфигурация командного файла линкёра, то после загрузки ПО JTAG-ом, PC устанавливается на точку входа (содержимое вектора сброса или начало функции main()). И это вне зависимости от того, на какие адреса линковали - хоть в FLASH хоть в SRAM хоть во внешнюю SDRAM. При установке в настройка линкера CooCox старт адреса 0x08001000, после компиляции и запуска отладки у меня во втором слове памяти по адресу 0x00000004 почему весит значение с адресом 0x00010101. Да и вообще я вижу, что в памяти какая то бяка вместо моей программы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба При установке в настройка линкера CooCox старт адреса 0x08001000, после компиляции и запуска отладки у меня во втором слове памяти по адресу 0x00000004 почему весит значение с адресом 0x00010101. Да и вообще я вижу, что в памяти какая то бяка вместо моей программы. Так если линкуете с адреса 0x08001000, то зачем смотрите на адрес 0x00000000??? И что такое старт адрес 0x08001000? У Вас там таблица векторов прерываний расположена? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxntf 0 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Так если линкуете с адреса 0x08001000, то зачем смотрите на адрес 0x00000000??? И что такое старт адрес 0x08001000? У Вас там таблица векторов прерываний расположена? Смотрю на адрес 0x00000004 потому что внем записано 0x00010101 и у меня отладчик висит на этом адресе после старта. Хотя смотрел бинарник после компиляции, там вроде все верно. (по крайней мере код программы есть) Наверное я что то делаю не так. Можете поэтапно указать все изменения проекта под бутлоадер от стандартного проекта, пусть даже который создаем через визар. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Хотя смотрел бинарник после компиляции, там вроде все верно. (по крайней мере код программы есть) Наверное я что то делаю не так. Как Вы смотрите бинарник? Как там видите адреса? Смотреть надо map-файл. По нему проверяете куда у Вас скомпоновалась таблица векторов прерываний и прочие секции кода и данных. Также там указана точка входа ПО (в IAR называется "Entry symbol"). Вот с этой точки входа отладчик и стартует. Я не знаю кокос, пользуюсь IAR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба Как-то слишком кудряво и лишнее разименование. Надо быть проще: ((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)(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба 1. #define ADDR 0x08001004 ... ((void(*)(void))ADDR)(); У ТС адрес 0x08001004 - не адрес функции, а адрес вектора reset в таблице прерываний, который указывает на функцию. Так что там ещё разыменование забыли. А если-б это был адрес функции, бит0 был бы равен ==1, а не 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 5 апреля, 2016 Опубликовано 5 апреля, 2016 · Жалоба У ТС адрес 0x08001004 - не адрес функции, а адрес вектора reset в таблице прерываний, который указывает на функцию. Поял. А если-б это был адрес функции, бит0 был бы равен ==1, а не 0. Это смотря какой режим - не только на кортексах свет клином сошелся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться