打印
[ZLG-MCU]

uc/os-ii下的LM3S的UART问题 急急急 等待回复

[复制链接]
4283|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wahahaabc|  楼主 | 2008-5-18 22:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
UART发送使用查询式发送,也就是调用库函数UARTCharPut(),源代码如下:
void CommSendData( INT8U ch, const INT8U *ptr, INT16U nBytes )
{
      INT32U        base;

      switch (ch)
      {
            case COMM1:
            base = COMM1_BASE;
            break;

            case COMM2:
            base = COMM2_BASE;
            break;

            default:
             return;
      }

      while( nBytes-- )
      {
            UARTCharPut( base, *(ptr++) );
      }
}

UART接收采用中断方式,系统开辟一个软件接收FIFO,用一个计数型信号量跟踪这个软件接收FIFO中的有效数据个数,其流程如下:
(1)产生串口接收中断
(2)读取接收到的字符
(3)如果软件接收FIFO没有满,将读取到的字符放入软件接收FIFO中
(4)OSSemPost(计数型信号量)

在一个任务中,就可以按以下方式取出接收到的数据:
(1)OSSemPend(计数型信号量)
(2)如果步骤(1)成功,读取软件接收FIFO中的数据

现在问题描述如下:
用LM3S8962的两个UART,波特率115200,使用“捷通串口调试软件V4.1”,将串口调试软件设置为“发送周期:10ms,连续不断的自动发送”,一次发送的数据量是100个字节,之所以在10ms的周期内发送100个字节,是因为115200的波特率的通讯量极限差不多是每秒10K/S,10ms发送100个字节,则1s就发送10K字节。

打开两个“捷通串口调试软件”,每个调试软件对应到LM3S8962的一个UART,按上面的设置不断的连续发送数据,LM3S8962将接收到的数据在从相应的串口发送回来,这样发送一段时间以后,其中一个UART就会再也接收不到数据,而另一个串口还是可以正常收发。???????

出现这种情况以后,仔细调试发现。那个接收不到数据的串口的软件FIFO计数值是满的(例如:软件FIFO的大小为100,则软件FIFO计数值就是100),而那个计数型信号量却为0,这样,当产生接收中断以后,发现软件FIFO是满的,则丢弃刚收到的数据,而在一个任务中要执行下面的操作才能接收到数据:
(1)OSSemPend(计数型信号量)
(2)如果步骤(1)成功,则从软件FIFO中取出数据
因为此时计数型信号量为0,所以任务无法从软件FIFO中取数,而任务不取数,则发送接收中断以后,接收中断有发现软件fifo是满的,有不会将数据放入软件fifo。正确的情况是计数型信号量的值应该和软件FIFO中的有效数据个数完全一致。
请问这是什么原因引起的??????

代码如下:
/////////////// 产生接收中断以后,调用该函数将刚接收到的数据放入软件FIFO///////////////

void  CommPutRxChar (INT8U ch, INT8U c)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    OS_SEM_DATA sem;
    INT8U err;
    COMM_RING_BUF *pbuf;


    switch (ch) {                                          /* Obtain pointer to communications channel */
        case COMM1:
             pbuf = &Comm1Buf;
             break;

        case COMM2:
             pbuf = &Comm2Buf;
             break;

        default:
             return;
    }

    OS_ENTER_CRITICAL();

    if (pbuf->RingBufRxCtr < COMM_RX_BUF_SIZE) {           /* See if buffer is full                    */
        pbuf->RingBufRxCtr++;                              /* No, increment character count            */
        *(pbuf->RingBufRxInPtr++) = c;                     /* Put character into buffer                */
        if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) { /* Wrap IN pointer           */
            pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
        }

        OS_EXIT_CRITICAL();

        OSSemPost(pbuf->RingBufRxSem);                     /* Indicate that character was received     */

        return;
    }
    else
    {
      OS_EXIT_CRITICAL();
      }
}


/////////// 任务调用下面的函数从软件fifo中取数////////////////////

INT8U  CommGetChar (INT8U ch, INT16U to, INT8U *err)
{
    INT8U          c;
    INT8U          oserr;
    COMM_RING_BUF *pbuf;
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
      OS_SEM_DATA sem;


    switch (ch) {                                          /* Obtain pointer to communications channel */
        case COMM1:
             pbuf = &Comm1Buf;
             break;

        case COMM2:
             pbuf = &Comm2Buf;
             break;

        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    OSSemPend(pbuf->RingBufRxSem, to, &oserr);             /* Wait for character to arrive             */

    if (oserr == OS_ERR_TIMEOUT) {                         /* See if characters received within timeout*/
        *err = COMM_RX_TIMEOUT;                            /* No, return error code                    */
        return (NUL);
    } else if(oserr == OS_ERR_NONE) {
        OS_ENTER_CRITICAL();
        pbuf->RingBufRxCtr--;                              /* Yes, decrement character count           */
        /*
        OSSemQuery(pbuf->RingBufRxSem, &sem );

        if( pbuf->RingBufRxCtr!=sem.OSCnt )
            FAIL();
            */

        c = *(pbuf->RingBufRxOutPtr++);                    /* Get character from buffer                */
        if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) {     /* Wrap OUT pointer     */
            pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
        }
        OS_EXIT_CRITICAL();
        *err = COMM_NO_ERR;
        return (c);
    }

    return (NUL);
}

相关帖子

沙发
zlgarm| | 2008-5-19 08:35 | 只看该作者

检查

检查
1) OS_CRITICAL_INT_PRIO 是否等于0。
2) 任务堆栈和主堆栈是否溢出。

(zlgarm_zsg)

使用特权

评论回复
板凳
wahahaabc|  楼主 | 2008-5-19 10:20 | 只看该作者

RE:2楼

(1)OS_CRITICAL_INT_PRIO定义在os_cpu_a.asm中,其值如下:
OS_CRITICAL_INT_PRIO    EQU     (0 << 5)
ZLG公司的移植代码的OS_CRITICAL_INT_PRIO值默认为0,这个偶没有对其更改

(2)偶原来也是怀疑“任务堆栈和主堆栈溢出”,于是将任务堆栈和主堆栈都定义的很大,还是同样的问题,程序中定义的堆栈大小如下:
UART0任务大小:4096
UART1任务大小:4096
主堆栈大小(startup.s文件):Stack   EQU     4096
并且在UART0和UART1任务中并没有定义太多的局部变量,应该不会造成任务堆栈溢出

不知还有什么原因会造成这种问题?请各位大侠多指教

使用特权

评论回复
地板
wahahaabc|  楼主 | 2008-5-19 13:32 | 只看该作者

怎么没人

使用特权

评论回复
5
zlgarm| | 2008-5-19 18:36 | 只看该作者

ARM7出现过

相似的问题,我在ARM7上遇到过。我的情况是波特率为115200时,速度太高了,UCOS-II关了中断做其他事情去,来不及接收。建议你把波特率调小点试试看。

(zlgarm_zsg)

使用特权

评论回复
6
wahahaabc|  楼主 | 2008-5-26 15:02 | 只看该作者

RE:5楼

(1)“建议你把波特率调小点试试看”
因为通信协议要求的波特率为115200,且通讯协议不由我们控制,所以,波特率无法更改。
(2)“相似的问题,我在ARM7上遇到过。我的情况是波特率为115200时,速度太高了,UCOS-II关了中断做其他事情去,来不及接收”
在波特率很高时,如果没有流控,来不及接收只能导致丢失数据。偶的情况和zlgarm大侠的情况不一样,描述如下:
“打开两个“捷通串口调试软件”,每个调试软件对应到LM3S8962的一个UART,按上面的设置不断的连续发送数据,LM3S8962将接收到的数据在从相应的串口发送回来,这样发送一段时间以后,其中一个UART就会再也接收不到数据,而另一个串口还是可以正常收发。???????”
“UART就会再也接收不到数据”

使用特权

评论回复
7
zlgmcu| | 2008-5-26 17:54 | 只看该作者

利用FIFO中断接收,可以有效减少中断处理的次数

如果没有FIFO,则每接收一个字节的数据都要中断处理一次,如果系统正忙于其它事情,则可能造成数据丢失。

如果利用FIFO,则可以在连续接收多个字节的数据时才中断处理一次,大大减少了丢数据的可能性。接收FIFO未填满而后续数据长时间不来时,也会产生超时中断,能有效避免接收无响应的情况。

详见这里的UART原理、用法、库函数及例程:
【Luminary开发工具及开发指南】
http://www.zlgmcu.com/luminary/exploitation_guide.asp

(zlgmcu_wdx)

使用特权

评论回复
8
wahahaabc|  楼主 | 2008-5-27 08:34 | 只看该作者

RE:7楼

偶一直都是使用FIFO,接收和发送都是使用中断

使用特权

评论回复
9
john1337| | 2011-4-9 09:20 | 只看该作者
发送没必要用中断,只需阻塞发送就可以了,不然会加大中断进入的频繁程度,可能会导致你上面遇到的情况。

使用特权

评论回复
10
chenyelong| | 2011-4-9 12:31 | 只看该作者
刚学习ARM

使用特权

评论回复
11
hxy6951| | 2011-4-9 17:53 | 只看该作者
会不会是存数据指针和取数据指针初始化的问题

使用特权

评论回复
12
-自己人| | 2011-4-9 18:55 | 只看该作者
裸机的调试通过没有?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

119

主题

627

帖子

0

粉丝