UART TX_CALLBACK_SIZE question

⚠️
你好。。谢谢你来参加论坛。令人兴奋的消息!我们现在正在移动到我们的新论坛平台,将提供更好的功能,并包含在主对话网站的过程。所有帖子和账号都已迁移。我们现在只接受新论坛上的流量-请在//www.xmece.com/support. 我们将在未来几天内修复bug/优化搜索和标记。
3个职位/0个新职位
最后一篇文章
克克特林
离线
Last seen:3 years 10 months ago
已加入:2016-08-24 00:17
UART TX_CALLBACK_SIZE question

Hi Dialog Engineer,

I am using the DSPS application firmware as my baseline code to start with.
我有一个DA通过UART线路与外部MCU通信。UART的波特率为56.7kbps。

I have implemented two functions to send data across from the DA to the external MCU.

功能1:
-DA通电后,此功能从闪存读取数据,并通过UART线路下载外部MCU固件。由于外部MCU实际上可以启动并使用其固件运行,因此此功能始终100%正常工作。代码如下:

//从闪存地址“address”和“size”读取QPI固件/表&
// write it out the UART channel(s) where the QPI(s) attached to
void user_sps_qpi_fw_upload(unsigned int address) {

字节buf[2];
// read the firmware size in bytes stored in flash from the Host UI flash program.
//固件len是flash中每个FW地址部分的前两个字节
unsigned int fwLen;
if(spi_flash_read_data(buf, address, USER_FLASH_QPI_FWSIZE_HDR) == USER_FLASH_QPI_FWSIZE_HDR) {
fwLen = (buf[0] << 8) | buf[1];
address += USER_FLASH_QPI_FWSIZE_HDR;
}
无符号字符数据\u ptr[用户\u FLASH \u QPI \u CI \u BLK \u SIZE];
//计算闪存读取次数。每次读取的字节数为USER\ FLASH\ QPI\ CI\ BLK\ u SIZE字节
int n = fwLen/USER_FLASH_QPI_CI_BLK_SIZE + 1;
对于(int i=0;i// read the QPI FW from Flash. This can be FW, Degamma Table, LUM Tables
unsigned int ret = spi_flash_read_data(data_ptr, address + i*USER_FLASH_QPI_CI_BLK_SIZE,
USER_FLASH_QPI_CI_BLK_SIZE);
uart2\写入(数据\ ptr、用户\闪存\ QPI\ CI\ BLK\大小,NULL);
uart2_finish_transfers();
}
}

- In this function, I am reading USER_FLASH_QPI_CI_BLK_SIZE = 256 bytes at a time from Flash and write over the UART2.

功能2:
-此函数读取从BLE线路传入的数据,并通过UART2总线将其发送到外部MCU。代码如下:

void user_ble_push(uint8_t* wrdata, uint16_t write_amount)
{
ASSERT_ERR(wrdata != NULL);
断言错误(写入金额!=0);

bool send_flow_off = false;

// write the BLE "data" to the peripheral buffer "ble_to_periph_buffer"
用户缓冲区写入项(&B)到缓冲区,wrdata,写入量;

//check if buffer is almost full and issue to send a XOFF if so
send\u flow\u off=user\u check\u buffer\u most\u full(&ble\u to\u periph\u buffer);

//if XOFF must be send, send asap
if(发送流){
用户发送流控制(流关闭);
}
//start transmitting
__禁用irq();

if(!uart_qpi_tx_callbackbusy) {
uart\u qpi\u tx\u callbackbusy=真;
uart\u qpi\u tx\u回调(uart\u STATUS\u INIT);
}
__启用\u irq();
}

-此函数是DSPS示例应用程序固件的一部分。我把它修改成我们自己的应用程序。uart\u qpi\u tx\u callback()与DSPS示例中的内容相同。以下是此功能的代码,供您参考:

static void uart_qpi_tx_callback(uint8_t res)
{
static uint8_t size=0;
uint8\u t*periph\u tx\u ptr=NULL;

//函数在未运行时从uart transmit isr或应用程序调用
开关(res)
{
case UART_STATUS_OK:
//获取数据和指针
size=user\u periph\u pull(&periph\u tx\u ptr,size);
break;
案例UART\状态\初始化:
size=user\u buffer\u read\u address(&ble\u to\u periph\u buffer,&periph\u tx\u ptr,tx\u CALLBACK\u size);
break;
default:
断言错误(0)//错误:从未知源调用回调
}
//if there is data available, send data over periph
if(size > 0) {
uart2\ U写(外围发送\ ptr、大小和uart\ qpi\ U发送\ U回调);
return;
}
//缓冲区中没有数据,因此回调已完成
uart\u qpi\u tx\u callbackbusy=false;
}

我对以上两个功能的问题:

1.在函数1中,我实际使用的是大小为256字节的UART写入。我知道TX FIFO的大小只有16个字节。为什么我的案子会这样。我不是在抱怨。我只是想更好地理解它。

2.在函数二,我有问题发送任何东西more than 16 bytes to the external MCU. If I sent 16 bytes or less, the MCU received everything. If I sent a packet that is more than 16 bytes, the bytes beyond the 16th byte will not be received. However, if I were to step into the uart2_write() function one line at a time and walk through the uart2_thr_empty_isr() inside uart2_write(), I can see all the data and the data will end up be received by the external MCU correctly. This will happen every time. If I step into the code, it will work. If I let the code run, It will fail every time.

Please let me know what you see and explain to me what's going on?

谢谢你的关注,
--Khai

Device:
MT_dialog
离线
Last seen:3 months 2 days ago
工作人员
已加入:2015-06-08 11:34
嗨,克克特林,

嗨,克克特林,

1. The FIFO has 16 bytes but that doesn't mean that you can only send 16 bytes at a time, i mean that as long as you keep on pushing data in the FIFO then the UART will output the data and you can keep on pushing data as long as the FIFO has room (if the FIFO has room for additional bytes is checked by the uart2_txfifo_full_getf() ), if the FIFO is full and you keep on pushing data, that means that the data will be overwritten and apparently you will have missing bytes. In the UART driver the first 16 bytes are pushed from the uart2_write() function and as soon as the uart2_txfifo_full_getf() returns 0 (no more room in the FIFO) the function will return and wait for the UART FIFO to get empty, as soon as it gets empty, a UART interrupt will hit indicating an empty FIFO and the uart2_thr_empty_isr() is getting invoked in interrupt context in order to re-fill the FIFO.

2.关于单步执行代码时可以看到所有数据,如果正常运行代码则只能看到16个字节的事实,我只能假设这是因为UART FIFO有时间通过手动和单步执行代码获取MCU提供的数据并打印出来,因此UART FIFO中总是有空间的(while(uart2\u txfifo\u full\u getf())函数总是非零的,所以所有的打印都是通过uart2\u write()调用的uart2\u thr\u empty\u isr()完成的)。但在实际情况中,处理器全速运行,在第一个16字节后调用uart2\u write(),FIFO将变满,uart2\u thr\u empty\u isr()将返回并等待UART FIFO打印所有数据,在此之后,UART中断将发生,以通知FIFO为空,并且您可以将更多数据推入FIFO,因此UART2\u处理程序()将被调用,并且为了让UART2\u thr\u empty\u isr()填充下一批16字节,因此显然UART2\u处理程序中的UART2\u thr\u empty\u isr()从未被调用。我相信这很可能就是为什么在第二种情况下只能得到16字节的数据的原因,但是您需要对此进行更多的调试,因为这只是一个假设,我无法预见在这种情况下会发生什么,以及您无法从另一方获得数据的确切原因是什么。

Thanks MT_dialog

克克特林
离线
Last seen:3 years 10 months ago
已加入:2016-08-24 00:17
你好,先生,

你好,先生,

谢谢你带我通过uart2\u write()机制。在您解释了FIFO的工作原理之后,我简单地将每16字节等待1毫秒的事务设置为允许FIFO时间在再次发送下一个16字节块之前清空其数据。这就像一个冠军。

谢谢您,
--Khai