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单步执行和直接运行的结果还不一样。球大神指点。
本来怀疑这个串口助手有问题,刚才又换了一个,还是一样。
当电脑发出n个字符时,8670会接收2次,第一次接收第一个字符,第二次接收剩余的n-1个字符
本帖最后由 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是在是不懂。
又怀疑是串口转换硬件的问题,换了一个不同厂家的转换器,还是一样的:Q
学习学习,MARKMARK 因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第一个字符,然后再把余下的输出。之前有网友分析可能是流控制的问题。 Wney 发表于 2017-9-18 15:52
因为CSR没有开放具体代码,只给出UART的接口。目前普遍的情况是,当UART中有数据流,他会输出数据流中的第 ...
给力了! 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 数据。 Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...
大神分析的太透彻了,这些资料都在哪些文档里看的啊? Andy_Bao 发表于 2017-9-19 21:19
这个现象不奇怪。 VM 程序问题。
最根本的原因,没有理解 CSR VM programing environment . 这个是 VM ( ...
while(1)那个是当时为了测试那么写的。
实际做的时候,注册了一个消息处理函数,通过MESSAGE_MORE_DATA接收的。
页:
[1]
2