Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeRTOS общие вопросы
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Страницы: 1, 2
MALLOY2
Начинаю осваивать данную ось, до этого не имел дел с RTOS для встраиваемых систем. Имею опыт работы на винде с много поточными приложениями.
Скачав последнюю версию и взяв оттуда порт под IAR str912.
Для старта использую иарвский менагер памяти. Создал две задачи обе просто мигают светодиодами, сразу напоролся на грабли с стеками, оказалось размер стека задается не в байтах, а в тугриках с размером portSTACK_TYPE, в этом есть свой смысл но вот в описании что то я об этом нигде не встретил.

Вопросы будут касательно стеков и режимов работы ядра ARM.

1. В каких режимах работает процессор ?
Пока ястно одно в майн он попадает в режиме SVC, в тасках он в режиме SYS, переключение задач выполняется по SWI 0, а другие функции кернела в каком режиме работают ?

2. Режимы FIQ, Abort и UND наверное не интересно так как пока они не используются. CSTACK используется в режимах SYS и USR этот стек где нибудь используется или смело можно ставить 0 ?

3. Какой нужен размер стека для SVC режима ?

4. Судя из обвертки IRQHandler прерывания не могут быть вложенными. От сюда размер стека для IRQ задается по задаче максимально его используемого или не так ? Для тиков используется прерываение от таймера в нем вызывается функция vTaskSwitchContext(); она получается работает в режиме IRQ. Установив брекпоин в этой функции оказалось что в ходе работы она работает в 2 режимах IRQ и SVC както криво получается sad.gif

5. Существует минимальный размер стека для задачи ? или в каком стеке хранится контекст задачи в стеке задачи или в стеке режима SVC ?



P.S. Сильно не пинайте если вопросы уже обсуждались я просто не нашел.
Aurochs
Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
1. В каких режимах работает процессор ?
Пока ястно одно в майн он попадает в режиме SVC, в тасках он в режиме SYS, переключение задач выполняется по SWI 0, а другие функции кернела в каком режиме работают ?

В том же режиме, что и вызывающая их задача.

Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
2. Режимы FIQ, Abort и UND наверное не интересно так как пока они не используются. CSTACK используется в режимах SYS и USR этот стек где нибудь используется или смело можно ставить 0 ?

Да, можно и даже смело smile.gif

Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
3. Какой нужен размер стека для SVC режима ?

Такой, чтобы его хватило для работы до запуска шедулера (или, возможно, после его останова)

Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
4. Судя из обвертки IRQHandler прерывания не могут быть вложенными. От сюда размер стека для IRQ задается по задаче максимально его используемого или не так ? Для тиков используется прерываение от таймера в нем вызывается функция vTaskSwitchContext(); она получается работает в режиме IRQ. Установив брекпоин в этой функции оказалось что в ходе работы она работает в 2 режимах IRQ и SVC както криво получается sad.gif

В чем кривизна то? Код все равно построен так, что функция vTaskSwitchContext() не будет одновременно выполняться и в том и в другом режиме. По поводу IRQ стека выводы Ваши верные, но только советую все равно задавать его с запасом - при его переполнении уж очень трудно диагностируемые дефекты могут возникать...

Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
5. Существует минимальный размер стека для задачи ?

В файле FreeRTOSConfig.h он задается параметром configMINIMAL_STACK_SIZE

Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
или в каком стеке хранится контекст задачи в стеке задачи или в стеке режима SVC ?

В стеке задачи
MALLOY2
Цитата
Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
3. Какой нужен размер стека для SVC режима ?

Такой, чтобы его хватило для работы до запуска шедулера (или, возможно, после его останова)


а причем тут время до запуска шедулера, ведь сам шедулер работает в режиме SVC и что он стеку не хавает ?


Цитата
В чем кривизна то? Код все равно построен так, что функция vTaskSwitchContext() не будет одновременно выполняться и в том и в другом режиме. По поводу IRQ стека выводы Ваши верные, но только советую все равно задавать его с запасом - при его переполнении уж очень трудно диагностируемые дефекты могут возникать...


для одного и друго стека надо учитывать потребление стека функцией vTaskSwitchContext();


Цитата
Цитата(MALLOY2 @ Apr 24 2009, 16:33) *
5. Существует минимальный размер стека для задачи ?

В файле FreeRTOSConfig.h он задается параметром configMINIMAL_STACK_SIZE


Убил, так какой туда размер поставить ? сколько минимум стека надо, зная что моя задача не требует вообще стека для своих целей?
Я поставил из расчета R0-R15 + CPSR (16) и получил датааборт, что-то еще хранится там.
zltigo
Цитата(MALLOY2 @ May 17 2009, 19:17) *
Я поставил из расчета R0-R15 + CPSR (16) и получил датааборт, что-то еще хранится там.

Естественно хранится - смотрим port.c
MALLOY2
Код
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
    portSTACK_TYPE *pxOriginalTOS;
    pxOriginalTOS = pxTopOfStack;
    *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;        
    pxTopOfStack--;
    *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa;    /* R14 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
    pxTopOfStack--;
    *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212;    /* R12 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;    /* R11 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x10101010;    /* R10 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x09090909;    /* R9 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x08080808;    /* R8 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x07070707;    /* R7 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x06060606;    /* R6 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x05050505;    /* R5 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x04040404;    /* R4 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x03030303;    /* R3 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x02020202;    /* R2 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) 0x01010101;    /* R1 */
    pxTopOfStack--;    
    *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
    pxTopOfStack--;
    *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
    pxTopOfStack--;
    *pxTopOfStack = portNO_CRITICAL_NESTING;
    return pxTopOfStack;    
}


Я так понимаю по этому коду можно сказать что минимальный размер стека должен быть 18.
asd6715
Не могу понять как реализована вытесняющая многозадачность во freeRTOS.
Я работал с uC/OS-II. Так это делалось так, пример для АРМа: настраивался интервальный таймер PIT, который с заданой частотой и вызывал функцию OSTimeTick, которая уже и отдавала управление готовой на выполнения задачи с самым высоким приоритетом. Ну и после завершения обработки прерывания управление готовой на выполнения задачи с самым высоким приоритетом тоже отдаеться...

Как это реализовывает во фриРТОС никак понять не могу, обьясните пожалуйста.
HARMHARM
Цитата(asd6715 @ Jul 14 2009, 10:49) *
Не могу понять как реализована вытесняющая многозадачность во freeRTOS.
Я работал с uC/OS-II. Так это делалось так, пример для АРМа: настраивался интервальный таймер PIT, который с заданой частотой и вызывал функцию OSTimeTick, которая уже и отдавала управление готовой на выполнения задачи с самым высоким приоритетом. Ну и после завершения обработки прерывания управление готовой на выполнения задачи с самым высоким приоритетом тоже отдаеться...

Как это реализовывает во фриРТОС никак понять не могу, обьясните пожалуйста.

Точно так же, в вытесняющем режиме. Функция называется vPortPreemptiveTick.
Есть еще и кооперативный режим.
asd6715
Ещё не смог разобраться. Как фриРТОС работает с задачами с одинаковым приоритетом... Помогите разобраться.
zltigo
Цитата(asd6715 @ Jul 15 2009, 13:03) *
Ещё не смог разобраться. Как фриРТОС работает с задачами с одинаковым приоритетом... Помогите разобраться.

Значит так - читаем документацию и задаем КОНКРЕТНЫЕ вопросы.
asd6715
Да Вы правы, полное занурение в документацию, это выход.
Тогда просто просьба поделитесь пожалуйства примером кода со сборкой freertos для sam7 для простейшего примера. так скажем что бы все по минимуму.
aaarrr
Цитата(asd6715 @ Jul 16 2009, 03:06) *
Тогда просто просьба поделитесь пожалуйства примером кода со сборкой freertos для sam7 для простейшего примера. так скажем что бы все по минимуму.

А чем примеры из \Demo не угодили?
zltigo
Цитата(asd6715 @ Jul 16 2009, 02:06) *
Да Вы правы, полное занурение в документацию, это выход.

Не юродствуйте - ответы на все ваши "вопросы" лежат в пределах нескольких минут чтения оглавления, причем даже не всего документа, а раздела Getting Started.
asd6715
Цитата(zltigo @ Jul 16 2009, 11:17) *
Не юродствуйте - ответы на все ваши "вопросы" лежат в пределах нескольких минут чтения оглавления, причем даже не всего документа, а раздела Getting Started.
Дело в том что я начинающий и очень мало опыта, поэтому много понимаю с трудом. Вот прочитав документацию я так и не понял чем отличается
Task от Co-Routine обьясните пожалуйста.
head_sk
Co-routines хороший функционал. Это реализация кооперативной RTOS внутри каждой задачи.
Co-Routine это все задачи равны и передают управление друг другу.
Tasks - одна задача выполняет роль операционной системы которая переключает задачи.

Для Co-Routine есть куча ограничений: все переменные делать статическими, стек не сохраняется, не вызывать сервисы RTOS из вызываемых процедур и даже из switch конструкций и т.д. короче очень сильные ограничения.

Co-Routine планируються (schedule) вызовом функции vCoRoutineSchedule (). Лучшее всего разместить вызов vCoRoutineSchedule () внутри idle hook. Это позволит tsak'ам и Co-Routine быть легко смешанными в пределах того же самого приложения.

Сейчас гуру меня поправят если я не прав,
qwerty
1111493779.gif Господа, а не у кого нет документов "Using the FreeRTOS Real Time Kernel - A Practical Guide" and the reference manual "FreeRTOS Reference Manual - API functions and Configuration Options" ? А то у меня проект на этой операционке, а начальство боится покупать (палить кредитки) в инете laughing.gif . Скинте плиз на мыло.
zltigo
Цитата(qwerty @ Jul 21 2009, 08:11) *

1. Нет.
2. А там ничего нет сверх того, что есть в Online.
3. Если горько надо Offline - сдерите копию сайта. На этом форуме такое несколько раз проделывали - можете и поискать.
AlexMad
Цитата(head_sk @ Jul 19 2009, 12:19) *
Co-routines хороший функционал. Это реализация кооперативной RTOS внутри каждой задачи.
Co-Routine это все задачи равны и передают управление друг другу.
Tasks - одна задача выполняет роль операционной системы которая переключает задачи.


А как Co-Routine относится к ресурсам по сравнению с Tasks? Ноги вопроса растут из примеров на АВР и АРМ. в Примерах с LPC используется Tasks. Я, вроде бы, разобрался, как там и что можно делать. А вот в примерах с АВР используется Co-Routine и при этом простое переключение
Цитата
Set the definition configUSE_PREEMPTION within Demo/AVR_ATMega323_WinAVR/FreeRTOSConfig.h to 1 to use pre-emption or 0 to use co-operative.
и перенос задачи из проекта на АРМ в проект с АВР не прокатывает.

И вот вопрос - пример на АВР сделан Co-Routine просто чтобы показать возможности и мне нужно его покурить, чтобы запустить Tasks, или, все-таки, для АВР стоит использовать Co-Routine?



Хм... поторопился я. Там и Tasks тоже есть и они работают... а моя задача почему-то не стартует... будем искать где прокололся.
asd6715
Не ругайте строго не могу найти функцию. В uc/os-II есть такая функция как OSSchedLock, которая отключает диспетчеризацию. Есть ли во freeRTOS аналог этой функции?? Я искал - не нашел, так это из-за того что её там нет или плохо искал...
zltigo
Цитата(asd6715 @ Jul 25 2009, 16:23) *
плохо искал...

Не полохо, а вообще не искали sad.gif
Раздел Kernel Control
void vTaskSuspendAll( void );
Suspends all real time kernel activity while keeping interrupts (including the kernel tick) enabled.
After calling vTaskSuspendAll () the calling task will continue to execute without risk of being swapped out until a call to xTaskResumeAll () has been made.
API functions that have the potential to cause a context switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler is suspended.

Название, правда, неудачное, что и сам Автор признал используя в коммерческих версиях систем вместо этого разумные названия:
vTaskSuspendScheduler()/xTaskResumeScheduler();
Я у себя тоже переименовал smile.gif
Код
/*
zlt[    
   The function name is a little misleading, which is why, as part of the code review, the functions
   vTaskSuspendAll() and xTaskResumeAll() were renamed vTaskSuspendScheduler() and xTaskResumeScheduler()
   respectively for the SafeRTOS code
void vTaskSuspendAll( void );
*/
extern volatile unsigned portBASE_TYPE uxSchedulerSuspended;

#define vTaskSuspendScheduler()    { ++uxSchedulerSuspended; }
// ]zlt
asd6715
Чесно признаюсь, просто прочитал название функции, подумал что это не то, и даже описание не читал, соррии
petrovichs
Не обьясните как толком пользоваться функцией vTaskStartTrace?
Я прописал
Код
#define configQUEUE_REGISTRY_SIZE       10
#define configUSE_TRACE_FACILITY    1

Далее вызвал
Код
vTaskStartTrace(TraceBuffer, 2000);

В эту область данных в двоичном формате начались записываться некие данные, как прочитать не понятно.
convtrce.exe я так нигде и не нашел.
Как получить из этой функции информацию подобную вот это?

Объясните если кто вкурсе, плз.
zltigo
Цитата(petrovichs @ Aug 3 2009, 12:33) *
Как получить из этой функции информацию подобную вот это?

Так это к трассировке никакого отношения не имеет, это просто текущее состояние системы - там в буферок сразу текст сбрасывается.
Криво sad.gif
В оригинале что-то типа prvListTaskWithinSingleList() смотрите.

При наличии консоли, сразу в нее буфер печати и сбрасывать. У меня там еше сразу занятость стека проверяется и адрес TCB выдается. Выглядит так:
Цитата
ps
R 5 Console tcb=40003FB0:96/480
R 0 Idle tcb=400041D8:380/600
B 3 LAPD2 tcb=40005D80:144/480
B 3 LAPD3 tcb=40006540:144/480
B 3 LAPD1 tcb=400055C0:176/480
B 4 SPItx tcb=40004758:136/200
B 3 LAPD0 tcb=40004E00:208/480
B 2 HDLC0TX tcb=40004C28:152/400
B 2 HDLC1TX tcb=400053E8:152/400
B 2 HDLC2TX tcb=40005BA8:152/400
B 2 HDLC3TX tcb=40006368:152/400
B 1 Checker tcb=40006768:96/120
head_sk

Что-то подобное что есть на этой картинке можно получить с помощью вызова функции vTaskList(). Вообще task.c небольшой файлик, советую с ног до головы его просмотреть smile.gif
asd6715
Извините что задаю очень глупые вопросы. Но я ещё новичек, как не стараюсь понять некоторые вопросы так и не получаеться. Надеюсь на вашу помощь. Я не могу понять чем отличаються функции с концовкой "fromISR" и без этой концовки? А то я использую у себя в прерывании xSemaphoreGive и все вроде бы прекрасно работает smile.gif В чем разница и в чем загвоздка?
Faradey
сказать больше чем это сделали разработчик(-и) FreeRTOS сложно, поэтому прочтите сами:
API Usage - light weight
salvian
когда стартует шэдулер отключаются прерывания, а вот когда они включаются я найти не смог. не подскажет ли кто когда это происходит?
aaarrr
При восстановлении контекста в vPortISRStartFirstTask.
mariaoi
Здравствуйте. Не подскажите как во freeRTOS определить максимальный размер стека который занимал каждый процесс на протяжении своей работы?
Спасибо!
head_sk
В свое время для себя писал:

Код
#if ( configUSE_TRACE_FACILITY == 1 )

static void prvGetMaxStackSize( unsigned portLONG *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )
    {
    volatile tskTCB *pxNextTCB, *pxFirstTCB;
    unsigned portSHORT usStackRemaining;

        /* Write the details of all the TCB's in pxList into the buffer. */
        listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
        do
        {
            listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
            usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned portCHAR * ) pxNextTCB->pxStack );
                        if(usStackRemaining < pcWriteBuffer[pxNextTCB->uxTCBNumber])
                          pcWriteBuffer[pxNextTCB->uxTCBNumber] = usStackRemaining;

        } while( pxNextTCB != pxFirstTCB );
    }
#endif

#if ( configUSE_TRACE_FACILITY == 1 )

    void vStackListWithMaxUsedSize( unsigned portLONG *pcWriteBuffer )
    {
    unsigned portBASE_TYPE uxQueue;

        vTaskSuspendAll();
        {
            pcWriteBuffer[ 0 ] = ( signed portCHAR ) 0x00;
            strcat( ( portCHAR * ) pcWriteBuffer, ( const portCHAR * ) "\r\n" );

            uxQueue = uxTopUsedPriority + 1;

            do
            {
                uxQueue--;

                if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
                {
                    prvGetMaxStackSize( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );
                }
            }while( uxQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY );

            if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
            {
                prvGetMaxStackSize( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );
            }

            if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
            {
                prvGetMaxStackSize( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );
            }

            #if( INCLUDE_vTaskDelete == 1 )
            {
                if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
                {
                    prvGetMaxStackSize( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR );
                }
            }
            #endif

            #if ( INCLUDE_vTaskSuspend == 1 )
            {
                if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
                {
                    prvGetMaxStackSize( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR );
                }
            }
            #endif
        }
        xTaskResumeAll();
    }

#endif
KolyanV
Цитата(mariaoi @ Oct 17 2009, 15:17) *
Здравствуйте. Не подскажите как во freeRTOS определить максимальный размер стека который занимал каждый процесс на протяжении своей работы?
Спасибо!

Смотрите описание функции API uxTaskGetStackHighWaterMark()
Mr.Woland
Здравствуйте, не поскажите, есть-ли в FreeRTOS поддержка рабоы на 2х ядрах PowerPC405/440 ?
GetSmart
Заранее извиняюсь за плохое знание аглицкого. Кто может подсказать по-русски предназначение дефайна configIDLE_SHOULD_YIELD ?

И ещё вопросик: Почему прерывание таймера, переключающее тред на следующий сделано с максимальным приоритетом? ИМХО логичнее делать минимальный.
zltigo
Цитата(GetSmart @ Nov 12 2009, 12:10) *
Кто может подсказать по-русски предназначение дефайна configIDLE_SHOULD_YIELD ?

Вопрос не совсем понятен - проблемы, например, с хитро-английским модальным глаголом should, так в этом конкретном случае для выражения меньшей степени уверенности, нежели must - т.е. хорошо ложится на русское "может быть"? Или проблемы с переводом комментариев?
Цитата
Почему прерывание таймера, переключающее тред на следующий сделано с максимальным приоритетом? ИМХО логичнее делать минимальный.

Это относится к конкретному порту - делайте, как считаете нужным в Вашем конкретном случае.
GetSmart
Цитата(zltigo @ Nov 12 2009, 15:30) *
Вопрос не совсем понятен - проблемы, например, с хитро-английским модальным глаголом should, так в этом конкретном случае для выражения меньшей степени уверенности, нежели must - т.е. хорошо ложится на русское "может быть"? Или проблемы с переводом комментариев?

Для тех, кто в танке повторю вопрос:
Кто может подсказать по-русски предназначение дефайна configIDLE_SHOULD_YIELD ?

За ответ на второй вопрос спасибо.
zltigo
Цитата(GetSmart @ Nov 12 2009, 12:38) *
Для тех, кто в танке повторю вопрос:

Тогда считайте, что я в танке, ибо отвечать не понимая, что Вам не понятно не могу.
GetSmart
На что влияет установка configIDLE_SHOULD_YIELD в 0 или в 1 ?
Надеюсь так понятней.
zltigo
Цитата(GetSmart @ Nov 12 2009, 12:51) *
Надеюсь так понятней.

Это написано в комментариях
/* When using preemption tasks of equal priority will be
timesliced. If a task that is sharing the idle priority is ready
to run then the idle task should yield before the end of the
timeslice.
*/
В реальности в Idle может быть полезным следить не сколько за наличием задач с приоритетом равным Idle (лично я не пользую таких), сколько за приоритетными задачами которые были включены в список в результате работы планировщика из обработчика прерывания, но сам обработчик не содержит громоздкого сохранения контекста и соответственно YIELD() из такого обработчика не вызывается.
GetSmart
Объясните пожалуйста глобальный смысл в дефайнах FreeRTOSа конструкций типа этой. Просто 0x0020 не катит?
Код
( ( unsigned portLONG ) 0x0020 )
zltigo
Цитата(GetSmart @ Nov 12 2009, 16:07) *
Объясните..

Относительно "portLONG" - чисто бзик Автора, от которого он в конце концов, слава те господи, отказался. Ну а
(unsigned long)0x0020
или
0x0020UL
это для полной определенности, дабы и человеку было видно и самым разным компиляторам нималейших шансов для непонимания не оставить.
GetSmart
Цитата(zltigo @ Nov 12 2009, 20:33) *
Относительно "portLONG" - чисто бзик Автора, от которого он в конце концов, слава те господи, отказался.

От этого "бзика" у меня в проге не хотели компилиться конструкции типа
Код
#define AdcRate        8000
#define AdcDivider    (((configCPU_CLOCK_HZ/4/11) + (AdcRate/2)) / AdcRate)

#if    (AdcDivider > 256)
#error "Недопустимая частота сэмплирования АЦП"
#endif


А вот при определении
Код
#define configCPU_CLOCK_HZ            ( 24000000UL )
вместо
#define configCPU_CLOCK_HZ            ( ( unsigned portLONG ) 24000000 )

Эта конструкция (#if ...) нормально препроцессором отрабатывается.

Цитата(zltigo @ Nov 12 2009, 16:07) *
/* When using preemption tasks of equal priority will be
timesliced. If a task that is sharing the idle priority is ready
to run then the idle task should yield before the end of the
timeslice.*/

Я опять ничерта не понял smile.gif. Особенно слово yield в данном контексте (вообще применительно к RTOS)
zltigo
Цитата(GetSmart @ Nov 13 2009, 07:02) *
Особенно слово yield в данном контексте (вообще применительно к RTOS)

Я озадачен sad.gif. yield - "прекратить,уступить" ключевое понятие, а taskyield() самая "главная" функция именно RTOS. Это собственно переключение контекста. Используется, как для добровольного, так и для принудительного по таймеру перехода на другую задачу. Глагол should в этом контексте описан ранее.
GetSmart
Цитата(zltigo @ Nov 13 2009, 19:36) *
Я озадачен sad.gif. yield - "прекратить,уступить" ключевое понятие

Мерси боку. Знаю много аглицких слов, но этого не знал. А в словаре у него с десяток разных смыслов. Не поймёшь какой здесь.
Terminator
Цитата(zltigo @ Nov 12 2009, 16:07) *
В реальности в Idle может быть полезным следить не сколько за наличием задач с приоритетом равным Idle (лично я не пользую таких), сколько за приоритетными задачами которые были включены в список в результате работы планировщика из обработчика прерывания, но сам обработчик не содержит громоздкого сохранения контекста и соответственно YIELD() из такого обработчика не вызывается.


Т.е. если в обработчике прерывания(в котором нет YIELD), скажем в очередь складывается что-либо, то высокоприоритетная задача которая ждёт сообщений из этой очереди вызовется только в момент смены контекста вызванного каким-нибудь другим событием?
И соответственно configIDLE_SHOULD_YIELD установленный в 1 поможет ускорить эту смену?

Я правильно понимаю?
zltigo
Цитата(Terminator @ Nov 17 2009, 13:50) *
Т.е. если в обработчике прерывания(в котором нет YIELD), скажем в очередь складывается что-либо, то высокоприоритетная задача которая ждёт сообщений из этой очереди вызовется только в момент смены контекста вызванного каким-нибудь другим событием?

Да, когда прерванная задача отдаст управление, или будут разборки по таймерному прерыванию.
Цитата
И соответственно configIDLE_SHOULD_YIELD установленный в 1 поможет ускорить эту смену?

Для текущей официальной реализации, насколько я помню, это работает только для задач с приоритетом равным IDLE, т.е. при наличии в очереди задачи с таким приоритетом ей отдается управление. У Вас есть такие задачи? Но, естественно, в IDLE можно наворотить всякого и реализовать любой механизм, нежели надо.
Terminator
Цитата(zltigo @ Nov 17 2009, 17:13) *
Для текущей официальной реализации, насколько я помню, это работает только для задач с приоритетом равным IDLE, т.е. при наличии в очереди задачи с таким приоритетом ей отдается управление. У Вас есть такие задачи? Но, естественно, в IDLE можно наворотить всякого и реализовать любой механизм, нежели надо.


Нет, задач с IDLE приоритетом у меня нет. Т.е. получается, что в худшем случае высокоприоритетная задача будет ждать 1 тик?
zltigo
Цитата(Terminator @ Nov 17 2009, 14:31) *
Т.е. получается, что в худшем случае высокоприоритетная задача будет ждать 1 тик?

Точнее время IDLE, которое все-же меньше тика и только в том случае, если прерывание попадет на IDLE. Можно сделать аккуратно обход проблемы, можно и абсолютно бездумно железно-тупо не разбирая очереди влепить заплатку от этого, например, взводить глобальный флаг запроса вызова yield() в IDLE, если было послано сообщение из обработчика прерывания вызванного из IDLE. Для малозагруженных систем, которые в основном в IDLE и пребывают некий эффект даст.
GetSmart
Подскажите пожалуйста ответ на два вопроса.
1. Как "кошерно" заблокировать переключение нужного (или текущего) треда во FreeRTOS-овском прерывании от таймера. То есть, работая в этом треде чтобы не произошло (неожиданного) переключения на другой тред.
2. Какую функцию системы надо вызвать, чтобы при очередном YIELD() (или после portRESTORE_CONTEXT() на выходе из прерывания) стал активным какой-то заданный тред.
zltigo
Цитата(GetSmart @ Nov 19 2009, 15:34) *
Подскажите пожалуйста ответ на два вопроса.
1. Как "кошерно" заблокировать переключение нужного (или текущего) треда во FreeRTOS-овском прерывании от таймера. То есть, работая в этом треде чтобы не произошло (неожиданного) переключения на другой тред.

vTaskSuspendScheduler()/xTaskResumeScheduler() это максимально кошерно с фиксацией пропусков тиков, наверстыванием упущенного.... Ну а если чуть-чуть, то запретить прерывания.
Цитата
2. Какую функцию системы надо вызвать, чтобы при очередном YIELD() (или после portRESTORE_CONTEXT() на выходе из прерывания) стал активным какой-то заданный тред.

YIELD и RESTORE_CONTEXT это вещи вообще-то несколько разные, хотя первая и включает в себя вторую.
Добавить его в соответствующую очередь (не забыть убрать, если уже в какой-то есть). Либо аккуратно 'ручками', либо тупо изменив/задрав ему приоритет через vTaskPrioritySet().
Только, полагаю, Вы опять зря такие манипуляции делать собираетесь smile.gif. Обычно достаточно иметь заранее созданные спящие задачи с нужным, путь максимальным приоритетом и просто xTaskResumeFromISR()
GetSmart
Цитата(zltigo @ Nov 19 2009, 19:20) *
Ну а если чуть-чуть, то запретить прерывания.

Эта идея у меня была первой, но она сбиват счётчик тиков таймера и влияет на delay() для других тредов.
Цитата(zltigo @ Nov 19 2009, 19:20) *
Только, полагаю, Вы опять зря такие манипуляции делать собираетесь smile.gif. Обычно достаточно иметь заранее созданные спящие задачи с нужным, путь максимальным приоритетом и просто xTaskResumeFromISR()

Я так и собирался делать спящий тред, а потом, в нужный мОмент его активизировать.
Я правильно понимаю, что если у треда максимальный приоритет, то прерывание от таймера FreeRTOS не меняет тред на следующий? Тред сменится только если сам тред вызовет YIELD() ?
zltigo
Цитата(GetSmart @ Nov 19 2009, 16:53) *
Я правильно понимаю, что если у треда максимальный приоритет, то прерывание от таймера FreeRTOS не меняет тред на следующий? Тред сменится только если сам тред вызовет YIELD() ?

Нет, если он добровольно отправится спать или ждать сообщения. Вызов yield() ничего не изменит - если задача с максимальным приоритетом одна, то она и продолжится. Если задач с одинаковым приоритетом несколько, то переключится на другую с таким-же.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.