Здраствуйте.
Попробовал недавно scmRTOS - понравилось, но толку...для xmeg поддержки нет, а хотелось бы.
Появилось желание перенести версию 3.10 на хмегу. Но возникло столько вопросов и непонятных
моментов, что кажется хотелки так хотелками и остануться...
Попытаюсь здесь изложить моменты которые, как мне кажется нужно поменять в версии и
вызывающие у меня сомнения.
хотелось бы увидеть критику/советы как сделать лучше/как делать не надо, тд и тп.
Общие для разных схем переключения контекста моменты.
1. Функции SetDataSP/GetDataSP:
Заменить на (для начала сгодится, хотя лишний call/ret, но как лучше не нашёл):
Код
GetDataSP:
mov R16, R28
mov R17, R29
ret
SetDataSP:
mov R29,R17
mov R28,R16
ret
и соотв.
Код
extern "C" {
TStackItem* GetDataSP();
};
extern "C" {
void SetDataSP(TStackItem* sp);
};
2. Добавить в контекст RAMP_XYD. С этим понятно.
3. Были тут высказаны идеи о включении в контекст
регистра разрешённых прерываний, но мне кажется что это необязательно.
Или нет?
I. Схема переключения контекста по прерыванию.
1. Добавить запрет прерыванию после перехода на вектор ContextSwitcher_ISR,
но пока не понял куда именно добавить чтоб и наверняка и критическая секция
была как можно короче?
Код
save_SREG
cli; запрет прерываний
save_SP
save_regs
save_SFRS
;cli; запрет прерываний или здесь правильней?
mov r16,r28 ; load current stack pointer
mov r17,r29
; as argument
xcall OS_ContextSwitchHook ;
mov r28,r16 ; set next stack pointer
mov r29,r17 ; from return value
2. Ещё совершенно непонятный для меня момент: каким уровнем лучше расположить
ContextSwitcher_ISR? Или не это непринципиально, а атомарность переключения?
С этой схемой как бы всё. Или нет? Тогда что я упустил?
II. Схема с прямой передачей управления.
1. Прерывания с TISRW_SS
Если я правильно понял, то в мегах выход из прерывания при переключении
реализуется таким путём:
Код
переход на вектор прерывания->
функция прерывания->
вариант 1: перепланировка не нужна->reti
вариант 2: перепланировка нужна->OS_ContextSwitcher->ret
Если использовать прерывания, использующие сервисы ОС, только одного уровня,
то можно так:
Код
OS_ContextSwitcher:
save_SREG
save_SP
save_regs
save_SFRS
mov r30,r16; Curr_SP_addr
mov r31,r17;
std Z+0,r28; save process's Stack Pointer
std Z+1,r29;
mov r28,r18; load next process Stack Pointer
mov r29,r19;
lds R16, 0x00A0; PMIC.STATUS
andi R16, 7
BRNE Int_RestoreContext
L_RestoreContext:
restore_SFRS
restore_regs
restore_SP
restore_SREG
ret
Int_RestoreContext:
restore_SFRS
restore_regs
restore_SP
restore_SREG
reti
Но решение какое-то ограниченное...
Попробовал изменить TISRW_SS
CODE
class TISRW_SS
{
public:
INLINE TISRW_SS(byte int_level) {
#if scmRTOS_CONTEXT_SWITCH_SCHEME==0
CurrentInterruptLevelMask=~int_level;
CurrentInterruptLevelMask&=scmRTOS_INTERRUPT_LEVEL_MASK;
#endif
ISR_Enter();
}
INLINE ~TISRW_SS() { ISR_Exit(); }
private:
#if scmRTOS_CONTEXT_SWITCH_SCHEME==0
byte CurrentInterruptLevelMask;
#endif
//-----------------------------------------------------
INLINE void ISR_Enter() // volatile
{
TCritSect cs;
if(Kernel.ISR_NestCount++ == 0)
{
SavedSP.DataSP = GetDataSP();
SavedSP.ReturnSP = GetReturnSP();
SetISRStackPointers();
}
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
DisableContextSwitch();
#endif
}
//-----------------------------------------------------
INLINE void ISR_Exit()
{
TCritSect cs;
if (--Kernel.ISR_NestCount==0) {
SetReturnSP(SavedSP.ReturnSP);
SetDataSP (SavedSP.DataSP);
}
#if scmRTOS_CONTEXT_SWITCH_SCHEME==0
if (PMIC.STATUS&CurrentInterruptLevelMask) return ;
#endif
Kernel.SchedISR();
}
//-----------------------------------------------------
};
Но тоже какая-та ерунда: теперь получается что все прерывания
одного уровня должны либо использовать, либо не использовать TISRW_SS.
В общем тоже костыль получился, хотя и выглядит работающим (см. приложение).
В связи с этой проблемой вопрос: можно ли заставить IAR сделать функию
прерывания ещё и __monitor (возможно ли это в хмегах вообще - запретить прерывание более
высокого уровня след. командой после перехода с вектора прерывания и будет ли этот
запрет отрабатываться)? Этот вариант завтра попробую.
Спасибо.
Нажмите для просмотра прикрепленного файла