2016-12-12 2 views
1

Я использую целевую библиотеку CrossWorks с контроллером stm32f. В моем проекте у меня есть некоторые внешние прерывания. Пока они работают, и потому, что я более или менее украл конфигурацию из предыдущих проектов, я был бы склонен сказать, что это должно быть правильно. Все ISR обработчиков выглядеть примерно так:CTL_UNSUPPORTED_CALL_FROM_ISR с библиотекой CrossWorks

void __attribute__((interrupt("IRQ"))) EXTI2_TSC_IRQHandler(void) 
{ 
    if ((EXTI_GetITStatus(BUTTON_6_INTERRUPT_LINE) != RESET)) { 
     ctl_enter_isr(); 
     /* Clear the EXTI line 2 pending bit */ 
     EXTI_ClearITPendingBit(BUTTON_6_INTERRUPT_LINE); 
     if(somecondition) 
      globalcounter++; 
     else 
      myLibFunction(); 
     ctl_exit_isr(); 
    } 
} 

Все работает идеально, до тех пор, somecondition верно. Если вызывается myLibFunction(), функция ctl_handle_error вызывается с аргументом CTL_UNSUPPORTED_CALL_FROM_ISR, и прошивка перезапускается. Пока что так ясно.

Документация, касающаяся этой ошибки, отсутствует (или я слишком тупой, чтобы ее найти). Я просто комментарий выше функции ctl_handle_error, который читает:

An interrupt service routine has called a tasking library function 
that could block or is otherwise unsupported when called from inside 
an interrupt service routine. 

Предполагая, что эта информация верна, то, что считается «функция блокировки» по Crossworks? Функция не имеет никаких циклов. Единственное управление потоком - if(). Нет рекурсии, while, for или что-то еще. Общая длина разборки во всех случаях составляет менее 50 инструкций.

Я ищу общее объяснение (или ссылку на документацию), какие функции считаются приемлемыми в ISR, а какие нет. Или, если моя информация неверна, почему я вообще получаю эту ошибку.

UPDATE

Моя проблема была решена, благодаря Павлу за указание меня к нему. Но я пока не хочу закрывать вопрос. Для бонусных очков я хотел бы понять, как CrossWorks обнаруживает функцию блокировки и как можно прекратить выполнение функции во время выполнения, когда выполняется блок кода, который может блокироваться.

Я знаю, что это тяжелая редакция, но на данный момент ответов нет, и она соответствует общему вопросу о документации и «как» за ней.

+1

Не могли бы вы разместить myLibFunction? – LPs

+1

Кажется, библиотека думает, что вы называете функцию, которая, например, I/O, действие, которое требует асинхронности и ожидания прерываний (т. Е. Блокировки). Вы не можете вызвать такую ​​функцию из ISR. –

+0

@Paul Ogilvie, вы на месте. В подфункции myLibFunction() у меня был вызов 'debug_print'. Это функция CrossWorks lib, которая печатает отладочные сообщения через интерфейс jtag. Я не обратил на это внимания. Моя вина и я извиняюсь за то, что трачу ваше время. Эта функция была «блокирующей». Мне действительно было бы интересно узнать, как CrossWorks идентифицирует эти функции или как он завершает выполнение, когда он сталкивается с таким кодом. Я уточню вопрос, чтобы побудить людей глубже вникать в это. – jwsc

ответ

1

Вы можете понять, находитесь ли вы внутри прерывания или нет, просматривая регистры hw. Например:

if(__get_IPSR() & IPSR_THREADED_MODE) { 
    /* I am not in interrupt context */ 
} else { 
    /* I am in interrupt context */ 
} 

Функция __get_IPSR() можно найти в core_cmFunc.h при использовании CMSIS для STM32. Я бы предположил, что вызываемая вами функция проверит, в каком контексте она работает и действует на нее (т. Е. Заканчивается или что-то еще).

+0

Таким образом, это «отказ от блокировки функций» работает только в том случае, если сама функция проверяет неправильный контекст? Если я напишу функцию, которая делает какое-то зло, ожидая, но не проверяя контекст, это не будет поймано? – jwsc

+0

Это правильно. Но у вас появятся серьезные проблемы. Сторожевой сторож, вероятно, лаял бы, если бы вы его реализовали. – staringlizard

+0

Вы правы. просто попробовал его с бесконечным циклом while в прерывании. Работает без участия CrossWorks. Ооо, теперь я разочарован;) – jwsc

Смежные вопросы