QUOTE (derstik @ May 9 2012, 09:29)

Может кто поднимал usb под scmrtos?
Я не поднимал, но если у вас несколько источников системного прерывания, то вы можете написать свой обработчик, из которого вызывать и обработчик системного таймера и обработчики остальных устройств. Примерно так:
CODE
OS_INTERRUPT void Sys_IRQ_handler()
{
OS::TISRW ISR;
SYSTEM_TIMER_HANDLER();
Receiver_uart.handler();
IRQ_DONE();
}
В обработчиках остальных устройств надо будет проанализировать флаг, на предмет - ваш ли источник вызвал системное прерывание. В обработчике системного таймера такой анализ есть (если это не прерывание от таймера, Tmp будет равен нулю):
CODE
// SYSTEM_TIMER_HANDLER(): while() used instead of do-while()
// to allow other interrupt sources on AT91C_ID_SYS.
// Write your own handler instead of OS::system_timer_isr() to handle other SYS sources
#define SYSTEM_TIMER_HANDLER() \
do \
{ \
volatile uint32_t Tmp = AT91C_BASE_PITC->PITC_PIVR >> 20; \
while (Tmp) \
{ \
--Tmp; \
OS::system_timer_handler(); \
} \
} \
while(0)
Вот так у меня сделан обработчик DBGU:
CODE
template<uint_fast8_t rx_size, uint_fast8_t tx_size>
void uart<rx_size, tx_size>::handler()
{
uint32_t Flags = pUART->US_CSR;
Flags &= pUART->US_IMR;
if(Flags & AT91C_US_TXRDY)
{
if(Tx_buffer.get_count())
{
uint8_t Data;
Tx_buffer.pop(Data, 1);
pUART->US_THR = Data;
}
else
pUART->US_IDR = AT91C_US_TXRDY;
}
if(Flags & AT91C_US_RXRDY)
{
uint8_t Data = pUART->US_RHR; // read anyway
pUART->US_CR = AT91C_US_RSTSTA; // clear errors if any
if(Rx_buffer.get_free_size())
Rx_buffer.push(Data);
}
}
Думаю, что совершенно необязательно отказываться от PIT в качестве системного таймера - ведь разработчики кристалла предполагали совместное использование нескольких источников на системном прерывании.