alt3857 0 8 июня, 2011 Опубликовано 8 июня, 2011 · Жалоба Привет! В Cortex-M3 есть прерывание PendSV, в чем его основная цель? В доках нашел "PendSV is an interrupt-driven request for system-level service. In an OS environment, use PendSV for context switching when no other exception is active". Т.е. как я понял оно нужно (рекомендовано ARM-ом) для выполнения переключения контекста операционной системой. Но в операционке все равно задействован SysTick Timer и его прерывание для проверки необходимости переключения на каждый тик, почему контекст нельзя переключать в нем, зачем дополнительно нужно PendSV? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 8 июня, 2011 Опубликовано 8 июня, 2011 · Жалоба Но в операционке все равно задействован SysTick Timer и его прерывание для проверки необходимости переключения на каждый тик, почему контекст нельзя переключать в нем, зачем дополнительно нужно PendSV? Необходимость переключения контекста в операционной системе может возникать далеко не только по тику таймера. Поэтому данная возможность должна быть доступна в произвольный момент времени. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gladov 0 9 июня, 2011 Опубликовано 9 июня, 2011 · Жалоба Необходимость переключения контекста в операционной системе может возникать далеко не только по тику таймера. Поэтому данная возможность должна быть доступна в произвольный момент времени. Именно поэтому таймер лишь генерирует запрос на переключение. Аналогичный запрос может быть сгенерирован и "изнутри" ОС, например, при освобождении какого-то ресурса, ожидаемого процессом. А вот обработка запроса переключения производится из PendSV. Операция вынесена в прерывание чтобы была возможность обеспечить атомарность действий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 9 июня, 2011 Опубликовано 9 июня, 2011 · Жалоба Весь сок PendSV,SVC и Systick (pendSTset) поймете, когда захотите lock-free ось написать :) штука крутая, мне понравилось Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 9 июня, 2011 Опубликовано 9 июня, 2011 · Жалоба Операция вынесена в прерывание чтобы была возможность обеспечить атомарность действий. Дело не в атомарности! Это запрос на переключение контекста, который будет выполнен после выхода из критического участка (где прерывания запрещены) или после выхода из прерывания от устройства где получены данные для приоритетной задачи и т.п. Очень удобная вещь! А учитывая методы входа/выхода кортекса в прерывания позволяет быстро и удобно переключить задачу после обработки прерываний! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 10 июня, 2011 Опубликовано 10 июня, 2011 · Жалоба Это запрос на переключение контекста, который будет выполнен после выхода из критического участка Весь смысл этих операций, чтобы НЕ блокировать прерывания. а на pendsv можно навешать не только переключение контекста, у меня там висит обработчик очереди запросов от хардварных прерываний(у которых приоритет всегда выше,чем у pendsv,systick) на выполнения системных функций. В итоге локов нету, система всегда совершает прогресс и оверхед минимальный(ну так инструкций 20-30) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 11 июня, 2011 Опубликовано 11 июня, 2011 · Жалоба ... у меня там висит обработчик очереди запросов от хардварных прерываний(у которых приоритет всегда выше,чем у pendsv,systick) на выполнения системных функций. А можно поинтересоваться в общих чертах, что за прерывания и какие системные функции? Кроме того, если приоритет выше, значит они должны прерывать pendsv,systick, так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 11 июня, 2011 Опубликовано 11 июня, 2011 · Жалоба А можно поинтересоваться в общих чертах, что за прерывания ну там от DMA, SPI, UART, USB итд. и какие системные функции? ну там SignalSemaphore, SetSemaphore, CloseMutex итд Кроме того, если приоритет выше, значит они должны прерывать pendsv,systick, так? да, совершенно верно. И их могут прервать прерывания с еще вышим припритетом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 11 июня, 2011 Опубликовано 11 июня, 2011 · Жалоба ну там SignalSemaphore, SetSemaphore, CloseMutex итд А смысл использовать для этих целей PendSV? Для этого есть SVCall. А PendSV это асинхронный запрос, который или из прерывания запрашивается или из критической секции. т.е. из участка кода с более высоким приоритетом чем PendSV иначе PendSV будет себя вести как SVCall. В System Level Programmers’ Model есть глава SVCall, PendSV and critical region code avoidance Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 12 июня, 2011 Опубликовано 12 июня, 2011 · Жалоба А смысл использовать для этих целей PendSV? Для этого есть SVCall. А PendSV это асинхронный запрос, который или из прерывания запрашивается так речь и шла о прерываниях: у меня там висит обработчик очереди запросов от хардварных прерываний(у которых приоритет всегда выше,чем у pendsv,systick) на выполнения системных функций доступ к системным функциям из обычных тредов ессно через SVC а критических секций нет, они на cortex-m3 просто не нужны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 12 июня, 2011 Опубликовано 12 июня, 2011 · Жалоба Вы код для семафоров, в таком случае, свой используете? Там же по умолчанию критические секции расставлены. Очередь запросов у вас не переполняется? В чем вообще плюсы от использования lock free оси? Не проще ли использовать QP Framework - там имхо тоже lock free, но честнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 13 июня, 2011 Опубликовано 13 июня, 2011 · Жалоба Вы код для семафоров, в таком случае, свой используете?конечно свой. ось вообще вся своя. Там же по умолчанию критические секции расставлены.у меня по умолчанию ничего не расставлено, по умолчанию у меня пустая папка, где со временем вырастают файлики с кодом :) Очередь запросов у вас не переполняется?нет. во первых ошибка переполняния обрабатывается и выводится сообщение. во вторых размер очереди выбирается так, чтобы хватило в самом худшем случаи. контроллеры с меньше,чем 64кб оперативки не беру. В чем вообще плюсы от использования lock free оси?Если есть хоть какая-то работа с внешним потоком данных, то это прямой прирост производительности, во первых. прерывание выполняется сразу, а не ждет хз сколько, пока система отработает какую-то ерунду, часто вообще не мешающую выполнятся тому же прерыванию. прерывание далеко не всегда обращается к системной функции,а блокируем мы его(их всех) всегда,ибо не знаем,будет ли оно обращатся или нет. Потом гораздо меньше лажи с приоритетами... вернее если код не lock-free, то и приоритеты прерываний можно засунуть по-дальше, толку от них мало. Потом lock-free у меня только запись в очередь, а чтение и остальные функции wait-free. Вообще про плюсы и минусы lock-free/wait-free можно почитать в инете, но все зависит от конкретной платформы. на armv7 мне показалось, что это круто, и я не ошибся (касается конкретно только моих проектов). Не проще ли использовать QP Framework - там имхо тоже lock free, но честнее.мне сложнее, это надо вьезжать в этот фреймворк,материть его,если что-то мне там не нра итп.. Написать ось, которая будет соответствовать моим требованием займет не более недели времени, что гораздо проще и интереснее, чем драконится с каким-то фреймворком недельку-вторую Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alt3857 0 14 июня, 2011 Опубликовано 14 июня, 2011 · Жалоба brag, можете коротенький пример последовательности переключения контекста привести, на примере 2 функций (из одной в другую)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 14 июня, 2011 Опубликовано 14 июня, 2011 · Жалоба конкретный пример вотъ. код вроде простой и понятный... собственно переключение. приоритет самый низкий F_NAKED void ePendSV(void){ register U32 rpsp asm("r3"); asm volatile(" mrs %0,PSP; stmdb %0!,{r4-r11,lr}" :"=r"(rpsp)); pRunTcb->psp=rpsp; pRunTcb=pReadyTcb; rpsp=pRunTcb->psp; asm volatile(" ldmia %0!,{r4-r11,lr}; msr PSP,%0; bx lr" :"+r"(rpsp)); } naked и асм.вставки тк gcc тупой не умеет юзать ldm/stm. а кусок сишного кода тк леньки мне и синтакс gas - бей головой дуба :D писать не удобно также тут исключен код, перегружающий MPU регионы, нету у STM32F1 MPU. на NXP моя ось еще и защищенная ;) постановка задачи,готовой к выполнению в очередь. используется внутри практически всех системных функций (CreateThread,OpenMutex итд). приоритет этих функций всегда выше или равен PendSV. void tcbEnqueueReady(t_bragOsTcb *tcb){ U32 prio; prio=tcb->priority; cdllEnqueue(&readyQueue[prio],&tcb->queueNode); readyPrioMsk|=1<<(31-prio); if(prio<pReadyTcb->priority){ pReadyTcb=tcb; PendSVset(); } } Системные функции могут вызыватся только: 1. из SVC, в данном случаи приоритет выше, чем у PendSV. сделаете иначе - попадете на оооочень неприятные грабли! лень расписывать(много невсемпонятного текста) почему, но скажу пару ключевых слов: Приоритет, Стек, Tail-chainning. Если интересно - порисуйте диаграмки последовательности выполнения и все станет понятно. 2. из Systick. приоритет равен PendSV Ессно выше приведенный код получается автоматически защищен от race-conditions. Удаление задачи из очереди. Здесь PendSVset выполняется всегда, тк так сложилось, что у меня эта функция удаляет из очереди только ту задачу, которая в данный момент выполняется. но с ее помощью можно удалить любую задачу из очереди, при этом можно сделать проверку, чтобы даром не выполнять пустое переключение контекста,не влияющее на ход работы системы. void tcbDequeueReady(t_bragOsTcb *tcb){ U32 prio; cdllRemove(&tcb->queueNode); prio=tcb->priority; if(cdllIsEmpty(&readyQueue[prio]))readyPrioMsk&=~(1<<(31-prio)); pReadyTcb=getNextReadyTcb(); PendSVset(); } cdllХххх - работа с обычным двусвязным списком. getNextReadyTcb - достает из головы этого самого списка(у меня их 32,на каждый тредовый приоритет свой список,выбирается не пустой список самого высокого приоритета) адрес tcb PendSVset используется только в этих двух функциях, ну и еще при инициализации системы, чтобы переключится на первый тред. ну и самый сок, добавление запроса в lock-free очередь. может использоватся любым прерыванием с любым приоритетом. int SrqEnqueue(U32 a0,U32 a1,U32 svc){ register U32 r0 asm("r0"); register U32 r1 asm("r1"); U32 tail,newtail; // lockless enqueue do{ asm volatile("ldrex %0,%1" :"=r"(tail) :"m"(srqQueue.tail)); newtail=(tail+1)%MAX_SRQ_QUEUE_ITEMS; if(newtail==srqQueue.head)return ERR_QUEUE_FULL; asm volatile("strex %0,%2,%1" :"=&r"(r),"=m"(srqQueue.tail) :"r"(newtail)); }while(r); // write data r0=a0;r1=a1; asm volatile("stmia %3,{%0,%1,%2}" : :"r"(r0),"r"(r1),"r"(svc),"r"(&srqQueue.buf[tail]) :"memory"); PendSTset(); return 0; } MAX_SRQ_QUEUE_ITEMS кратно степени двойки - % заменяется компиллером на обычный AND. PendSTset - гыгы :) там выгрузка этой очереди, и системный таймер там же. не хотелось нагружать маленький красивенький pendsv всякой ерундой, пусть pendsv будет именно pendsv и не более ;) void eSystick(void){ ..... блаблалбла-декларация.... SrqDequeueRun(); if(!IsSystick())return; ..... блаблабла--системный таймер........ IsSystick - это действительно таймер тикнул? выгрузка из очереди. wait-free. выполняется только из eSystick. здесь все просто,никаких хитростей. void SrqDequeueRun(void){ register U32 r0 asm("r0"); register U32 r1 asm("r1"); U32 a0,a1,svc; t_srqItem *data; U32 head; head=srqQueue.head; if(head==srqQueue.tail)return; while(head!=srqQueue.tail){ data=&srqQueue.buf[head]; head=(head+1)%MAX_SRQ_QUEUE_ITEMS; asm volatile("ldmia %3,{%0,%1,%2}" :"=r"(r0),"=r"(r1),"=r"(svc) :"r"(data)); a0=r0;a1=r1; /*if(svc>=sizeof(svcTable)/sizeof(t_Callback))*/ a0=((int(*)(U32,U32))svcTable[svc])(a0,a1); } srqQueue.head=head; } на RVCT все обходится почти без асма с тем же результатом, он ldm/stm нормально генерит. Только алгоритмический код у него немного тормознее выходит (базового кода моей оси это не касается), или это я просто привык писать под gcc,выработалось чутье его алгоритмов оптимизации :)) Мютексы простые, без наследования приоритетов. Мне это не нужно. и производительность в + Семафоры есть простые и с таймаутом - примитивы только set,signal,wait,wait+timeout тред можно только создать и убить с другого треда. сам тред может себя остановить на некоторое время или выгрузится. также его могут убить обработчики fault-ов через ту же lock-free srq. Ну и в принципе все. Никаких критических секций, никаких циклов поиска итп. KIS - keep it simple ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться