Сергей Борщ 143 15 мая, 2006 Опубликовано 15 мая, 2006 · Жалоба Написал порт scmRTOS (http://scmrtos.narod.ru/) для ARM. Отлаживал на AT91SAM7S64. Поскольку опыта в ARMах пока маловато (второй проект на ARM и первый с асмом), то перед тем как связываться с автором хотелось бы чтобы кто-то более опытный глянул. Порт лежит тут: http://upload.caxapa.ru/scmRTOS_arm.zip Спасибо всем. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pat 0 15 мая, 2006 Опубликовано 15 мая, 2006 · Жалоба чтобы кто-то более опытный глянул. Порт лежит тут: Я не шибко опытный, но что то компилер не находит идентификатор AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 15 мая, 2006 Опубликовано 15 мая, 2006 · Жалоба >Я не шибко опытный, но что то компилер не находит идентификатор AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE. Виноват, ставил патч от ИАРа. #ifndef AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE #define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED #endif Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pat 0 15 мая, 2006 Опубликовано 15 мая, 2006 · Жалоба Скомпилир все ОК. Запускаю отладку в симуляторе. После выполнения подпрограммы в файле OS_Target_asm.s79 ContextRestore MOV LR, R0 ; use LR_svc as stack pointer LDMFD LR!, {R0} ; pop saved CPSR MSR SPSR_cxsf, R0 ; LDMFD LR, {R0-LR}^ ; restore all regs and reti NOP ADD LR, LR, #15*4 LDMFD LR, {PC}^ ; reti Улетает в неизвесном направлении. Еще не хочет компилироваться в режиме ARM пишет Internal Error: [symbol_lookup_M31]: symbol not found for mode 1 (backend generating) (P0: 0, P1: 0) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 15 мая, 2006 Опубликовано 15 мая, 2006 · Жалоба Скомпилир все ОК. Запускаю отладку в симуляторе. После выполнения подпрограммы в файле OS_Target_asm.s79 Улетает в неизвесном направлении. Действительно. Хотя в железе работает. Завтра попробую найти где разница и кто же работает правильно - ядро или симулятор :-). Кстати, в симуляторе не будут вызываться прерывания таймера со всеми вытекающими. Еще не хочет компилироваться в режиме ARM пишет Internal Error: [symbol_lookup_M31]: symbol not found for mode 1 (backend generating) (P0: 0, P1: 0) компилятор падает от конструкции if(SysTickCount == 146) __no_operation(); в void OS::TKernel::SystemTimer(). Это рудимент - я ошибку искал. Но почему такая безобидная конструкция выбивает компилятор - наверное вопрос к его разработчикам. Причем __no_operation() без условия или другое действие в условии компилится нормально. В общем выкинуть этот кусок кода. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Запускаю отладку в симуляторе. После выполнения подпрограммы в файле OS_Target_asm.s79 Улетает в неизвесном направлении. Проблема в команде LDMFD LR, {R0-LR}^ ; restore all regs and reti (коментарий в ней конечно неправильный) согласно документу ARM DDI 0029E: LDM with R15 in transfer list and S bit set (Mode changes) If the instruction is a LDM then SPSR_<mode> is transferred to CPSR at the same time as R15 is loaded. R15 not in list and S bit set (User bank transfer) For both LDM and STM instructions, the User bank registers are transferred rather than the register bank corresponding to the current mode. В данной же ситуации симулятор загружает SPSR_irq в CPSR хотя R15 отсутствует в списке регистров. Получается это ошибка симулятора. Или я где-то недопонял? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба В данной же ситуации симулятор загружает SPSR_irq в CPSR хотя R15 отсутствует в списке регистров. Данная команда в любом случае должна перегрузить CPSR. Если в списке будет R15, то они обновятся одновременно. Это делается в обработчиках прерываний. Если R15 в списке нету, то выполнение продолжится дальше, но CPSR будет перегружен, при этом сменится режим привилегий и банк регистров на тот, который был указан в SPSR. Вы вообще сами написали этот ASM-файл или сильно переделали чужой? Каким-то очень страшным он мне показался. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба В данной же ситуации симулятор загружает SPSR_irq в CPSR хотя R15 отсутствует в списке регистров. Данная команда в любом случае должна перегрузить CPSR. Странно, но почему-то в моем макете с AT91SAM7S64 при отладке через MT-Link перегрузки CPSR не происходит. Могу попробовать на LPC2119, но не думаю что будет большая разница. Если в списке будет R15, то они обновятся одновременно. Это делается в обработчиках прерываний. Пробовал так (через MT-Link). Получалось что загружаются привилегированные регистры после чего переключается режим и SP, LR содержат совсем не то. Вы вообще сами написали этот ASM-файл или сильно переделали чужой? Каким-то очень страшным он мне показался. Первый блин :-) Поэтому и прошу советов что можно сделать лучше. Долго смотрел на переключатель контекстов FreeRTOS, потом правил файл порта от MSP430. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Напишите комментарии в ASM-файле к каждой команде. И ещё отдельно текстом что вообще должен делать этот файл. (каждая точка входа (Public Name)) Может тогда я смогу помочь исправить. А то ооочень трудно воспринимаемая прога. Код перемешан с какими-то отладочными командами. А вообще, я писал пол года назад на асме что-то похожее. Там была организована мультизадачность с временным разделением. Для каждой задачи был свой стек и сохранялся контекст. Очень быстрая (2 мкс переключение задач), но без каких-либо наворотов. Все задачи писались как обычные процедуры на Си, только прерывание переключения задач на асме. Процессор LPC2138. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Вопрос: почему у вас в xcl-файле начальные адреса RAM и ROM совпадают? У 7-ых армов одно общее адресное пространство, поэтому адреса должны быть разными. В LPC-шке ROM начинается с 0x00, а внутренняя RAM с 0x40000000. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Напишите комментарии в ASM-файле к каждой команде.все описал, отладочное убрал. Вопрос: почему у вас в xcl-файле начальные адреса RAM и ROM совпадают?Проект отлаживаю в ОЗУ, файл .xcl из ИАРовского примера для проекта в ОЗУ.src.zip Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Всё-равно как-то запутанно. Попробуйте разобраться с моим обработчиком. Может переделаете после этого свой. MODULE MULTI_TASK PUBLIC TASK_IRQ EXTERN TASK_DATA RSEG IRQ_STACK RSEG ICODE CODE32 VIC_ORG EQU 0xFFFFF000 VICSoftInt EQU 0xFFFFF018 VICSoftIntClear EQU 0xFFFFF01C VICVectAddr EQU 0xFFFFF030 VIC_TIMER1 EQU 5 T1_ORG EQU 0xE0008000 T1IR EQU 0xE0008000 T1TC EQU 0xE0008008 T1MR0 EQU 0xE0008018 TASK_IRQ: sub lr,lr,#4 stmdb sp!,{lr} mrs lr,SPSR stmdb sp!,{r12,lr} mov r12,sp ; указатель в стеке IRQ msr CPSR_cf,lr ; перек. в SYSTEM с разреш. прерыван. stmdb sp!,{r0-r11,lr} ldmia r12!,{r9-r11} stmdb sp!,{r9-r11} ; R12, CPSR, PC ldr lr,=TASK_DATA+8 ldr r11,[lr,#-4] ; TaskCur str sp,[lr,+r11,LSL #3] add r11,r11,#1 ldr r10,[lr,#-8] ; TaskMax cmp r11,r10 bcc TaskIrq50 mov r11,#0 TaskIrq50: str r11,[lr,#-4] ; TaskCur add lr,lr,r11,LSL #3 TaskIrq60: ldr sp,[lr,#+0] ; указатель SP новой задачи ldr r11,[lr,#+4] ; период задачи в тиках ldr lr,=T1_ORG str r11,[lr, #+T1MR0 - T1_ORG] mov r11,#0 str r11,[lr, #+T1TC - T1_ORG] ; сброс таймера в 0 mov r11,#0xff str r11,[lr, #+T1IR - T1_ORG] ; сброс установленных битов ldmia sp!,{r9-r11} stmdb r12!,{r9-r11} ; R12, CPSR, PC ldmia sp!,{r0-r11,lr} mrs r12,CPSR orr r12,r12,#0xD2 bic r12,r12,#0x0D msr cpsr_cf,r12 ; перезагрузка LR и SP ldr r12,=VIC_ORG mov lr,#(1 << VIC_TIMER1) str lr,[r12,#+VICSoftIntClear - VIC_ORG] str lr,[r12,#+VICVectAddr - VIC_ORG]; сброс приоритетов VIC ldmia sp!,{r12,lr} msr SPSR_cf,lr ldmia sp!,{pc}^ LTORG END ____________________________________ Из си-шного файла: #define TaskMax 3 typedef struct { void (*Task)(); xLong Ticks; } st_task_rec; typedef struct { xLong Max; xLong Cur; st_task_rec List[TaskMax]; } st_task; st_task TASK_DATA; void RegisterTask(void (*task)(), xInt prior) { static const xLong priorTime[speedTaskMax] = {PCLKFREQ/50,PCLKFREQ/100,PCLKFREQ/200}; if (TASK_DATA.Max >= TaskMax) return; if (prior >= SpeedTaskMax) prior = SpeedTaskMax-1; TASK_DATA.List[TASK_DATA.Max].Task = task; TASK_DATA.List[TASK_DATA.Max++].Ticks = priorTime[prior]; } Вообще, у каждой задачи свой стек, в котором по прерыванию таймера (или по команде симуляции аппаратного прерывания) сначала сохраняется контекст (R0-R12,LR, SP, CPSR_main, PC), затем происходит переключение на стек новой задачи и обратная загрузка контекста и переход на прерванную задачу. При всём этом немного используется IRQ-стек. Иначе нельзя. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Всё-равно как-то запутанно. Попробуйте разобраться с моим обработчиком. Может переделаете после этого свой. Спасибо, изучу. Сходу нарвался на ошибку: sub lr,lr,#4 ; подвинули адрес возврата stmdb sp!,{lr}; сохранили его на стеке прерываний mrs lr,SPSR ; взяли CPSR процесса в LR stmdb sp!,{r12,lr}; сохранили его и R12 mov r12,sp ; указатель в стеке IRQ msr CPSR_cf,lr ; перек. в SYSTEM с разреш. прерыван. ; а также в THUMB если процесс был в THUMB ; тут все и упало Проблема еще и в том, что scmRTOS написана на С++ и там к данных объектов добраться из АСМа в общем случае нельзя (или настоятельно не рекомендуется - я так понял). При всём этом немного используется IRQ-стек. Иначе нельзя. Ну, у меня кажется получилось :-) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба msr CPSR_cf,lr ; перек. в SYSTEM с разреш. прерыван. ; а также в THUMB если процесс был в THUMB ; тут все и упало Не, разумеется вы это должны доработать. В моей системе THUMB задачи не использовались. Важна была скорость исполнения, а размер не существеннен. Добавьте сброс THUMB-бита. А команды сохранения и восстановления контекста как бы парные (точнее префиксы stmDB и ldmIA). У вас они почему-то одни и те же. К тому же лишние инкременты указателей после этих команд, когда всё это можно сделать прямо в команде. Кстати, 12 байт используемых в стеке IRQ - это просто смешно как мало. Разбирайтесь. Если что - пишите сюда. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spf 0 17 мая, 2006 Опубликовано 17 мая, 2006 · Жалоба Первый блин :-) Поэтому и прошу советов что можно сделать лучше. Долго смотрел на переключатель контекстов FreeRTOS, потом правил файл порта от MSP430.Еще думаю можно посмотреть на порты uCOS-II для ARM. (http://www.ucos-ii.com/) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться