Neo_Matrix 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба Такая проблема: Есть файл 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); - пробовал - не работает. Спасибо всем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба void vDeleteUart(void const * argument); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба Такая проблема: Как бы помягче.... Вы хоть в документацию одним глазом загляните ЧТО нужно указывать xTaskResumeFromISR(). И это СОВЕРШЕННО не адрес функции, а Handle. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 (изменено) · Жалоба В первом сообщении закралась ошибка, vDeleteUart необходимо заменить на vDeleteSTR. Немного промахнулся с копи-пастом. zltigo Хорошо, как тогда его использовать? С "мейна" все работает хорошо, как хэндл использовать в "библиотечном" файле? Просто написать в начале irq.c BaseType_t vDeleteSTR; или TaskHandle_t vDeleteSTR; Както так? Изменено 25 февраля, 2016 пользователем Neo_Matrix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба как хэндл использовать в "библиотечном" файле? Как и любую переменую. Что за проблема? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 (изменено) · Жалоба Хорошо допустим есть 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 с прерывания, обработчик которого вынесен в отдельный .с файл ? Если можно примером кода. Изменено 25 февраля, 2016 пользователем Neo_Matrix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба И описание и пример кода http://www.freertos.org/taskresumefromisr.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 (изменено) · Жалоба x893 Спасибо, но если бы все было в одном main.c все сработало бы.Я не могу понять как в данном случае объявить ХЭНДЛ в стороннем файле, если extern применить не ясно как(для меня). В моем случае получается multiply defined vDeleteSTR. Изменено 25 февраля, 2016 пользователем Neo_Matrix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба В другом файле написать 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(); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Спасибо, но если бы все было в одном main.c все сработало бы. Разумется нет. Совсем нет. Сам вызов принципиально неправилен и не рабоспособен. Документация! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 16 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Разумется нет. Совсем нет. Сам вызов принципиально неправилен и не рабоспособен. Документация! Угу. И нехотение читать что там за "ошибка при компиляции". А многие еще и варнинги отключают и не понимают что с ними вообще делать, типа "скомпилировалось- значит в исходнике все нормально" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба В другом файле написатьextern TaskHandle_t xHandle; Все теперь понял. Это и был основной вопрос, спасибо! Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)). Между прочим код компилится без варнингов и без ошибок, если все сгрузить в мейн. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Относительно гневных комментариев: Сам вызов буду осуществлять через cmsis_os, Весь код приведен только как пример(кстати если его записать только в мейне, то все будет работать(возможно не долго)). Между прочим код компилится без варнингов и без ошибок, если все сгрузить в мейн. Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС. Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле. Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Чтобы сообщить задаче ОС о некоем событии в ISR, используются средства синхронизации ОС. Как то: мэйлбоксы, семафоры, мьютексы и т.п. Читайте описание на свою ОС. Например: задача ждёт в функции ожидания мэйлбокса -> ISR отправляет сообщение в сей мэйлбокс -> задача просыпается, выполняет работу, опять выходит на функцию ожидания мэйлбокса. И так в цикле. Так стандартно строятся все задачи - обработчики неких событий от периферии (от ISR). Не понял к чему это сказано, вопрос был несколько иным... Какое отличие между тем, что задача ожидает очередь или семафор от применения засыпания в конце задачи и дальнейшим пробуждением из прерывания. То что очередь может передать данные - не в счет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Не понял к чему это сказано, вопрос был несколько иным... Какое отличие между тем, что задача ожидает очередь или семафор от применения засыпания в конце задачи и дальнейшим пробуждением из прерывания. То что очередь может передать данные - не в счет. Вопрос вроде был "Как правильно разбудить задачу vDeleteSTR с прерывания" если я не ошибаюсь. Обычно простое засыпание (без привязки к средствам синхронизации ОС) задачи ОС - это засыпание на N тактов сис.таймера. Задача конечно проснётся и обнаружит событие, но не сразу после его его возникновения, как если бы ждала мэйлбокса. Данные не обязательно передавать через мэйлбокс - достаточно факта вызова функции MailboxPost() в ISR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться