pkuzhx 发表于 2017-3-2 15:28:22

8670 uart调试的诡异问题

本帖最后由 pkuzhx 于 2017-3-2 15:34 编辑

使用CSR8670进行简单的uart调试,基本功能如下:
1)上电后8670给电脑发送"Uart test:\r\n"
2)电脑给8670发数据,8670会把收到的数据发回给电脑

代码是根据视频教程中改的:
/* property: Transport must set to Raw */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include <sink.h>
#include <source.h>
#include <panic.h>
#include <pio.h>
#include <stream.h>
#include <vm.h>

#define MAX_GETINPUTLINE_LENGTH 30

static void send(const char *s)
{
      uint16 n = strlen(s);
      Sink uart = StreamUartSink();
      if(uart && SinkClaim(uart, n) != 0xFFFF)
      {
                memcpy(SinkMap(uart), s, n);
                SinkFlush(uart, n);
      }
}

static bool GetInput(char *s)
{
      int uart_size   = 0;
      int inp_str_len = 0;

      Source uart_source = StreamUartSource();
      uart_size = SourceSize(uart_source);

      if(uart_size)
      {
                memset(s, 0x00, MAX_GETINPUTLINE_LENGTH);

                if(uart_size > MAX_GETINPUTLINE_LENGTH)
                {
                        inp_str_len = MAX_GETINPUTLINE_LENGTH - 1;
                }
                else
                {
                        inp_str_len = uart_size;
                }

                /* copy data to UART */
                memcpy(s, SourceMap(uart_source), inp_str_len);
                SourceDrop(uart_source, inp_str_len);
                return TRUE;
      }
      return FALSE;

}

int main(void)
{
      char s;

      Source uart_source;
      /*Sink   uart_sink;
      uart_sink   = StreamUartSink();*/
      uart_source = StreamUartSource();
      SourceEmpty(uart_source);

      send("Uart test:\r\n");
      while (1)
      {
                if(GetInput(s))
                {
                        send("start\r\n");
                        send(s);
            send("\r\nend\r\n");
                }
      }
         
      return 0;
}
现在的问题是,如果在while中,不加入send("start\r\n");和send("\r\nend\r\n");,就没问题,电脑发什么就能收到什么。
但是加上这两句以后,比如我发asdf,本来应该收到:
start
asdf
end实际却收到的是:
start
a
end
start
sdf
end最诡异的是,如果我debug,单步执行,那就收到的还是:
start
asdf
end
实在想不通为什么会把电脑的数据分成两段,而且debug单步执行和直接运行的结果还不一样。球大神指点。

pkuzhx 发表于 2017-3-2 15:33:30

本来怀疑这个串口助手有问题,刚才又换了一个,还是一样。
当电脑发出n个字符时,8670会接收2次,第一次接收第一个字符,第二次接收剩余的n-1个字符

pkuzhx 发表于 2017-3-2 15:44:44

本帖最后由 pkuzhx 于 2017-3-2 15:47 编辑

现在确定应该是这个代码有点小问题了,哪位大神帮忙看看问题出在哪里,应该怎么修改。我在GetInput中增加了一句debug语句,来跟踪接收到的数据长度:static bool GetInput(char *s)
{
        int uart_size   = 0;
        int inp_str_len = 0;

        Source uart_source = StreamUartSource();
        uart_size = SourceSize(uart_source);
    if(uart_size)
      printf("uart_size = %d\n", uart_size);

        ……
}

当我在电脑发送asdf时,在print channel 0会收到:
uart_size = 1
uart_size = 3确实是把一个字串拆成了两端。

但是如果在if(GetInput(s))前增加断点,就不会拆,而是直接uart_size = 4!!!
苍天啊,谁告诉我这是怎么一回事。对uart是在是不懂。






pkuzhx 发表于 2017-3-2 15:55:55

又怀疑是串口转换硬件的问题,换了一个不同厂家的转换器,还是一样的:Q

sigrace 发表于 2017-9-18 14:29:40

学习学习,MARKMARK

Wney 发表于 2017-9-18 15:52:45

因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第一个字符,然后再把余下的输出。之前有网友分析可能是流控制的问题。

pkuzhx 发表于 2017-9-18 17:40:01

Wney 发表于 2017-9-18 15:52
因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第 ...

给力了!                           

Andy_Bao 发表于 2017-9-19 21:19:13

pkuzhx 发表于 2017-9-18 17:40
给力了!

这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM (virtual machine) in SoC (System On Chip) , 与bare metal embedded programming environment 是完全不同的。 做个比拟来讲, 在 SoC 里运行的,除了你的 VM code 之外, 还有 kernel , 还有其他的 high priority thread, 而你的 VM code 是 lowest priority thread.VM 的 programming model 是 Event-Driven , 主要工作就是 provide event handler , 可以向 kernel / System thread 请求 register a System Message Handler, to react to System Message.
在 VM code 里用 while(1) poll UART status , 是极其错误的。 应该向系统 register UART message, 在 event handler 里处理 UART 数据。

pkuzhx 发表于 2017-9-20 08:16:54

Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...

大神分析的太透彻了,这些资料都在哪些文档里看的啊?

pkuzhx 发表于 2017-9-20 08:35:17

Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...

while(1)那个是当时为了测试那么写的。
实际做的时候,注册了一个消息处理函数,通过MESSAGE_MORE_DATA接收的。
页: [1] 2
查看完整版本: 8670 uart调试的诡异问题