1. 背景
由于之前有听说华为出了starlink的mcu方案,所以就想要看看它和ble/wifi的mcu方案的优劣故做此测评。
2. 方案
由于我大部分使用的数据流向是Client -> Server,所以只做了单个方向的测试。测试的时候是直接挨在一起测试的,应该可以忽略信号质量的问题。测试分为两个部分:
- 单向传输:不考虑任何丢包,只计算发送出去的字节数和总时间。
- 回环传输:由Client端发送数据包到Server端,然后Server端返回相同的数据包,计算单次回环的时间。
3. 实现
3.1 单向传输
单向传输就是把示例的Server/Client代码的串口透传部分删除,然后Client端的写入成功回调中加入如下代码段,然后在主线程中进行计时。(别问为什么不用信号量和消息队列,问就是我不会优化,怕计时不准确)
void sle_uart_client_sample_write_cfm_cb(uint8_t client_id, uint16_t conn_id,
ssapc_write_result_t *write_result, errcode_t status)
{
unused(client_id);
unused(conn_id);
unused(write_result);
unused(status);
send_complete_s = true;
// 发送完上一次之后再次发送
if (transmit_count_s == SLE_TRANSMIT_MAX_COUNT) {
test_complete_s = true;
}
else {
errcode_t err = sle_throughput_write(test_data_s, SLE_MAX_SEND_SIZE);
if (err == 0) {
transmit_count_s += 1;
}
}
}
void *sle_uart_client_write_task(const char *arg)
{
unused(arg);
unsigned int start_tick = 0;
unsigned int end_tick = 0;
for (unsigned int i = 0; i < sizeof(test_data_s); i ++) {
test_data_s[i] = (i % 10) + '0';
}
while(!get_g_connect_success_state()) {
osal_mdelay(10);
}
osal_mdelay(1000);
sle_throughput_write(test_data_s, SLE_MAX_SEND_SIZE);
start_tick = osal_jiffies_to_msecs(osal_get_jiffies());
while (1) {
if (test_complete_s == true) {
break;
}
osal_yield();
}
end_tick = osal_jiffies_to_msecs(osal_get_jiffies());
osal_printk("test transmit count is %u.\r\n", transmit_count_s);
osal_printk("test transmit time is %u.\r\n", end_tick - start_tick);
// 参考延时
start_tick = osal_jiffies_to_msecs(osal_get_jiffies());
osal_mdelay(1000);
end_tick = osal_jiffies_to_msecs(osal_get_jiffies());
osal_printk("test delay time is %u.\r\n", end_tick - start_tick);
return NULL;
}
注:要将以下代码段添加在连接完成事件后
sle_uart_client_sample_set_phy_param();
osal_msleep(SLE_UART_TASK_DELAY_MS);
sle_low_latency_rx_enable();
sle_low_latency_set(get_g_sle_uart_conn_id(), true, SLE_UART_LOW_LATENCY_2K);
3.1 回环测试
回环测试的代码修改可能就稍微多一点
- Server端需要将ssaps_server_write_request_cbk函数中添加如下代码段,用于将写入的数据发回去。
errcode_t ret = 0;
if ((write_cb_para->length > 0) && write_cb_para->value) {
do {
ret = sle_uart_server_send_report_by_handle(write_cb_para->value, write_cb_para->length);
if (ret != 0) {
osal_printk("errcode is %d.\r\n", ret);
}
} while(ret != 0);
}
- Client端发完一个数据包之后等待接收。
start_tick = osal_jiffies_to_msecs(osal_get_jiffies());
sle_loopback_write(test_data_s, SLE_MAX_SEND_SIZE - 1);
while (1) {
osal_yield();
now_tick = osal_jiffies_to_msecs(osal_get_jiffies());
if (recv_byte_s == 0) {
if (now_tick - start_tick > SLE_LOOPBACK_TIMEOUT) {
break;
}
continue;
}
else if (recv_byte_s != send_byte_s) {
break;
}
else {
break;
}
}
end_tick = osal_jiffies_to_msecs(osal_get_jiffies());
used_tick = end_tick - start_tick;
if (used_tick > SLE_LOOPBACK_TIMEOUT) {
osal_printk("[err] recv bytes timeout.\r\n");
hal_reboot_chip();
}
else if (recv_byte_s == send_byte_s) {
osal_printk("[success] loop used time is %u.\r\n", used_tick);
}
else if (recv_byte_s != send_byte_s) {
osal_printk("[err] recv bytes num error, send bytes is %u, recv bytes is %u.\r\n", send_byte_s, recv_byte_s);
hal_reboot_chip();
}
4. 结论
- 单向传输测试:共发送5000 * 507字节,总用时203235ms。速率约为12474Byte/s。
- 回环传输测试:一次回环传输的时间约为50-55ms
5. 吐槽
- sle连接后,第一次连接的mtu默认失败,总会变回251。我这边是直接进行复位重新连接的。
- 文档太少,函数注释也只有大致的功能介绍,找不到sdk的文档。优化类的操作也只有看着例程拆出来。
- 打印去不掉,可能会占用一部分时间。
- 速度和延时和我之前测过的BLE芯片相比略有不足。
- 测试回环时传输过程的丢包/断联次数较多,目前排查不出原因。