Прерывания не работают при переходе к приложению (STM32) - PullRequest
1 голос
/ 12 марта 2019

Обновление: Может быть, лучший вопрос, который нужно задать, - как мне отладить эту проблему?Я использую VS Code с отладчиком OpenOCD.Я всегда чистую сборку.Лучшее, что я могу сделать, когда я выполняю JumpToApplication (), это посмотреть, по каким адресам останавливается отладчик, когда я делаю паузу / шаг.

Я могу перенести программу в раздел A (@address 0x8060000) и проверить его с помощьюпроверка CRC.Программа запускает все, что в цикле, пока нормально (переключение LED3, UART);однако переключение LED2 на основе прерывания по таймеру не работает.Когда я прошиваю программу нормально (т.е. не с моего загрузчика), она работает на 100%, включая переключение LED2.

Вот некоторые ресурсы, к которым я обращался ( 1 , 2, 3 , AN2606 ).Как заставить прерывания работать для моего второго приложения?Ресурсы рекомендуют мне убирать ожидающие прерывания, но я не знаю, как лучше к этому подойти.В моем приложении загрузчика я использую периферийные устройства ETH, UART и GPIO, поэтому я буду просматривать руководство и читать регистры, чтобы очистить флаги прерываний, но как насчет других прерываний, таких как NMI, HardFault, мне нужно выяснить, как их очищать, какЧто ж?В моем поиске в Google я не нашел удобных функций для очистки всех ожидающих прерываний, существует ли он?

Ниже я включаю файл функции перехода / компоновщика для приложения загрузчика по адресу 0x8000000 и файл main.c / linkerдля приложения по адресу 0x8060000:

ФУНКЦИЯ ПЕРЕКЛЮЧЕНИЯ В ПРОГРАММЕ ЗАГРУЗЧИКА НА 0x8000000

void ApplicationManager::RunActivePartition()
{     
    JumpToApplication = (void (*)(void)) (*((uint32_t *) (active_partition.address + 4)));

    /* Set vector table offset register */
    SetVectorTable(MemoryInfo::BTLR_ADDRESS, MemoryInfo::PARTITION_A_OFFSET_FROM_BTLR);

    /* STM32 needs the stack pointer to start at the beginning of
    ** the application in flash. This must happen last */ 
    __set_MSP(*(__IO uint32_t*) active_partition.address);

    JumpToApplication();


    /*************** Other things I have tried ***************/
    /* Reset RCC clock configuration */
    // HAL_RCC_DeInit();

    /* Disable peripheral clocks */
    // __HAL_RCC_GPIOA_CLK_DISABLE();
    // __HAL_RCC_GPIOB_CLK_DISABLE();
    // __HAL_RCC_GPIOC_CLK_DISABLE();
    // __HAL_RCC_GPIOD_CLK_DISABLE();
    // __HAL_RCC_GPIOG_CLK_DISABLE();
    // __HAL_RCC_GPIOH_CLK_DISABLE();
    // __HAL_RCC_PWR_CLK_DISABLE();

    /* Disable Peripherals */
    // HAL_CRC_MspDeInit(&hcrc);
    // HAL_UART_DeInit(&huart3);

    /* Disable and reset systick timer */
    // SysTick->CTRL= 0;
    // SysTick->LOAD = 0;
    // SysTick->VAL = 0;

    /* Disable all interrupts */
    // __disable_irq();

    /* Clear pending interrupts */

    /* Remap system memory */
    // SYSCFG->MEMRMP = SYSCFG_MEMRMP_MEM_MODE_0; // 

    /*************** What I want to add when more basic implementation works ***************/
    // /* Relocate vector interrupt table to RAM */
    // CopyVectorInterruptTable();

    // /* TODO: Patch VIT with bootloader interrupt handlers (ex: hard fault handler) */
    // PatchVectorInterruptTable();

    // if (!CopyandPatchOkay())
    // {
    //     LOG_DEBUG("Vector interrupt table not probably copied and/or patched \n");
    // }
    // else
    // {
    //     LOG_DEBUG("Device ready to jump into application \n");
    // }
}

ФАЙЛ ПОДКЛЮЧЕНИЯ ДЛЯ ПРИМЕНЕНИЯ (BOOTLOADER) 0x8000000

/* Highest address of the user mode stack */
_estack = 0x20010000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
}

ПРИЛОЖЕНИЕ В ПРИЛОЖЕНИИ0x8060000

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim10)
{
 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  SCB->VTOR = 0x8060000; //---- @berendi's suggestion
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_TIM10_Init();
  /* USER CODE BEGIN 2 */
  uint32_t count = 0;
  HAL_TIM_Base_Start_IT(&htim10);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    for (uint32_t i=0; i < 100000; i++);
    HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
    _printf("Hi %d \n", count);
    count++;
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

LINKER FILE ДЛЯ ПРИМЕНЕНИЯ (INTERRUPT-BLINKY) 0x8060000

/* Highest address of the user mode stack */
_estack = 0x20010000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8060000, LENGTH = 1024K
}

1 Ответ

2 голосов
/ 12 марта 2019

В проектах, генерируемых STM32CubeMX, функция SystemInit() в system_stm32f4xx.c, вызываемая кодом запуска перед main(), сбрасывает регистр адреса таблицы векторов в начало FLASH.

/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
                                   This value must be a multiple of 0x200. */

/* -- snip -- */

#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif

Вы можете отредактировать этот файл напрямую (и не запускать STM32CubeMX в проекте снова, поскольку он , кажется, перезаписывает этот файл ), или просто снова установить правильное значение в main(), прежде чем разрешать прерывания.

...