settz0r 0 23 октября, 2018 Опубликовано 23 октября, 2018 · Жалоба Добрый день, написал самый обычный код в KEIL UVISION с миганием диода и установкой прерывания через EXTI. Хочу запрограммировать плату через бутлодер по адресу 0х8004000(начальный адрес 0х8000000). Для этого пишу такие строчки: __set primask(0); // глобальное запрещение прерываний NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8004000); // непосредственно перенос таблицы прерываний __set_PRIMASK(0); // разрешение прерываний В настройках проекта нужный адрес выставил в Target и Linker. Достаточно ли этих строчек для переноса или нужно что то еще? Код без EXTI или SysTick без проблем переноситься, а с прерыванием никак не получается. Сразу говорю, с HAL'ом и STM32CubeMX не работаю. Работаю с SPL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mcheb 0 23 октября, 2018 Опубликовано 23 октября, 2018 · Жалоба Делается как-то так // Turn GPIOA clock off bit_clear(RCC->APB2ENR, RCC_APB2ENR_IOPAEN); // Turn GPIOB clock off LED1_CLOCK_DIS; //bit_clear(RCC->APB2ENR, RCC_APB2ENR_IOPBEN); SCB->VTOR = USER_PROGRAM; asm volatile("msr msp, %0"::"g"(*(volatile u32 *) USER_PROGRAM)); // __set_MSP(appStack); userProgram(); for(;;); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 23 октября, 2018 Опубликовано 23 октября, 2018 · Жалоба лови готовый код, а то ещё потом подводные камни встретишь... JumpToApplication(ADDR_USER_START); обрати внимание - в NVIC_SetVectorTable смещение относительное задаётся, а не абсолютный адрес void JumpToApplication(uint32_t addr) { typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; if(addr < ADDR_USER_START) { // printf("Try to start User App from BL code area!\r\n"); return; } /* Test if user code is programmed starting from address "ADDR_USER_START" */ uint32_t estack_label = (*(__IO uint32_t*)addr) & 0x2FFE0000; // printf("estack_label @ 0x%08X: 0x%08X\r\n", addr, estack_label); // printf("ADDR_RAM_START, RAM_SIZE: 0x%08X, 0x%08X\r\n", ADDR_RAM_START, RAM_SIZE); if (estack_label == ADDR_RAM_START) { __disable_irq(); // __disable_fault_irq(); NVIC_SetVectorTable(NVIC_VectTab_FLASH, FLASH_BL_SIZE); JumpAddress = *(__IO uint32_t*) (addr + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) addr); __set_CONTROL(0x00000000); // switch to "main" stack pointer PSP // код найден по ссылке code from http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2011/freertos_Cortex_M3_port_fault-stack_MSP_setup_4606104.html // Ensure that normal processing runs on PSP ("Process" Stack // Pointer, in "thread mode" or "normal mode"). Processor starts // out of reset using MSP, so unless the RTL has already switched, we // need to switch here. // printf("CONTROL register=%08lX, stack in use is %s\n", // __get_CONTROL(), (__get_CONTROL()&0x2) ? "PSP, need to switch." : "MSP, OK."); // if( (__get_CONTROL()&0x2) != 0 ) { // // Ooops, we're using PSP "Process" Stack Pointer // // Set up "main" stack pointer and switch to it // //__set_MSP(__get_PSP()); // copy current stack pointer value into PSP // __set_MSP(*(__IO uint32_t*) addr); // __set_CONTROL(0x00000000); // switch to "main" stack pointer PSP // //__set_CONTROL(0x00000002); // switch to "process" stack pointer PSP // printf("After stack pointer switch: CONTROL register=%08lX, stack in use is %s\n",__get_CONTROL(), (__get_CONTROL()&0x2)?"PSP":"MSP"); // } Jump_To_Application(); } else { printf("No UserApp!\n"); }; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alevnew 0 23 октября, 2018 Опубликовано 23 октября, 2018 (изменено) · Жалоба Вот мой код (где то с инета дернул), использую для F103 для перехода в основную прогу из загрузчика (использую в кейле, dword = uint32_t). #define MAIN_PROG_ADDRESS 0x08002000 //jump to new vector table __ASM void boot_jump(dword address){ LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter address } int main(void){ ..... ..... SCB->VTOR=MAIN_PROG_ADDRESS; boot_jump(MAIN_PROG_ADDRESS) } Изменено 23 октября, 2018 пользователем alevnew Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A.Lex 0 23 октября, 2018 Опубликовано 23 октября, 2018 · Жалоба Открываем system_stm32f1xx.c Находим строку #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ и корректируем #define VECT_TAB_OFFSET 0x00004000U Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
settz0r 0 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба 23 часа назад, alevnew сказал: Вот мой код (где то с инета дернул), использую для F103 для перехода в основную прогу из загрузчика (использую в кейле, dword = uint32_t). #define MAIN_PROG_ADDRESS 0x08002000 //jump to new vector table __ASM void boot_jump(dword address){ LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter address } int main(void){ ..... ..... SCB->VTOR=MAIN_PROG_ADDRESS; boot_jump(MAIN_PROG_ADDRESS) } выдает ошибку в виде того, что SP и PC не идентифицированы. Вопрос, где данные регистры описаны? 21 час назад, A.Lex сказал: Открываем system_stm32f1xx.c Находим строку #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ и корректируем #define VECT_TAB_OFFSET 0x00004000U бесполезно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A.Lex 0 24 октября, 2018 Опубликовано 24 октября, 2018 (изменено) · Жалоба Quote бесполезно Да ладно! У меня уже для STM32F1xx и STM32F4xx работает. Это для программы, которая будет загружаться бутлодером. Кстати, я это подсмотрел у STM в проектах для IAP Изменено 24 октября, 2018 пользователем A.Lex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба 16 минут назад, A.Lex сказал: Кстати, я это подсмотрел у STM в проектах для IAP Редкостный идиотизм авторов "библиотеки". Во-первых, накой приложению вообще куда-то двигать свои вектора? Этим должен заниматься загрузчик. К моменту запуска приложения все вектора уже подвинуты и нефиг туда лазать. Во-вторых, я полдня убил, чтобы свой загрузчик в проект коллеги встроить, а коллега так и не сумел. Видите-ли, вы должны отредактировать адрес своего приложения в библиотечном(!) файле. То есть вы должны хранить сотни мегабайт исходника всей этой библиотеки с каждым(!) своим проектом, потому что под любой проект эти исходники может понадобиться слегка "подточить". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A.Lex 0 24 октября, 2018 Опубликовано 24 октября, 2018 (изменено) · Жалоба Quote Редкостный идиотизм авторов "библиотеки" Не спорю Изменено 24 октября, 2018 пользователем A.Lex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alevnew 0 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба 1 час назад, settz0r сказал: выдает ошибку в виде того, что SP и PC не идентифицированы. Вопрос, где данные регистры описаны? А что за компилятор? Я так понимаю, это ни в каких файлах не описано - компилятор по директиве понимает, что это ассемблер, а ассемблер у него, видимо, вшит. Проверено, работает как в четвертом, так и в пятом кейле. 23 часа назад, A.Lex сказал: Открываем system_stm32f1xx.c Находим строку А зачем это делать? В кейле же надо просто сделать sct файл. Типа: LR_IROM1 0x08004000 (0x00020000 - 0x4000) { ; load region size_region ER_IROM1 0x08004000 (0x00020000 - 0x4000) { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x0000C000 { ; RW data ; *(ram_code) ; flash erase/write functions .ANY (+RW +ZI) } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A.Lex 0 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба Quote В кейле же надо просто сделать sct файл. Это само собой. Тут речь о размещении таблицы векторов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
settz0r 0 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба 20 минут назад, alevnew сказал: А что за компилятор? Обычный кейловский компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alevnew 0 24 октября, 2018 Опубликовано 24 октября, 2018 · Жалоба 27 минут назад, A.Lex сказал: Тут речь о размещении таблицы векторов Ну так компилятор там ее и разместит. В данном случае, по адресу из sct файла 0x08004000. Никаких проблем не возникает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться