Виж темите без отговор | Виж активните теми
Дата и час: Съб Апр 20, 2024 9:35 am
Автор |
Съобщение |
TheWizard
Ранг: Форумен бог
Регистриран на: Сря Апр 27, 2005 11:48 am Мнения: 4716
|
ARM7EJ-S прекъсвания
Имам един джигитайски SoC със ARM7EJ-S ( с малко документация ) и направих една "щуротия" - портнах му FreeRTOS обаче порт няма... и сглобих от налични "парчета" (без много мислене) като SAM91 ... и взе, че тръгна тъпото е че всичкото IRQ са на един вектор, а още по тъпото е че 3 таймера са на една маска (имам някъв OS_TIMER с еденична маска, но не съм го разучил) и ако използвам GPT1 за порт-тикс става мазало... условно: та сложих в GPT1_Handler() един флаг = 1 и като се върна в IRQ_Handler() проверявам за този флаг и джъткам вече тика и контекста туй бла-бла работи обаче имам YIELD и генерирам SWI 0 Питанката ми е когато се случи SWI какво става с IRQ ARM документацията казва, че IRQ автоматично се disable и авто enable при return демек трябва ли да съм спокоен за SAVE_CONTEXT RESTORE_CONTEXT във SWI
_________________ main[-1u]={1};
|
Съб Юни 13, 2020 8:51 am |
|
|
TheWizard
Ранг: Форумен бог
Регистриран на: Сря Апр 27, 2005 11:48 am Мнения: 4716
|
Re: ARM7EJ-S прекъсвания
изобщо не очаквах, че от толкова армаджии няма отговор...
_________________ main[-1u]={1};
|
Пон Юни 15, 2020 6:43 pm |
|
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 5:52 pm Мнения: 10369 Местоположение: Добрич
|
Re: ARM7EJ-S прекъсвания
Както сам си си отговорил при влизане в сервизен режим и изобщо всякакъв режим над юзер прекъсванията се забраняват автоматично. Вече не помня дали 7-цата позволяваше да разрешиш прекъвсванията в сервизен режим, но то не виждам по каква логика ще го правиш. Обикновено системите се проектират така, че сервизния режим да е над прекъсванията, които са OS-aware. Точно с идеята там да напъхаш тред и интеръпт сейф процедури по лесен начин. Що се отнася до прекъсванията... хич не лоша идея да е само 1 вектор. Проблемът при 7-цата е в това, че интеръпт контролера е по избор на производителя. Но всеки уважаващ себе си производител слагаше NVIC, демек такъв дето поддържа вложени прекъсвания. И тогава съвсем естествено си идва на мястото в общия вектор само да провериш дали си в първо прекъсвание и ако си, да си сейвнеш контекста, да разрешиш прекъсванията и да си извикаш текущото. На излизане само гледаш дали си последен и ако да - затваряш вратата. Тъпа е по-скоро "модерната" логика да имаш 100-200 вектора и във всеки вектор да проверяваш. Но както и да е, това беше офтопик...
|
Пон Юни 15, 2020 8:30 pm |
|
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 10:22 pm Мнения: 3074
|
Re: ARM7EJ-S прекъсвания
Модерна....колко ...40-50г И това беше офтопик
|
Пон Юни 15, 2020 8:53 pm |
|
|
TheWizard
Ранг: Форумен бог
Регистриран на: Сря Апр 27, 2005 11:48 am Мнения: 4716
|
Re: ARM7EJ-S прекъсвания
Миро 10х
NVIC е ама няма да правя сложнотии... системната документация ми липсва - памет, дма, плл... и реверсвам
_________________ main[-1u]={1};
|
Пон Юни 15, 2020 9:36 pm |
|
|
gicho
Ранг: Форумен бог
Регистриран на: Пон Мар 13, 2006 12:59 pm Мнения: 3855 Местоположение: Габрово
|
Re: ARM7EJ-S прекъсвания
Ама сериозно ли се оплакваш че новите имат повече от един вектор???
|
Вто Юни 16, 2020 8:11 am |
|
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 5:52 pm Мнения: 10369 Местоположение: Добрич
|
Re: ARM7EJ-S прекъсвания
Напълно сериозно! Ето какъв ми е кода за атмелските АРМ7: | | | | Код: //------------------------------------------------------------------------------ // IRQ EXCEPTION // On entry if REG_CTASK!=0 then the interrupt is not nested and the current // task context is saved. On exit, the highest priority task is run. // If the interrupt is nested, no context switch is needed //------------------------------------------------------------------------------
.func IRQ_handler IRQ_handler: sub lr, lr, #4 cmp REG_CTASK, #0 beq nested_irq_handler
str lr, [REG_CTASK, #tsk_pc]! mrs r11, SPSR stmdb REG_CTASK, {r0-r7, r11-r14}^ nop mov REG_CTASK, #0 swp r0, r0, [REG_AIC_IVR] msr CPSR_c, #ARM_MODE_SVC ldmib r0, {r1, r2} mov lr, pc bx r2 //ISR(r0-info, r1-base)
msr CPSR_c, #ARM_MODE_IRQ | I_BIT str r0, [REG_AIC_IVR, #AIC_EOICR - AIC_IVR] return_to_current_task: ldr REG_CTASK, [REG_MTASK, #tsk_renext] add r11, REG_CTASK, #tsk_pc ldr lr, [r11] ldmdb r11, {r0-r7, r11-r14}^ nop msr SPSR_cxsf, R11 movs pc, lr
nested_irq_handler: stmfd sp!, {r0-r5, r12, lr} mrs r4, SPSR swp r0, r0, [REG_AIC_IVR] msr CPSR_c, #ARM_MODE_SVC mov r5, lr ldmib r0, {r1, r2} mov lr, pc bx r2 //ISR(r0-info, r1-base)
mov lr, r5 msr CPSR_c, #ARM_MODE_IRQ | I_BIT str lr, [REG_AIC_IVR, #AIC_EOICR - AIC_IVR] msr SPSR_cxsf, R4 ldmfd sp!, {r0-r5, r12, pc}^ .endfunc .func SWI_handler
| | | | |
Това включва влизане в прекъсване, обработка на вложените прекъсвания, спасяване на контекста, възстановяване на контекста. Включва още поддръжка на драйвери, щото NVIQ-a не се програмира с указатели към функции, а указатели към драйвери... И всичко е само този код. При куртексите е пръснат на 100 места, налагат се 100 трика, изобщо боза!
|
Вто Юни 16, 2020 8:27 am |
|
|
gicho
Ранг: Форумен бог
Регистриран на: Пон Мар 13, 2006 12:59 pm Мнения: 3855 Местоположение: Габрово
|
Re: ARM7EJ-S прекъсвания
И как стои въпросът със закъснението на обработката на прекъсванията, особено ако имаш софтуерно приоритизиране? На дъртите и ние слагахме подобни дивотии, ама това яде време да се изпълни. В какъв смисъл кодът е разхвърлян? На разните вектори са различните хендлъри, които нямат нищо общо помежду си. Общ код няма - освен ако не стигат векторите/приоритетите и искаш да ги разшириш още повече софтуерно - т.е. когато искаш да имаш много софтуерни тредове. Ама то при кортексите има достатъчно място за още няколко софтуерни прекъсвания, когато хардуерните не стигат, или, по-точно, като имаш нужда от едно хардуерно събитие да се "разклониш" и избереш една от няколко линии на обработка с друг приоритет. Ако тръгнеш в посоката да си правиш тредове заради самите тях, т.е. заради ОС-а или модела на обработка, ще ти трябват много "изкуствени" тредове, което си е проблем на дизайна. И пак не виждам защо да не ползваш наличните множество вектори/приоритети от хардуера, и да си добавиш колкото ти трябва за "софтуерните" - т.е. хардуерните обслужват I/O-процесите, а оттам насетне приложението добавя шедюлър (ако има нужда). Все пак доста работа се свършва от хардуера и няма смисъл да не се ползват наличните функционалности, поне за най-бързите процеси/събития. Дъвкали сме го много, но все пак - защо да не си сложа подходящия код в "UART TX ready" прекъсването и там директно да да видя има ли още в буферите за предаване към TX фифо-то на УАРТ-а, оставяйки който както иска от другата страна помпи във софтуерния буфер? Какво повече ми трябва, за да направя буферирано I/O? Защо да съм задължен да хвана прекъсването и да събудя софтуерен тред на шедюлъра, който да извади от буфера и да прави нещо нанатък - може би да събуди друг тред, който да измисли какво да праща... Сещам се за една причина - ако хардуера е дървен и не ми предоставя прекъсване "tx ready", или ако мина на polling понеже overhead-а от обработките на прекъсвания са ми казали да не ползвам прекъсване. Мисля си че целта е максимално бързо да се разбере че има място във фифото и трябва да го допълним с още данни - колкото по-бързо и сигурно стигнем до това заключение и почнем обработката на точния код за допълване. Ако има някаква дупка в хардуерното преценяване има логика да трупаме код - ама ако няма не е ли безсмислено? Едит: какво е указател към драйвер и в кой стандарт е дефинирано? Това че C++ обектите не могат да се викат през указател към функция си е "специфика" на езика и има решение, което всъщност е C решението за обект. Не виждам защо кусур на определен език ще определя дизайн на хардуера - особено за език, който се бие да е най-доброто за "системно програмиране"
|
Вто Юни 16, 2020 3:47 pm |
|
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 5:52 pm Мнения: 10369 Местоположение: Добрич
|
Re: ARM7EJ-S прекъсвания
Мда... дъвкали сме го много пъти, ама напредък йок Ти се опитваш през твоята камбанария да гледаш света, обаче в случая аз ползвам една по-утъпкана пътека с банален ОС и банално/стандартно изпълнение. Баналното изпълнение включва нишки, които си щъкат отдолу. Могат да се сменят доброволно или доброзорно. Вика му се шедулинг алгоритъм. При доброволното нишката казва "аз ша спя" при което вика сервизната функция за спане и тя трябва да спаси контекста на нишката, да вземе друг контекст на друга нишка, да го възстанови и при излизане хуква новия контекст демек нишка. При доброзорната смяна идва външен сигнал, т.е. прекъсване. Не всяко прекъсване сменя нишки естествено. Просто нишки дето чакат хардуера на практика чакат някакво прекъсване. За да е още по-реално, прекъсванията могат да идват накуп, т.е. докато обработваш едно посредата идва друго и така нишките за събуждане може да са няколко, ама ти трябва да събудиш само едно естествено. Цялата тая дандания има различни имплементации. При по-простите може да се действа с конкретика. Демек в прекъсването решаваш дали ще сменяш контексти и т.н. Фреертос-а май беше на тоя принцип. Проблемът е, че става мазало щото не спасиш ли контекста преди първото прекъсване и позволиш второ и то реши да сменя вече не е ясно какво ще сменя и т.н. Затова има по-чисто решение. При първо прекъсване текущия контекст се спасява. При последно се възстановява. По средата под "текущ контекст" се разбира указателя към текущата нишка. Няма проблем този указател да се променя N пъти, т.е. може да имаш 100 вложени прекъсвания, всяко може да си сигнализира нишки и да събужда и да убива, въобще може да става всичко без проблем. На въпроса за драйвер - драйвера е всичко, което ти е необходимо за да обслужваш дадена периферия. Джелязна или виртуална, все тая. Работата е там, че някои периферии се дублират и често по повече от един път. Примерно може да имаш 5 UART-a. И тъй като под "драйвер" се разбира нещо стандартно, то няма никаква логика за 5 еднакви хардуера да имаш 5 различни софтуера. Говорим за един драйвер за UART, който може да се инсталира 5 пъти или колкото там искаш. И под инсталация е добре да не са 5 набора от макроси дето генерират 5 комплекта процедури, щото не е много ефикасно така по 5 пъти. И те така стигаме до един набор от функции, които НЕ СЕ дублират. Както и при обектното програмиране. Имаш клас, имаш и инстанция. Но реално обекта ти представлява един указател. От този указател може да извлечеш всичко за инстанцията и/или класа. Абсолютно по същия начин е при драйверите - имаш указател (или индекс) от който може да стигнеш до каквото ти трябва... Сега какво става, когато имаш общ вектор на прекъсванията. Както казах NVIQ-а се програмира не с указатели към ISR, а с указатели към драйвери. Идва прекъсване, влизаш в общия вектор, четеш един указател от тип драйвер, викаш функцията за прекъсване на тоя драйвер. Естествено тъй като тази функция е "виртуална" трябва да й подадеш параметър (this) на конкретния драйвер. Тоя параметър си е същия указател с който си програмирал контролера на прекъсванията. Какво става ако няма общ вектор - ми ти нямаш 5 отделни процедури за UART примерно. Така че и да имаш 5 отделни вектора това не ти помага, ти пак трябва да отидеш на едно място. Само дето се налага първо да отидеш на някое от 5-те места, да видиш на кое си отишъл, да си сметнеш кой ти е тоя драйвер и след това да извикаш функцията му за прекъсване. Така цялото ускорение от хардуерното диспатчване отива на кино, щото софтуерно се налага да го ревърснеш... За да е още по-шантово излизането при куртексите и допълнително усложнено. Реално в прекъсване не знаеш при излизане дали ще излезеш или ще влезеш в друго, щото има там една заигравка и пестят от спасяване на регистри. Демек при излизане от прекъсване не можеш да възстановяваш контексти. Прави се чрез pending прекъсване, което трябва да сложиш с по-нисък приоритет от най-ниското нормално прекъсване и трябва да се аборнираш за него, то евентуално да възстанови контекста. Освен ако него не го прекъснат, тогава ще възстанови един, ще зацикли и възстанови друг. И за да е още по-шантово, покрай всичките тия "ускорения" при викане на софтуерно прекъсване не може да ползваш регистри. Не знаеш дали някой няма да те прекъсне и да ги омаже. Софтуерните прекъсвания трябва да претакват параметрите си през стека. На излизане пък резултатът се претаква... И за да е още по-шантово всичките тия прекъсвания на прекъсвания и оптимизации стават много капризни на тема приоритети и инверсия на приоритети. Имаш и хардуерни стекове за тия приоритети. Съответно имаш хард фаулт, ако се омажат и трябва да гледаш да не ги омазваш, въобще манджа с грозде... С две думи, четвърта архитектура е архитектурата, която е подходяща за ОС. При куртексите я омазаха... и после пак се върнаха на нея.
|
Вто Юни 16, 2020 5:03 pm |
|
|
Цецо
Ранг: Форумен бог
Регистриран на: Пон Сеп 27, 2004 8:22 am Мнения: 15501 Местоположение: София
|
Re: ARM7EJ-S прекъсвания
Т.е. при примера с UART-а na Cortex-a прекъсването ще се развърже НЕ по-бавно от на стария ARM. Т.е. не губиш нищо, реално е същото, а според мен и една идея по-бързо. Просто трябва да извикаш УАРТ драйвера с някакво ID или хендъл и толкоз. А понеже си в точно определено прекъсване, то и този хендъл е недвусмислено ясен в момента на прекъсването. Тук не коментираме извратеностите на STM да комбинират по няколко сорса на един вектор, особенно ако говорим за пинови прекъсвания. Обаче ако трябва да отработиш някакво специфично прекъсване, което не изисква унификация със себеподобни, отделните вектори са много по-удобни, защото уникалния код си живее в собствен контекст още от евента и не си меша капите с другите. Т.е. по отношение на прекъсванията Кортекса е по - добре или в най-лошия случай равен на ARM7, не е ли тъй?
_________________ "Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.
|
Вто Юни 16, 2020 6:15 pm |
|
|
gicho
Ранг: Форумен бог
Регистриран на: Пон Мар 13, 2006 12:59 pm Мнения: 3855 Местоположение: Габрово
|
Re: ARM7EJ-S прекъсвания
Тъй де. И когато има нужда от "унификация на себеподобни" най-простият начин е да сложиш отделни прости хендлъри на всеки отделен вектор, като uart0_int(), uart1_int() и т.н. Всяка от тях просто вика още една - унифицираната, примерно uart_common_int(&UART0context) за уарт0, и т.н. А пък който иска може да слага едно и също на всички вектори, и после още веднъж да търси информация как да стигне до уникалните - но това е цената на наследството - направено за общ вектор понякога преминава нататък, в следващата генерация, нищо че вече има отделни, и остава софтуерния диспатч (при положение че целия интеръпт контролер е мислен за да спести този софтуерен слой). Мисля, че е по-лесно да обединиш (омешаш) разни съставки в едно, отколкото да разделиш от кюпа отделните.
|
Вто Юни 16, 2020 7:33 pm |
|
|
TheWizard
Ранг: Форумен бог
Регистриран на: Сря Апр 27, 2005 11:48 am Мнения: 4716
|
Re: ARM7EJ-S прекъсвания
да де ама ако имаш N таймера на един вектор, сис-тика и смяна на контекста става мазало намерих OS_TIMER...(от недокументираните) ще тествам да го пусна на 1 мс IRQ, че е сам на вектор
Тоя SoC е MT6261 / МТ250х - на джигитайските 2G модули чипсета ( 260MHz с по 4 мега флаш и рам ) затрих му firmware и цъка FreeRTOS и Ардуино - бареметал ( no GSM ) подкарах му и блутута, ама немам "лесен" стек за BT 3.0 ... със BLE стек вика, че не разбира командите
_________________ main[-1u]={1};
|
Вто Юни 16, 2020 8:03 pm |
|
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 8:21 pm Мнения: 27998 Местоположение: София
|
Re: ARM7EJ-S прекъсвания
Ами когато имаш някакъв ОС/по адванс шедулър не мога да кажа до колко има смисъл от много вектори, няма достатъчно о-ит, но ако караш без такъв, а според мен малките армове нямат нужда от подобни екстри, конкретно ОС-и, то многото вектори започвт да са критични когато искаш да изтискаш максимума от един контролер. Да прави се и с едно прекъсване, като на дъртите пикльовци, не е да не съм ги изстисквал до максимум, но многото вектори в много случаи си имат предимства. Примерно реализацията при 51-ците на силабс е много по-удобна от един вектор при дъртите 16-ки.
|
Вто Юни 16, 2020 10:31 pm |
|
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 5:52 pm Мнения: 10369 Местоположение: Добрич
|
Re: ARM7EJ-S прекъсвания
Като скорост - да. Операциите по завързване и развързване са еднакви, но инструкшън сета на куртекса е по-добър и става с две, докато на стария трябват поне 3 инструкции. Допълнителното ускорение на куртекса идва от спасяването на регистрите, което го прави в прелюдията. Но макар, че това спестява няколко клока също създава главоболия, защото понякога се прави, понякога не се прави. Съответно не може да разчиташ на регистри в софтуерните прекъсвания. С две думи при куртекса има много "ускорения", които заради няколко клока усложняват и бъркат доста неща. Не случайно се ползват само в куртекс-М, при всички останали си е класическата концепция. А пък ST са уникати... не им стига отделен вектор за периферия, ами някои периферии като USB могат да имат по два вектора. Разбирам да беше за критични периферии като да кажем таймери, които може да искаш да ги пуснеш да цвъкат през микросекунди. А те слагат по няколко таймера на общ вектор, пък USB се шири на два. По принцип ако спасяваш и възстановяваш винаги контекста при влизане/излизане от първо ниво прекъсване ОС-а се опростява значително. Нямаш нужда сис-тика да ти е специален, нямаш нужда от нищо. Допълнително опростяване е ако важните системни функции са ти софтуерни прекъсвания. Така ти отпада и нуждата да забраняваш прекъсвания и всякакви гимнастики по синхронизации. Не помня точно как беше при фреертоса... той май слагаше save/restore във всеки ISR, който иска да ползва кърнела? Аз се възползвах от атмелите, при които може да избираш всеки вектор дали да ти прави IRQ или FIQ. Съответно контекстите ги спасявах за всички IRQ-та още в хендлъра. А ако за нещо няма нужда да се спасяват контексти просто го пусках като FIQ и там хендлъра е чист и бърз.
|
Сря Юни 17, 2020 8:45 am |
|
|
TheWizard
Ранг: Форумен бог
Регистриран на: Сря Апр 27, 2005 11:48 am Мнения: 4716
|
Re: ARM7EJ-S прекъсвания
....той май слагаше save/restore във всеки ISR.... - аха подкарах OS_TIMER - той бил "умен" ( има отделен вътрешен ARM за системни операции, систик, слип, вейкъп...) ... един таймер IRQ и един брояч сис-тик-брояч тея са му набутали няколко ARM-a и няколко DSP периферии ... баси
_________________ main[-1u]={1};
|
Сря Юни 17, 2020 1:19 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 7 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|