目录
  • 一、准备工作
  • 二、软件设计
  • 三、编译代码
  • 四、测试

SLE 串口透传测试

该教程演示如何通过两块开发板实现SLE数据传输测试,A开发板通过串口接收数据,然后通过SLE传输给B开发板,B开发板通过串口将接收到的数据打印出来;同样,B开发板通过串口接收数据,然后通过SLE传输给A开发板,A开发板通过串口将接收到的数据打印出来。在测试中需要一块开发板做为Server端,另外一块开发板做为Client端,两块开发板配对后就可以互发消息了。

一、准备工作

  • 准备2块BearPi-HM Nano 2开发板

二、软件设计

SLE串口透传客户端主要代码分析

打开device\bearpi\bearpi_hm_nano2\app\E1_sle_uart_client\sle_uart.c,这部分代码为UART初始化的代码,首先要在 uart_attr_t 结构体中配置波特率、数据位、停止位、奇偶检验位,然后通过 uapi_uart_init() 函数对串口进行配置,这里默认使用是的和开发板Typec口连接的串口0作为透传串口,开发者也可改为其他串口。

static void uart_init_config(void)
{
    uart_attr_t attr = {
        .baud_rate = SLE_UART_BAUDRATE,
        .data_bits = UART_DATA_BIT_8,
        .stop_bits = UART_STOP_BIT_1,
        .parity = UART_PARITY_NONE
    };

    uart_pin_config_t pin_config = {
        // .tx_pin = CONFIG_UART_TXD_PIN,
        // .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(SLE_UART_BUS);
    uapi_uart_init(SLE_UART_BUS, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}

以下这部分的代码,首先通过 uapi_uart_register_rx_callback() 注册串口中断回调,在回调函数中将串口接收到的数据通过ssapc_write_req() 函数发送出去。另外使用sle_uart_client_init函数注册星闪数据接收回调,在sle_uart_notification_cb回调函数中将星闪接收到的数据使用uapi_uart_write函数通过串口发送出来。

void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    printf("\n sle uart recived data : %s\r\n", data->data);
    uapi_uart_write(SLE_UART_BUS, (uint8_t *)(data->data), data->data_len, 0);
}

static void sle_uart_client_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
    uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
    sle_uart_send_param->data_len = length;
    sle_uart_send_param->data = (uint8_t *)buffer;
    ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
}

static void *sle_uart_client_task(const char *arg)
{
    unused(arg);

    /* UART init config. */
    uart_init_config();

    uapi_uart_unregister_rx_callback(SLE_UART_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(SLE_UART_BUS,
                                                   UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
                                                   1, sle_uart_client_read_int_handler);
    osDelay(500);
    sle_uart_client_init(sle_uart_notification_cb, sle_uart_indication_cb);
    
    if (ret != ERRCODE_SUCC) {
        printf("Register uart callback fail.");
        return NULL;
    }

    return NULL;
}

SLE串口透传服务端主要代码分析

打开device\bearpi\bearpi_hm_nano2\app\E2_sle_uart_server\sle_uart.c,这部分代码为UART初始化的代码,首先要在 uart_attr_t 结构体中配置波特率、数据位、停止位、奇偶检验位,然后通过 uapi_uart_init() 函数对串口进行配置,这里默认使用是的和开发板Typec口连接的串口0作为透传串口,开发者也可改为其他串口。

static void uart_init_config(void)
{
    uart_attr_t attr = {
        .baud_rate = SLE_UART_BAUDRATE,
        .data_bits = UART_DATA_BIT_8,
        .stop_bits = UART_STOP_BIT_1,
        .parity = UART_PARITY_NONE
    };

    uart_pin_config_t pin_config = {
        // .tx_pin = CONFIG_UART_TXD_PIN,
        // .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(SLE_UART_BUS);
    uapi_uart_init(SLE_UART_BUS, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}

以下这部分的代码,首先通过 uapi_uart_register_rx_callback() 注册串口中断回调,在回调函数中将串口接收到的数据通过sle_uart_server_send_report_by_handle() 函数发送出去。另外使用sle_uart_server_init函数注册星闪数据接收回调,在ssaps_server_write_request_cbk回调函数中将星闪接收到的数据使用uapi_uart_write函数通过串口发送出来。

static void ssaps_server_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para,
    errcode_t status)
{
    printf("%s ssaps write request callback cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
        SLE_UART_SERVER_LOG, server_id, conn_id, write_cb_para->handle, status);
    if ((write_cb_para->length > 0) && write_cb_para->value) {
        printf("\n sle uart recived data : %s\r\n", write_cb_para->value);
        uapi_uart_write(SLE_UART_BUS, (uint8_t *)write_cb_para->value, write_cb_para->length, 0);
    }
}

static void sle_uart_server_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    if (sle_uart_client_is_connected()) {
        sle_uart_server_send_report_by_handle(buffer, length);
    } else {
        printf("%s sle client is not connected! \r\n", SLE_UART_SERVER_LOG);
    }
}

static void *sle_uart_server_task(const char *arg)
{
    unused(arg);

    sle_uart_server_init(ssaps_server_read_request_cbk, ssaps_server_write_request_cbk);

    /* UART init config. */
    uart_init_config();

    uapi_uart_unregister_rx_callback(SLE_UART_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(SLE_UART_BUS,
                                                   UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
                                                   1, sle_uart_server_read_int_handler);
    if (ret != ERRCODE_SUCC) {
        printf("%s Register uart callback fail.[%x]\r\n", SLE_UART_SERVER_LOG, ret);
        return NULL;
    }
    while (1) {
        osDelay(SLE_UART_TASK_DURATION_MS);
    }
    return NULL;
}

三、编译代码

编译 SLE UART Client代码

修改 device\bearpi\bearpi_hm_nano2\app路径下 BUILD.gn 文件,指定 sle_uart_client 参与编译。

"E1_sle_uart_client:example",
# "E2_sle_uart_server:example",
# "E3_sle_gateway_client_udp:example",
# "E4_sle_gateway_server_udp:example",
# "E5_sle_gateway_client_oc:example",
# "E6_sle_gateway_server_oc:example",      

编译 SLE UART Server代码

修改 device\bearpi\bearpi_hm_nano2\app路径下 BUILD.gn 文件,指定 sle_uart_server 参与编译。

"E1_sle_uart_client:example",
# "E2_sle_uart_server:example",
# "E3_sle_gateway_client_udp:example",
# "E4_sle_gateway_server_udp:example",
# "E5_sle_gateway_client_oc:example",
# "E6_sle_gateway_server_oc:example",      

四、测试

烧录固件后先启动server设备,再启动client设备,在串口工具的输入框中输入数据并发送,测试server和client设备之间的数据收发,如下图所示。

Alt text