|
Как из обработчика прерывания(вынесен в отдельный файл) вызвать xTaskResumeFromISR |
|
|
|
Feb 25 2016, 15:58
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Такая проблема: Есть файл 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); - пробовал - не работает. Спасибо всем.
|
|
|
|
|
Feb 25 2016, 20:50
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
В первом сообщении закралась ошибка, vDeleteUart необходимо заменить на vDeleteSTR. Немного промахнулся с копи-пастом. zltigoХорошо, как тогда его использовать? С "мейна" все работает хорошо, как хэндл использовать в "библиотечном" файле? Просто написать в начале irq.c Код BaseType_t vDeleteSTR; или TaskHandle_t vDeleteSTR; Както так?
Сообщение отредактировал Neo_Matrix - Feb 25 2016, 20:54
|
|
|
|
|
Feb 25 2016, 21:44
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Хорошо допустим есть 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 - Feb 25 2016, 21:46
|
|
|
|
|
Feb 25 2016, 22:19
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
x893 Спасибо, но если бы все было в одном main.c все сработало бы.Я не могу понять как в данном случае объявить ХЭНДЛ в стороннем файле, если extern применить не ясно как(для меня). В моем случае получается multiply defined vDeleteSTR.
Сообщение отредактировал Neo_Matrix - Feb 25 2016, 22:19
|
|
|
|
|
Feb 26 2016, 08:18
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Цитата В другом файле написатьextern TaskHandle_t xHandle; Все теперь понял. Это и был основной вопрос, спасибо! Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)). Между прочим код компилится без варнингов и без ошибок, если все сгрузить в мейн.
|
|
|
|
|
Feb 26 2016, 08:38
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Neo_Matrix @ Feb 26 2016, 14:18)  Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)). Между прочим код компилится без варнингов и без ошибок, если все сгрузить в мейн. Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС. Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле. Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR).
|
|
|
|
|
Feb 26 2016, 08:55
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Цитата(jcxz @ Feb 26 2016, 10:38)  Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС. Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле. Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR). Не понял к чему это сказано, вопрос был несколько иным... Какое отличие между тем, что задача ожидает очередь или семафор от применения засыпания в конце задачи и дальнейшим пробуждением из прерывания. То что очередь может передать данные - не в счет.
|
|
|
|
|
Feb 26 2016, 10:14
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Цитата(jcxz @ Feb 26 2016, 11:04)  Вопрос вроде был "Как правильно разбудить задачу vDeleteSTR с прерывания" если я не ошибаюсь. Обычно простое засыпание (без привязки к средствам синхронизации ОС) задачи ОС - это засыпание на N тактов сис.таймера. Задача конечно проснётся и обнаружит событие, но не сразу после его его возникновения, как если бы ждала мэйлбокса. Данные не обязательно передавать через мэйлбокс - достаточно факта вызова функции MailboxPost() в ISR. Да, возможно я не очень точно описал мою проблему. Проблема была в объявлении ХЕНДЛА в отдельном файле не main.c. Собственно уже решено, всем спасибо. Цитата(zltigo @ Feb 26 2016, 12:03)  Между прочим, он должен РАБОТАТЬ, а не только компилится с подавленным варнингами. Работать пробуждение написаное Вам НЕ будет ни при каком раскладе. Спорить не хочу, но это работает на Дискавери 4. Варнинги у меня не подавлены. С чего Вы вообще взяли, что подавлены варнинги? В любом случае x893 уже дал ответ на поставленный вопрос. Да и выше было сказано о примере кода, а не о конечном варианте.
|
|
|
|
|
Feb 26 2016, 12:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Neo_Matrix @ Feb 26 2016, 12:14)  Спорить не хочу, но это работает на Дискавери 4. Если работает, то что то другое. Без вариантов. QUOTE Варнинги у меня не подавлены. С чего Вы вообще взяли, что подавлены варнинги? C этим вообще просто - подсовывание при вызове адреса функции вместо хандлера процесса есть 100% причина ругаться.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 29 2016, 07:31
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Neo_Matrix @ Feb 25 2016, 18:58)  Но чего и следовало ожидать, vDeleteUart не объявлена в irq.c, соответственно при компиляции ошибка. Как правильно сделать? Для решения этой задачи надо объявить хэндлер (который присваивается в CreateTask() глобальным. Заодно осознать, что хэндлер - это просто переменная (пусть и "хитрого" типа). Как использовать переменную в двух модулях одновременно, написано во всех букварях (первая же ссылка - http://www.c-cpp.ru/books/extern ). А "как правильно" написано в статьях Курница (гуглится "Курниц FreeRTOS"). Очень рекомендую. Ещё очень рекомендую инструкцию от scmRTOS - просто и понятно расписаны все принципы микро-операционки. Цитата(zltigo @ Feb 26 2016, 15:40)  C этим вообще просто - подсовывание при вызове адреса функции вместо хандлера процесса есть 100% причина ругаться. Вот кстати необязательно. Авторы FreeRTOS очень любят указатели на void. Соответственно, можно наворотить всякой фигни, и оно успешно соберётся. Работать, конечно же, это не станет.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 29 2016, 19:10
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (esaulenka @ Feb 29 2016, 09:31)  Вот кстати необязательно. Авторы FreeRTOS очень любят указатели на void. Соответственно, можно наворотить всякой фигни, и оно успешно соберётся. Работать, конечно же, это не станет. В данном случае все совершенно однозначно - даже вместо: * void подсунуть что-то типа функции: void (*)(void) без реальных издевательств нереально.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|