Отговори на тема  [ 76 мнения ]  Отиди на страница Предишна  1, 2, 3, 4, 5, 6  Следваща
Zero copy TCP/IP стек 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение 
> Но от какво зависи то ? От това колко време прекъсванията са забранени например, когато се изпълняват системни заявки към РТОС.

Доколкото става дума за това колко латентност внася самата ОС, зависят практически само от това.

> Обикновенно вътре при обработката на тези системни заявки - прекъсванията се забраняват.

О не. Това би било напълно неграмотен подход, не съм виждал ОС, която да прави това.

> Примерно при взимане на мемори блок от РТОС - функцията за заделяне на памет държи
> прекъсванията забранени докъто се изпълнява. т.е. по времето на критичната и секция.

Не, заделянето на памет си е системна функция като всяка друга. Няма нужда да маскира
прекъсванията.

> Е, ако процесора поддържа хардуерно приоритети на прекъсванията си и позволява вложени
> прекъсвания - проблем няма, ако се използват "фаст интеръпти". т.е.това са прекъсвания, чийто
> приоритет е над системният ( най-висок е) и в които е ЗАБРАНЕНО извикването на системни
> за РТОС-а функции.

Е, хубава система беше 68к (и е в рамките на CF) със 7-те си хардуерно вместени IRQ нива.
Някои Power ядра имат 2 такива нива, които впрочем стигат практически за всичко.

Но да вика човек системни функции насред IRQ handler е самоубийствено безумие.
Не ми идва на ум да ми е трябвало подобно нещо последните 25 години :-).
Прекъсванията се обслужват всяко в индивидуален контекст, системните функции
са в контекста на таска, който ги вика - няма разумен начин да бъдат съвместени двете
насред обработката на самото прекъсване.

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Пон Юни 22, 2009 5:12 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Под небивалици имах предвид, по-скоро невъзможността няколко човека едновременно да включим на една и съща вълна... Както в случая Цецо си човърка кортекса, а пък аз нямам нито време нито желание да го почвам.
Иначе това което описва Цецо е по-скоро "недоразумение" и не е въпрос на "миро-гледи" ;-) Не съм ги измислил аз нещата, просто на мен ми трябваше читав ОС и го направих (доколкото можах), използвайки стандартни концепции.
В основата стои това което описва tqi - т.н. сериен интерфейс. Аз поне не познавам сериозен ОС, който да не е стъпил върху нещо подобно - и при Windwos е така, при UNIX/Linux е още по-видимо, че даже и tqi с неговия DPS е постъпил по същия начин. Тук няма нито алтернативи, нито е въпрос на авторство и кой от кого е крал. Просто няма друг познат вариант и всички така го правят!
Ех, разбира се, имплементацията навсякъде е различна, но въпросът беше че тъпо да водим тук някакви разисквания за и против....

Иначе аз действително много държа на тази концепция и това беше може над 90% от мотивацията ми да седна да пиша собствен ОС. Просто не успях да намеря ОС с такава концепция, който да не изисква огромни ресурси от към памет и флаш.
А пък причинините да държа на тази концепция са главно две - първо очаквах да работим много хора и второ проектът се очертаваше да бъде голям. В действителност не познах нито едното, нито другото - не работим "много" хора - само двама сме... И второ проектът се оказа не просто сложен, а много по-сложен и в това се състои грешката ни, че може би не трябваше да пишем сами толкова неща, а да сменим хардуера с по-добър и да ползваме Linux или нещо подобно.

Както и да е, всеки допуска грешки ;-) Покрай ОС-а и изобщо проектите имам много грешки. Не всичко се получи перфектно, обаче тая концепция е едно от нещата които се получиха добре и съм много горд. По-точно доволен, щото както казах самата концепция не е мое изобретение ;-)

Предполагам Цецо се опасява, че ако в една ОС има и драйвери нещата се усложняват, системата става тромава, трябва й памет и т.н. Нищо подобно! Това е решение, което аз до ден днешен не съм открил някакъв проблем или недостатък. Верно в моя случай, архитектурата на АРМ7 е такава, че тя просто си плаче за драйверна система. И ако някой се опитва да я ползва без такава, ще срещне мнооооого повече проблеми, това мога да го гарантирам! При Кортекс нещата са малко по-различни, там върнаха обратно контролерската архитектура, което според мен е грешка от техническа гледна точка, но хората вероятно я правят умишлено заради маркетинга и клиентите дето по една или друга причина не ползват ОС или ползват само някакво щракало на таскове :D


Пон Юни 22, 2009 5:30 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
tgi,
не се забраняват само "фаст" интеръптите по време на изпълнението на "критичните" секции в системните (за ртос-а) функции. Останалите прекъзвания се забраняват (поне в 3 от РТОС-ите с които съм се занимавал е така).

Как например в система в която са разрешени вложените прекъсвания се решава проблема с вземането на памет от РТОС-а например в две от прекъванията, които са с различен приоритет, и високоприоритетното по всяко време може да прекъсне нископриоритетното? (ако в момента на прекъсването на ниспоприоритетното то изпълнява системна функция за взимане на памет - а и високоприоритетното извиква същата системна функция ...) Е точно в този случай в критичните секции на системноте функции за много кратко време (в критичните им секции) се забраняват прекъсванията (с изключение на "фаст" интеръптите в които е ЗАБРАНЕНО да се извикват системни функции на РТОС-а).
Иначе сист.функция от едното прекъсване би започнала да модифицира данните за мемориблоковете на РТОС-а, но преди да е завършила - другото прекъсване я прекъсва и няма достъп до "валидни" данни за мемориблоковете, тъй като обработката им не е завършила в прекъснатото прекъсване ...

Не ми е известно как без забраняване на прекъсванията би могло да се избегне този проблем...


Пон Юни 22, 2009 5:38 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение 
> не се забраняват само "фаст" интеръптите по време на изпълнението на "критичните" секции в
> системните (за ртос-а) функции. Останалите прекъзвания се забраняват (поне в 3 от РТОС-ите с
> които съм се занимавал е така).

Явно не разбирам каква е разликата между fast и останалите прекъсвания, може би въпрос
на CPU архитектура, която не познавам. Но ако прекъсванията са си прекъсвания като прекъсвания,
няма нужда да бъдат маскирани докато траят системните функции (дори ако - както например
е в 6800, 6809, 68HC11 - SWI инструкцията маскира прекъсването; в такъв случай в рамките
на SWI handler-a нещата се обработват така, че преди да отиде в кода за съответната системна
функция прекъсванията се разрешават).

> Как например в система в която са разрешени вложените прекъсвания се решава проблема с вземането
> на памет от РТОС-а например в две от прекъванията, които са с различен приоритет, и високоприоритетното
> по всяко време може да прекъсне нископриоритетното?

Никак. Такива работи ***не се правят*** в рамките на IRQ handler. Заделянето на памет е работа
на тасковете, които инициализират и ползват (комуникират с) кода, обслужващ прекъсванията.

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Пон Юни 22, 2009 5:52 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
Идеята на фаст интеръптите е бърза реакция на евент, като обработката му е за минимално време и освен тоса не се извикват системни функции на РТОС-а, които на излизане от интеръпт-а може да предизвикат редиспечиризация.


Вто Юни 23, 2009 2:04 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Значи тук и двамата гледате и говорите за различни парченца от пъзела...

Всичко зависи от архитектурата на системата, имам предвид софтуерна и хардуерна. Започва се от изискванията на периферията - каква латентност позволява. След това архитектурата на ядрото и прекъсванията и се стига до организацията на драйверната система и кърнела.
Тия неща са навързани в редичка и всяко дава или ограничава степените на свобода на останалите. Но съвкупността им е определяща и без тя да се знае не може да кажеш дали времето за влизане е определящо или не. Дали в IRQ се викат или не се викат системни функции.
Мога да дам примери и от двете крайности - примерно при мен няма НИКАКВО значение колко е забавянето при влизане в прекъсване. Факт, който ми позволява да си викам системни функции в прекъсванията и да си правя каквото си поискам. Но има и системи в които е точно обратното. Всичко е въпрос на организация и няма единствено или правилно решение - има решения, които спазват изискванията и такива, които поради недомислици не могат да ги спазят.

Интересно е, че много програмисти не успяват да превключат мисленето си от еднозадачна на многозадачна архитектура. А теорията всъщност е доста по-различна. Примерно бързината при влизане в прекъсване е важен параметър на еднозадачна система. Колкото по-бързо реагираш на едно събитие - толкова повече събития може да обработваш.
При многозадачните системи, самата реакцията няма почти никакво значение. Дори и най-тъпия процесор влиза в прекъсване за под микросекунда, докато един квант (времето за разцъкване на задачи) е не по-малко от една милисекунда, т.е. съотношението е 1:1000.
В случая важна подробност са изискванията на периферията. Ако тя е тъпо направена, ще имаш много прекъсвания преди да се слезе на ниво задача. Ако е умна, а тя тенденцията е такава имаш едно-две прекъсвания и получаваш примерно пакет, който трябва да слезе надолу по-стека. С други думи при умната имаш да кажем съотношение 2:1 (две прекъсвания на една обработка в таск). При тъпа периферия обикновено е от порядъка на 10-30:1. Вече трябва да е уникално тъпа периферия, че да стане над 100:1, но тогава грешката е на "архитекта".
Та мисълта ми е, че при правилна архитектура имаш няколко прекъсвания и едно активиране на таск - това е практически условието да работи една задача. Грубо казано ако системата има 10 задачи, в рамките на един квант от 1ms, би трябвало да могат и 10-те задачи да се извъртят и на задача казахме се падат по няколко интеръпта, значи примерно да се обратят и 20-на интеръпта.
Сега да речем че искаме да подобрим времето за влизане в интеръпт 1000 пъти, т.е. от 1 микро го направим на 1 нано секунда. Хубаво, значи ще пестим по 20 микро на 1 милисекунда и кво се пада то? Два процента подобрение на системата?
----------------------------------

Иначе на теория пълната програма в една ОС включва IRQ-та с приоритети, DSR-и с приоритети и таскове/процеси с приоритети. Като приоритетите могат да се правят от хардуера или да се емулират софтуерно. В някои системи приоритетите се гледат само при избор кое прекъсване да се обработи първо, без да има прекъсване в прекъсването. В други се ползват вложени прекъсвания.

Тук ще отворя скобка за приротетите, макар че съм го писал и преди... Значи приоритетът не бива да се бърка с "важността" на нещото, а по-скоро приоритетът на даден обект се определя от честотата на използването му. Приоритети са необходими, когато в една система има задачки-закачки с различна честота. Примерно имаме два еднакви USB контролера, обаче единия без DMA или буфери, а дръгия по-умен. В единия случай честотата на извикване може да стигне 1МХц докато другия доста по-ниска, съответно първия ще трябва да е с много по-висок приоритет, въпреки че и двете USB могат да имат еднаква важност за системата.
Вложените прекъсвания правят нещата още по-истински, щото в примера с "умното УСБ" и изобщо перифериите с ниска честота (приоритет) изискват по-голяма обработка - щото получават примерно цял пакет и трябва да се види какъв е пакета, накъде да се пусне надолу за обработка и т.н. И ако не може да се прекъсва, това би провалило тъпото USB и то ще изпъска байтове.
Напрактика обаче се избягват "тъпи" периферии и тогава вложените прекъсвания имат една друга полза, стига ОС-а да е читав. Значи нормално ОС-а му трябва малко повече обработка при влизане в първото прекъсване - спасяват се контексти и т.н... Докато следващите вложени прекъсвания могат да си спестят тоя "овърхед". Така с натоварване на системата тя почва да бачка малко по-добре, макар че както казах ефектът от подобни подобрения не е толкова съществен.
Бързите прекъсвания при ARM7 могат да се ползват за още по-голямо подобрение. Обикнвено не се прехващат от ОС-вете т.е. не се тормозят с никакви софтуерни овърхеди. Освен това регистрите от R8 нагоре са банкирани и FIQ (ако е само един) даже има на разположение свободни регистри, т.е. влизай в FIQ и директно бачкаш...

Относно ползването на системни функции във IRQ и съответно забраняването на IRQ по време на системни функции tqi е частично прав... По принцип в IRQ не може да се викат всякакви системни функции, примерно нещо от сорта на sleep() си е направо абсурдно, макар че би било полезно понякога ;-) Навсякъде си има ограничения - при Windows имаш нива и за всяко ниво ако не се съобразяваш с dispatch level то се грижи да ти напомни учтиво с BSOD ;-)
Но при малките системи, перифериите не са с чак такава разлика в честотите и съответно приоритетите няма нужда да са много (достатъчно е да можеш да се въползваш от вложените прекъсвания) и съответно софтуерния стек няма нужда да е с нива - т.е. или си в IRQ или не си и това определя какво може да ползваш. А пък системните функции не са безбройни, нито пък чак толкова времеемки. Примерно като се прави динамична памет с размер 20-30к, то и без да правиш сортировки по страници и т.н. си бачка доволно бързо. И цялото това нещо като работи на "умен" контролер дето перифериите са да кажем с двойно буферирани ДМА-та ти позволява да се вдигнат всякакви ограничения. Спокойно IRQ-тата могат да ползват всякакви неблокиращи функции дето не изискват да си таск.
И за забраняванията на прекъсванията е по-същия начин - в по-гляма ОС би било самоубийство да ги забраниш, то пак се забраняват, ама само докато мине през семафорчето примерно. Но пък АРМ7/9 забраняването на прекъсвания е проблем, семафорчетата пък без забранявания на прекъсвания или смяна на режима също са проблем. Изобщо стандартния подход е голям голям проблем...
Затова пък нестандартния просто заспива - аз ползвам SWI за системни функции, примерно викам malloc - то си влиза, свършва си работата и излиза. Прекъсванията си се забраняват и разрешават автоматично - аз нямам грижа нито да забранявам нито да работя със семафори, нищо, абсолютно нищо... И като код излиза по-малко и работи по-бързо. С други думи "безумието" при големието не толкова безумно при малките... Ех, естествено аз си правя сметка на системните функции и не се уливам, даже повечето са ми на асемблер, което ми дава гаранция че няма да блокирам прекъсванията прекалено много. И на практика резултатите са повече от добри. Алтернативата би усложнила много нещата, щото като тръгнеш примерно да заделяш памет или да приспиваш/събуждаш таск и не забраниш прекъсванията става мазало... Идва прекъсване то не може директно да сигнализира таскове, щото ще стигне до семафор на който обаче не може да блокира. Ако трябва да се прави чисто, трябва да има истиска драйверна архитектура да сигналиразаш не на таск, а на DSR, ама това е още един кърнел като сложност и мнго голям овърхед. Далеч по-просто и ефикасно е да се задържи прекъсванието и след това да му се даде пълна свобода, отколкото да го пуснеш да тича веднага, ама с вързани крака...

бтв. SWI-тата при АРМ не забраняват FIQ, така че ако някой толкова му трябва "бързо" прекъсване - няма проблем... има го, но не може да ползва почти никакви системни функции ;-)


Вто Юни 23, 2009 2:25 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение 
emilvtc написа:
Идеята на фаст интеръптите е бърза реакция на евент, като обработката му е за минимално време и освен тоса не се извикват системни функции на РТОС-а, които на излизане от интеръпт-а може да предизвикат редиспечиризация.


Хм. В моя свят идеята на всички хардуерни прекъсвания е такава.

Възможно е да има някой РТОС, дето има за идея да му се викат функциите от такъв "бавен"
IRQ handler - шарен свят. Но смисълът от ползването на хардуерно
прекъсване за такава цел е нулев.

Миро, с повечето от това, дето пишеш съм съгласен. Възможно е разбира се някоя системна
функция да бъде викната безнаказано от IRQ handler-а, ако кодът и няма отношение към
това кой таск я вика - например hexdec или нещо подобно, ама кой с всичкия си прави такива
работи насред прекъсване? Впрочем *не знам* дали това би минало в DPS, никога не ми е хрумвало
да опитвам. Всъщност за баш ниското ниво няма да мине, самият sc handler (sc е вид trap в power
за системни повиквания) манипулира стековете и ще стане една... По-високото ниво, дето вървят
на user ниво, може и да може, не съм сигурен.

Но съм сигурен,че и ти знаеш прекрасно, че никак - ама никак - не е без значение времето
за реакция на прекъсване. А то се определя от най-лошия случай на забавяне.
Наскоро сглобих една DPS система за вътрешно ползване. Та там на едно прекъсване
са клоците на два PS2 интерфейса, обратният ход на дисплея (та да тръгне опресняването
през DMA за SXGA формат), ATA и не се сещам още колко от вътрешните периферии.
По никакъв начин не си пречат, всъщност гледах жицата на това за обратния ход и
оставаше под 5 микросекунди до свалянето му по време на интензивно disk I/O; инак
беше към 1. (това на 400 MHz MPC5200 със 128М DDRAM и дисплей контролер през PCI
на 66 MHz). И вдигането от 1 до 5 е главно заради обсебването на *бъса* (20+ мегабайта
в секунда към/от диска).
Та това няма как да стане без човек да е параноичен по отношение на латентността
от ден първи на изграждането на системата - преполагам, че си съгласен с това :-) .

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Вто Юни 23, 2009 3:58 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
Май наистина с tgi говориме за различни неща.

tgi, прекрасен пример за извикване на системна функция по прекъсване е обработката на системните таймери. Когато даден хардуерен таймер изтече , той примерно трябва да събуди даден таск който е "приспан" и чака евент от него. А-ми точно в този случай точно в прекъсването се извиква системна функция за сетване на евент флаг. Е- ако РТОС-а е преемптив - то на излизане от прекъзване ЗАДЪЛЖИТЕЛНО ще се направи проверка за редиспечеризация. Така ако текущо-прекъснатият таск от прекъсването е по-нископриоритетен от този, които е приспан и чакасетването на евент флага от таймера - то на излизане от прекъсването ще има редиспечиризация и процесора след RETI инструкцията на излизане от прекъсването ще започне да изпълнява "събуденият" таск, а не таска, който е бил прекъснат от прекъсването ...
Не разбирам защо това да е странно ?!? Всичките ми проекти и програми ги градя на тази логика и си работят прекрасно ... Греша ли някъде ?

А ето един пример където трябва "фаст" интеръпт.
Представете си Кортекс на ST, който няма фифо на уарта, а има ДМА на уарта. Представете си, че баудрейта е набримчен на максималният (няколко мегабита).
Представете си и, че по този сериен интерфейс приемаме стриим от данни (неизвестна дължина). Армираме си ДМА-то за определен брой от байтове и преди да ги приемеме - проблем няма. Проблема идва, когато трябва да приемеме последният байт(съгласно ДМА настройките). При приемането му ДМА-то се дезармира и ни се генерира прекъсване, указващо ни че ДМА-то е приело указаният брой байтове. Да, но стрийма от данни постъпващи на уарт-а не спира. За да не изпуснем байт трябва много бързо да армираме ДМА-то отново и то за време по-малко от времето за предаване на един байт през уарт-а. Е-те в този случай ни трябва ФАСТ прекъсване, което е над "системно" ниво и може да прекъсне процесора (и други прекъсвания) дори когато се изпълняват системни функции. (примерно както по-горе писах извикването на системна функция "СЕТ_ЕВЕНТФЛАГ" изпълнявана в друго прекъсване).

Незнам за вас, но на мене всичко това ми изглежда логично и съвсем нормално ...

Е, не така стоят нещата в РТОС-и които не са преемптив. Аз лично не ги харесвам и не ги използвам. Те са много икономични от към стек, но пък даден таск може да "вземе" управлението САМО когато текущоизпълняваният таск го "пусне" ...


Вто Юни 23, 2009 5:13 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение 
emilvtc написа:
Май наистина с tgi говориме за различни неща.

tgi, прекрасен пример за извикване на системна функция по прекъсване е обработката на системните таймери. Когато даден хардуерен таймер изтече , той примерно трябва да събуди даден таск който е "приспан" и чака евент от него. А-ми точно в този случай точно в прекъсването се извиква системна функция за сетване на евент флаг. Е- ако РТОС-а е преемптив - то на излизане от прекъзване ЗАДЪЛЖИТЕЛНО ще се направи проверка за редиспечеризация. Така ако текущо-прекъснатият таск от прекъсването е по-нископриоритетен от този, които е приспан и чакасетването на евент флага от таймера - то на излизане от прекъсването ще има редиспечиризация и процесора след RETI инструкцията на излизане от прекъсването ще започне да изпълнява "събуденият" таск, а не таска, който е бил прекъснат от прекъсването ...
Не разбирам защо това да е странно ?!? Всичките ми проекти и програми ги градя на тази логика и си работят прекрасно ... Греша ли някъде ?


А, не, това не е странно. Просто наричаме нещата с различни имена, това, което описваш, е нормално.
Аз не наричам системна фунцкия пипанията на флагове и т.н. от IRQ обработката, за мене "системна
функция" минава през някакъв вид софтуерно прекъсване и т.н., става дума за по-тежки неща от това.
Инак такива работи ги правят всички, предполагам :-) .

Цитат:
А ето един пример където трябва "фаст" интеръпт.
Представете си Кортекс на ST, който няма фифо на уарта, а има ДМА на уарта. Представете си, че баудрейта е набримчен на максималният (няколко мегабита).
Представете си и, че по този сериен интерфейс приемаме стриим от данни (неизвестна дължина). Армираме си ДМА-то за определен брой от байтове и преди да ги приемеме - проблем няма. Проблема идва, когато трябва да приемеме последният байт(съгласно ДМА настройките). При приемането му ДМА-то се дезармира и ни се генерира прекъсване, указващо ни че ДМА-то е приело указаният брой байтове. Да, но стрийма от данни постъпващи на уарт-а не спира. За да не изпуснем байт трябва много бързо да армираме ДМА-то отново и то за време по-малко от времето за предаване на един байт през уарт-а. Е-те в този случай ни трябва ФАСТ прекъсване, което е над "системно" ниво и може да прекъсне процесора (и други прекъсвания) дори когато се изпълняват системни функции. (примерно както по-горе писах извикването на системна функция "СЕТ_ЕВЕНТФЛАГ" изпълнявана в друго прекъсване).

Незнам за вас, но на мене всичко това ми изглежда логично и съвсем нормално ...


Ами за нормално нормално е, но то латентността си е основен параметър, няма какво да
я дъвчем. Естествено е, че по-високоприоритетните прекъсвания са с по-ниска латентност;
в някои платформи има повече от един приоритет, в други няма (немаскируемите не ги броим,
те не са за "нормална" работа).

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Вто Юни 23, 2009 5:26 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Относно ST кортекса и липсата на Фифо на UART е наистина малко куца историята. Само с DMA трудно може да се постигне функционалността на 16550 FIFO... и се налага да се правят разни тъпи еквилибристики. Ама това си е проблем на дизайна на чипа. За толкоз пари - толкоз :)

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Вто Юни 23, 2009 5:26 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
tgi написа:
Хм. В моя свят идеята на всички хардуерни прекъсвания е такава.

Не само при теб, почти всички "големи" се стараят да не вкарват много овърхед в IRQ Handler или в самия ISR... Но това си има цена - не можеш да ползваш кърнела и ти трябва посредник на по-ниско ниво (DSR или аналогично).
Простичко казано ако имаш да кажем SPI, който се ползва от различни таскове. Всеки таск вика системна функция за писане и/или четене и или блокира докато мине операцията или прави нещо междувременно и после проверява. Та имаш два критични момента - в единия таска пуска заявката, в другия SPI сетва резултата от операцията.
Най-елементарния начин да се направи е драйвер с функция което приема заявките и ISR, който сигнализира. Ако се забраняват прекъсванията всичко си идва на мястото - таска вика SWI с заяката, което на влизане само определя кой драйвер (функция) да извика, а на излизане решава дали да върне управлението на същия таск или да го приспи и извика следващия по ред...
Драйверската функция пък проверява дали хардуера е свободен, ако да - зарежда DMA-тата и излиза, ако не - слага заявката в опашка и пак излиза.
ISR-a пък преглежда статус на SPI-а и вика функция с която казва "дай такъв резултат на тая заявка", след което си проверява дали има други заявки и евентуално зарежда следващата...

От това по-просто - здраве.... Аз даже съм ги опростил максимално нещата, примерно IRQ-контролера се прогамира не с адреси на ISR-функции ами с адреси на драйвер структури. В IRQ hendler-a вземам адреса , зареждам накуп няколко регистъра и бой по съдържанието на единия от тях. Така ISR-те ми са функции с параметри и така получавам понятие като "инстанция на драйвер", щото мога да имам не един ами няколко SPI контролера. Но като код пиша само една функция - а тя в параметрите си получава указател към данните на инстанцията и указател към хардуерните регистри на съответния контролер.

Въпросът е, че като работа всичко което правя, така или иначе трябва да се направи. То няма да е ОС с драйвери, ако тасковете не пущат заявки към драйверите и драйверите не сигнализарат за резултата от операциите. И на теория по-правилното е донякъде това което говориш ти - черната работа по завките и резултатите да не се прави при забренени прекъсвания нито в ISR-и. Прави се в DSR ниво което е над тасковете и под ISR-те. Но в тоя вариант имаш пак овърхед, щото в IRQ-то виждаш че примерно данните са изпратени по SPI, обаче вместо да сигнализираш на клиента, сигнализираш DSR. С две думи вместо да свършиш директно работата си записваш "тая работа трябва да се свърши... когато му дойде времето". Съответно при слизане в нивата трябва да имаш проверки "абе сега ли му е времето да свърша тва и тва"...

Разбира се, в една голяма система където има мноооого черна работа и сега налага да имаш бърза реакция на IRQ - нямаш избор, правиш го както казва теорията. Обаче в АРМ7 мога да си позволя лукса да опростя - като имам черана работа - просто я свършвам. Без мисля за семафори, без да си водя бележки и да оставям днешната работа за по-добри времена...



Цитат:
Но съм сигурен,че и ти знаеш прекрасно, че никак - ама никак - не е без значение времето
за реакция на прекъсване.

Както казах има случаи в които е жизненоважно и случаи в които няма никакво значение... Не забравяй че повечето от нещата ги говорим в контекста на АРМ7/Кортекс. А отделно аз ползвам Атмелски чипове с двойно буферирани ДМА-та. Примерно ако пращам по UART/SPI... мога да заредя 100 байта на едното и 100 на другото. Като се пратят първите 100 получавам прекъсване. Сега това прекъсване, дали ще го обработя след 1 байт време или след 99 байта няма абсолютно никакво значение. Хардуерът така или иначе си бачка и навън пакетите се изстрелват залепени един след друг ... И като цяло почти всички периферии са буферирани и не са капризни от към IRQ-реакция.
Ех, понякога се налага да правя и неща без периферия и тогава реакцията си става критична... Последното беше с четеца за карти, дето по схема е вързан към UART с хардуерен ISO7816 и си бачка... Да ама едни клиенти казаха искаме да ползваме евтини мемори карти, а те с един шибан I2C-подобен интерфейс, който трябваше да емулирам софтуерно.... На всичкото отгоре сложили едно изискване клокът да е между 7 и 50kHz, което е между рак и щука. Твърде бързo за таск, щото мимималния ми sleep е 1ms (падам под 1kHz) и твърде бавно за циклене щото вдигам CPU usage за твърде дълго....


Вто Юни 23, 2009 5:28 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
emilvtc написа:
tgi, прекрасен пример за извикване на системна функция по прекъсване е обработката на системните таймери. Когато даден хардуерен таймер изтече , той примерно трябва да събуди даден таск който е "приспан" и чака евент от него. А-ми точно в този случай точно в прекъсването се извиква системна функция за сетване на евент флаг. Е- ако РТОС-а е преемптив - то на излизане от прекъзване ЗАДЪЛЖИТЕЛНО ще се направи проверка за редиспечеризация. Така ако текущо-прекъснатият таск от прекъсването е по-нископриоритетен от този, които е приспан и чакасетването на евент флага от таймера - то на излизане от прекъсването ще има редиспечиризация и процесора след RETI инструкцията на излизане от прекъсването ще започне да изпълнява "събуденият" таск, а не таска, който е бил прекъснат от прекъсването ...
Не разбирам защо това да е странно ?!? Всичките ми проекти и програми ги градя на тази логика и си работят прекрасно ... Греша ли някъде ?

Така го правят всички и това казвам че не удачно за АРМ, щото идва прекъсване, те спасят малко регистри за да могат да работят, после ги възстановяват, после проверки.. и ако са наложи пак ги записват в контекста и зареждат друг контекст.... Мноооого и излишна работа ;-)
Далеч по-просто е при влизане в IRQ да си запиша *всички* регистри в текущия контекст, а те при мен са всичко на всичко 8 регистъра, щото горните ги ползвам за ОС-а и там си ми стои поинтер към текущия контекст. Влизам си в прекъсване, то ако иска събужда тасковете, като просто поставя таска в списъка на ктивни таскове. А при излизане от върха на тоя списък ми стои таска с най-висок приоритет, който може да не е същия като тоя, който съм прекъснал. Но това няма значение - просто му зареждам контекста и му давам управлението.




Цитат:
Представете си Кортекс на ST, който няма фифо на уарта, а има ДМА на уарта.


Че няма ли receive timeout? И при Атмел е с ДМА, обаче си пускам интеръпт по таймоут и след N на брой бита пауза ме известява... Всъщност аз даже не проверявам дали интеръпта е поради изчерпване на DMA или timeout - вземам оставащите байтове за трансфер (може и да са нула) ъпдейтва дължината за клиента и почвам следващата заявка ако има...



Цитат:
Е, не така стоят нещата в РТОС-и които не са преемптив. Аз лично не ги харесвам и не ги използвам. Те са много икономични от към стек

Не знам кое те навежда на мисълта че щом е преемтив му трябва стек? Аз си имам прости таскове дето са буквално със стек от 0 (нула) байта ;-)
Причината е много проста - контекста се спасява в TCB-то (което е и по-правилно), а системните функциии работят в supervisor mode и съответно не ползват user stack. А пък GCC-то е достатъчно умно, че като му сложиш един цикъл дето вика само системни функции и ползва 2-3 променливи да ползва само регистри...


Вто Юни 23, 2009 5:51 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
Миро,
добре направената периферия на Атмел (както споменаваш) определено облекчава живота на програмиста и вдига производителността на системата и винаги е добре да я има :-). А при батерийнозахранени устройства тя спомага и за намаляване на консумацията и удългаване на живота на батерията (процесора е в слип докъто се преточват данни по серийните интерфейси например и няма "будни" таскове...)

tgi, явно вече говорим за едни и същи неща. Само искам да отбележа, че при изпълнението на системни (за ртос-а) функции за кратко време (в критичната си секция) прекъсванията се забраняват (с изклщчение на ФАСТ прекъсванията за които говоря). (Сист. функция за сетване на евент флаг не прави изключение)
Не ми е известна РТОС, която никога да не забранява прекъсванията при обработката на системни заявки ...
Не всички РТОС-и и процесори поддържат тези ФАСТ прекъсвания. Изискванията към процесора е да поддържа приоритети на прекъсванията, както и вложени прекъсвания ... Ако това е на лице - останалото зависи от имплементацията на РТОС-а...


Вто Юни 23, 2009 5:58 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
Миро,

Таймаута на уарта помага само за да се разбере кога трафикът е спрял ()свършил или прекъснал". Ако стрийма не непрекъснат - той не помага...

А относно РТОС-а, юзер стека и контекста - това зависи МНОООГО и от компилатора.
За това смятам, че една РТОС ако е правена за GCC - трябва да се компилира и използва с GCC. Иначе все нещо трябва да се "портне" ...

Това е една от причините да не искам да се обвързвам с платен компилатор и да се стремя към използването на GCC ...


Вто Юни 23, 2009 6:10 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
emilvtc написа:
Само искам да отбележа, че при изпълнението на системни (за ртос-а) функции за кратко време (в критичната си секция) прекъсванията се забраняват
....
Не ми е известна РТОС, която никога да не забранява прекъсванията при обработката на системни заявки ...


Това което гледаш е един порт... иначе същата РТОС, но портната за друга архитектура може и да не забранява прекъсванията ;-)
Проблемът се нарича "атомични операции"....


Цитат:
Таймаута на уарта помага само за да се разбере кога трафикът е спрял ()свършил или прекъснал". Ако стрийма не непрекъснат - той не помага...

те затова хората слагат двойно буферирани ДМА-та ;-) Зареждаш двете... като свърши едното трябва да го презаредиш преди и второто да се е изчерпало...
Не че проблемът се решава много чисто... Щото идеята е хем да нямаш проблем с трансфера, хем да нямаш memcpy(). Но в много случаи трябва да избереш или едното или другото, въпреки двойните ДМА-та... Примерно ако получаваш пакети с променлива дължина. Пускаш първото за хедъра, второто за тялото на пакета. И като получиш хедъра корегираш дължината на второто в движение. И зареждаш за следващия хедър...
Принципно става, обаче ако по протокол може да има нулева дължина или дължина от 1-2 байта, ползата от двойното ДМА става отрицателна ;-) Всъщност пак може да се ползва ама с претокване през по-голям буфер и после memcpy. То затова понякога не се прави стековете с zero copy...


Вто Юни 23, 2009 6:22 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 76 мнения ]  Отиди на страница Предишна  1, 2, 3, 4, 5, 6  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни