Цитата(singlskv @ Sep 22 2006, 23:42)

Цитата(viael @ Sep 22 2006, 20:43)

Народ ну кто знает как запретить компилятору сохранять контекст(регисры) при входе в прерывание.
Я уже задавал такой вопрос в основном форуме по AVR на что получил единсвенный ответ:
Код
__raw __interrupt void my_interrupt_function(void)
{
...
}
Напишите поподробнее что Вы конкретно хотите получить.
Как Вы планируете сохранять контекст самостоятельно?
Чем не устраивает стандартный вариант ?
Хотелось бы увидеть конкретную задачу.
Конкретная задача это портировать небольшую ОС которую я написал "под себя" на CodeVision.
У меня в прерывании от к.л. таймера сидит шендулер, при входе в прерывание сохраняется контекст задачи в отведенные для нее стеки, при выходе загружается контекст наиболее приорететной задчи.
Для реализации всего этого необходимо запретить компилятору при входе в прерывания сгружать регистры в стек.
Вот так реализовано в CodeVision
Код
#pragma savereg-
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
#asm
Kernel_start:
;сохраняем контекст задачи
PUSH R0 ;рабочие регистры используемые компилятором(см.CodeVision HELP:SRAM Memory Organization)
PUSH R1
PUSH R15
PUSH R22
PUSH R23
PUSH R24
PUSH R25
PUSH R26
PUSH R27
PUSH R30
PUSH R31
IN R0,SREG
PUSH R0
mov r10,r28 ;сохраняем указатель на програмный стек
mov r11,r29
in r12,SPL ;сохраняем указатель на аппаратный стек
in r13,SPH
mov r28,r2 ;загружаем указатели на стеки используемые ядром ОС
mov r29,r3
out SPL,r4
out SPH,r5
#endasm
OS_Central_table.CurrentTask->SwPtr=OS_SwPtr;
OS_Central_table.CurrentTask->HwPtr=OS_HwPtr;
Kernel_tcb_counter=OS_Central_table.RunningTask;
Kernel_Max_prio_task=NULL;
Kernel_next_task=OS_Central_table.CurrentTask->Next_task;
Kernel_Max_prio=255;
do
{
if(OS_Sets_Delay)//если произошло прерывание обслуживаем задачи в состоянии ожидания
{
if(Kernel_next_task->status==delay)
{
if((Kernel_next_task->Task_delay)>1) Kernel_next_task->Task_delay--;
else Kernel_next_task->status=run;
}
}
if(Kernel_next_task->status==run)//запускаем самую приоритетную задачу
{ //для задач с равными приоритетами FIFO(round-robin)
if(Kernel_Max_prio>=Kernel_next_task->prio)
{
Kernel_Max_prio_task=Kernel_next_task;
Kernel_Max_prio=Kernel_next_task->prio;
Kernel_Max_prio--;
}
}
Kernel_next_task=Kernel_next_task->Next_task;
}while(--Kernel_tcb_counter);
OS_Sets_Delay=1;
OS_SwPtr=Kernel_Max_prio_task->SwPtr;
OS_HwPtr=Kernel_Max_prio_task->HwPtr;
OS_Central_table.CurrentTask=Kernel_Max_prio_task;
#asm
mov r28,r10 ;set sw stack
mov r29,r11
out SPL,r12
out SPH,r13
; Pop all registers uses compiler except SW stack pointer
POP R0
OUT SREG,R0
POP R31
POP R30
POP R27
POP R26
POP R25
POP R24
POP R23
POP R22
POP R15
POP R1
POP R0
#endasm
}
#pragma savereg+