找回密码
 立即注册

使用微信账号登录

只需一步,快速开始

查看: 10438|回复: 14

[CSR8系列] 8670 uart调试的诡异问题

[复制链接]
连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
发表于 2017-3-2 15:28:22 | 显示全部楼层 |阅读模式

马上注册,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册  

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

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

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

  6. #include <sink.h>
  7. #include <source.h>
  8. #include <panic.h>
  9. #include <pio.h>
  10. #include <stream.h>
  11. #include <vm.h>

  12. #define MAX_GETINPUTLINE_LENGTH 30

  13. static void send(const char *s)
  14. {
  15.         uint16 n = strlen(s);
  16.         Sink uart = StreamUartSink();
  17.         if(uart && SinkClaim(uart, n) != 0xFFFF)
  18.         {
  19.                 memcpy(SinkMap(uart), s, n);
  20.                 SinkFlush(uart, n);
  21.         }
  22. }

  23. static bool GetInput(char *s)
  24. {
  25.         int uart_size   = 0;
  26.         int inp_str_len = 0;

  27.         Source uart_source = StreamUartSource();
  28.         uart_size = SourceSize(uart_source);

  29.         if(uart_size)
  30.         {
  31.                 memset(s, 0x00, MAX_GETINPUTLINE_LENGTH);

  32.                 if(uart_size > MAX_GETINPUTLINE_LENGTH)
  33.                 {
  34.                         inp_str_len = MAX_GETINPUTLINE_LENGTH - 1;
  35.                 }
  36.                 else
  37.                 {
  38.                         inp_str_len = uart_size;
  39.                 }

  40.                 /* copy data to UART */
  41.                 memcpy(s, SourceMap(uart_source), inp_str_len);
  42.                 SourceDrop(uart_source, inp_str_len);
  43.                 return TRUE;
  44.         }
  45.         return FALSE;

  46. }

  47. int main(void)
  48. {
  49.         char s[MAX_GETINPUTLINE_LENGTH];

  50.         Source uart_source;
  51.         /*Sink   uart_sink;
  52.         uart_sink   = StreamUartSink();*/
  53.         uart_source = StreamUartSource();
  54.         SourceEmpty(uart_source);

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

楼主热帖
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-3-2 15:33:30 | 显示全部楼层
本来怀疑这个串口助手有问题,刚才又换了一个,还是一样。
当电脑发出n个字符时,8670会接收2次,第一次接收第一个字符,第二次接收剩余的n-1个字符
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-3-2 15:44:44 | 显示全部楼层
本帖最后由 pkuzhx 于 2017-3-2 15:47 编辑

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

  5.         Source uart_source = StreamUartSource();
  6.         uart_size = SourceSize(uart_source);
  7.     if(uart_size)
  8.         printf("uart_size = %d\n", uart_size);

  9.         ……
  10. }
复制代码


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

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






积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-3-2 15:55:55 | 显示全部楼层
又怀疑是串口转换硬件的问题,换了一个不同厂家的转换器,还是一样的
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:6天
签到总奖励:31金币
发表于 2017-9-18 14:29:40 | 显示全部楼层
学习学习,MARKMARK
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1397天
签到总奖励:23877金币
发表于 2017-9-18 15:52:45 | 显示全部楼层
因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第一个字符,然后再把余下的输出。之前有网友分析可能是流控制的问题。
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-9-18 17:40:01 | 显示全部楼层
Wney 发表于 2017-9-18 15:52
因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第 ...

给力了!                           
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:26天
签到总天数:830天
签到总奖励:33308金币
发表于 2017-9-19 21:19:13 | 显示全部楼层

这个现象不奇怪。 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 数据。
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-9-20 08:16:54 | 显示全部楼层
Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...

大神分析的太透彻了,这些资料都在哪些文档里看的啊?
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

连续签到天数:1天
签到总天数:1023天
签到总奖励:12600金币
 楼主| 发表于 2017-9-20 08:35:17 | 显示全部楼层
Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...

while(1)那个是当时为了测试那么写的。
实际做的时候,注册了一个消息处理函数,通过MESSAGE_MORE_DATA接收的。
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

小黑屋|手机版|我爱蓝牙网 - 52Bluetooth

GMT+8, 2024-4-28 16:54 , Processed in 0.190830 second(s), 25 queries , Gzip On, MemCached On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表