1238 lines
28 KiB
C
Executable File
1238 lines
28 KiB
C
Executable File
// Copyright 2022-2023 Beken
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
|
|
#include <os/mem.h>
|
|
#include "string.h"
|
|
|
|
#include <common/bk_include.h>
|
|
|
|
#include "bk_uart.h"
|
|
|
|
#include "sdio_utils.h"
|
|
#include "sdio_slave_driver.h"
|
|
#include "sdio_test.h"
|
|
#if CONFIG_TRNG_SUPPORT
|
|
#include "driver/trng.h"
|
|
#endif
|
|
#include <driver/aon_rtc.h>
|
|
#include "driver/wdt.h"
|
|
#include "bk_wdt.h"
|
|
|
|
|
|
#if CONFIG_SDIO_TEST_EN
|
|
|
|
static bool s_sdio_test_inited = false;
|
|
static beken_queue_t s_sdio_test_msg_que = NULL;
|
|
static beken_thread_t s_test_sdio_thread = NULL;
|
|
|
|
static volatile uint8_t s_sdio_test_main_case;
|
|
static volatile uint8_t s_sdio_test_sub_case;
|
|
|
|
#define SDIO_CHAN_MAX_CNT 2
|
|
|
|
//static beken_thread_t s_sdio_test_thread_handle = NULL;
|
|
|
|
#define SDIO_BUFFER_SIZE 2048
|
|
|
|
//tx/rx has seperate thread, then it can random tx/rx, on only one thread, tx/rx has to one by one
|
|
static beken_thread_t s_tx_thread_handle[SDIO_CHAN_MAX_CNT];
|
|
static beken_queue_t s_sdio_ch_x_tx_msg_que[SDIO_CHAN_MAX_CNT];
|
|
static volatile uint32_t s_tx_tp_sub_case[SDIO_CHAN_MAX_CNT];
|
|
|
|
static beken_thread_t s_rx_thread_handle[SDIO_CHAN_MAX_CNT];
|
|
static beken_queue_t s_sdio_ch_x_rx_msg_que[SDIO_CHAN_MAX_CNT];
|
|
static volatile uint32_t s_rx_tp_sub_case[SDIO_CHAN_MAX_CNT];
|
|
|
|
static sdio_tp_statisic_t s_tx_tp_statistic[SDIO_CHAN_MAX_CNT];
|
|
static sdio_tp_statisic_t s_rx_tp_statistic[SDIO_CHAN_MAX_CNT];
|
|
#if CONFIG_TRNG_SUPPORT
|
|
static uint32_t wait_ms = 3000;
|
|
static uint32_t rx_wait_ms = 0;
|
|
#endif
|
|
|
|
#if 0
|
|
static bk_err_t sdio_test_tx_cb(sdio_node_ptr_t head_p, sdio_node_ptr_t tail_p, uint32_t count)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
sdio_node_ptr_t cur_p = head_p;
|
|
uint32_t i = count, j = 0;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
//check tx data after finish
|
|
while(cur_p && (i > 0))
|
|
{
|
|
for(j = 0; j < cur_p->len; j += 4)
|
|
{
|
|
os_printf("0x%08x ", *(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j));
|
|
if(j % 16 == 0)
|
|
os_printf("\r\n");
|
|
}
|
|
|
|
cur_p = cur_p->next;
|
|
i--;
|
|
}
|
|
|
|
//TODO:release buffer
|
|
//WARNING: Application should should use self CHAN_ID and CHAN_DIRECT.
|
|
bk_sdio_chan_push_free_list(SDIO_CHAN_PLATFORM, SDIO_CHAN_TX, head_p, tail_p, count);
|
|
|
|
//notify app task finish read
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
#else
|
|
static bk_err_t sdio_test_tx_cb( sdio_node_ptr_t head_p, sdio_node_ptr_t tail_p, uint32_t count)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
sdio_chan_id_t chan_id = SDIO_CHAN_PLATFORM;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
if(s_sdio_ch_x_tx_msg_que[chan_id % SDIO_CHAN_MAX_CNT])
|
|
{
|
|
|
|
sdio_test_tp_msg_t msg;
|
|
|
|
msg.param1 = chan_id % SDIO_CHAN_MAX_CNT;
|
|
msg.param2 = (uint32_t)head_p;
|
|
msg.param3 = (uint32_t)tail_p;
|
|
msg.param4 = count;
|
|
|
|
ret = rtos_push_to_queue(&s_sdio_ch_x_tx_msg_que[chan_id % SDIO_CHAN_MAX_CNT], &msg, BEKEN_NO_WAIT);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("sdio test tx msg failed\r\n");
|
|
}
|
|
|
|
}
|
|
else //sync:
|
|
{
|
|
//TODO:release buffer to free list mem-pool
|
|
//WARNING: Application should should use self CHAN_ID and CHAN_DIRECT.
|
|
ret = bk_sdio_chan_push_free_list(chan_id, SDIO_CHAN_TX, head_p, tail_p, count);
|
|
if(ret)
|
|
{
|
|
SDIO_LOG_ERR("err release buff");
|
|
}
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
//notify app task finish write
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
static bk_err_t sdio_test_tx_init(uint32_t chan_id, uint32_t buf_cnt, uint32_t buf_size)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
ret = bk_sdio_init_channel(chan_id, SDIO_CHAN_TX, buf_cnt, buf_size);
|
|
if(ret != BK_OK)
|
|
{
|
|
SDIO_LOG_ERR("init channel");
|
|
return ret;
|
|
}
|
|
bk_sdio_register_chan_cb(chan_id, SDIO_CHAN_TX, (sdio_chan_cb_t)sdio_test_tx_cb);
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
|
|
////////////////////////////////////////////
|
|
|
|
volatile uint8_t g_sdio_log_level = SDIO_LOG_DEBUG_LEVEL;
|
|
|
|
void sdio_set_log_level(uint8_t level)
|
|
{
|
|
SDIO_LOG_ERR("%s:%d", __func__, level);
|
|
g_sdio_log_level = level;
|
|
}
|
|
|
|
|
|
void sdio_set_tx_delay_time(uint32_t time_ms){
|
|
wait_ms = time_ms;
|
|
}
|
|
|
|
void sdio_set_rx_delay_time(uint32_t time_ms){
|
|
rx_wait_ms = time_ms;
|
|
}
|
|
|
|
|
|
|
|
extern uint32_t sdio_list_compute_total_length(sdio_list_t *list_p);
|
|
|
|
|
|
static void sdio_test_tx_tp_thread(void *arg)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
sdio_chan_id_t chan_id = (sdio_chan_id_t)arg;
|
|
uint32_t val_test[SDIO_CHAN_MAX_CNT] = {0};
|
|
struct timeval rtc_start_time = {0, 0};
|
|
|
|
#if (CONFIG_TASK_WDT)
|
|
bk_task_wdt_stop();
|
|
#endif
|
|
|
|
while(1)
|
|
{
|
|
sdio_test_tp_msg_t msg;
|
|
sdio_node_ptr_t buf_p = NULL;
|
|
uint32_t len = SDIO_TEST_BUFFER_SIZE * SDIO_TEST_BUFFER_CNT;
|
|
uint32_t size = 0;
|
|
|
|
if(s_tx_tp_sub_case[chan_id] == 0)
|
|
{
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//wait_ms = bk_rand() % 1000;
|
|
//rtos_delay_milliseconds(wait_ms);
|
|
#endif
|
|
|
|
if(s_tx_tp_statistic[chan_id].end_time)
|
|
{
|
|
sdio_set_log_level(SDIO_LOG_DEBUG_LEVEL);
|
|
|
|
SDIO_LOG_ERR("TP:start_t=%u,end_t=%u, period_t=%u, cnt=%d,len=%d",
|
|
(uint32_t)s_tx_tp_statistic[chan_id].start_time,
|
|
(uint32_t)s_tx_tp_statistic[chan_id].end_time,
|
|
(uint32_t)(s_tx_tp_statistic[chan_id].end_time - s_tx_tp_statistic[chan_id].start_time),
|
|
s_tx_tp_statistic[chan_id].payload_cnt,
|
|
s_tx_tp_statistic[chan_id].total_len);
|
|
}
|
|
|
|
s_tx_tp_statistic[chan_id].start_time = 0;
|
|
s_tx_tp_statistic[chan_id].end_time = 0;
|
|
|
|
continue;
|
|
}
|
|
else if(s_tx_tp_statistic[chan_id].start_time == 0) //start, first entry
|
|
{
|
|
sdio_set_log_level(SDIO_LOG_ERR_LEVEL);
|
|
//s_tx_tp_statistic[chan_id].start_time = riscv_get_mtimer();
|
|
bk_rtc_gettimeofday(&rtc_start_time, 0);
|
|
s_tx_tp_statistic[chan_id].start_time = 1000000 * (rtc_start_time.tv_sec) + rtc_start_time.tv_usec;
|
|
}
|
|
|
|
//request write buf
|
|
ret = bk_sdio_chan_pop_free_node(chan_id, SDIO_CHAN_TX, &buf_p, &size);
|
|
if((ret == BK_OK) && buf_p)
|
|
{
|
|
s_tx_tp_statistic[chan_id].payload_cnt++;
|
|
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//len = bk_rand() % SDIO_TEST_BUFFER_SIZE;
|
|
#endif
|
|
SDIO_LOG_INFO("pop node, len = %d, size = %d\n", len, size);
|
|
len = len < size? len : size;
|
|
|
|
|
|
uint32_t *ptmp = (uint32_t *)((uint8_t *)buf_p + sizeof(sdio_node_t));
|
|
|
|
for (int i = 0; i < len/4; i++) {
|
|
//*ptmp = val_test[chan_id] + 0x10000000 * (chan_id);
|
|
*ptmp = val_test[chan_id] + (0x90000000);
|
|
ptmp++;
|
|
}
|
|
SDIO_LOG_INFO("val_test[%d] = 0x%x\n", chan_id, val_test[chan_id]);
|
|
val_test[chan_id]++;
|
|
|
|
#if 0
|
|
buf_p->pbd.len = len + sizeof(sdio_sw_pbd_t); //SDIO ASIC will read this value to SDIO FIFO
|
|
buf_p->sw_pbd.len = len; //valid data size, exclude sdio_sw_pbd_t
|
|
buf_p->sw_pbd.type = sdio_get_core_id();
|
|
buf_p->sw_pbd.sub_type = chan_id;
|
|
#else
|
|
buf_p->len = len;
|
|
#endif
|
|
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//wait_ms = bk_rand() % 20;
|
|
rtos_delay_milliseconds(wait_ms);
|
|
|
|
#endif
|
|
//request read
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
ret = bk_sdio_slave_sync_write(chan_id, buf_p, buf_p, 1, BEKEN_WAIT_FOREVER);
|
|
#else
|
|
ret = bk_sdio_slave_sync_write(chan_id, buf_p, buf_p, 1);
|
|
#endif
|
|
if(ret)
|
|
{
|
|
SDIO_LOG_ERR("write fail");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SDIO_LOG_ERR("no free buff");
|
|
}
|
|
//wait write finish
|
|
ret = rtos_pop_from_queue(&s_sdio_ch_x_tx_msg_que[chan_id], &msg, SDIO_TEST_TP_MSG_WAIT_TIME);
|
|
if (kNoErr == ret)
|
|
{
|
|
sdio_list_t list;
|
|
//deal APP data
|
|
list.head = (sdio_node_ptr_t)msg.param2;
|
|
list.tail = (sdio_node_ptr_t)msg.param3;
|
|
list.count = msg.param4;
|
|
s_tx_tp_statistic[chan_id].total_len += sdio_list_compute_total_length(&list);
|
|
|
|
//release buffer
|
|
ret = bk_sdio_chan_push_free_list(chan_id, SDIO_CHAN_TX, list.head, list.tail, list.count);
|
|
} else {
|
|
SDIO_LOG_ERR("TX Tp rtos_pop_from_queue error\r\n");
|
|
}
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
}
|
|
|
|
|
|
|
|
static bk_err_t sdio_test_tx_tp_init(uint32_t chan_id, uint32_t buf_cnt, uint32_t buf_size)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
char str_name[64];
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
bk_trng_start();
|
|
#endif
|
|
|
|
//tx hasn't init thread
|
|
if(s_tx_thread_handle[chan_id] == NULL)
|
|
{
|
|
memset(str_name, 0, sizeof(str_name));
|
|
snprintf(str_name, sizeof(str_name), "%s_ch%d_dir%d", SDIO_TEST_TP_THREAD_NAME, (int32_t)chan_id, SDIO_CHAN_TX);
|
|
ret = rtos_create_thread(
|
|
&s_tx_thread_handle[chan_id],
|
|
SDIO_TEST_TX_TP_PRIORITY+chan_id,
|
|
str_name,
|
|
sdio_test_tx_tp_thread,
|
|
SDIO_TEST_TX_TP_THREAD_STACK_SIZE,
|
|
(beken_thread_arg_t)chan_id
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init thread ret=%d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
//tx notify queue init
|
|
if(s_sdio_ch_x_tx_msg_que[chan_id] == NULL)
|
|
{
|
|
memset(str_name, 0, sizeof(str_name));
|
|
snprintf(str_name, sizeof(str_name), "%s_ch%d", SDIO_TEST_TX_TP_MSG_QUEUE_NAME, (int32_t)chan_id);
|
|
ret = rtos_init_queue(&s_sdio_ch_x_tx_msg_que[chan_id],
|
|
str_name,
|
|
sizeof(sdio_test_tp_msg_t),
|
|
SDIO_TEST_TX_TP_MSG_QUEUE_COUNT
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init queue ret=%d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
ret = sdio_test_tx_init(chan_id, buf_cnt, buf_size);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("tx init fail=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
|
static bk_err_t sdio_test_tx_sub_case(SDIO_TEST_MSG_T *msg_p)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
|
|
|
|
switch(msg_p->sub_case)
|
|
{
|
|
//chan id, buf_cnt, buf_size
|
|
case SDIO_TEST_TX_INIT:
|
|
{
|
|
sdio_chan_id_t id = msg_p->param1;
|
|
uint32_t buf_size = msg_p->param2;
|
|
uint32_t buf_cnt = msg_p->param3;
|
|
|
|
ret = sdio_test_tx_init(id, buf_cnt, buf_size);
|
|
break;
|
|
}
|
|
|
|
//len, value
|
|
case SDIO_TEST_TX_SINGLE_PACKET:
|
|
{
|
|
sdio_node_ptr_t buf_p = NULL;
|
|
uint32_t len = msg_p->param1;
|
|
uint32_t value = (uint32_t)msg_p->param2;
|
|
uint32_t size;
|
|
|
|
ret = bk_sdio_chan_pop_free_node(SDIO_CHAN_PLATFORM, SDIO_CHAN_TX, &buf_p, &size);
|
|
if((ret == BK_OK) && buf_p)
|
|
{
|
|
//fill data
|
|
if(len > size)
|
|
{
|
|
len = size;
|
|
SDIO_LOG_ERR("max packet size=%d, len=%d", size, len);
|
|
}
|
|
|
|
if(value == 12345678) {
|
|
|
|
#if 0
|
|
for (int i = 0; i < len; i++) {
|
|
//buf_p[i]
|
|
*((uint8_t *)(buf_p + sizeof(sdio_node_t) + i)) = i & 0xff;
|
|
}
|
|
|
|
#else
|
|
memset((uint8_t *)buf_p + sizeof(sdio_node_t), 0, len);
|
|
|
|
uint8_t *send_data = (uint8_t *)os_zalloc(len);
|
|
if (send_data == NULL) {
|
|
os_printf("send buffer malloc failed\r\n");
|
|
break;
|
|
}
|
|
for (int i = 0; i < len; i++) {
|
|
send_data[i] = i & 0xff;
|
|
}
|
|
memcpy((uint8_t *)buf_p + sizeof(sdio_node_t), send_data, len);
|
|
os_free(send_data);
|
|
#endif
|
|
|
|
} else {
|
|
memset((uint8_t *)buf_p + sizeof(sdio_node_t), value, len);
|
|
}
|
|
|
|
|
|
buf_p->len = len;
|
|
|
|
//request write
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
ret = bk_sdio_slave_sync_write(SDIO_CHAN_PLATFORM, buf_p, buf_p, 1, BEKEN_WAIT_FOREVER);
|
|
#else
|
|
ret = bk_sdio_slave_sync_write(SDIO_CHAN_PLATFORM, buf_p, buf_p, 1);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
SDIO_LOG_ERR("no free buff");
|
|
ret = BK_FAIL;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_TX_MANY_SINGLE_PACKETS:
|
|
{
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_TX_MULTI_PACKETS:
|
|
{
|
|
break;
|
|
}
|
|
|
|
//chan id, buf_cnt, buf_size
|
|
case SDIO_TEST_TX_TP_INIT:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1;
|
|
uint32_t buf_size = msg_p->param2;
|
|
uint32_t buf_cnt = msg_p->param3;
|
|
|
|
ret = sdio_test_tx_tp_init(chan_id, buf_cnt, buf_size);
|
|
break;
|
|
}
|
|
|
|
//len, value
|
|
case SDIO_TEST_TX_TP_START:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1 % SDIO_CHAN_MAX_CNT;
|
|
wait_ms = msg_p->param2;
|
|
s_tx_tp_sub_case[chan_id] = 1;
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_TX_TP_STOP:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1 % SDIO_CHAN_MAX_CNT;
|
|
struct timeval rtc_end_time = {0, 0};
|
|
bk_rtc_gettimeofday(&rtc_end_time, 0);
|
|
s_tx_tp_statistic[chan_id].end_time = 1000000 * (rtc_end_time.tv_sec) + rtc_end_time.tv_usec;
|
|
|
|
s_tx_tp_sub_case[chan_id] = 0;
|
|
break;
|
|
}
|
|
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
case SDIO_TEST_TX_SINGLE_BUF:
|
|
{
|
|
extern bk_err_t bk_sdio_slave_tx(char* buf_p, uint32_t len, uint32_t timeout_ms);
|
|
|
|
uint32_t timeout = 20000;
|
|
uint32_t buf_len = msg_p->param1;
|
|
uint8_t *send_data = (uint8_t *)os_zalloc(buf_len);
|
|
if (send_data == NULL) {
|
|
SDIO_LOG_ERR("send buffer malloc failed\r\n");
|
|
return ret;
|
|
}
|
|
for (int i = 0; i < buf_len; i++) {
|
|
send_data[i] = i & 0xff;
|
|
}
|
|
bk_sdio_slave_tx((char* )send_data, buf_len, timeout);
|
|
if (send_data) {
|
|
os_free(send_data);
|
|
}
|
|
send_data = NULL;
|
|
SDIO_LOG_INFO("sdio send raw data, data_len=%d\n", buf_len);
|
|
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
#if 0
|
|
static bk_err_t sdio_test_rx_cb(sdio_node_ptr_t head_p, sdio_node_ptr_t tail_p, uint32_t count)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
sdio_node_ptr_t cur_p = head_p;
|
|
uint32_t i = count, j = 0;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
//deal data
|
|
while(cur_p && (i > 0))
|
|
{
|
|
for(j = 0; j < cur_p->len; j += 4)
|
|
{
|
|
os_printf("0x%08x ", *(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j));
|
|
if(j % 16 == 0)
|
|
os_printf("\r\n");
|
|
}
|
|
|
|
cur_p = cur_p->next;
|
|
i--;
|
|
}
|
|
|
|
//TODO:release buffer to free list mem-pool
|
|
//WARNING: Application should should use self CHAN_ID and CHAN_DIRECT.
|
|
ret = bk_sdio_chan_push_free_list(SDIO_CHAN_PLATFORM, SDIO_CHAN_RX, head_p, tail_p, count);
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
|
|
static bk_err_t sdio_test_rx_cb( sdio_node_ptr_t head_p, sdio_node_ptr_t tail_p, uint32_t count)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
static uint32_t rx_val_test[SDIO_CHAN_MAX_CNT] = {0};
|
|
int print_len = 2048;
|
|
sdio_chan_id_t chan_id = SDIO_CHAN_PLATFORM;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
//async: notify APP rx thread, default usage method
|
|
if(s_sdio_ch_x_rx_msg_que[chan_id % SDIO_CHAN_MAX_CNT])
|
|
{
|
|
|
|
//dump received data to check data validation
|
|
sdio_node_ptr_t cur_p = head_p;
|
|
uint32_t i = count, j = 0;
|
|
while(cur_p && (i > 0))
|
|
{
|
|
//not print received data by default
|
|
#if 0
|
|
os_printf("core_id=0x%x, payload cur_p=0x%08x \r\n", chan_id, cur_p);
|
|
for(j = 0; j < print_len; j += sizeof(uint32_t))
|
|
{
|
|
os_printf("0x%08x ", *(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j));
|
|
if(j && (j % 16 == 0))
|
|
os_printf("\r\n");
|
|
}
|
|
#else
|
|
for (j = 4; j < print_len - 4; j += sizeof(uint32_t)) {
|
|
if(*(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j) != (rx_val_test[chan_id] + 0x10000000 * (chan_id))) {
|
|
os_printf("rx_tp_cb error, cur_p_word[%d] = 0x%x, correct value is 0x%x.\n" , j, *(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j), (rx_val_test[chan_id] + 0x10000000 * (chan_id)) );
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
rx_val_test[chan_id]++;
|
|
|
|
cur_p = (sdio_node_ptr_t)cur_p->next;
|
|
i--;
|
|
}
|
|
/////////////////
|
|
|
|
sdio_test_tp_msg_t msg;
|
|
|
|
msg.param1 = chan_id % SDIO_CHAN_MAX_CNT;
|
|
msg.param2 = (uint32_t)head_p;
|
|
msg.param3 = (uint32_t)tail_p;
|
|
msg.param4 = count;
|
|
|
|
ret = rtos_push_to_queue(&s_sdio_ch_x_rx_msg_que[chan_id % SDIO_CHAN_MAX_CNT], &msg, BEKEN_NO_WAIT);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("sdio test rx msg failed\r\n");
|
|
}
|
|
|
|
}
|
|
else //sync:
|
|
{
|
|
|
|
sdio_node_ptr_t cur_p = head_p;
|
|
uint32_t i = count, j = 0;
|
|
|
|
//deal data
|
|
while(cur_p && (i > 0))
|
|
{
|
|
os_printf("sync: chan_id=0x%x, payload cur_p=0x%08x \r\n", chan_id, cur_p);
|
|
|
|
for(j = 0; j < print_len; j += sizeof(uint32_t))
|
|
{
|
|
|
|
os_printf("0x%08x ", *(uint32_t *)((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j));
|
|
|
|
if(j && (j % 16 == 0))
|
|
os_printf("\r\n");
|
|
}
|
|
|
|
#if 0
|
|
extern uint32_t looptest_flag;
|
|
if (looptest_flag == 1) {
|
|
for (j = 0; j < (cur_p->sw_pbd.len - 4); j++) {
|
|
if( *((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j) != ((j + 0x84) % 256)) {
|
|
os_printf("loopback error, cur_p_byte[%d] = 0x%x, correct value is 0x%x.\n" , j, *((uint8_t *)cur_p + (sizeof(sdio_node_t)) + j), ((j + 0x80) % 256) );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
os_printf("\r\n");
|
|
|
|
cur_p = (sdio_node_ptr_t)cur_p->next;
|
|
i--;
|
|
}
|
|
|
|
//TODO:release buffer to free list mem-pool
|
|
//WARNING: Application should should use self CHAN_ID and CHAN_DIRECT.
|
|
ret = bk_sdio_chan_push_free_list(chan_id, SDIO_CHAN_RX, head_p, tail_p, count);
|
|
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
static bk_err_t sdio_test_rx_init(uint32_t chan_id, uint32_t buf_cnt, uint32_t buf_size)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
ret = bk_sdio_init_channel(chan_id, SDIO_CHAN_RX, buf_cnt, buf_size);
|
|
if(ret != BK_OK)
|
|
{
|
|
SDIO_LOG_ERR("init channel");
|
|
return ret;
|
|
}
|
|
|
|
ret = bk_sdio_register_chan_cb(chan_id, SDIO_CHAN_RX, (sdio_chan_cb_t)sdio_test_rx_cb);
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//one channel one thread
|
|
static void sdio_test_rx_tp_thread(void *arg)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
sdio_chan_id_t chan_id = (sdio_chan_id_t)arg%SDIO_CHAN_MAX_CNT;
|
|
struct timeval rtc_start_time = {0, 0};
|
|
|
|
#if (CONFIG_TASK_WDT)
|
|
bk_task_wdt_stop();
|
|
#endif
|
|
|
|
while(1)
|
|
{
|
|
sdio_test_tp_msg_t msg;
|
|
sdio_node_ptr_t buf_p = NULL;
|
|
uint32_t len = SDIO_TEST_BUFFER_SIZE * SDIO_TEST_BUFFER_CNT ;
|
|
#if 0
|
|
uint32_t value = 0;
|
|
#endif
|
|
uint32_t size = 0;
|
|
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//rx_wait_ms = bk_rand() % 1000;
|
|
#endif
|
|
//rtos_delay_milliseconds(rx_wait_ms);
|
|
|
|
if(s_rx_tp_sub_case[chan_id] == 0) //stop status
|
|
{
|
|
if(s_rx_tp_statistic[chan_id].end_time)
|
|
{
|
|
sdio_set_log_level(SDIO_LOG_DEBUG_LEVEL);
|
|
|
|
SDIO_LOG_ERR("TP:start_t=%u,end_t=%u,period_t=%u,cnt=%d,len=%d",
|
|
(uint32_t)s_rx_tp_statistic[chan_id].start_time,
|
|
(uint32_t)s_rx_tp_statistic[chan_id].end_time,
|
|
(uint32_t)(s_rx_tp_statistic[chan_id].end_time - s_rx_tp_statistic[chan_id].start_time),
|
|
s_rx_tp_statistic[chan_id].payload_cnt,
|
|
s_rx_tp_statistic[chan_id].total_len);
|
|
}
|
|
s_rx_tp_statistic[chan_id].start_time = 0;
|
|
s_rx_tp_statistic[chan_id].end_time = 0;
|
|
|
|
continue;
|
|
}
|
|
else if(s_rx_tp_statistic[chan_id].start_time == 0) //start, first entry
|
|
{
|
|
sdio_set_log_level(SDIO_LOG_ERR_LEVEL);
|
|
|
|
bk_rtc_gettimeofday(&rtc_start_time, 0);
|
|
s_rx_tp_statistic[chan_id].start_time = 1000000 * (rtc_start_time.tv_sec) + rtc_start_time.tv_usec;
|
|
}
|
|
|
|
//request read buf
|
|
ret = bk_sdio_chan_pop_free_node(chan_id, SDIO_CHAN_RX, &buf_p, &size);
|
|
if((ret == BK_OK) && buf_p)
|
|
{
|
|
s_rx_tp_statistic[chan_id].payload_cnt++;
|
|
|
|
len = len < size? len : size;
|
|
#if 0
|
|
//fill dirty data
|
|
if(value == 12345678)
|
|
{
|
|
for(uint32_t i = 0; i < len; i++)
|
|
*(uint8_t *)((uint8_t *)buf_p + sizeof(sdio_node_t) + i) = i & 0xff;
|
|
}
|
|
else
|
|
{
|
|
memset((uint8_t *)buf_p + sizeof(sdio_node_t), value, len);
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
buf_p->pbd.len = len + sizeof(sdio_sw_pbd_t); //SDIO ASIC will read this value to SDIO FIFO
|
|
buf_p->sw_pbd.len = len; //valid data size, exclude sdio_sw_pbd_t
|
|
#else
|
|
buf_p->len = len;
|
|
#endif
|
|
|
|
|
|
//request read
|
|
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
ret = bk_sdio_slave_sync_read(chan_id, buf_p, buf_p, 1, BEKEN_WAIT_FOREVER);
|
|
#else
|
|
ret = bk_sdio_slave_sync_read(chan_id, buf_p, buf_p, 1);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//rx_wait_ms = bk_rand() % 1000;
|
|
#endif
|
|
//SDIO_LOG_DEBUG("rx tp no free node, all nodes poped.");
|
|
//SDIO_LOG_ERR("rx tp no free node, all nodes poped.");
|
|
|
|
//rtos_delay_milliseconds(rx_wait_ms);
|
|
}
|
|
|
|
//wait read finish
|
|
#if (CONFIG_TRNG_SUPPORT)
|
|
//rx_wait_ms = bk_rand() % 10;
|
|
#endif
|
|
ret = rtos_pop_from_queue(&s_sdio_ch_x_rx_msg_que[chan_id], &msg, SDIO_TEST_TP_MSG_WAIT_TIME);
|
|
if (kNoErr == ret)
|
|
{
|
|
sdio_list_t list;
|
|
//deal APP data
|
|
list.head = (sdio_node_ptr_t)msg.param2;
|
|
list.tail = (sdio_node_ptr_t)msg.param3;
|
|
list.count = msg.param4;
|
|
s_rx_tp_statistic[chan_id].total_len += sdio_list_compute_total_length(&list);
|
|
|
|
//release buffer
|
|
ret = bk_sdio_chan_push_free_list(chan_id, SDIO_CHAN_RX, list.head, list.tail, list.count);
|
|
} else {
|
|
//SDIO_LOG_ERR("RX rtos_pop_from_queue error\r\n");
|
|
}
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
}
|
|
|
|
|
|
|
|
|
|
static bk_err_t sdio_test_rx_tp_init(uint32_t chan_id, uint32_t buf_cnt, uint32_t buf_size)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
char str_name[64];
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
//rx hasn't init thread
|
|
if(s_rx_thread_handle[chan_id] == NULL)
|
|
{
|
|
memset(str_name, 0, sizeof(str_name));
|
|
snprintf(str_name, sizeof(str_name), "%s_ch%d_dir%d", SDIO_TEST_TP_THREAD_NAME, (int32_t)chan_id, SDIO_CHAN_RX);
|
|
ret = rtos_create_thread(
|
|
&s_rx_thread_handle[chan_id],
|
|
SDIO_TEST_RX_TP_PRIORITY+chan_id,
|
|
str_name,
|
|
sdio_test_rx_tp_thread,
|
|
SDIO_TEST_RX_TP_THREAD_STACK_SIZE,
|
|
(beken_thread_arg_t)chan_id
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init thread ret=%d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
//rx notify queue init
|
|
if(s_sdio_ch_x_rx_msg_que[chan_id] == NULL)
|
|
{
|
|
memset(str_name, 0, sizeof(str_name));
|
|
snprintf(str_name, sizeof(str_name), "%s_ch%d", SDIO_TEST_RX_TP_MSG_QUEUE_NAME, (int32_t)chan_id);
|
|
ret = rtos_init_queue(&s_sdio_ch_x_rx_msg_que[chan_id],
|
|
str_name,
|
|
sizeof(sdio_test_tp_msg_t),
|
|
SDIO_TEST_RX_TP_MSG_QUEUE_COUNT
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init queue ret=%d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
ret = sdio_test_rx_init(chan_id, buf_cnt, buf_size);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("rx init fail=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
static bk_err_t sdio_test_rx_sub_case(SDIO_TEST_MSG_T *msg_p)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
switch(msg_p->sub_case)
|
|
{
|
|
//chan id, buf_cnt, buf_size
|
|
case SDIO_TEST_RX_INIT:
|
|
{
|
|
sdio_chan_id_t id = msg_p->param1;
|
|
uint32_t buf_size = msg_p->param2;
|
|
uint32_t buf_cnt = msg_p->param3;
|
|
|
|
ret = sdio_test_rx_init(id, buf_cnt, buf_size);
|
|
break;
|
|
}
|
|
|
|
//len, value
|
|
case SDIO_TEST_RX_SINGLE_PACKET:
|
|
{
|
|
sdio_node_ptr_t buf_p = NULL;
|
|
uint32_t len = msg_p->param1;
|
|
uint8_t value = (uint8_t)msg_p->param2;
|
|
uint32_t size = 0;
|
|
|
|
ret = bk_sdio_chan_pop_free_node(SDIO_CHAN_PLATFORM, SDIO_CHAN_RX, &buf_p, &size);
|
|
if((ret == BK_OK) && buf_p)
|
|
{
|
|
len = len < size? len : size;
|
|
//fill dirty data
|
|
memset((uint8_t *)buf_p + sizeof(sdio_node_t), value, len);
|
|
buf_p->len = len;
|
|
|
|
//request read
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
ret = bk_sdio_slave_sync_read(SDIO_CHAN_PLATFORM, buf_p, buf_p, 1, BEKEN_WAIT_FOREVER);
|
|
#else
|
|
ret = bk_sdio_slave_sync_read(SDIO_CHAN_PLATFORM, buf_p, buf_p, 1);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
SDIO_LOG_ERR("no free buff");
|
|
ret = BK_FAIL;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_RX_MANY_SINGLE_PACKETS:
|
|
{
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_RX_MULTI_PACKETS:
|
|
{
|
|
break;
|
|
}
|
|
|
|
|
|
//chan id, buf_cnt, buf_size
|
|
case SDIO_TEST_RX_TP_INIT:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1;
|
|
uint32_t buf_size = msg_p->param2;
|
|
uint32_t buf_cnt = msg_p->param3;
|
|
|
|
ret = sdio_test_rx_tp_init(chan_id, buf_cnt, buf_size);
|
|
break;
|
|
}
|
|
|
|
//len, value
|
|
case SDIO_TEST_RX_TP_START:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1 % SDIO_CHAN_MAX_CNT;
|
|
rx_wait_ms = msg_p->param2;
|
|
s_rx_tp_sub_case[chan_id] = 1;
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_RX_TP_STOP:
|
|
{
|
|
sdio_chan_id_t chan_id = msg_p->param1 % SDIO_CHAN_MAX_CNT;
|
|
struct timeval rtc_end_time = {0, 0};
|
|
bk_rtc_gettimeofday(&rtc_end_time, 0);
|
|
s_rx_tp_statistic[chan_id].end_time = 1000000 * (rtc_end_time.tv_sec) + rtc_end_time.tv_usec;
|
|
s_rx_tp_sub_case[chan_id] = 0;
|
|
break;
|
|
}
|
|
|
|
#if CONFIG_SDIO_SYNC_TRANS
|
|
case SDIO_TEST_RX_SINGLE_BUF:
|
|
{
|
|
extern bk_err_t bk_sdio_slave_rx(char* buf_p, uint32_t len, uint32_t timeout_ms);
|
|
|
|
uint32_t timeout = 20000;
|
|
uint32_t buf_len = msg_p->param1;
|
|
uint8_t *recv_data = (uint8_t *)os_malloc(buf_len);
|
|
if (recv_data == NULL) {
|
|
SDIO_LOG_ERR("recv buffer malloc failed\r\n");
|
|
return ret;
|
|
}
|
|
os_memset(recv_data, 0xff, buf_len);
|
|
bk_sdio_slave_rx((char* )recv_data, buf_len, timeout);
|
|
SDIO_LOG_INFO("sdio dma recv, data_len=%d\n", buf_len);
|
|
for (int i = 0; i < buf_len; i++) {
|
|
SDIO_LOG_INFO("recv_buffer[%d]=0x%x\n", i, recv_data[i]);
|
|
}
|
|
if (recv_data) {
|
|
os_free(recv_data);
|
|
}
|
|
recv_data = NULL;
|
|
|
|
|
|
break;
|
|
}
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
|
|
static bk_err_t sdio_test_send_msg(SDIO_TEST_MSG_T *msg_p)
|
|
{
|
|
bk_err_t ret = BK_FAIL;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
if (s_sdio_test_msg_que)
|
|
{
|
|
ret = rtos_push_to_queue(&s_sdio_test_msg_que, msg_p, BEKEN_NO_WAIT);
|
|
if (kNoErr != ret)
|
|
SDIO_LOG_ERR("sdio test send msg failed\r\n");
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the sdio test case.
|
|
*
|
|
* This API set the sdio driver test case.
|
|
* - It will tested with the selected case.
|
|
* - Every case param has itself mean.
|
|
*
|
|
* @attention 1. This API should be called after sdio test inited.
|
|
*
|
|
* @return
|
|
* - BK_OK: succeed
|
|
* - others: other errors.
|
|
*/
|
|
bk_err_t bk_sdio_set_test_case(
|
|
uint8_t main_case,
|
|
uint8_t sub_case,
|
|
uint32_t param1,
|
|
uint32_t param2,
|
|
uint32_t param3,
|
|
uint32_t param4
|
|
)
|
|
{
|
|
SDIO_TEST_MSG_T msg;
|
|
|
|
if(main_case >= SDIO_TEST_MAX_MAIN_CASE)
|
|
{
|
|
SDIO_LOG_ERR("main case id %d is big then %d", main_case, SDIO_TEST_MAX_MAIN_CASE);
|
|
return BK_FAIL;
|
|
}
|
|
|
|
msg.main_case = main_case;
|
|
msg.sub_case = sub_case;
|
|
msg.param1 = param1;
|
|
msg.param2 = param2;
|
|
msg.param3 = param3;
|
|
msg.param4 = param4;
|
|
|
|
return sdio_test_send_msg(&msg);
|
|
}
|
|
|
|
static void sdio_test_thread(void *arg)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
while(1)
|
|
{
|
|
SDIO_TEST_MSG_T msg;
|
|
|
|
ret = rtos_pop_from_queue(&s_sdio_test_msg_que, &msg, BEKEN_WAIT_FOREVER);
|
|
if (kNoErr == ret)
|
|
{
|
|
//
|
|
switch(msg.main_case)
|
|
{
|
|
case SDIO_TEST_TX:
|
|
{
|
|
if(msg.sub_case >= SDIO_TEST_TX_MAX_SUB_CASE)
|
|
{
|
|
SDIO_LOG_ERR("sub case id %d is big then %d", msg.sub_case, SDIO_TEST_TX_MAX_SUB_CASE);
|
|
break;
|
|
}
|
|
|
|
sdio_test_tx_sub_case(&msg);
|
|
break;
|
|
}
|
|
|
|
case SDIO_TEST_RX:
|
|
{
|
|
if(msg.sub_case >= SDIO_TEST_RX_MAX_SUB_CASE)
|
|
{
|
|
SDIO_LOG_ERR("sub case id %d is big then %d", msg.sub_case, SDIO_TEST_RX_MAX_SUB_CASE);
|
|
break;
|
|
}
|
|
|
|
sdio_test_rx_sub_case(&msg);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
//TODO: Assert
|
|
}
|
|
|
|
/**
|
|
* @brief Init the sdio driver test program.
|
|
*
|
|
* This API init the sdio driver test program.
|
|
* - It will create a task do selected test case.
|
|
* - It can select test case by command line.
|
|
*
|
|
* @attention 1. This API should be called after sdio inited finish.
|
|
*
|
|
* @return
|
|
* - BK_OK: succeed
|
|
* - others: other errors.
|
|
*/
|
|
bk_err_t bk_sdio_test_init(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
if(s_sdio_test_inited)
|
|
{
|
|
SDIO_LOG_INFO("has inited");
|
|
return ret;
|
|
}
|
|
|
|
ret = rtos_init_queue(
|
|
&s_sdio_test_msg_que,
|
|
SDIO_TEST_MSG_QUEUE_NAME,
|
|
sizeof(SDIO_TEST_MSG_T),
|
|
SDIO_TEST_MSG_QUEUE_COUNT
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init queue ret=%d", ret);
|
|
goto err_exit;
|
|
}
|
|
|
|
ret = rtos_create_thread(
|
|
&s_test_sdio_thread,
|
|
SDIO_TEST_PRIORITY,
|
|
SDIO_TEST_THREAD_NAME,
|
|
sdio_test_thread,
|
|
SDIO_TEST_THREAD_STACK_SIZE,
|
|
NULL
|
|
);
|
|
if (kNoErr != ret)
|
|
{
|
|
SDIO_LOG_ERR("init thread ret=%d", ret);
|
|
goto err_exit;
|
|
}
|
|
|
|
s_sdio_test_inited = true;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
//return, or err_exit release resources caused bug.
|
|
return ret;
|
|
|
|
err_exit:
|
|
if(s_sdio_test_msg_que)
|
|
{
|
|
rtos_deinit_queue(&s_sdio_test_msg_que);
|
|
s_sdio_test_msg_que = NULL;
|
|
}
|
|
|
|
if(s_test_sdio_thread)
|
|
{
|
|
rtos_delete_thread(&s_test_sdio_thread);
|
|
s_test_sdio_thread = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Deinit the sdio driver test program.
|
|
*
|
|
* This API init the sdio driver test program.
|
|
* - It will delete the test thread and queue.
|
|
*
|
|
* @attention 1. This API should be called after sdio inited finish.
|
|
*
|
|
* @return
|
|
* - BK_OK: succeed
|
|
* - others: other errors.
|
|
*/
|
|
bk_err_t bk_sdio_test_deinit(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_ENTRY();
|
|
|
|
if(s_sdio_test_msg_que)
|
|
{
|
|
ret = rtos_deinit_queue(&s_sdio_test_msg_que);
|
|
if (BK_OK != ret)
|
|
{
|
|
SDIO_LOG_ERR("deinit queue ret=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
s_sdio_test_msg_que = NULL;
|
|
}
|
|
|
|
if(s_test_sdio_thread)
|
|
{
|
|
ret = rtos_delete_thread(&s_test_sdio_thread);
|
|
if (BK_OK != ret)
|
|
{
|
|
SDIO_LOG_ERR("delete thread ret=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
s_test_sdio_thread = NULL;
|
|
}
|
|
|
|
SDIO_LOG_DEBUG_FUNCTION_EXIT();
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
#endif //CONFIG_SDIO_TEST_EN
|