Отговори на тема  [ 18 мнения ]  Отиди на страница 1, 2  Следваща
ARM assembler to C 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение ARM assembler to C
Събота и неделя реших да изпробвам CoIDE, защото била out of the box, заработи от раз на няколко машини, изрових от мазето една Luminary демо платка с LM3S8962, пуснах CoOS-а на нея, пуснах IP стека с прост Web сървър, SD картата е по SPI, събраха се 5 задачи и ми хареса как работи CoOS. Та сега искам да я изпробвам и на PIC32. Всичко по CoOS е написано на C, което се компилира безпроблемно на PIC32, има един файл в който има 5 функции, които са на асемблер, двете най-простите от тях ги пренаписах на C, но другите 3 искат по детайлно познаване на Cortex М0-M3 . Някой може ли да удари едно рамо и да напише тези 3 функции на C ? Или поне на всеки ред на ARM асемблера да вмъкне коментар кое къде се копира ( като е при SetEnvironment() ) ? На мен ще ми трябва поне седмица да направя някакъв първоначален порт....

Още инфо което ми трябва: каква е GCC конвенцията при предаване на параметри на функции при ARM Cortex M3 ?
Доколкото виждам, ако е един единствен указател, се използва регистъра R0...

Код:

U32 NVIC_INT_CTRL  = 0xE000ED04;            // Interrupt control state register
U32 NVIC_PENDSVSET = 0x10000000;            // Value to trigger PendSV exception
U32 INT_EXIT       = 0xFFFFFFFC;

void SetEnvironment(OS_STK *pstk)   {
    __asm volatile
    (   
       " SUB    R0,#28 \n"      // R0 = R0 - 28
       " MSR    PSP,R0 \n"      // PSP = R0 ( Move the contents of a general-purpose register to a special register. )
       " BX      LR  \n"        // BX is branch indirect (register)
    );
}

/**
******************************************************************************
* @brief      Do ready work to Switch Context for task change
* @param[in]  None   
* @param[out] None 
* @retval     None.      
*
* @par Description
* @details    This function is called to Do ready work to
*              Switch Context for task change
******************************************************************************
*/
void SwitchContext(void)    {
  __asm volatile
  (
      " LDR     R3,=NVIC_INT_CTRL  \n"
     " LDR     R3,[R3]            \n"
     " LDR     R2,=NVIC_PENDSVSET \n"
     " LDR     R1,[R2]            \n"
      " STR     R1, [R3]           \n"
      " BX      LR               \n"   
  );
}

void PendSV_Handler(void)
{
////////debug block /////////////////////////
  __asm volatile
(
    " LDR    R3,=TCBRunning \n"
    " LDR    R1,[R3]        \n"    // R1 == running tcb
    " LDR    R2,=TCBNext    \n"
    " LDR    R2,[R2]        \n"    // R2 == next tcb
   
    " CMP    R1,R2          \n"
    " BEQ    exitPendSV     \n"             
   
    " MRS    R0, PSP        \n"    // Get PSP point (can not use PUSH,in ISR,SP is MSP )
    " STMDB  R0!,{R4-R11}   \n"    // Store r4-r11,r0 -= regCnt * 4,r0 is new stack
                                   // top point (addr h->l r11,r10,...,r5,r4)
    " STR    R0,[R1]        \n"    // Save orig PSP
     
    " STR    R2, [R3]       \n"    // TCBRunning  = TCBNext;
    " LDR    R0, [R2]       \n"    // Get SP of task that be switch into.
    " LDMIA  R0!,{R4-R11}   \n"    // POP {R4-R11},R0 += regCnt * 4
    " MSR    PSP, R0        \n"    // Mov new stack point to PSP
   

    " exitPendSV:           \n"
   " LDR    R3,=OSSchedLock\n"
   " MOVS   R0, #0x0       \n"
   " STRB   R0, [R3]       \n"
    " ORR    LR,LR,#0x04    \n"    // Ensure exception return uses process stack
    " BX     LR             \n"    // Exit interrupt
  );
}

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пон Мар 26, 2012 8:56 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
Пирев, що се занимаваш с глупости?

колко пъти да ти казвам, че това е твоят ОС ;-)

Иначе прехвърлянето на горните функции едва ли ще ти помогне особено... Освен ако нямаш идея как да емулираш Pending service на MIPS-a.

SwitchContext() пуска заявка за пендинг сървис, за целта се пише константата NVIC_PENDSVSET в регистър NVIC_INT_CTRL (те имат едно излишно четене за заблуда на противника ;-) )

А пък в хендлъра (PendSV_Handler) правят смяна на контекста. Имат някакви глобални указатели TCBRunning и TCBNext, ако са еднакви пропускат смяната. Иначе спасяват текущия контекст в *TCBRunning, зареждат новия от next-a и го правят running... Такива ми ти работи, само че не виждам какво те топли това. За PIC32 ще трябва да го пренапишеш като за PIC32.


Пон Мар 26, 2012 9:52 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение Re: ARM assembler to C
miro_atc написа:
колко пъти да ти казвам, че това е твоят ОС ;-)

Няма проблем, можеш да го повтаряш колкото си искаш :) , но аз ще си портна CoOS . За PIC32 ще го напиша изцяло на C, пък и за dsPICxx ще е на C.

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пон Мар 26, 2012 10:00 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Съб Окт 13, 2007 12:12 pm
Мнения: 712
Мнение Re: ARM assembler to C
Много добре Пирев! :) Погледни порта във FreeRTOS как е направен, китайчетата едва ли са открили топлата вода?!


Пон Мар 26, 2012 10:13 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
¶ написа:
miro_atc написа:
колко пъти да ти казвам, че това е твоят ОС ;-)

Няма проблем, можеш да го повтаряш колкото си искаш :) , но аз ще си портна CoOS . За PIC32 ще го напиша изцяло на C, пък и за dsPICxx ще е на C.


Ей, луд умора няма :D

И каква е целта (ако не тайна)?

Иначе като ще се трепеш, що не вземеш да направиш твоя версия... мисля че мога да ти помогна с разни идеи. Особено ако целта ти е да направиш нещо просто и ефикасно. Примерно ето как изглежда при мен смяната на контекста:

Код:
//*----------------------------------------------------------------------------
//*         PendSV handler
//*----------------------------------------------------------------------------
FUNC(   sys_pendsv_handler   )
   mrs               r3, PSP                                                        // Recover PSP into R12
   stmia             REG_CTASK, {r3-r9}                                             // Push non-stack registers
   ldr               REG_CTASK, [REG_MTASK, #tsk_renext]
   ldmia             REG_CTASK, {r3-r9}                                             // Restore non-stacked registers
   msr               PSP, r3                                                        // Set PSP to R12
   bx                lr                                                             // Return back to Thread
ENDF(   sys_pendsv_handler   )


точно 3 пъти по-малко инструкции от кокосите...


Пон Мар 26, 2012 10:39 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение Re: ARM assembler to C
miro_atc написа:
Ей, луд умора няма :D

И каква е целта (ако не тайна)?


Лудите също са полезни ( понякога ) :D Целта ли ? CoOS просто ми хареса, семпла и добре структурирана документация, добре структурирани функции и типове данни, ..... е, за прозападните маниаци сигурно ще е кощунство да се портва китайска OS, ама това си е техен проблем :o

miro_atc написа:
Иначе като ще се трепеш, що не вземеш да направиш твоя версия... мисля че мога да ти помогна с разни идеи. Особено ако целта ти е да направиш нещо просто и ефикасно.

Защо да се трепя ? Мисля още дъълги години да живея :D

То е ясно, че при PIC32/dsPIC ще е моя версия. Разполагам с достатъчно на брой PIC32/dsPIC развойни платки, така че ще ми е лесно да проверя дали всичко при CoOS е наред. При ARM разполагам с 3-4 на брой платки, на първата всичко заработи от раз, като имам време ще изпробвам CoOS и на Primer2 с STM32xxx. NuttX е .... една голяма какафония, стотици файлове, неясна концепция, а бе не ми хареса, нея съм я отписал. FreeRTOS също не попада в полезрението ми. RetroBSD ме заинтригува, но е много обемиста, та поне засега няма да се занимавам с нея.

miro_atc написа:
точно 3 пъти по-малко инструкции от кокосите...

Няма да я използвам на ARM, така че ми е все тая дали е с 3 или 4 инструкции в повече. Пък и все пак CoOS е дело на китайски студенти, но като за студентска работа си е доста добре.

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пон Мар 26, 2012 11:30 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: ARM assembler to C
Още един китайски RTOS - http://en.rt-thread.org/ поддържа и ARM и MIPS
А това е тежката артилерия http://ecos.sourceware.org/ малко е големичко, но ако си поиграе човек с настройките му може да падне под 20кб, ако има повечко памет си струва да му се ползва POSIX поддръжката.

И да се закача малко си Миро :)

Код:
ALWAYS_INLINE
void port_context_switch(struct port_context *from, struct port_context *to)
{
   asm volatile("\n"
         "stmia   %0,{r0-r15}\n"
         "ldmia   %1,{r0-r15}"
#if !defined(ARM_STM_PC_OFFSET) || ARM_STM_PC_OFFSET==12
         "\n nop"
#endif
         : /* no outputs */
         : "r"(from), "r"(to)
         : "memory");
}      /* -----  end of function port_context_switch  ----- */


или

Код:
NEVER_INLINE
__attribute__((naked))
void port_context_switch(struct port_context *from, struct port_context *to)
{
   asm volatile("\n"
         "push   {r4-r11,lr}\n"
         "str   sp,[%0]\n"
         "ldr   sp,[%1]\n"
         "pop   {r4-r11,pc}"
         : /* no outputs */
         : "r"(&from->stack), "r"(&to->stack)
         : "memory");
}      /* -----  end of function port_context_switch  ----- */

_________________
Мразя да мразя ...


Вто Мар 27, 2012 1:35 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
palavrov написа:
И да се закача малко си Миро :)


Недей да се закачаш ;-)
И двете парчета дето си дал за 4-та и 7ма архитектура са извадки дето само местят регистрите. Липсва кода който вика тия извадки. Като го сложиш, тогава ще сравняваме... Това, което вероятно ти убягва е, че при мен няма друг код ;-)


Вто Мар 27, 2012 8:47 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: ARM assembler to C
miro_atc написа:
palavrov написа:
И да се закача малко си Миро :)


Недей да се закачаш ;-)
И двете парчета дето си дал за 4-та и 7ма архитектура са извадки дето само местят регистрите. Липсва кода който вика тия извадки. Като го сложиш, тогава ще сравняваме... Това, което вероятно ти убягва е, че при мен няма друг код ;-)

Айде сега, не ми е убягнало разбира се ... между другото и двата варианта са за 4+ ARM архитектура ... но не стават за thumb и thumb2, и варианта който се инлайнва наистина е с много по-малко инструкции, но не бих се хванал на бас че е по бърз - записва 15 регистъра вместо 10 както е варианта със запис в стека. Ето ти повече код:
Код:
void task_yeld()
{
   port_interrupt_status interrupt_status = port_interrupt_disable();

   struct task *old_task = task_current();

   task_list.tail = list_head(&task_list);

   struct task *new_task = task_current();

   port_context_switch(&old_task->context, &new_task->context);

   port_interrupt_restore(interrupt_status);
}      /* -----  end of function task_yeld  ----- */

Ето ти го дизасемблирано:
Код:
00000264 <task_yeld>:
264:   e10f2000    mrs   r2, CPSR
268:   e38230c0    orr   r3, r2, #192   ; 0xc0
26c:   e121f003    msr   CPSR_c, r3
270:   e59f1024    ldr   r1, [pc, #36]   ; 29c <task_yeld+0x38>
274:   e5913000    ldr   r3, [r1]
278:   e5933000    ldr   r3, [r3]
27c:   e5813000    str   r3, [r1]
280:   e2831004    add   r1, r3, #4
284:   e5933000    ldr   r3, [r3]
288:   e2833004    add   r3, r3, #4
28c:   e881ffff    stm   r1, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}
290:   e893ffff    ldm   r3, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}
294:   e121f002    msr   CPSR_c, r2
298:   e12fff1e    bx   lr
29c:   30000094    .word   0x30000094

Имай в предвид, че тук е и кода на schedulera който взема следащия таск. Ако можеш да покажеш нещо по-оптимално на C или assembler - давай :)

_________________
Мразя да мразя ...


Вто Мар 27, 2012 9:53 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
palavrov написа:
Ако можеш да покажеш нещо по-оптимално на C или assembler - давай :)


давам

Виж tmos/ports/cortex-m3/exceptions.S и services.S. Първият файл е за хендлърите, вторият с всички функции на кърнела. Те това е всичко ако не броим хедърите, ама те не генерират код...


Вто Мар 27, 2012 10:53 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: ARM assembler to C
miro_atc написа:
palavrov написа:
Ако можеш да покажеш нещо по-оптимално на C или assembler - давай :)


давам

Виж tmos/ports/cortex-m3/exceptions.S и services.S. Първият файл е за хендлърите, вторият с всички функции на кърнела. Те това е всичко ако не броим хедърите, ама те не генерират код...

Ако съм проследил правилно логиката, аналогичен код на моя започва от TaskDelay: - преброих някъде към 22-23 инструкции, моя пример е с 14 инструкции, е като обем твоя код е по малък заради 16 битовите опкодове.

_________________
Мразя да мразя ...


Сря Мар 28, 2012 12:02 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
palavrov написа:
аналогичен код на моя


Къде видя аналогия? Според мен няма аналогия между preemptive и nonpremptive multitasking...

Едно е да броиш дървета, друго е да видиш гората отгоре ;-)


Сря Мар 28, 2012 12:29 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: ARM assembler to C
Гледай сега, това, че има функция която explicit-но прехвърля контрола на друг таск не значи непременно, че scheduler-а е preemptive. Ползвах го като пример защото в нея се вижда на едно място всичко на куп - общия брой инструкции който се изпълнява когато има task switching. Затова и потърсих аналогично нещо в твоята ОС-ка - като съзнателно извадих само парче код.

Както и да е, не ми се разправя - успех!

_________________
Мразя да мразя ...


Сря Мар 28, 2012 10:59 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение Re: ARM assembler to C
palavrov написа:
Гледай сега, това, че има функция която explicit-но прехвърля контрола на друг таск не значи непременно, че scheduler-а е preemptive.


И аз това се опитвам да ти кажа... това че прехвърляш контрол не изначава че правиш истински task switch ;-)
Ако се напънеш малко тоя yeld може да го замениш с един call и тогава ще ме биеш отвсякъде...


Цитат:
Ползвах го като пример защото в нея се вижда на едно място всичко на куп - общия брой инструкции който се изпълнява когато има task switching. Затова и потърсих аналогично нещо в твоята ОС-ка


Да, ама аналогия няма щото в моя ОС няма yeld и не може да има. А в твоя няма preemption и не може да има. И двамата правим смяна на контекст, но причините са коренно различни. Ако искаш да се сравняваме трябва или ти да добавиш premeption и приоритети, или аз да направя твоя вариант. За мен няма никакъв смисъл да се занимавам с nonpriemtive кърнел. Но на твое място бих разкарал забраната за прекъсвания, от нея няма никаква файда щото така или иначе не може да имаш premeption. Отделно, ако си забелязал идеята - може един или два регистъра да се заделят само за кърнела. Това спестява още инструкции, но това е компромис, който може да направиш само ако не ползваш чужд код като мен. Това е основната причина да имам по-кратък switch спрямо кокосите (които също са preemptive и затова се сравнявам с тях).
На това трябва да обърне внимание и Пирев, защото при MIPS стандартно има заплюти два регистъра за ОС и ще е грехота да не се възползва ;-)


Чет Мар 29, 2012 12:14 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: ARM assembler to C
Извинявай - грешно съм се изразил - исках да напиша, че и моето е с preemptivе multitasking, ама имам и функция която 'ръчно' да превключи на следващия таск. Приоритетите нарочно ги махнах за да опростя нещата - честно казано досега не ми се е налагало да ползвам приоритети така, че компромиса беше лесен (не казвам, че няма смисъл от тях, просто на мен не ми трябват). Отделно не ползвам double linked list, ами single linked cyclic list с указател към последния елемент, вместо към първия. По този начин добавянето към опашката е елементарно, а достъпа до главата е през един указател повече. И шедулера не прави никакви калкулации кой да е следващия таск - просто се мести една позиция в кръговия лист. Като се налага някой таск да поспи повече време се разкача от списъка с активни задачи и се закача в друг списък на чакащи. Ако чака някой мутекс, пак така. Прекъсванията ми трябват за да синхронизирам достъпа до таск листа. Ако не беше приемптив мултитаскинг наистина няма смисъл от пипането им.

_________________
Мразя да мразя ...


Пет Мар 30, 2012 2:09 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 18 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: Google [Bot] и 31 госта


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

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