This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: Re: Serial Driver + Multithreading


>"Chris C." wrote:
>> 
>> 1. only transmit  to pc (in loop)
>> 2. only receive from pc
>> 3. transmit to (in loop) and receive from pc (hold on the enter key to
send
>> a block of data)
>> 
>> In case 1 and 2, the serial driver can work fine but it can't work in
case
>> 3. The problem occured in case 3 was that it can work correctly within a
>> short time and then it can't do the transmit and receive. I use the
Ctrl+C
>> to break the program, I always see it break in the idle_thread_main.
>> 
>> What is the possible problem that cause the program run into this
function?
>
>You could look at the eCos at91 serial driver anyway for comparison
>purposes. Without seeing your ISR/DSR it would be difficult to guess
>anyway.
>
>> What is the best way to do the debugging?
>
>Use "info threads" to list other threads than the idle thread, and then the
>"thread" command to switch GDB's view of threads. Type "help" to get more
>information on GDB commands, or read the GDB manual.
>
>Jifl

Sorry for placing the long code here. Do you know what wrong with the code
or the possible problem that cause this driver can't run in case 3?

static cyg_uint32 
at91eb40_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
    serial_channel *chan = (serial_channel *)data;    
    at91eb40_serial_info *l_pAT91_info = (at91eb40_serial_info
*)chan->dev_priv;    
    volatile USART_REGS *l_pUSART = ((USART_REGS *) l_pAT91_info->base);

    cyg_drv_interrupt_mask(vector);
    l_pAT91_info->intrStatus = (l_pUSART->US_IMR & l_pUSART->US_CSR);
    
    if ((l_pAT91_info->intrStatus & US_TIMEOUT) != 0)
    {
        if (l_pUSART->US_RCR != l_pAT91_info->rx_buf_size)
        {
            l_pUSART->US_RCR = 0;   // disable rx buffer
            
            switch (l_pAT91_info->current_buf)
            {
            case BUF_0:
                l_pAT91_info->rxByte = l_pUSART->US_RPR -
l_pAT91_info->rx_buf0_base_address;
                l_pUSART->US_RPR = l_pAT91_info->rx_buf1_base_address;
                l_pUSART->US_RCR = l_pAT91_info->rx_buf_size;
                l_pAT91_info->pRxBUF = (cyg_uint8 *)
l_pAT91_info->rx_buf0_base_address;
                l_pAT91_info->current_buf = BUF_1;
                //HAL_DIAG_LED(2);
                break;
            case BUF_1:
                l_pAT91_info->rxByte = l_pUSART->US_RPR -
l_pAT91_info->rx_buf1_base_address;
                l_pUSART->US_RPR = l_pAT91_info->rx_buf0_base_address;
                l_pUSART->US_RCR = l_pAT91_info->rx_buf_size;
                l_pAT91_info->pRxBUF = (cyg_uint8 *)
l_pAT91_info->rx_buf1_base_address;
                l_pAT91_info->current_buf = BUF_0;
                //HAL_DIAG_LED(4);
                break;
            }

            l_pAT91_info->buf_empty = false;
            HAL_DIAG_LED(2);
        }
          
        l_pUSART->US_RTOR = l_pAT91_info->rx_timeout;
        l_pUSART->US_CR = US_STTTO; // start rx time-out
    }
    else if ((l_pAT91_info->intrStatus & US_ENDRX) != 0)
    {
        l_pUSART->US_RTOR = 0;
        
        switch (l_pAT91_info->current_buf)
        {
        case BUF_0:
            l_pUSART->US_RPR = l_pAT91_info->rx_buf1_base_address;
            l_pUSART->US_RCR = l_pAT91_info->rx_buf_size;
            l_pAT91_info->pRxBUF = (cyg_uint8 *)
l_pAT91_info->rx_buf0_base_address;
            l_pAT91_info->current_buf = BUF_1;
            break;
        case BUF_1:
            l_pUSART->US_RPR = l_pAT91_info->rx_buf0_base_address;
            l_pUSART->US_RCR = l_pAT91_info->rx_buf_size;
            l_pAT91_info->pRxBUF = (cyg_uint8 *)
l_pAT91_info->rx_buf1_base_address;
            l_pAT91_info->current_buf = BUF_0;
            break;
        }
        
        l_pAT91_info->rxByte = l_pAT91_info->rx_buf_size;
        l_pUSART->US_RTOR = l_pAT91_info->rx_timeout;
        l_pUSART->US_CR = US_STTTO;
        l_pAT91_info->buf_empty = false;
    }

    cyg_drv_interrupt_acknowledge(vector);
    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
}

static void       
at91eb40_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t
data)
{
    serial_channel *chan = (serial_channel *)data;    
    at91eb40_serial_info *l_pAT91_info = (at91eb40_serial_info
*)chan->dev_priv;    
    volatile USART_REGS *l_pUSART = ((USART_REGS *) l_pAT91_info->base);
    
    static int chars_avail = 0;

    if (l_pAT91_info->buf_empty == false)
    {
        cyg_uint16 l_totalBytes = l_pAT91_info->rxByte;
        int l_loop = 0;
        
        for (l_loop = 0; l_loop < l_totalBytes; l_loop++)
            (chan->callbacks->rcv_char)(chan, l_pAT91_info->pRxBUF[l_loop]);
  
        l_pAT91_info->buf_empty = true;
    }
    else if ((l_pAT91_info->intrStatus & US_ENDTX) != 0)
    {
        xmt_req_reply_t l_bufferEmpty;
        
        (chan->callbacks->data_xmt_done)(chan, chars_avail);
        l_bufferEmpty = (chan->callbacks->data_xmt_req)
                        (chan, l_pAT91_info->tx_buf_size, &chars_avail,
(unsigned char**) &l_pUSART->US_TPR);
        
        switch (l_bufferEmpty)
        {
        case CYG_XMT_OK:
            l_pUSART->US_TCR = chars_avail;
            break;
        case CYG_XMT_EMPTY:
            l_pUSART->US_TCR = 0;
            chars_avail = 0;
            break;
        }
    }

    cyg_drv_interrupt_unmask(vector);
}

Thank you very much!

----------------------------------------------------
Chris

_________________________________________________________________________
Sure, you can have free email. But free Email, Voicemail and Faxmail?
Check it out at http://www.2bzd.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]