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

Как из обработчика прерывания(вынесен в отдельный файл) вызвать xTaskResumeFromISR

Такая проблема:

Есть файл main.c в нем имеется задача РТОС, которая объявлена как void vDeleteSTR(void const * argument); сама функция такая

void vDeleteUart(void const * argument)
{
//Здесь удаляем строку
vTaskSuspend(NULL); // Здесь засыпаем, пока прерывание не разбудит...
}

Сам обработчик прерывания вынесен в отдельный файл допустим irq.c

void USART3_IRQHandler(void)
{
xTaskResumeFromISR(vDeleteUart);// Пробовал писать так
}

Но чего и следовало ожидать, vDeleteUart не объявлена в irq.c, соответственно при компиляции ошибка. Как правильно сделать?

extern void vDeleteSTR(void const * argument); - пробовал - не работает.

Спасибо всем.

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


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

Такая проблема:

Как бы помягче.... Вы хоть в документацию одним глазом загляните ЧТО нужно указывать xTaskResumeFromISR(). И это СОВЕРШЕННО не адрес функции, а Handle.

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


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

В первом сообщении закралась ошибка, vDeleteUart необходимо заменить на vDeleteSTR. Немного промахнулся с копи-пастом.

zltigo

Хорошо, как тогда его использовать? С "мейна" все работает хорошо, как хэндл использовать в "библиотечном" файле?

Просто написать в начале irq.c

BaseType_t vDeleteSTR;
или 
TaskHandle_t vDeleteSTR;

Както так?

Изменено пользователем Neo_Matrix

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


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

как хэндл использовать в "библиотечном" файле?

Как и любую переменую. Что за проблема?

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


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

Хорошо допустим есть main.c c с содержимым:

#include "irq.h"
void vDeleteSTR(void const * argument);

int main(void)
osThreadDef(DeleteSTR, vDeleteSTR, osPriorityIdle, 0, 1024);
DeleteSTRHandle = osThreadCreate(osThread(DeleteSTR), NULL);
osKernelStart();
while(1){}

void vDeleteSTR(void const * argument)
{
//Здесь удаляем строку
vTaskSuspend(NULL); // Здесь засыпаем, пока прерывание не разбудит...
}

 

Есть файл irq.c c содержимым:

 

void USART3_IRQHandler(void)
{
xTaskResumeFromISR(vDeleteSTR);// Пробовал писать так
}

 

Как правильно разбудить задачу vDeleteSTR с прерывания, обработчик которого вынесен в отдельный .с файл ?

Если можно примером кода.

Изменено пользователем Neo_Matrix

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


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

x893

Спасибо, но если бы все было в одном main.c все сработало бы.Я не могу понять как в данном случае объявить ХЭНДЛ в стороннем файле, если extern применить не ясно как(для меня). В моем случае получается multiply defined vDeleteSTR.

Изменено пользователем Neo_Matrix

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


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

В другом файле написать

 

extern TaskHandle_t xHandle;

void vAnExampleISR( void )
{
BaseType_t xYieldRequired;

     // Resume the suspended task.
     xYieldRequired = xTaskResumeFromISR( xHandle );

     if( xYieldRequired == pdTRUE )
     {
         // We should switch context so the ISR returns to a different task.
         // NOTE:  How this is done depends on the port you are using.  Check
         // the documentation and examples for your port.
         portYIELD_FROM_ISR();
     }
}

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


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

Спасибо, но если бы все было в одном main.c все сработало бы.

Разумется нет. Совсем нет. Сам вызов принципиально неправилен и не рабоспособен. Документация!

 

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


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

Разумется нет. Совсем нет. Сам вызов принципиально неправилен и не рабоспособен. Документация!

Угу. И нехотение читать что там за "ошибка при компиляции". А многие еще и варнинги отключают и не понимают что с ними вообще делать, типа "скомпилировалось- значит в исходнике все нормально"

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


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

В другом файле написатьextern TaskHandle_t xHandle;

Все теперь понял. Это и был основной вопрос, спасибо!

 

Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)).

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

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


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

Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)).

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

Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС.

Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле.

Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR).

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


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

Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС.

Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле.

Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR).

Не понял к чему это сказано, вопрос был несколько иным...

Какое отличие между тем, что задача ожидает очередь или семафор от применения засыпания в конце задачи и дальнейшим пробуждением из прерывания. То что очередь может передать данные - не в счет.

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


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

Не понял к чему это сказано, вопрос был несколько иным...

Какое отличие между тем, что задача ожидает очередь или семафор от применения засыпания в конце задачи и дальнейшим пробуждением из прерывания. То что очередь может передать данные - не в счет.

Вопрос вроде был "Как правильно разбудить задачу vDeleteSTR с прерывания" если я не ошибаюсь.

Обычно простое засыпание (без привязки к средствам синхронизации ОС) задачи ОС - это засыпание на N тактов сис.таймера. Задача конечно проснётся и обнаружит событие, но не сразу после его его возникновения, как если бы ждала мэйлбокса. Данные не обязательно передавать через мэйлбокс - достаточно факта вызова функции MailboxPost() в ISR.

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


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

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

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

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

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

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

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

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

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

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