|
|
  |
Написал порт scmRTOS под ARM, интересны отзывы |
|
|
|
May 15 2006, 17:20
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Скомпилир все ОК. Запускаю отладку в симуляторе. После выполнения подпрограммы в файле 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)
|
|
|
|
|
May 15 2006, 17:44
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Pat @ May 15 2006, 20:20)  Скомпилир все ОК. Запускаю отладку в симуляторе. После выполнения подпрограммы в файле 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() без условия или другое действие в условии компилится нормально. В общем выкинуть этот кусок кода.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2006, 14:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Pat @ May 15 2006, 20:20)  Запускаю отладку в симуляторе. После выполнения подпрограммы в файле 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 отсутствует в списке регистров. Получается это ошибка симулятора. Или я где-то недопонял?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2006, 15:43
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата В данной же ситуации симулятор загружает SPSR_irq в CPSR хотя R15 отсутствует в списке регистров. Данная команда в любом случае должна перегрузить CPSR. Если в списке будет R15, то они обновятся одновременно. Это делается в обработчиках прерываний. Если R15 в списке нету, то выполнение продолжится дальше, но CPSR будет перегружен, при этом сменится режим привилегий и банк регистров на тот, который был указан в SPSR. Вы вообще сами написали этот ASM-файл или сильно переделали чужой? Каким-то очень страшным он мне показался.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 16 2006, 16:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ May 16 2006, 18:43)  Цитата В данной же ситуации симулятор загружает SPSR_irq в CPSR хотя R15 отсутствует в списке регистров. Данная команда в любом случае должна перегрузить CPSR. Странно, но почему-то в моем макете с AT91SAM7S64 при отладке через MT-Link перегрузки CPSR не происходит. Могу попробовать на LPC2119, но не думаю что будет большая разница. Цитата Если в списке будет R15, то они обновятся одновременно. Это делается в обработчиках прерываний. Пробовал так (через MT-Link). Получалось что загружаются привилегированные регистры после чего переключается режим и SP, LR содержат совсем не то. Цитата Вы вообще сами написали этот ASM-файл или сильно переделали чужой? Каким-то очень страшным он мне показался. Первый блин :-) Поэтому и прошу советов что можно сделать лучше. Долго смотрел на переключатель контекстов FreeRTOS, потом правил файл порта от MSP430.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2006, 18:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ May 16 2006, 19:32)  Напишите комментарии в ASM-файле к каждой команде. все описал, отладочное убрал. Цитата(GetSmart @ May 16 2006, 21:09)  Вопрос: почему у вас в xcl-файле начальные адреса RAM и ROM совпадают? Проект отлаживаю в ОЗУ, файл .xcl из ИАРовского примера для проекта в ОЗУ.
Прикрепленные файлы
src.zip ( 2.34 килобайт )
Кол-во скачиваний: 63
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2006, 19:17
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Всё-равно как-то запутанно. Попробуйте разобраться с моим обработчиком. Может переделаете после этого свой.
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-стек. Иначе нельзя.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 16 2006, 19:57
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ May 16 2006, 22:17)  Всё-равно как-то запутанно. Попробуйте разобраться с моим обработчиком. Может переделаете после этого свой. Спасибо, изучу. Сходу нарвался на ошибку: Код 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-стек. Иначе нельзя. Ну, у меня кажется получилось :-)
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2006, 20:20
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата msr CPSR_cf,lr ; перек. в SYSTEM с разреш. прерыван. ; а также в THUMB если процесс был в THUMB ; тут все и упало Не, разумеется вы это должны доработать. В моей системе THUMB задачи не использовались. Важна была скорость исполнения, а размер не существеннен. Добавьте сброс THUMB-бита. А команды сохранения и восстановления контекста как бы парные (точнее префиксы stmDB и ldmIA). У вас они почему-то одни и те же. К тому же лишние инкременты указателей после этих команд, когда всё это можно сделать прямо в команде. Кстати, 12 байт используемых в стеке IRQ - это просто смешно как мало. Разбирайтесь. Если что - пишите сюда.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|