1. В сообществе нашего форума Вконтакте создан раздел по продаже электронных компонентов.
    Каждый может продать в нем свои залежавшиеся детали. Подробности здесь.

Туториал STM32F100 зависает на вызове обработчика прерывания

Тема в разделе "STM8/STM32", создана пользователем radioengineer, 24 фев 2016.

  1. radioengineer

    radioengineer Администратор Команда форума

    Сообщения:
    3.559
    Симпатии:
    354
    Адрес:
    Алматы
    Наткнулся сегодня на интересную особенность при работе с STM32F100 в Keil. Пишу проект на C++, кроме этого пишу библиотеки на чистом Си, в частности есть библиотека для работы с таймерами, в которой описаны все процедуры и обработчики прерываний от таймеров. Так вот при отладке выяснилось, что процессор тупо виснет, когда должен вызываться обработчик прерывания по переполнению Timer 3. Код примерно таков:
    PHP:
    // Обработчик прерывания TIM3 - таймаут ожидания ответа на AT команду
    void TIM3_IRQHandler(void)
    {
        
    timeoutFlag true;            // Установить флаг конца таймаута ответа на AT команду
        
    TIM3->SR &= ~TIM_SR_UIF;        // Сбросить флаг прерывания Update
        
    NVIC_DisableIRQ(TIM3_IRQn);        // Запретить прерывания TIMER3
        
    __disable_irq();            // Глобально запретить прерывания
    }

    void tim_init(uint16_t valueTIM_TypeDef TIMxuint16_t prescaler)
    {
        
    timeoutFlag false;
        
    TIMx->PSC prescaler 1;        // Установить делитель, по умолчанию на миллисекунды
        
    TIMx->CR1 |= TIM_CR1_OPM;        // Режим одного импульса, выключит таймер по совпадению с регистром  ARR
        
    TIMx->ARR value;            // Загружаем количество отсчитываемых мс
        
    TIMx->CNT 0;                // Обнуляем счетный регистр
      
        
    __enable_irq();                // Глобально разрешить прерывания
        
    NVIC_EnableIRQ(TIM3_IRQn);        // Разрешить прерывания TIMER3
        //NVIC_SetPriority(TIM3_IRQn, 2);
        
    TIMx->DIER |= TIM_DIER_UIE;
        
    TIMx->CR1 |= TIM_CR1_CEN;        // Включить таймер  
    }
    При отладке я попадал в бесконечный цикл без выхода, так как будто я разрешаю прерывание Timer 3 (NVIC_EnableIRQ(TIM3_IRQn)) и при этом не пишу обработчик, хотя он присутствует. Иногда такое еще случается, если не добавить ассемблерный файл startup_stm32f10x_md_vl.s в проект, в котором как раз и объявлены имена обработчиков, например в моем случае TIM3_IRQHandler. В моем случае проблема была как раз в том, что весь проект на C++ и необходимо было использовать конструкцию для включения сишной компоновки в C++ проекте:
    PHP:
    #ifdef __cplusplus
    extern "C" {
    #endif

    // Обработчик прерывания TIM3 - таймаут ожидания ответа на AT команду
    void TIM3_IRQHandler(void)
    {
        
    timeoutFlag true;            // Установить флаг конца таймаута ответа на AT команду
        
    TIM3->SR &= ~TIM_SR_UIF;        // Сбросить флаг прерывания Update
        
    NVIC_DisableIRQ(TIM3_IRQn);        // Запретить прерывания TIMER3
        
    __disable_irq();            // Глобально запретить прерывания
    }

    #ifdef __cplusplus
    }
    #endif
    Вот что описано в MSDN по поводу этой конструкции:
    Последнее редактирование: 24 фев 2016
     
  2. Alex

    Alex В доску свой

    Сообщения:
    191
    Симпатии:
    13
    В C++ дядя Страуструп ввел такую фичу, как перегруженные ф-ии. Которые хотя и называются в программе одинаково, но имею разное наполнение и содержание. И вот чтобы эту концепцию протянуть через *.obj файлы без конфликта меток пришлось ввести name mangling. С помощью этого механизма имена переменных и ф-ий в *.obj файлах дополняются специальными длинными аббревиатурами, чтобы исключить конфликт имен. Проблема в том, что этот механизм срабатывает всегда и объявив например void T_irq(); ты в *.obj файле получить можешь имя для ф-ии вроде _T_irq_v_f. Чтобы нормально спрягать код на C++ с C или ASM, где name mangling отсутствует, введено extern "C", которое отключает name mangling у экспортируемых или импортируемых имен переменных/ф-ий. Extern "C" ф-ии не могут быть перегружены.
    radioengineer нравится это.

Поделиться этой страницей