Цитата(nemo777 @ Aug 25 2009, 18:10)

как используются функции OSIntEnter(), OSIntExit() ?
Вот обработчик из отдельного асмового файла. BSP_USARTC0_RXC_IRQ_Hndlr - мой обработчик прерывания. Изначально взят из порта, скачанного с Micriuma, изменил только ссылку на свой обработчик.
BSP_USARTC0_RXC_IRQ_vect:
CLI ; Disable Global Interrupts to avoid breaking context save
PUSH_ALL ; Save all registers and status register
PUSH_SREG_INT ; Save the SREG but with interrupts enabled
PUSH_SP ; Save the task's hardware stack pointer onto task's stack
LDS R16,OSIntNesting ; Notify uC/OS-II of ISR
INC R16 ;
STS OSIntNesting,R16 ;
CPI R16,1 ; if (OSIntNesting == 1) {
BRNE BSP_USARTC0_RXC_IRQ_vect_1
LDS R30,OSTCBCur ; OSTCBCur->OSTCBStkPtr = Y
LDS R31,OSTCBCur+1
ST Z+,R28
ST Z+,R29 ; }
BSP_USARTC0_RXC_IRQ_vect_1:
CALL BSP_USARTC0_RXC_IRQ_Hndlr ; Call Handler written in C
CALL OSIntExit ; Notify uC/OS-II about end of ISR
POP_SP ; Restore the hardware stack pointer from task's stack
POP_SREG_INT ; Restore status register (DISABLE interrupts)
POP_ALL ; Restore all registers
SEI ; Enable interrupts, since RETI does not on Xmega
RETI
Цитата(Vladimir_T @ Aug 25 2009, 20:25)

Непосредственно из прерывания сервисы ОС вызывать нельзя. Можно находясь в прерывании вызвать вспомогательную функцию в которой и устанавливается, например, семафор:
OSSemPost (Sem_LCD); // установить семафор для прорисовки дисплея
В отладчике можно проследить за переменной-семафором.
Сейчас попробовал - не работает. Смотрю в отладчике, при вызове OSSemPost параметр
pevent равен нулю и в жирном месте процедура вылетает. Если вызываю из задачи, то все нормально. Сам этот параметр при вызове располагается в регистрах R24-R25. Не может система при вызове прерывания как-нибудь кривить их?
INT8U OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore */
/* Ready HPT waiting on event */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
OS_EXIT_CRITICAL();
OS_Sched(); /* Find HPT ready to run */
return (OS_ERR_NONE);
}
if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */
pevent->OSEventCnt++; /* Increment semaphore count to register event */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */
return (OS_ERR_SEM_OVF);
}