jenya7 0 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба Есть два таска - главный и логер с одинаковым приоритетом.В логере я записываю во флеш память большой кусок данных 4096 байт по SPI. do { spi_rw_flash(0x00, &flash_data); *buff_in++ = flash_data; /* read data to buffer */ leng--; }while( leng > 0); время записи 20 милисекунд. время переключения между тасками 2 милисекунды. по идее за эти 20 милисекунд должно быть 10 переключений между тасками.на деле я вижу что во время записи в логер главный таск застревает.Вопрос почему? И второй вопрос - если пришло время переключения таска - скедюлер даст SPI дозаписать текущий байт или выйдет посередине? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба Все зависит от того в каком режиме RTOS работает, preemptive RTOS scheduler, or cooperative RTOS scheduler. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба Все зависит от того в каком режиме RTOS работает, preemptive RTOS scheduler, or cooperative RTOS scheduler. у меня preemptive RTOS scheduler. может стоит перейти на cooperative? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба у меня preemptive RTOS scheduler. может стоит перейти на cooperative? Наоборот, поведение похоже на cooperative. Как работает в FreeRTOS Any number of tasks can share the same priority. If configUSE_TIME_SLICING is not defined, or if configUSE_TIME_SLICING is set to 1, then Ready state tasks of equal priority will share the available processing time using a time sliced round robin scheduling scheme. https://freertos.org/RTOS-task-priority.html Еще https://freertos.org/a00110.html#configUSE_TIME_SLICING configUSE_TIME_SLICING By default (if configUSE_TIME_SLICING is not defined, or if configUSE_TIME_SLICING is defined as 1) FreeRTOS uses prioritised preemptive scheduling with time slicing. That means the RTOS scheduler will always run the highest priority task that is in the Ready state, and will switch between tasks of equal priority on every RTOS tick interrupt. If configUSE_TIME_SLICING is set to 0 then the RTOS scheduler will still run the highest priority task that is in the Ready state, but will not switch between tasks of equal priority just because a tick interrupt has occurred. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба Есть два таска - главный и логер с одинаковым приоритетом.В логере я записываю во флеш память большой кусок данных 4096 байт по SPI. do { spi_rw_flash(0x00, &flash_data); *buff_in++ = flash_data; /* read data to buffer */ leng--; }while( leng > 0); время записи 20 милисекунд. время переключения между тасками 2 милисекунды. по идее за эти 20 милисекунд должно быть 10 переключений между тасками.на деле я вижу что во время записи в логер главный таск застревает.Вопрос почему? И второй вопрос - если пришло время переключения таска - скедюлер даст SPI дозаписать текущий байт или выйдет посередине? Я надеюсь, у вас spi_rw_flash отдаёт управление шедулеру при первом удобном случае (работает только по прерываниям, используя средства межпроцессного взаимодействия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 июня, 2018 Опубликовано 6 июня, 2018 · Жалоба ...с одинаковым приоритетом Вот и ответ - нет причин переключаться. И второй вопрос - если пришло время переключения таска - скедюлер даст SPI дозаписать текущий байт или выйдет посередине? А что шедулер знает про SPI? Если SPI аппаратный, то пересылку слова закончит железка. Если нужно использовать SPI в разных задачах, то в любом случае придется разделять ресурс самостоятельно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 7 июня, 2018 Опубликовано 7 июня, 2018 · Жалоба Я надеюсь, у вас spi_rw_flash отдаёт управление шедулеру при первом удобном случае (работает только по прерываниям, используя средства межпроцессного взаимодействия. функция без прерываний uint8_t spi_rw_flash(uint8_t tx, uint8_t* rx) { uint16_t counter_retry = 0; uint8_t err = 0; g_uiRecFlag_SFL = 0; // send byte err |= SFL_SPI_SendChar(tx); // wait until event of receive occurred while(!g_uiRecFlag_SFL){ counter_retry++; if (counter_retry > SPI_TIMEOUT_RETRY) return 1; }; // receive and save data in . err |= SFL_SPI_RecvChar(rx); g_uiRecFlag_SFL = 0; return err; } а как нужно отдавать управление шедулеру? по идее он сам знает когда переключиться на другой таск. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 7 июня, 2018 Опубликовано 7 июня, 2018 · Жалоба функция без прерываний uint8_t spi_rw_flash(uint8_t tx, uint8_t* rx) Вот не делал бы я поллинг в системе, которая является событийно-ориентированный. Вы просто угробляете время проца, вместо того, чтобы отдать его более важной задачи. Я понимаю, что сейчас этой задачи нет. Но всё равно, так лучше не делать. а как нужно отдавать управление шедулеру? по идее он сам знает когда переключиться на другой таск. Да, если это ос вытесняющая, то таймер переключит вас с одного процесса на другой. Ну, а если вы молотите поллингом в задаче, у которой приоритет наивысший, то задачи с меньшим приоритетом никогда не получат управление. Нужно использовать прерывания, и ждать в задаче событий (используя семафоры, очереди, уведомления). Вот тогда, пока благородная железка занимается своим делом, вы ждёте прерывание, а процессор отдаёт это ожидание задаче, которая хочет что-то поделать, пусть она даже и низкоприоритетная. Когда железка закончит, она вызывает прерывание, а в прерывании вы сигналите задаче: "задача, для тебя есть работа". И если нет других, более приоритетных задач, то она получает управление. Обратите внимание, что в обоих случаях (по поллингу и с исопльзованием средств ос) задача ждёт, но время тратиться по-разному. Почитать об этом вы можете в руководство на любую ос. Я рекомендую на scmRTOS. Там всё доходчиво разъяснено. Также почитайте эту тему более, чем десятилетней давности. Там я задавал такие же вопросы))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 7 июня, 2018 Опубликовано 7 июня, 2018 · Жалоба функция без прерываний Переделайте на DMA. Кинул ссылку на буфер - запустил - забыл. По окончанию можно прерывание выставить, а если на хале - прописать колбэк. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
datiqor 0 8 июня, 2018 Опубликовано 8 июня, 2018 · Жалоба Вот эта настройка : configUSE_TIME_SLICING, установлена в 1 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 8 июня, 2018 Опубликовано 8 июня, 2018 · Жалоба Вот эта настройка : configUSE_TIME_SLICING, установлена в 1 ? главное что бы она не была установлена в 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
datiqor 0 10 июня, 2018 Опубликовано 10 июня, 2018 · Жалоба главное что бы она не была установлена в 0. Неа! В исходниках ОС вот так проверяется : #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) .... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 13 июня, 2018 Опубликовано 13 июня, 2018 · Жалоба Неа! В исходниках ОС вот так проверяется : #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) .... А если дальше поискать то можно найти в FreeRTOS\Source\include\FreeRTOS.h такие строчки: #ifndef configUSE_TIME_SLICING #define configUSE_TIME_SLICING 1 #endif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться