This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:TI-RTOS
您好!
我已经尝试过多种方法来使用 TI-RTOS 读取全部8个 UART、但在读取时不会丢失数据、每次读取的数据不能超过3-4个。 如果您有任何建议来处理使用 TI-RTOS (必须是 TI-RTOS)读取全部8个 UART 的内容、我将不胜感激。
每个 UART 每1到4秒以19200波特接收20-64字节数据。 我的目标是能够将每个 UART 的数据存储在缓冲区中、直到接收到一个终止字符来表示数据包的末尾、然后复制缓冲区并在其他地方使用。
我已经尝试了以下许多不同的方法:
1) 1)最初修改了 Enet_s2E 示例、该示例使用 FreeRTOS 使用8个 UART。 它可以工作、但由于 USB/插座要求、必须使用 TI-RTOS。
2) 2)修改了针对多个 UART 的 TI-RTOS 示例"uartecho"
a)每个 UART 一个任务、无需回调即可进行读取
a1)通过队列发送字符,以便由单独的任务聚合
a1)将字符复制到 char[]缓冲区中、以由 单独的任务聚合
b)每个 UART 一个任务、通过回调任务进行读取
b1)在回调中、通过队列发送字符、以由 单独的任务聚合
b2)在回调中、将字符复制到 char[]缓冲区中、以便由 单独的任务聚合
B3)调用读取的计时器
B4)信标和缓冲区、以最大程度地缩短回调时间
基本上、我已经尝试了很多方法和选项的变体、一次读取的字节数、没有一个接近全部8次读取、没有丢失数据。 有人知道 TI-RTOS 中可以无问题地处理全部8个 UART 的任何方法吗? 在调度方面、我们需要能够在一侧运行一些额外的低优先级任务、例如 USB 和套接字。
谢谢!
您好 Todd、
看起来先前初始化的 UART 与数据损坏相关的问题更少。 当我仅设置1至3个 UART 时、所有数据均已正确接收。 当使用 UART 的任意组合(例如:1/2/3或2/5/6)时、此功能有效。 当我设置3个或4个以上的 UART 时、字符开始丢失。 在8个 UART 设置中、只有前5个设置将接收数据、最后几个设置将几乎没有接收到数据(UART 1-2错过了几个字符、3-5个丢失的字符、6-8个收到的字符非常少)。
我还注意到、当任务或回调运行更多代码并花费更长的时间来执行时、会丢弃更多数据。 在尝试了许多方法之后、我目前正在尝试最大程度地减少读取任务和回调函数的开销。 单独在项目中运行代码或同时运行其他任务(例如:USB 和以太网套接字任务)时、没有太大的区别(如果有)。
下面是一个示例、说明我当前如何在环路中设置 UART 以及如何读取/处理数据。 希望您有一些神奇的公式、例如"使用回调和队列、将 XYZ 设置为___"。 我感觉自己很近!
非常感谢您的帮助!
#define UART_READ_TASK_STACK_SIZE 1024 #define MAX_NUM_RX_Bytes 8 //一次性接收的最大 RX 字节
// 在 Task_Structurt uartReadTaskStruct[UART_count]下的读取任务创建中使用的结构和堆栈; 字符 uartReadTaskStack[UART_count][UART_READ_TASK_STACK_SIZE];
//除了回调函数 UART_Params 之外、UART 参数是相同的 UARTParams; UART_Params_init (&UARTParams); UARTParams.baudrate = UART_baud_rate;// 19200 UARTParams.writeDataMode = UART_DATA_binary; UARTParams.readEcho = UART_ECHO_OFF; UARTParams.readMode = UART_MODE_UART0;/ UART+= UART0+= UARTRAT0+设置为接收 任务;UART0+设置为等待 UART0+回调拨;UART0+等待 UART0+(UART0+ )
//回调函数将端口号添加到读取回调任务 args UARTParams.readCallback = UARTRxCallbackFuncs[uartLoop; UARTHandles[uartLoop ]= UART_OPEN (UARTsAvailable[uartLoop ]、&UARTParams); if (!UARTHandles[uartloop]){ System_printf ("UART%d 未打开"、uartLoop);// UART 始终未打开问题 } //创建任务以定期读取 UART taskParams.STACKSIZE = UART_READ_TASK_STACK_SIZE; taskParams.priority = 3; taskParams.arg0 = uartLoop; taskParams.stack =&uartReadTaskStack[uartLoop; Task_construction (&uartReadTaskStruct[uartLoop)、(Task_funcPtr) UARTReadTask、&taskParams、NULL); } //回调函数 静态 void multipleByteReadCallback (UART_Handle handle、void * rxBuf、size_t size、uint8_t port) { //将 rxBuf 复制到 txBuf memset (UARTRxBufCopy[port]、0、MAX_NUM_RX_Bytes); memcpy (UARTRxBufCopy[port]、rxBuf、size); Semaphore_post (readSemaphore[port]); } //读取函数 静态空 UARTReadTask (UARg arg0、UARg arg1){ int port =(int) arg0; size_t charsReceivedSize; while (1){ UART_READ (UARTHandles[port]、UARTRxBuf[port]、MAX_NUM_RX_Bytes); Semaphore_pend (readSemaphore[port]、BIOS_wait_forever); charsReceivedSize = strlen (UARTRxBufCopy[port]); //将接收到的字符复制到部分数据包缓冲区 //如果接收到数据字符结束,打印数据(或添加到队列) Task_sleep (10);//在有睡眠和没有睡眠的情况下尝试,不同的时间,5-25似乎有所帮助 } }
您好、请选择用户名、
您是否为每个 UART 配置了 M3模块或特定的中断优先级? ROV 是否指示分配给每个 UART 的任何类型的 FIFO 中断优先级? 如果 FIF0未受限制或仅轮询、我们如何预计串行数据不会丢失?
您好、用户:
您还可以尝试查看 CPU 负载、看看您是否有周期以该波特率处理来自8个 UART 的数据。
只需将以下内容添加到.cfg 文件中即可:
xdc.useModule('ti.uia.sysbios.LoggingSetup');
然后在 CCS 中使用 RTOS 分析器来查看 CPU 负载。
此致、
Janet
Janet、您好!
我目前正在旅行、无法测试系统。 通常、仅读取8个 UART 时、CPU 负载是否会成为一个问题?
我知道代码和设置的差异可能会显著改变性能、但总的来说 TM4C1294NCPDT 应该没有足够的 CPU? 通过使用 Arduino sketch、我能够完美读取全部8个 UART、并将数据存储在50行代码中。 我们还能让它与 FreeRTOS 配合使用而不会出现任何问题、还能运行完整的以太网 Web 服务器。
谢谢你。
您好、用户:
由于每个 UART 有一个任务、我想知道任务切换是否会产生大量开销。 这就是我认为查看 CPU 负载可能有用的原因。
此致、
Janet
Janet、您好!
感谢您的建议、减少运行的任务会产生很大的影响! 我创建了一个单个读取任务、并在每个 UART 上连续循环。 在循环超过6个 UART 时、大约90%的字符将要到来、但从数据流看、FIFO 缓冲区在被读取前被溢出。
10%的缺失会导致部分数据包与完整数据包混合、例如<123456 <1234567890>而不是<1234567890><1234567890>。 大约10个数据包可以正常运行、然后是一个混合运行的数据包。 没有明显的 UART 模式。
数据每4秒发送64个字符、缓冲区大小是128个字符的两倍:
unsigned FlowuartTivaRingBuffer[EK_TM4C1294XL_UARTCOUNT][128]; /* UART 配置结构* / const UARTTiva_HWAttrs uartTivaHWAttrs[EK_TM4C1294XL_UARTCOUNT]={ .baseAddr = UART0_BASE、UART0_Control ~= UART0_UART24_UART0_UART0_UART24_UR_UR_T.EK-R = T.UART24_UART0_UART24_UART_UART0_UART24_UR_UR_UR_UR_UR_ENTRINT_UART0_U .ringBufSize = sizeof (uartTivaRingBuffer[EK_TM4C1294XL_UART0]) }、 { .baseAddr = UART1_base、 .intNum = INT_UART1、 .intPriority =(~0)、 .FlowControl = UART_FlowControl_NONE、 .ringBufPtr = INT_Tiva40XL_TivaUrg环路 缓冲器[EK_UART1494X1] .ringBufSize = sizeof (uartTivaRingBuffer[EK_TM4C1294XL_UART1]) }、...
我在测试项目中使用以下最小代码、但仍然无法获取完整数据:
UART_Params UARTParams; UART_PARAMS_INIT (&UARTParams); UARTParams.波特 率= UART_BAUD_RATE; UARTParams.readReturnMode = UART_RETURN_NEWLINE; UARTParams.readEcho = UART_ECHO_OFF; 静态空 UARTReadTask (UARg arg0、UARg arg1){ int 端口; int charsReceivedSize; uint8_t sizeLoop; 字符接收器; while (1){ 对于(端口= 0;端口< UART_COUNT;端口++){ if (!UARTsActivated[port]){ 继续; } charsReceivedSize = UART_Read (UARTHandles[port]、UARTRxBuf[port]、MAX_NUM_RX_Bytes); for (sizeLoop = 0;sizeLoop '="">'){ System_printf ("UART%d 接收到%s\n"、端口、dataPacketRxBuffer[port]); system_flush(); dataPacketRxBufferIndex[port]= 0; } } }
我尝试让 CPU 记录器正常工作、但无法获得任何内容、甚至在查看论坛上的所有提示后、执行相关项目也无法正常工作。 我甚至还尝试了 Resource Explorer 中的新示例、但运气不好。 我想我只是习惯使用常规的计算机和 Linux、在这些计算机和 Linux 中、事情似乎更简单、工作正常。 这些 TI 产品似乎会在每次机会时都出现故障。
我感谢您的帮助、尤其是对一些简单代码的帮助、因为这看起来应该很简单。
谢谢你。
我知道 TI-RTOS 要复杂得多、但这就是 Arduino 的易用性(我们如何使用 Energia 在 TM4C1294NCPDT 上进行原型设计)。 TI 只是不发布与 Arduino 配合使用所需的 UART/USB/Ethernet 驱动程序、因此我们不得不用 C 语言编写它...
char termChart ='>'; char 字符; int baudrate = 19200; HardwareSerial *Serials[8]={&Serial、&Serial1、&SERIAL2、&Serial3、&Serial4、 &Serial5、&Serial6、&Serial7}; String rxStrings[8]; String completedRxString; string storedRxString =""; //设置 void setup(){ Serial.begin(baudRate); Serial.println ("串行测试开始"); for (int i = 0;i < 8;i++){ rxStrings[i]=""; Series[i]->begin (budrate); } } void loop(){ for (int i = 0;i < 8;i++){ while (Serials[i]->available ()){ 字符=期刊[i]->read(); rxStrings[i].con概念(字符); if (字符== termChart){ // serial.print ("串行"+字符串(i)+":"); // serial.println (rxStrings[i]); 完整的 RxString = String (I)+":"+rxStrings[i]+";"; storedRxString.conomat (完整的 RxString); rxStrings[i]=""; } } if (storedRxString.length ()> 2000){ serial.println (storedRxString); storedRxString =""; } }
您好、用户:
我认为您可以执行与 Arduino 代码中所执行的操作类似的操作、只需执行一项任务即可读取 UART。 有一个 UART_CONTRAIN()命令,您可以使用它来检查 UART 上是否有可用的数据。 以下是我修改 uartecho 示例以使用 UART_CONTINU()调用的方法:
可 提供内部数据;
(笑声)
/*循环永久回显*/
while (1){
if ((UART_CONTROL (UART、UART_CMD_ISAVAILABLE、&dataAvailable)=UART_STATUS_SUCCESS)&&
(dataAvailable!= 0)){
UART_READ (UART、INPUT、1);
UART_WRITE (UART、INPUT、1);
}
}
还有一个 UART_CMD_GETRXCOUNT 控制命令、用于提供可读取的实际字符数。
此致、
Janet
Janet、您好!
您的代码比目前为止的任何代码都更有效、但仍然只能使8个 UART 中的5个正常工作、6个偶尔会丢失数据。
我们公司已决定 TI-RTOS 的质量和可靠性不够、因此我们将继续处理其他问题。 基本上、除了硬件之外、所有东西都很糟糕:CCS、TI-cloud、TI-RTOS、驱动程序、许可... 许多事情都不能正常工作。
我还建议我们完全抛弃 TI 的硬件、因为有很多更好的选择。 我们认为 TI 因优质电子组件而享有的声誉将超越其软件和操作系统、但我们发现、与 IBM 和许多其他大型公司一样、TI 并不真正获得它、这是一件麻烦事。
感谢你的帮助。
PS:如何能够选择不是您的名字和姓氏以及号码的用户名? 不必注册第二个虚拟帐户、这是没有帮助的。