luoyiming1984 发表于 2012-4-28 17:12:42

LPC2142做的一个基于RTX操作系统的UART程序,数据量大了会错

#define INT_LOCK(p)   do{p = VICIntEnable;VICIntEnClr = (U32)0xFFFFFFFF;}while(0)
#define INT_UNLOCK(p)   do{VICIntEnable = p;}while(0)


typedef struct{
        OS_SEM rxSem;
        INT16U rxFill;
        INT8U*rxPush;
        INT8U*rxPop;
        INT8UrxBuf;
        INT8U   rxTick;
       
        OS_SEM txSem;
        INT16U txFree;
        INT8U*txPush;
        INT8U*txPop;
        INT8UtxBuf;
        INT8UtxTick;
}UartQueue_t;



UartQueue_t UartQueue0;
UartQueue_t UartQueue1;


static void UartQueueInit(UartQueue_t* queue)
{
        os_sem_init (queue->rxSem, 0);
        queue->rxFill = 0;
        queue->rxPush = queue->rxBuf;
        queue->rxPop= queue->rxBuf;
        queue->rxTick = 0;
       
        os_sem_init (queue->txSem, UART_TX_SIZE);
        queue->txFree = UART_TX_SIZE;
        queue->txPush = queue->txBuf;
        queue->txPop= queue->txBuf;
        queue->txTick = UART_TX_EMPTY;
}


static BOOL UartRxPush(INT8U c,UartQueue_t* queue)   //in isr
{
        if(queue->rxFill < UART_RX_SIZE)
        {
                *queue->rxPush = c;
                queue->rxPush++;
                if(queue->rxPush == (queue->rxBuf + UART_RX_SIZE))
                {
                        queue->rxPush = queue->rxBuf;
                }               
                queue->rxFill++;
                isr_sem_send(queue->rxSem);
                return TRUE;
        }
        return FALSE;
}


static BOOL UartTxPop(INT8U *c,UartQueue_t* queue)   //in isr
{
        if(queue->txFree < UART_TX_SIZE)
        {
                isr_sem_send(queue->txSem);
                queue->txFree++;
                queue->txPop++;
                if(queue->txPop == (queue->txBuf + UART_TX_SIZE))
                {
                        queue->txPop = queue->txBuf;
                }
                if(queue->txFree < UART_TX_SIZE)
                {
                        *c = *queue->txPop;
                        return TRUE;
                }
        }
        return FALSE;
}


//run in task
static BOOL UartRxPop(INT8U *c,UartQueue_t* queue,INT16U timeout)
{
        if(OS_R_TMO != os_sem_wait(queue->rxSem,timeout))
        {
                INT32U p;
                INT_LOCK(p);
                if(queue->rxFill)
                {
                        *c = *queue->rxPop;
                        queue->rxPop++;
                        if(queue->rxPop == (queue->rxBuf + UART_RX_SIZE))
                        {
                                queue->rxPop = queue->rxBuf;
                        }
                        queue->rxFill --;
                }                       
                INT_UNLOCK(p);
                return TRUE;
        }
        return FALSE;
}





//run in task
static BOOL UartTxPush(INT8U c,UartQueue_t* queue,INT16U timeout)
{
        if(OS_R_TMO != os_sem_wait(queue->txSem,timeout))
        {
                INT32U p;
                INT_LOCK(p);
                if(queue->txFree)
                {
                        *queue->txPush = c;
                        queue->txPush++;
                        if(queue->txPush == (queue->txBuf + UART_TX_SIZE))
                        {
                                queue->txPush = queue->txBuf;
                        }
                        queue->txFree--;
                }
                INT_UNLOCK(p);
                return TRUE;
        }
        return FALSE;
}


/*
static INT16U UartRxFill(UartQueue_t* queue)
{
        return queue->rxFill;
}


//
static INT16U UartTxFree(UartQueue_t* queue)
{
        return queue->txFree;
}
*/


/*
INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)


*/
INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
        INT16U n;
        UartQueue_t *pqueue;
        tsk_lock();
        switch(port)
        {
                case PORT_UART0:
                        pqueue = &UartQueue0;
                break;
               
                case PORT_UART1:
                        pqueue = &UartQueue1;               
                break;
        }
       
        UartQueue0.rxTick = 0;
       
        for(n=0;n<size;n++)
        {
                if(FALSE == UartRxPop(buf,pqueue,timeout))
                {
                        break;
                }
                buf++;
        }
        tsk_unlock();
        return n;
}



INT16U UartWrite(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
        INT16U n = 0;
        UartQueue_t *pqueue;
        INT8Uch,*thr;
        INT32U *ier;
       
        tsk_lock();
       

       
        switch(port)
        {
                case PORT_UART0:
                {
                        pqueue = &UartQueue0;
                        thr = (INT8U*)&U0THR;
                        ier = (INT32U*)&U0IER;
                }
                break;
               
                case PORT_UART1:
                {
                        pqueue = &UartQueue1;
                        thr = (INT8U*)&U1THR;
                        ier = (INT32U*)&U1IER;
                }
                break;
        }
       
        *ier &= ~0x02;
        ch = *buf;
        for(n=0;n<size;n++)
        {
                if(FALSE == UartTxPush(*buf,pqueue,0))
                {
                        break;
                }
                buf++;
        }
        if(UART_TX_EMPTY == pqueue->txTick)
        {
                *thr = ch;
                pqueue->txTick = UART_TX_FULL;
        }
        *ier |= 0x02;
       
        for(;n<size;n++)
        {
                if(FALSE == UartTxPush(*buf,pqueue,timeout))
                {
                        break;
                }
                buf++;
        }
       
        tsk_unlock();
        return n;
}



/*---- UART 0 INTERRUPT ----*/
void UART0_IRQ(void) __irq
{
        INT32U INT_ID;
        INT8U i;
        INT_ID = U0IIR & 0x0E;
        if ((0x04 == INT_ID) || (0x0C == INT_ID))
        {
                /* Receive interrupt */
                for(i=0;i<16;i++)
                {
                        if ((U0LSR & 0x01)==0)
                        {
                                break;
                        }
                        UartRxPush(U0RBR,&UartQueue0);
                }
                UartQueue0.rxTick = i;
        }
                                    
        else if (0x02 == INT_ID)
        {
                INT8U c;
                /* Transmit interrupt */
                for(i=0;i<16;i++)
                {
                        if(FALSE == UartTxPop(&c,&UartQueue0))
                        {
                                UartQueue0.txTick = UART_TX_EMPTY;
                                break;
                        }
                        U0THR = c;
                }
        }
        VICVectAddr = 0;                  /* Acknowledge Interrupt               */       
}



/*---- UART 1 INTERRUPT ----*/

void UART1_IRQ(void) __irq
{
        INT32U INT_ID;
        INT8U i;
        INT_ID = U1IIR & 0x0E;
        if ((0x04 == INT_ID) || (0x0C == INT_ID))
        {
                /* Receive interrupt */
                for(i=0;i<16;i++)
                {
                        if ((U1LSR & 0x01)==0)
                        {
                                break;
                        }
                        UartRxPush(U1RBR,&UartQueue1);
                }
                UartQueue1.rxTick = i;
        }
                                    
        else if (0x02 == INT_ID)
        {
                INT8U c;
                /* Transmit interrupt */
                for(i=0;i<16;i++)
                {
                        if(FALSE == UartTxPop(&c,&UartQueue1))
                        {
                                UartQueue1.txTick = UART_TX_EMPTY;
                                break;
                        }
                        U1THR = c;
                }
        }
        VICVectAddr = 0;                  /* Acknowledge Interrupt               */       
}




/*UART INIT */
void UartIntiFonfig(INT8U port,INT8U slot,INT32U baud)
{
        if(port == PORT_UART0)
        {
    PINSEL0 &= 0xFFFFFFF0;
    PINSEL0 |= 0x00000005;
                PCONP = PCONP|0x08;
    U0LCR = 0x83;
    U0DLM = (FPCLK / 16) / baud / 256;
    U0DLL = (FPCLK / 16) / baud % 256;
    U0LCR = 0x03;
       
                U0FCR = 0x87;
                U0IER = 0x03;
    *(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART0_IRQ;
    *(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART0);
    VICIntEnable = (INT32U)(1 << VIC_UART0);
                UartQueueInit(&UartQueue0);
        }
        else if(port == PORT_UART1)
        {
    PINSEL0 &= 0xFFFFFFF0;
    PINSEL0 |= 0x00000005;
                PCONP = PCONP|0x08;
    U1LCR = 0x83;
    U1DLM = (FPCLK / 16) / baud / 256;
    U1DLL = (FPCLK / 16) / baud % 256;
    U1LCR = 0x03;
       
                U1FCR = 0x87;
                U1IER = 0x03;
    *(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART1_IRQ;
    *(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART1);
    VICIntEnable = (INT32U)(1 << VIC_UART1);
                UartQueueInit(&UartQueue1);               
        }
}
页: [1]
查看完整版本: LPC2142做的一个基于RTX操作系统的UART程序,数据量大了会错