Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

ARM - режими на работа.
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=1873
Страница 1 от 4

Автор:  Цецо [ Чет Фев 23, 2006 5:17 pm ]
Заглавие:  ARM - режими на работа.

Борейки се с това говедо (ARM7TDMI), задълбах в следната черна яма.

Трябва да си дефинирам стековете в линкерския файл (компилатора е ИАР, ама въпроса е общовалиден).

За някой режими е ясно (FIQ, IRQ, супервайзер) - дефинирам си там някакви стекове.

Но:

1) Има ли смисъл да дефинирам стек за Abort и Undefined? Аз засега мисля просто да ги насоча към ресет (или към някакъв безкраен цикъл) и да сложа някаква индикация по въпроса.

2) За системния и юзер мода нещата не са ми много ясни. Те така или иначе ползват едни и същи регистри. Няма логика да имат два стека. Освен това не мога да видя друга разлика между двата режима, освен че в юзерския не мога да пипам по CPSR/SPSR регистрите. Има ли други разлики между тия два режима?

Автор:  CM600 [ Чет Фев 23, 2006 6:25 pm ]
Заглавие: 

Ето затова трябва System режима -> http://www.arm.com/support/faqdev/1456.html 8O

А и в user не можеш да пипаш (т.е. можеш ама няма да стане) S - bit-a. в LDM/STM инструкциите.

Автор:  Zdrav [ Чет Фев 23, 2006 10:56 pm ]
Заглавие: 

Като за начало постави безкраен цикъл на всички неизползвани вектори - Undefined instruction, Software interrupt, Prefetch abort, Data abort. Така ще хванеш проблеми в програмата си овреме. Не е необходимо да дефинираш стекове за тези режими, които никога няма да използваш. Като за начало работи в supervisor режим. Доколкото разбрах целта ти е да пуснеш uLinux но по-нататък?
Какво означава дефинирането на стекове за съответния режим? Това е заделяне на памет за тях от линкера и начално установяване на r13 за съответния режим( r13 е стеков указател при ARM). Това става в самото начало - в процедурата на reset вектора. Ето например как става:

Код:
/******************************************************************************   
*                            System reset handler                             *   
******************************************************************************/   
do_reset:
   
    /*Set stack pointers for all modes used (Supervisor, IRQ and FIQ)*/           
    msr     cpsr_c, #0xd3       /* ensure we're in Supervisor mode */             
    ldr     sp, =__stack_svc    /* set Supervisor mode stack pointer */           
                                                                                 
    msr     cpsr_c, #0xd2       /* enter IRQ mode, with interrupts disabled */   
    ldr     sp, =__stack_irq    /* set IRQ mode stack pointer */                 
                                                                                 
    msr     cpsr_c, #0xd1       /* enter FIQ mode, with interrupts disabled */   
    ldr     sp, =__stack_fiq    /* set FIQ mode stack pointer */

и после накрая на reset процедурата след като сме подготвили средата за работа такава каквато я очаква компилатора на С или С++ извикваме main функцията.
Код:
/* Enable interrupts, enter supervisor mode and branch to start of 'C' code */
    msr     cpsr_c, #0x13       /* I=0 F=0 T=0 MODE=supervisor */               
    bl      main

В IAR нещата изглеждат по-различно, но основната идея е тази.
Когато процесорът влезе в "exeption" превключвайки режимите и преминавайки към процедурата към която му сочи съответния вектор той ще използва като стеков указател sp(r13). И преди това да се случи в него трябва да имаш коректен адрес. Ако имаш безкрайна врътка и не ползваш стека на съответния режим не е необходимо да дефинираш стекове и да инициализираш стековите указатели за тези режими.

Автор:  Цецо [ Пет Фев 24, 2006 10:49 am ]
Заглавие: 

Засега няма да пускам Линукс. Работя върху контролер с ограничени ресурси.

Защо да работя в супервайзер режим?

Аз си мислех да си бачкам като юзер.

Автор:  ДедоБоре [ Пет Фев 24, 2006 11:06 am ]
Заглавие: 

да допълня здравия за безкрайните врътки:

ако имаш свобовни телове, преди да влезеш във врътката слагаш някакъв код на теловете, че да можеш да разбереш на какъв ексепшън си се натресъл. ако нямаш много телове, а само един, може врътката да ти вади някаква битова поредица (нещо като) 01010000, което да си го гледаш на осцилоскопа.

Автор:  CM600 [ Пет Фев 24, 2006 12:31 pm ]
Заглавие: 

Аз доколкото виждам във всички примери от IAR след B main винаги си в System режим. В главата Handling Processor Exceptions стр. 133 от документацията пише точно за какво е добавен System режима в ARM v4 и 4Т. Не ми дава copy text акробата иначе бих го paste тука.

Автор:  Zdrav [ Пет Фев 24, 2006 12:35 pm ]
Заглавие: 

Цецо написа:
Засега няма да пускам Линукс. Работя върху контролер с ограничени ресурси.


Останах с впечатление от други дискусии тук, че правиш развойна платка с LPC2214 и закачени на външната му шина достатъчно FLASH и RAM. А това не е ограничен ресурс.

Цецо написа:
Защо да работя в супервайзер режим?

Аз си мислех да си бачкам като юзер.


Лично аз засега не съм използвал напълно възможностите, които предлагат различните режими на ARM7. В user mode не можеш да превключваш режимите освен ако не възникне "exeption". Както каза и CM600 не можеш да използваш и "S" в инструкциите тоест да копираш автоматично SPSR в CPSR и LR в PC. За друго не се сещам защото не излизам от supervisor режима и не съм се сблъсквал с подобни въпроси.

Има един документ на ARM там е доста по-подробно описано от другите ARM7 TDMI-S Technical Reference Manual-и. Нарича се ARM ARM (ARM Architecture Reference Manual).
На сайта на ARM ще намериш само това:
http://www.arm.com/documentation/books/1183.html
Но иначе го разпространяват в pdf вариант на едно free CD заедно със други тлъсти pdf-и.
Altera имат качен на сайта си този ARM ARM.
http://www.altera.com/literature/third- ... rm_arm.pdf
Препоръчително четиво. Особено Part A, Programmer's model.

Автор:  Цецо [ Пет Фев 24, 2006 4:53 pm ]
Заглавие: 

Ами не става въпрос за онази развойна платка. Исках друг човек да я прави, но той няма време, аз също, така че...
Та сега се уча в движение върху един проект с LPC2134. А там ресурсите са си ограничени. Ама на мен и не ми трябват много за това което трябва да направя.

Мерси за ARM описанието.

Това което разбрах от прочетеното е че юзерския режим е кон с капаци - т.е. не мога да го сменя ако не се появи външен ексепшън (а ако генерирам софтуерно прекъсване?). Това че не мога автоматично да съхранявам регистрите също е вързано с първото. Излиза че системния мод е еквивалентен на юзерския, само дето няма горните ограничения.

Сега съм в дилема - приложението ми е една основна програма и две прекъсвания. Честно казано не виждам какво пречи на основната програма да си работи в юзерски режим. От друга страна ИАР автоматично ме зарязва в системен режим при влизане в main (което обаче може да се коригира).

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

Автор:  Zdrav [ Пет Фев 24, 2006 6:45 pm ]
Заглавие: 

Ами то зависи и от конкретния вариант който са избрали PHILIPS за техните микроконтролери.
Освен това което беше казано до тук, съм срещал в описанието и един регистър на VIC, който може да забрани user mode да пипа по останалите VIC регистри. При други производители може да има и други подобни, но мисля че в LPC2000 всичко се изчерпва с това.

Със софтуерно прекъсване можеш да влизаш в IRQ режим и там да променяш каквото ти трябва.

Остави IAR-а да прави каквото си е наумил. :D

Автор:  Цецо [ Пет Фев 24, 2006 7:04 pm ]
Заглавие: 

Да оставя компилатора "да прави каквото трябва" - как пък не.

Автор:  CM600 [ Пет Фев 24, 2006 8:39 pm ]
Заглавие: 

Цецо в user режим не можеш да разрешаваш/забраняваш прекъсванията. IAR има едни intrinsic функции __disable_intrrrupts __enable...blah blah, с които от C код може да пипаш PSR, обаче тия функции предполагам че очакват CPU - то да си е в System режим, както си го оставя IAR по подразбиране.

Автор:  Zdrav [ Пет Фев 24, 2006 10:03 pm ]
Заглавие: 

Като ставаше дума за безкрайни врътки сочени от векторите на прекъсванията има и още нещо което може и вече да си се сетил. При това ядро и този VIC има една особенност, че ако причината за подадената заявка за прекъсване(флаг в периферията) изчезне(бъде свален) по някаква причина по време на подготовката на ядрото за влизане в прекъсване. То VIC няма да успее да определи източника на прекъсването и ще подаде във VICVectAddr стойността на VICDefVectAddr. А какво има там ??? При reset VICDefVectAddr е нулиран следователно в този неподходящ и неочакван момент ще се получи софтуерен reset. За това препоръчвам ти ако не го използваш този вектор да насочиш и него към една безкрайна врътка по време на развоя и дебъгването. А после при release варианта да смениш врътката с това:
Код:
stmfd   sp!, {r0}
ldr     r0, =VICVectAddr
str     r0, [r0]
ldmfd   sp!, {r0}
subs    pc, lr, #4

Което ще върне програмата там откъдето се е отлъчила от правия път. Разбира се ако такива своеволни събития са допустими.

Автор:  Цецо [ Съб Фев 25, 2006 12:47 am ]
Заглавие: 

Да видях я тая "особенност" с вектора по подразбиране.

А за прекъсванията - ами поне на LPC то - могат да се спират и от юзер режим. Направо в VIC-a. Balkanа вече ме открехна на тая хитрост.

Автор:  Balkana [ Съб Фев 25, 2006 2:32 am ]
Заглавие: 

@Цецо: Забравих да кажа, че таз хитрост ми яде главата вече :)
Ама си има и решението де, на няколко вида АРМ съм проверил, и е валидно:
Ако забраниш прекъсванията от контролера, то е възможно да се обработи прекъсване след инструкцията която пише в регистъра на контролера, т.е. за да се образува правилно критичната секция, необходимо е при забраната на прекъсванията да се напише:


Регистър_за_забрана = Забранено;
__asm("nop");

При разрешаването няма такъв проблем.

В дейташийта на любимия ми Микронас го пише с дребни букви, и го прочетох случайно, след което се плеснах по челото, щото вече бях набедил компилатора в неправомерни оптимизации; В резултат на липсата на NOP-а много рядко ми се образуваше проблем, тъй като получавам прекъсване в критичната си секция.

В 2 други дейташийта, тази особеност не се споменава; тествах с колеги със специално написан код и се повтори ефекта.

В LPC не знам как е, но е много вероятно да има повторение на същата особеност. На SAM7 и STR71x не съм чел още достатъчно подробно дейташийтовете.

Автор:  Zdrav [ Съб Фев 25, 2006 9:04 am ]
Заглавие: 

Друг вариант е да генерираш софтуерно на някой от неизползваните канали във VIC заявка за прекъсване и съответният вектор да те отведе до процедурата за забрана на прекъсванията. Т. е. ще се подсигуриш че забраната на прекъсванията става в IRQ режим и други прекъсвания няма да се намесят междувременно. По-бавно, но сигурно. :wink:

Страница 1 от 4 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/