Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeRTOS общие вопросы
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Страницы: 1, 2
HARMHARM
Цитата(GetSmart @ Nov 19 2009, 15:53) *
Эта идея у меня была первой, но она сбиват счётчик тиков таймера и влияет на delay() для других тредов.

А какая у Вас частота тиков? Потому что "чуть-чуть" это немного. По мне - до 500 мкс. Неужели у Вас тики больше 1000 Гц?
GetSmart
Цитата(HARMHARM @ Nov 19 2009, 23:54) *
Неужели у Вас тики больше 1000 Гц?

6000 кажется. А сидеть в треде приходится до 1/200 сек, то есть 30 тиков.
zltigo
Цитата(GetSmart @ Nov 19 2009, 21:57) *
6000 кажется.

Очень странное число. Высокие скорости тактирования, если подумать, реально нужны крайне редко, ибо устраивать что-то типа поллингa, вместо обработки событий, не кошерно. И размазывать время тонкими ломтиками между, например, задачами одного приоритета, тоже весьма не частный случай.
GetSmart
Цитата(zltigo @ Nov 20 2009, 01:08) *
...ибо устраивать что-то типа поллингa, вместо обработки событий, не кошерно.

А как насчёт поллинга состояния внешнего пина, который не в состоянии вызывать прерывание? Тред например смотрит, пин не в нужном состоянии. Тред делает YIELD(). Прерывания не ожидается, другие треды этот пин вообще не анализируют. Пока не пройдёт несколько тиков и управление не вернётся к первыому треду, он так и не узнает, что пин изменился. Реакция затормозится (можно даже пропустить активность пина). Понятно, что такие важные нюансы работы системы нужно изначально притягивать к прерываниям, но если эта фича всплыла уже после изготовления девайса, то что? Другой вариант решения есть, кроме быстрых тиков?

Сам "родил". Сделать частое прерывание от таймера, для выполнение короткого кода анализа пина. А треды пусть обычно (медленно) переключаются. Из IRQ в нужный мОмент активизируется нужный тред и всё. Хотя, если взвесить оверхед, то не пойму что лучше. Разве что реакция ускорится.
zltigo
Цитата(GetSmart @ Nov 20 2009, 11:41) *
Сам "родил"....

Вполне естественно.
Цитата
Хотя, если взвесить оверхед, то не пойму что лучше.

Слова-то какие. Дергать всю систему под опрос "забытого" пина не оверхед, а несколько команд в обработчике таймерного прерывания .... что за "весы" у Вас? У меня довольно часто используется сканирование в обработчике системного прерывания для фиксации факта неких внешних событий, хотя без проблем можно использовать отдельное прерывание (переферия у меня обычно в FPGA и все, включая дополнительный контроллер прерываний, свое). Но дело в том, что если частота таких внешних событий приближается к частоте системного тика, что происходит под нагрузкой, то потери на отдельный обработчик много больше, нежели на проверку бита в чужом регулярном обработчике. А уменьшение оверхеда в ненагруженной системе меня волнует мало smile.gif. "Типичный" обработчик системного прерывания со сканированием пина:
Код
void PreemptiveTick_Ext( void )
{
#if( USE_KVV_IO )
    if( IO0PIN & P0B_SRQ_KVV )
    {
        xTaskResumeFromISR( handle_KVV_task );
    }
#endif
    // Increment the tick counter.
    vTaskIncrementTick();

    // The new tick value might unblock a task.  Ensure the highest task that
    // is ready to execute is the task that will execute when the tick ISR
    // exits.
    vTaskSwitchContext();
    // Ready for the next interrupt.
    EXTINT = EXTINT_EINT1;        // Clear the EXT interrupt flag
    VICVectAddr    = 0;            // Dummy write to signal end of interrupt}
}
GetSmart
Цитата(zltigo @ Nov 20 2009, 16:12) *
Код
void PreemptiveTick_Ext( void )
...
}

Спасибо за пример. Но я не понял в нём кое-что. Если это обработчик IRQ, в котором используется xTaskResumeFromISR(), то почему он без макросов сохр/восст. контекста? И правильно ли я понял, что этот обработчик работает для FreeRTOSовских тиков, а оригинальный не используется?
zltigo
Цитата(GetSmart @ Nov 20 2009, 17:01) *
правильно ли я понял, что этот обработчик работает для FreeRTOSовских тиков, а оригинальный не используется?

Да, это обработчик тиков который висит вообще не на таймере, а на внешнем прерывании - в данном случае это связное оборудование для которого имеет место быть понятие "сверцикловая синронизация" и удобно иметь 2ms синхронизированное прерывание сверхцикла. Но принципиального значения это не имеет - просто скопипастил из проекта в котором сидел. Обертки находятся снаружи, бо они на ASM.
Код
#if configUSE_PREEMPTION_EXT == 1
vPortPreemptiveTickEntry_Ext:
        portSAVE_CONTEXT                    ; Save the context of the current task...
        ldr     r0, =PreemptiveTick_Ext;   before selecting the next task to execute.
        mov     lr, pc
        bx      r0
        portRESTORE_CONTEXT        ; Restore the context of the selected task.
#endif

Кстати, именно xTaskResumeFromISR() в отличии от vTaskResume() совершенно не требует сохранения/восстановления контекста smile.gif, ибо yield() из него НЕ вызывается, а возвращается только признак перепланировки по которому можно вызвать переключение контекста( и тогда обертки нужны ), а можно и не вызывать.
DSP-Starter
А никто не видел порт для blackfin?
aaarrr
Цитата(DSP-Starter @ Mar 1 2010, 17:59) *
А никто не видел порт для blackfin?

В 5.3.0 был среди Unsupported_Demos.
lazarev andrey
объясните непонятливому:

как можно корректно отлаживать проект под freertos? среда IAR...
скорее всего я что то недопонимаю в настройках проекта или еще где то.... когда берет управление сама ось, начинаются тормоза, переключение задач происходит за какие миллисекунды smile.gif
без отладчика переключение происходит значительно быстрее (не оценивал).
HARMHARM
Цитата(lazarev andrey @ Jun 1 2010, 17:35) *
как можно корректно отлаживать проект под freertos? среда IAR...

Отложить отладчик и пользоваться головой.
Реально уперся два раза при отладке. Один раз переполнение буфера, написал обработчик DABT/PABT с выводом в консоль. Второй раз уперся в spurious interrupt в UARTе LPC23xx, просто подумал как следует. Объем кода С++ под 60 тысяч строк, 250 кб бинарник.
Как начал работать с ARM, купил себе JetLink. Так в коробке и лежит.
GetSmart
У меня тоже есть общие вопросы.

1. Где-нибудь лежит дока на русском о FreeRTOS ?

2. Как запретить (временно) переключение тредов по таймеру без запрета (остальных) прерываний?
kan35
самое простое - запретить прерывание от этого таймера.
Штатные taskENTER_CRITICAL запрещают прерывания.
GetSmart
Цитата(kan35 @ Feb 14 2011, 14:15) *
самое простое - запретить прерывание от этого таймера.

Проц новый - LPC1768. Я пока толком не разобрался как это делается для SysTick таймера. Пока только сделал это

Код
#if ( configUSE_PREEMPTION == 1 )
    #define __disable_PREEMPTION()    *( volatile unsigned long *)0xe000e010 &= ~0x00000001
    #define __enable_PREEMPTION()    *( volatile unsigned long *)0xe000e010 |= 0x00000001
#else
    #define __disable_PREEMPTION()    {}
    #define __enable_PREEMPTION()    {}
#endif

Но это не запрещает прерывание от SysTick, а на время останавливает таймер.

Может кто знает как отключать прерывания от System Tick Timer?
Terminator
Цитата(GetSmart @ Feb 14 2011, 13:44) *
1. Где-нибудь лежит дока на русском о FreeRTOS ?

Не встречал
Цитата
2. Как запретить (временно) переключение тредов по таймеру без запрета (остальных) прерываний?

Код
{
vTaskSuspendAll();
... код ...
xTaskResumeAll();
}
не подходит?
GetSmart
Цитата(Terminator @ Feb 14 2011, 14:37) *
не подходит?

Если оно делает то, что мне надо, то подходит.
А то в моей версии остановки таймера есть один косяк. Таймер может остановиться в районе перехода 0->max и прерывание сработает. Тогда по таймеру больше переключений не будет.
kan35
Цитата(GetSmart @ Feb 14 2011, 12:56) *
Если оно делает то, что мне надо, то подходит.
А то в моей версии остановки таймера есть один косяк. Таймер может остановиться в районе перехода 0->max и прерывание сработает. Тогда по таймеру больше переключений не будет.

Вообще, конечно да,
vTaskSuspendAll();
xTaskResumeAll()
подходят лучше, но в данном случае все равно шедулер будет крутиться, не знаю на сколько это критично

Как запретить тики от таймера, смотрим как делается установка таймера, и по аналогии делаем обратные действия
Код
void prvSetupTimerInterrupt( void )
{
    /* Configure SysTick to interrupt at the requested rate. */
    *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
    *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
}

То есть типа
Код
*(portNVIC_SYSTICK_CTRL) &= ~(portNVIC_SYSTICK_ENABLE);

И с другой стороны это действие есть остановка системного времени если что... Не всегда это желательно.
А вообще, как что делается с таймером надо смотреть в на сайте ARM, у NXP описания наверное не будет

А если он остановится в районе перехода с 0 в MAX, то прерывание отработает вперед, чем вы остановите таймер, и уже остановите его когда вернетесь в эту задачу.
GetSmart
Цитата(kan35 @ Feb 15 2011, 13:22) *
То есть типа
Код
*(portNVIC_SYSTICK_CTRL) &= ~(portNVIC_SYSTICK_ENABLE);

И с другой стороны это действие есть остановка системного времени если что... Не всегда это желательно.
А вообще, как что делается с таймером надо смотреть в на сайте ARM, у NXP описания наверное не будет

А если он остановится в районе перехода с 0 в MAX, то прерывание отработает вперед, чем вы остановите таймер, и уже остановите его когда вернетесь в эту задачу.

Именно этот код остановки я и приводил. Т.к. дефайны portNVIC_SYSTICK_CTRL и др. определены только в port.c, то я их заменил на константы.

Дело в том, что если "прерывание отработает вперёд", то именно в этот момент тред может переключиться. И если вдруг в другом треде (долго) не будет самоинициируемых переключений треда, то он не даст работать другим тредам. Вот такой глюк-косяк.

С vTaskSuspendAll() + xTaskResumeAll() я проверил расшаривание периферии между несколькими тредами. Пока всё работает и не конфликтует.
zltigo
QUOTE (kan35 @ Feb 15 2011, 11:22) *
Вообще, конечно да,
vTaskSuspendAll();
xTaskResumeAll()
подходят лучше, но в данном случае все равно шедулер будет крутиться, не знаю на сколько это критично

"Крутиться" это вообще-то самый в общем случае правильный вариант - сохраняется течение времени и по Resume происходит восстановление с минимизацией проблем возникших из-за приостановки. Такая реализация вместо тупого запрета прерываний один из признаков серьезного похода к реализации OS.
Только названия системных вызовов дебильные sad.gif, причем в коммерческой версии названия нормальные:
vTaskSuspendScheduler()
xTaskResumeSchedulerl()

hip
Вопрос такой: пытаюсь запустить пример из Demo/CORTEX_LPC1768_GCC_RedSuite на LPCXpresso1768 + Base board.
Все прошивается и запускается, но не могу достучаться до веб сервера (пишет что превышено время ожидания).
Посмотрел демо борды, принципиальных отличий по обвязке (имею ввиду ethernet) не нашел.

Подскажите куда копать, плиз?

Спасибо!
zltigo
Не куда, а откуда. Начните копать с фиксации факта посылки ARP запроса, например, снифером потом ping... и так постепенно. Ну а остальное. кроме WEB работает? Вообще всякие "примеры" идущие с FreeRTOS это не есть FreeRTOS. Бывает они не работоспособны вообще, у меня, например, даже не задышал порт под Stelaris созданный под именно эту board. Я, правда, и разбираться не стал - мне было проще свой собирать.
hip
Ага, понятно.
У меня, просто получилось заставить работать пример RDB1768_Easyweb на LPCXpresso путем замены cr_startup_lpc17.c из примеров для Xpresso. Пробовал их диффать, но просветления не испытал. Собсно, я и думал что тут есть какая-то, не видимая моему глазу, разница в стартовой конфигурации.

Свой собрать, понятное дело, лучше, но я пока в стадии глубокого нуба и пытаюсь вообще понять что к чему...

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.