Ответ: небольшой примерчик (как сохранять стек возвратов)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Pol-SDG 22 января 2004 г. 14:19
В ответ на: Принцип действия многозадачных систем реального времени отправлено ДМ 22 января 2004 г. 00:04


Вот тебе реальный пример процедурки которая переключает стеки задач.
(для ix86).

// индекс текущей задачи
unsigned int tic;

// маска состояния задач
unsigned int tsw;

// массив базовых адресов задач
unsigned int tasks_ba[tcnt];

// если используется модель памяти LARGE
// используем дополнительный массив под хранение значений сегментов стека
#ifdef __LARGE__
unsigned int tasks_ss[tcnt];
#endif

// процедура планировщика
// переключение задач по кругу
// так как sheduler может быть вызван не только при обработке прерывания
// но и из задачи то для совместимости с Standart Stack Frame и Register Variables
// регистры bp sp si di сохраняются в контексте задачи
void sheduler(void){ // push bp ; mov bp, sp; push si ; push di ;
if (REF_WDT)
RefreshWDT();
asm {
// cli
mov ax, word [tic] // индекс текущей задачи
mov di, ax
shl di, 1
mov word [tasks_ba+di], sp // сохраняем указатель стека в базовом адресе задачи
#ifdef __LARGE__
mov word [tasks_ss+di], ss // сохраняем сегмент стека
#endif
}
next:
asm {
// переключаемся на следующую задачу
inc ax
cmp ax, tcnt
jb endif
xor ax, ax // ax=0
}
endif:
asm {
// проверяем состояние этой задачи (кроме базовой)
mov di, 1
or ax, ax
jz nottest

mov cx, ax
}
step:
asm {
shl di, 1
loop step
and di, word [tsw]
jz next
}
nottest:
asm {
mov word [tic], ax
mov si, ax
shl si, 1
mov sp, word [tasks_ba+si]
#ifdef __LARGE__
mov ss, word [tasks_ss+si] // сохраняем указатель в базовом адресе задачи
#endif

}
} // pop di; pop si; pop bp; ret;

pre/>

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru