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

STM32F103C8 перенос таблицы прерываний

Добрый день, написал самый обычный код в 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.

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


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

Делается как-то так

	// 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(;;);

 

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


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

лови готовый код, а то ещё потом подводные камни встретишь...

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");
    };
}

 

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


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

Вот мой код (где то с инета дернул), использую для 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)
}
Изменено пользователем alevnew

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


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

Открываем 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

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


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

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

бесполезно

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


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

Quote

бесполезно

Да ладно!

У меня уже для STM32F1xx и STM32F4xx работает. Это для программы, которая будет загружаться бутлодером.

Кстати, я это подсмотрел у STM в проектах для IAP 

Изменено пользователем A.Lex

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


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

16 минут назад, A.Lex сказал:

Кстати, я это подсмотрел у STM в проектах для IAP 

Редкостный идиотизм авторов "библиотеки". Во-первых, накой приложению вообще куда-то двигать свои вектора? Этим должен заниматься загрузчик. К моменту запуска приложения все вектора уже подвинуты и нефиг туда лазать. Во-вторых, я полдня убил, чтобы свой загрузчик в проект коллеги встроить, а коллега так и не сумел. Видите-ли, вы должны отредактировать адрес своего приложения в библиотечном(!) файле. То есть вы должны хранить сотни мегабайт исходника всей этой библиотеки с каждым(!) своим проектом, потому что под любой проект эти исходники может понадобиться слегка "подточить".

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


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

Quote

Редкостный идиотизм авторов "библиотеки"

Не спорю

Изменено пользователем A.Lex

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


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

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)
  }
}

 

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


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

Quote

В кейле же надо просто сделать sct файл. 

Это само собой.

Тут речь о размещении таблицы векторов

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


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

27 минут назад, A.Lex сказал:

Тут речь о размещении таблицы векторов

Ну так компилятор там ее и разместит. В данном случае, по адресу из sct файла 0x08004000.

Никаких проблем не возникает.

 

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


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

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

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

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

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

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

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

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

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

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