|
|
/*
|
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2021. All rights reserved.
|
|
|
* Description: Initial Draft
|
|
|
* Author: Hisilicon
|
|
|
* Create: 2012-12-22
|
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <pthread.h>
|
|
|
#include <unistd.h>
|
|
|
#include <arpa/inet.h>
|
|
|
#include "soc_errno.h"
|
|
|
#ifndef SOCT_MDBG_VERSION_LINUX // Android version
|
|
|
#include <cutils/properties.h>
|
|
|
#include <cutils/log.h>
|
|
|
#endif
|
|
|
|
|
|
#include "soc_log.h"
|
|
|
#include "securec.h"
|
|
|
|
|
|
#include "mpi_dbg_ir_debug.h"
|
|
|
#include "mpi_dbg_gpio_debug.h"
|
|
|
#include "mpi_dbg_i2c_debug.h"
|
|
|
#include "mpi_dbg_pwm_debug.h"
|
|
|
#include "mpi_dbg_panel_debug.h"
|
|
|
#include "mpi_dbg_pq_debug.h"
|
|
|
#include "uapi_uart.h"
|
|
|
#include "mpi_mdbg.h"
|
|
|
#include "mpi_system_ext.h"
|
|
|
#include "uapi_system.h"
|
|
|
#include "mpi_dbg_aq.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
#if __cplusplus
|
|
|
extern "C" {
|
|
|
#endif
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
#undef LOG_MODULE_ID
|
|
|
#define LOG_MODULE_ID SOC_ID_SYS
|
|
|
|
|
|
#define BACKLOG 20
|
|
|
#define MAXLEN 32
|
|
|
#define MDBG_CMDBUF_SIZE (0xFFFF + 0x100)
|
|
|
#define mdbg_offset_of(s, m) ((size_t) & (((s *)0)->m))
|
|
|
#define mdbg_size_of(s, m) (sizeof(((s *)0)->m))
|
|
|
#define mdbg_get_value(buf, s, m) ((*(s *)(buf)).m)
|
|
|
#define BUFLEN 1000
|
|
|
|
|
|
#define mdbg_check_return_if_fail(param, errno, str) do { \
|
|
|
if (param) { \
|
|
|
fprintf(stderr, "[%s %d] %s\n", __FUNCTION__, __LINE__, (str)); \
|
|
|
return errno; \
|
|
|
} \
|
|
|
} while (0)
|
|
|
|
|
|
/* ----------------------------------------------------------------------------- */
|
|
|
/* Local Types Declarations */
|
|
|
/* ----------------------------------------------------------------------------- */
|
|
|
static td_s32 g_server_sock_fd = -1;
|
|
|
static td_s32 g_net_process_flag = 1;
|
|
|
static td_s32 g_port = 4321;
|
|
|
|
|
|
static td_bool g_init = TD_FALSE;
|
|
|
static pthread_t g_muart_debug_pid;
|
|
|
static pthread_t g_mnet_debug_pid;
|
|
|
static td_u8 *g_buf = TD_NULL;
|
|
|
static td_bool g_pq_dbg = TD_TRUE;
|
|
|
static td_bool g_debug_request = TD_FALSE;
|
|
|
static td_bool g_debug_mode = TD_FALSE;
|
|
|
static td_bool g_exit_dbg = TD_FALSE;
|
|
|
static td_s32 g_net_dev_fd = -1;
|
|
|
static td_bool g_net_use = TD_TRUE;
|
|
|
static td_bool g_is_cts_enable = TD_FALSE;
|
|
|
static td_bool g_uart_open_dev = TD_TRUE;
|
|
|
static td_bool g_uart_switch = TD_FALSE;
|
|
|
static struct timespec g_delay = { 0 };
|
|
|
static ext_mdbg_chip g_mdbg_chip;
|
|
|
static td_u8 g_magic_char[] = {'s', 'o', 'c', 't', '_', 'p', 'q', '_', 't', 'o', 'o', 'l', '.', 's', 'h'};
|
|
|
|
|
|
/* 串口消息数据包 */
|
|
|
/* VRC send "soct_pq_tool.sh" then send 12byte data to dbg thread. */
|
|
|
/* so this message struct should 2 byte alignment. */
|
|
|
#pragma pack(2)
|
|
|
typedef struct {
|
|
|
td_u8 magic_num[4]; /* 魔数: 'H''L''T''V' 最多4个字符组成 */
|
|
|
td_u16 cmd; /* 命令, 参考MDBG_CMD_E */
|
|
|
td_u16 length; /* mdbg_data 的有效数据长度 */
|
|
|
td_u32 header_check_sum; /* 头校验码 */
|
|
|
td_u8 *mdbg_data; /* 有效数据 */
|
|
|
td_u32 data_check_sum; /* 有效数据校验码 */
|
|
|
} ext_mdbg_msg;
|
|
|
#pragma pack()
|
|
|
/* PQ命令 */
|
|
|
typedef enum {
|
|
|
/* COMMON */
|
|
|
EXT_MDBG_CMD_UART_SWITCH = 0x1000,
|
|
|
EXT_MDBG_CMD_ECHO_ACK = 0x1001,
|
|
|
|
|
|
/* TV */
|
|
|
EXT_MDBG_CMD_PQ = 0x6000,
|
|
|
EXT_MDBG_CMD_AQ = 0x7000,
|
|
|
|
|
|
/* PANEL */
|
|
|
EXT_MDBG_CMD_PANEL = 0x8000,
|
|
|
|
|
|
/* IR */
|
|
|
EXT_MDBG_CMD_IR = 0x9000,
|
|
|
|
|
|
EXT_MDBG_CMD_VIR,
|
|
|
|
|
|
/* 新添加COMM,GPIO,I2C,PWM */
|
|
|
EXT_MDBG_CMD_COMM,
|
|
|
|
|
|
EXT_MDBG_CMD_GPIO,
|
|
|
|
|
|
EXT_MDBG_CMD_I2C,
|
|
|
|
|
|
EXT_MDBG_CMD_PWM
|
|
|
} ext_mdbg_cmd_type;
|
|
|
|
|
|
static td_void *iapi_mdbg_net_server_start(td_void *para);
|
|
|
static td_s32 iapi_mdbg_net_create_thread(td_void);
|
|
|
static td_void *iapi_mdbg_net_process(td_void *args);
|
|
|
static td_void iapi_mdbg_net_send_flag(td_s32 client_sockfd, td_u8 error);
|
|
|
static td_void iapi_mdbg_net_read_data(td_u8 *buf, td_s32 count, td_s32 *read_size);
|
|
|
static td_void iapi_mdbg_net_write_data(const td_u8 *buf, td_s32 count);
|
|
|
static td_s32 iapi_mdbg_net_recv_data(td_s32 client_sockfd, td_u8 *buf, td_u32 count, td_s32 *read_size);
|
|
|
static td_s32 iapi_mdbg_net_check_data(const td_u8 *buf);
|
|
|
static td_s32 iapi_mdbg_parser_msg(const td_u8 *buf);
|
|
|
static td_void iapi_mdbg_uart_read_data(td_u8 *buf, td_s32 count, td_s32 *read_size);
|
|
|
static td_void iapi_mdbg_uart_write_data(td_u8 *buf, td_s32 count);
|
|
|
static td_s32 iapi_mdbg_uart_open_dev(td_void);
|
|
|
static td_void *iapi_mdbg_uart_thread(td_void *para);
|
|
|
static td_s32 iapi_mdbg_uart_close_dev(td_void);
|
|
|
static td_s32 iapi_mdbg_uart_read_msg(td_u8 *buf);
|
|
|
|
|
|
|
|
|
td_bool iapi_mdbg_is_valid_msg(const td_u8 *magic_num)
|
|
|
{
|
|
|
if (magic_num == TD_NULL) {
|
|
|
soc_err_print_null_pointer(magic_num);
|
|
|
return TD_FALSE;
|
|
|
}
|
|
|
|
|
|
/* 判断0,1,2,3个数组元素的值 */
|
|
|
if ((magic_num[0] != 'H') || (magic_num[1] != 'L') || (magic_num[2] != 'T') || (magic_num[3] != 'V')) {
|
|
|
return TD_FALSE;
|
|
|
}
|
|
|
|
|
|
return TD_TRUE;
|
|
|
}
|
|
|
|
|
|
/* 数据头数据校验 */
|
|
|
td_s32 iapi_mdbg_verify_header_checksum(const td_u8 *buf)
|
|
|
{
|
|
|
td_size_t total_len, i;
|
|
|
td_u32 check_sum1;
|
|
|
td_u32 check_sum2 = 0;
|
|
|
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
/* re-calculate checksum */
|
|
|
total_len = mdbg_offset_of(ext_mdbg_msg, header_check_sum);
|
|
|
check_sum1 = mdbg_get_value(buf, ext_mdbg_msg, header_check_sum);
|
|
|
|
|
|
for (i = 0; i < total_len; i++) {
|
|
|
check_sum2 += buf[i];
|
|
|
}
|
|
|
|
|
|
/* compare checksum */
|
|
|
if (check_sum1 != check_sum2) {
|
|
|
fprintf(stderr, "check header check_sum error!,check_sum1=%x,check_sum2=%x\n", check_sum1, check_sum2);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* 数据有效数据校验 */
|
|
|
td_s32 iapi_mdbg_verify_data_checksum(const td_u8 *buf, td_u32 checksum)
|
|
|
{
|
|
|
td_u32 total_len, i;
|
|
|
td_u32 check_sum1 = 0;
|
|
|
td_size_t header_size;
|
|
|
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
/* re-calculate checksum */
|
|
|
header_size = mdbg_offset_of(ext_mdbg_msg, mdbg_data);
|
|
|
total_len = mdbg_get_value(buf, ext_mdbg_msg, length);
|
|
|
|
|
|
for (i = 0; i < total_len; i++) {
|
|
|
check_sum1 += buf[i + header_size];
|
|
|
}
|
|
|
|
|
|
/* compare checksum */
|
|
|
if (checksum != check_sum1) {
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* 解析数据 */
|
|
|
td_s32 iapi_mdbg_parser_msg(const td_u8 *buf)
|
|
|
{
|
|
|
td_u32 data_length;
|
|
|
td_u16 mdbg_cmd;
|
|
|
const td_u8 *cmd_buf = TD_NULL;
|
|
|
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
mdbg_cmd = mdbg_get_value(buf, ext_mdbg_msg, cmd);
|
|
|
|
|
|
cmd_buf = buf + mdbg_offset_of(ext_mdbg_msg, mdbg_data);
|
|
|
data_length = mdbg_get_value(buf, ext_mdbg_msg, length);
|
|
|
soc_log_info("iapi:%u\n", mdbg_cmd);
|
|
|
switch (mdbg_cmd) {
|
|
|
case EXT_MDBG_CMD_UART_SWITCH:
|
|
|
uapi_uart_switch(0); // switch to system uart
|
|
|
g_debug_mode = TD_FALSE;
|
|
|
g_net_use = TD_TRUE;
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_ECHO_ACK:
|
|
|
case EXT_MDBG_CMD_VIR:
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_PQ:
|
|
|
mpi_pq_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_AQ:
|
|
|
mpi_aq_dbg_parser((td_u8 *)cmd_buf, (td_s32)data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_PANEL:
|
|
|
mpi_panel_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_IR:
|
|
|
mpi_ir_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_COMM:
|
|
|
// don't delete mpi_comm_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_GPIO:
|
|
|
mpi_gpio_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_I2C:
|
|
|
mpi_i2c_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
case EXT_MDBG_CMD_PWM:
|
|
|
// don't delete mpi_pwm_dbg_parser(cmd_buf, data_length);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
fprintf(stderr, "MDBG not have this CMD: %X\n", mdbg_cmd);
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_read_data(td_u8 *buf, td_s32 count, td_s32 *read_size)
|
|
|
{
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_log_err("buf was null!\n");
|
|
|
return;
|
|
|
}
|
|
|
if (read_size == TD_NULL) {
|
|
|
soc_log_err("read_size was null!\n");
|
|
|
return;
|
|
|
}
|
|
|
if (g_net_use == TD_TRUE) {
|
|
|
iapi_mdbg_net_read_data(buf, count, read_size);
|
|
|
} else {
|
|
|
iapi_mdbg_uart_read_data(buf, count, read_size);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_write_data(td_u8 *buf, td_s32 count)
|
|
|
{
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_log_err("buf was null!\n");
|
|
|
return;
|
|
|
}
|
|
|
if (g_net_use == TD_TRUE) {
|
|
|
iapi_mdbg_net_write_data(buf, count);
|
|
|
} else {
|
|
|
iapi_mdbg_uart_write_data(buf, count);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
static td_void iapi_mdbg_reigster_func(td_void)
|
|
|
{
|
|
|
mpi_pq_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
mpi_aq_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
mpi_panel_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
// don't delete mpi_pwm_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
// don't delete mpi_comm_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
mpi_ir_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
|
|
|
mpi_gpio_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
|
|
|
mpi_i2c_dbg_register_uart_func(iapi_mdbg_read_data, iapi_mdbg_write_data);
|
|
|
}
|
|
|
|
|
|
#ifndef SOCT_MDBG_VERSION_LINUX // Android version
|
|
|
static td_void iapi_mdbg_check_user_version(td_bool *cts_enable)
|
|
|
{
|
|
|
char value[PROPERTY_VALUE_MAX] = {0};
|
|
|
property_get("ro.build.type", value, "eng");
|
|
|
value[PROPERTY_VALUE_MAX - 1] = '\0';
|
|
|
if (strcmp(value, "user") == 0) {
|
|
|
*cts_enable = TD_TRUE;
|
|
|
fprintf(stderr, "android user version, close port 4321 \n");
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
static td_s32 iapi_mdbg_start_net_server(td_void)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
|
|
|
if (!g_is_cts_enable) {
|
|
|
g_net_process_flag = 1;
|
|
|
ret = pthread_create(&g_mnet_debug_pid, NULL, iapi_mdbg_net_server_start, NULL);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
/* here free g_buf will make uart fail,so not do it */
|
|
|
soc_log_err("Server thread create error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
}
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* Debug模块初始化 */
|
|
|
td_s32 uapi_mdbg_init(td_void)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
uapi_sys_init();
|
|
|
|
|
|
if (g_init == TD_TRUE) {
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
ret = ext_mpi_mdbg_get_chipversion(&g_mdbg_chip);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stderr, "get chipversion failed...\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* alloc cmd buffer memory */
|
|
|
g_buf = (td_u8 *)malloc(MDBG_CMDBUF_SIZE);
|
|
|
if (g_buf == TD_NULL) {
|
|
|
fprintf(stderr, "mdebug cmd buffer malloc error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
ret = memset_s(g_buf, MDBG_CMDBUF_SIZE, 0x00, MDBG_CMDBUF_SIZE);
|
|
|
if (ret != EOK) {
|
|
|
goto ERR_EXIT;
|
|
|
}
|
|
|
|
|
|
/* 注册回调函数 */
|
|
|
iapi_mdbg_reigster_func();
|
|
|
|
|
|
/* open uart device */
|
|
|
ret = iapi_mdbg_uart_open_dev();
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("iapi_mdbg_uart_open_dev failed!\n");
|
|
|
}
|
|
|
/* create uart recv thread */
|
|
|
ret = pthread_create(&g_muart_debug_pid, NULL, iapi_mdbg_uart_thread, g_buf);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
g_uart_open_dev = TD_FALSE;
|
|
|
// don't delete mpi_pq_dbg_update_uart_status(g_uart_open_dev, g_pq_dbg, g_uart_switch, g_is_cts_enable);
|
|
|
fprintf(stderr, "open_uart_dev or mdebug thread create error\n");
|
|
|
goto ERR_EXIT;
|
|
|
}
|
|
|
|
|
|
/* 4. 启动Net server */
|
|
|
#ifndef SOCT_MDBG_VERSION_LINUX // Android version
|
|
|
iapi_mdbg_check_user_version(&g_is_cts_enable);
|
|
|
#endif
|
|
|
// don't delete mpi_pq_dbg_update_uart_status(g_uart_open_dev, g_pq_dbg, g_uart_switch, g_is_cts_enable);
|
|
|
ret = iapi_mdbg_start_net_server();
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
goto ERR_EXIT;
|
|
|
}
|
|
|
|
|
|
g_init = TD_TRUE;
|
|
|
// #endif
|
|
|
return TD_SUCCESS;
|
|
|
|
|
|
ERR_EXIT:
|
|
|
free(g_buf);
|
|
|
g_buf = TD_NULL;
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* Debug模块去初始化 */
|
|
|
td_s32 uapi_mdbg_deinit(td_void)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
|
|
if (g_init == TD_FALSE) {
|
|
|
soc_dbg_func_exit();
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
g_net_process_flag = -1;
|
|
|
g_exit_dbg = TD_TRUE;
|
|
|
|
|
|
ret = pthread_join(g_muart_debug_pid, NULL);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("uart thread join error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
soc_log_info("uart thread join success\n");
|
|
|
|
|
|
ret = iapi_mdbg_uart_close_dev();
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("uart device close error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
soc_log_info("iapi_mdbg_uart_close_dev success\n");
|
|
|
|
|
|
g_debug_mode = TD_FALSE;
|
|
|
|
|
|
soc_info_print_bool(g_is_cts_enable);
|
|
|
if (!g_is_cts_enable) {
|
|
|
ret = pthread_join(g_mnet_debug_pid, NULL);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("net thread join error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
soc_log_info("net thread join success\n");
|
|
|
|
|
|
shutdown(g_server_sock_fd, 2); // 2代表关屏
|
|
|
soc_log_info("shutdown g_server_sock_fd success\n");
|
|
|
close(g_server_sock_fd);
|
|
|
g_server_sock_fd = -1;
|
|
|
soc_log_info("close g_server_sock_fd success\n");
|
|
|
}
|
|
|
|
|
|
if (g_buf != TD_NULL) {
|
|
|
free(g_buf);
|
|
|
g_buf = TD_NULL;
|
|
|
}
|
|
|
|
|
|
g_init = TD_FALSE;
|
|
|
|
|
|
uapi_sys_deinit();
|
|
|
soc_dbg_func_exit();
|
|
|
// #endif
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 uapi_mdbg_enter_debug_mode(td_bool enable)
|
|
|
{
|
|
|
g_pq_dbg = enable;
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* 获取调试模式 */
|
|
|
td_s32 uapi_mdbg_get_debug_mode(td_bool *enable)
|
|
|
{
|
|
|
if (enable == TD_NULL) {
|
|
|
soc_log_err("enable was null!\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
*enable = g_pq_dbg;
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_void *iapi_mdbg_net_server_start(td_void *para)
|
|
|
{
|
|
|
td_s32 ret, temp_fd;
|
|
|
td_u32 client_len;
|
|
|
struct sockaddr_in addr_serv, addr_client;
|
|
|
|
|
|
(td_void)(para);
|
|
|
|
|
|
g_server_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
if (g_server_sock_fd < 0) {
|
|
|
perror("socket fail");
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
if (memset_s(&addr_serv, sizeof(addr_serv), 0, sizeof(addr_serv)) != EOK) {
|
|
|
perror("call memset_s failed!\n");
|
|
|
close(g_server_sock_fd);
|
|
|
g_server_sock_fd = -1;
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
addr_serv.sin_family = AF_INET;
|
|
|
addr_serv.sin_port = htons(g_port);
|
|
|
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
client_len = sizeof(struct sockaddr_in);
|
|
|
if (bind(g_server_sock_fd, (struct sockaddr *)&addr_serv, sizeof(struct sockaddr_in)) < 0) {
|
|
|
perror("bind fail");
|
|
|
}
|
|
|
|
|
|
if (listen(g_server_sock_fd, BACKLOG) < 0) {
|
|
|
perror("listen fail");
|
|
|
}
|
|
|
|
|
|
while (g_net_process_flag == 1) {
|
|
|
printf("begin accept:\n");
|
|
|
temp_fd = accept(g_server_sock_fd, (struct sockaddr *)&addr_client, (socklen_t *)&client_len);
|
|
|
if (temp_fd < 0) {
|
|
|
perror("accept fail");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (g_net_dev_fd < 0) {
|
|
|
g_net_dev_fd = temp_fd;
|
|
|
} else {
|
|
|
fprintf(stderr, "last connection is not closed!\n");
|
|
|
(void)close(temp_fd);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
ret = iapi_mdbg_net_create_thread();
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stderr, "UAPI_MDBG_CreateThread error!\n");
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_net_create_thread(td_void)
|
|
|
{
|
|
|
pthread_t thread;
|
|
|
td_s32 ret;
|
|
|
pthread_attr_t child_thread_attr;
|
|
|
pthread_attr_init(&child_thread_attr);
|
|
|
pthread_attr_setdetachstate(&child_thread_attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
ret = pthread_create(&thread, &child_thread_attr, iapi_mdbg_net_process, (void *)g_buf); // 创建子线程
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stderr, "pthread_create error!\n");
|
|
|
pthread_attr_destroy(&child_thread_attr);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
pthread_attr_destroy(&child_thread_attr);
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_void *iapi_mdbg_net_process(td_void *args)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
|
|
|
if (args == TD_NULL) {
|
|
|
soc_log_err("args was null!\n");
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
if (g_net_use != TD_TRUE) {
|
|
|
fprintf(stderr, "Uart is use, Net can't use!\n");
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
while (1) {
|
|
|
td_s32 readesize = 0;
|
|
|
|
|
|
/* 1.接收数据 */
|
|
|
ret = iapi_mdbg_net_recv_data(g_net_dev_fd, (td_u8 *)args, MDBG_CMDBUF_SIZE, &readesize);
|
|
|
if (ret != TD_SUCCESS || readesize <= 0) {
|
|
|
fprintf(stderr, "iapi_mdbg_net_recv_data failed!\n");
|
|
|
iapi_mdbg_net_send_flag(g_net_dev_fd, 0xC0);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/* 2.校验数据 */
|
|
|
ret = iapi_mdbg_net_check_data((td_u8 *)args);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stderr, "check data failed! [%i]\n", ret);
|
|
|
iapi_mdbg_net_send_flag(g_net_dev_fd, 0xC0);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/* 3.解析数据 */
|
|
|
iapi_mdbg_net_send_flag(g_net_dev_fd, 0xD0);
|
|
|
|
|
|
ret = iapi_mdbg_parser_msg((td_u8 *)args);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stderr, "Parser data failed!\n");
|
|
|
}
|
|
|
|
|
|
iapi_mdbg_net_send_flag(g_net_dev_fd, 0xE0);
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
ret = close(g_net_dev_fd);
|
|
|
while (errno == EINTR) {
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 10 * 1000; // 10 * 1000 ns = 10us
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
ret = close(g_net_dev_fd);
|
|
|
}
|
|
|
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
fprintf(stdout, "close net_dev_fd failed!\n");
|
|
|
return TD_NULL;
|
|
|
} else {
|
|
|
g_net_dev_fd = -1;
|
|
|
}
|
|
|
|
|
|
fprintf(stdout, "connection close!\n");
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_net_send_flag(td_s32 client_sockfd, td_u8 error)
|
|
|
{
|
|
|
td_u8 ack;
|
|
|
ack = error;
|
|
|
send(client_sockfd, (void *)&ack, 1, 0);
|
|
|
|
|
|
while (errno == EINTR || errno == EAGAIN) {
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 10 * 1000; // 10 * 1000 ns = 10us
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
send(client_sockfd, (void *)&ack, 1, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static td_u32 mdbg_get_msg_header_size(td_void)
|
|
|
{
|
|
|
td_u32 header_size;
|
|
|
|
|
|
header_size = mdbg_size_of(ext_mdbg_msg, magic_num);
|
|
|
header_size += mdbg_size_of(ext_mdbg_msg, cmd);
|
|
|
header_size += mdbg_size_of(ext_mdbg_msg, length);
|
|
|
header_size += mdbg_size_of(ext_mdbg_msg, header_check_sum);
|
|
|
|
|
|
return header_size;
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_net_recv_data(td_s32 client_sockfd, td_u8 *buf, td_u32 count, td_s32 *read_size)
|
|
|
{
|
|
|
td_s32 recv_cnt;
|
|
|
fd_set read_fds;
|
|
|
struct timeval timeout;
|
|
|
td_s32 ret;
|
|
|
td_u32 header_size, data_offset, len;
|
|
|
|
|
|
mdbg_check_return_if_fail(buf == TD_NULL, TD_FAILURE, "buf is NULL!");
|
|
|
mdbg_check_return_if_fail(read_size == TD_NULL, TD_FAILURE, "read_size is NULL!");
|
|
|
|
|
|
FD_ZERO(&read_fds);
|
|
|
FD_SET(client_sockfd, &read_fds);
|
|
|
|
|
|
timeout.tv_sec = 5; // 设置时间5s
|
|
|
timeout.tv_usec = 0;
|
|
|
if (select(client_sockfd + 1, &read_fds, NULL, NULL, &timeout) <= 0) {
|
|
|
fprintf(stderr, "socketfd select failed or time out\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
header_size = mdbg_get_msg_header_size();
|
|
|
if (FD_ISSET(client_sockfd, &read_fds)) { // 测试sock是否可读,即网络上是否有数据
|
|
|
ret = recv(client_sockfd, buf, header_size, MSG_WAITALL); // 前12个字节代表头
|
|
|
while (errno == EINTR || errno == EAGAIN) {
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 10 * 1000; // 10 * 1000ns is 10us
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
if (recv(client_sockfd, buf, header_size, MSG_WAITALL) >= 0) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ((ret < (td_s32)header_size) || (header_size > count)) {
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
len = mdbg_get_value(buf, ext_mdbg_msg, length) + sizeof(td_u32); // mdbg_data length+chceksum
|
|
|
if (len > count - header_size) {
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
data_offset = (td_u32)mdbg_offset_of(ext_mdbg_msg, mdbg_data);
|
|
|
do {
|
|
|
recv_cnt = recv(client_sockfd, buf + data_offset, len, MSG_WAITALL);
|
|
|
} while ((recv_cnt < 0) && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN));
|
|
|
|
|
|
mdbg_check_return_if_fail(recv_cnt <= 0, TD_FAILURE, "error! recv_cnt <= 0");
|
|
|
mdbg_check_return_if_fail(recv_cnt != (td_s32)len, TD_FAILURE, "error! recv_cnt != (td_s32)len");
|
|
|
|
|
|
*read_size = (td_s32)(len + header_size);
|
|
|
}
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_net_check_data(const td_u8 *buf)
|
|
|
{
|
|
|
td_u32 checksum = 0;
|
|
|
td_size_t header_size;
|
|
|
td_u32 len;
|
|
|
errno_t sec_ret;
|
|
|
|
|
|
if (buf == NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* check Magic number is valid */
|
|
|
if (iapi_mdbg_is_valid_msg(((ext_mdbg_msg *)buf)->magic_num) != TD_TRUE) {
|
|
|
fprintf(stderr, "check magic number error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* check header checksum */
|
|
|
if (iapi_mdbg_verify_header_checksum((td_u8 *)buf) != TD_SUCCESS) {
|
|
|
fprintf(stderr, "check header checksum error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* verify data checksum */
|
|
|
header_size = mdbg_offset_of(ext_mdbg_msg, mdbg_data);
|
|
|
len = mdbg_get_value(buf, ext_mdbg_msg, length);
|
|
|
sec_ret = memcpy_s(&checksum, sizeof(td_u32), buf + header_size + len, sizeof(checksum));
|
|
|
if (sec_ret != EOK) {
|
|
|
fprintf(stderr, "call memcpy_s failed!errno=%d\n", sec_ret);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
if (iapi_mdbg_verify_data_checksum(buf, checksum) != TD_SUCCESS) {
|
|
|
fprintf(stderr, "check valid data checksum error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_net_read_data(td_u8 *buf, td_s32 count, td_s32 *read_size)
|
|
|
{
|
|
|
td_s32 recv_cnt;
|
|
|
fd_set read_fds;
|
|
|
struct timeval timeout;
|
|
|
td_s32 ret;
|
|
|
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return;
|
|
|
}
|
|
|
if (read_size == TD_NULL) {
|
|
|
soc_err_print_null_pointer(read_size);
|
|
|
return;
|
|
|
}
|
|
|
FD_ZERO(&read_fds);
|
|
|
FD_SET(g_net_dev_fd, &read_fds);
|
|
|
|
|
|
timeout.tv_sec = 5; // 设置时间为5s
|
|
|
timeout.tv_usec = 0;
|
|
|
ret = select(g_net_dev_fd + 1, &read_fds, NULL, NULL, &timeout);
|
|
|
if (ret < 0) {
|
|
|
fprintf(stderr, "socketfd select failed!\n");
|
|
|
return;
|
|
|
}
|
|
|
if (ret == 0) {
|
|
|
fprintf(stderr, "time out!\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (FD_ISSET(g_net_dev_fd, &read_fds)) { // 测试sock是否可读,即网络上是否有数据
|
|
|
do {
|
|
|
recv_cnt = recv(g_net_dev_fd, buf, count, MSG_WAITALL);
|
|
|
} while ((recv_cnt < 0) && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN));
|
|
|
|
|
|
if (recv_cnt < 0 || recv_cnt != count) {
|
|
|
fprintf(stderr, "recv data error!\n");
|
|
|
return;
|
|
|
} else if (recv_cnt == 0) {
|
|
|
fprintf(stderr, "socket is disconnected!\n");
|
|
|
return;
|
|
|
} else {
|
|
|
*read_size = count;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_net_write_data(const td_u8 *buf, td_s32 count)
|
|
|
{
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return;
|
|
|
}
|
|
|
send(g_net_dev_fd, buf, count, 0);
|
|
|
while (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 10 * 1000; // 10 * 1000 ns = 10us
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
send(g_net_dev_fd, buf, count, 0);
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
td_bool iapi_mdbg_uart_is_open_flag(const td_u8 *magic_num)
|
|
|
{
|
|
|
td_u8 i;
|
|
|
|
|
|
if (magic_num == TD_NULL) {
|
|
|
soc_err_print_null_pointer(magic_num);
|
|
|
return TD_FALSE;
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < sizeof(g_magic_char) / sizeof(td_u8); i++) {
|
|
|
if (magic_num[i] != g_magic_char[i]) {
|
|
|
return TD_FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return TD_TRUE;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_uart_read_data(td_u8 *buf, td_s32 count, td_s32 *read_size)
|
|
|
{
|
|
|
td_s32 ret_val;
|
|
|
td_s32 read_bytes = 0;
|
|
|
|
|
|
if (buf == NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return;
|
|
|
}
|
|
|
if (read_size == NULL) {
|
|
|
soc_err_print_null_pointer(read_size);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
*read_size = 0;
|
|
|
while (1) {
|
|
|
if (read_bytes >= count) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
ret_val = uapi_uart_read((char *)(buf + read_bytes), 1);
|
|
|
if (ret_val <= 0) {
|
|
|
break;
|
|
|
} else {
|
|
|
read_bytes += ret_val;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
*read_size = read_bytes;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
td_void iapi_mdbg_uart_write_data(td_u8 *buf, td_s32 count)
|
|
|
{
|
|
|
td_s32 ret_val;
|
|
|
|
|
|
if (buf == NULL) {
|
|
|
fprintf(stderr, "buf is null!\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
ret_val = uapi_uart_write((td_char *)buf, (td_u32)count);
|
|
|
if (ret_val < count) {
|
|
|
fprintf(stderr, "write uart date error!\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_uart_open_dev(td_void)
|
|
|
{
|
|
|
td_s32 ret_val;
|
|
|
|
|
|
ret_val = uapi_uart_init();
|
|
|
if (ret_val != TD_SUCCESS && ret_val != SOC_ERR_UART_OPENED) {
|
|
|
perror("open uart dev fail!");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* set defaulty baud speed to 115200 */
|
|
|
if (uapi_uart_set_speed(115200) != TD_SUCCESS) { // 设置波特率为115200
|
|
|
uapi_uart_deinit();
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* set defaulty uart attribue */
|
|
|
if (uapi_uart_set_attr(8, 1, 'N') != TD_SUCCESS) { // 设置串口的读写数据为8位
|
|
|
uapi_uart_deinit();
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_uart_close_dev(td_void)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
// 把串口切换回系统使用
|
|
|
uapi_uart_switch(0);
|
|
|
ret = uapi_uart_deinit();
|
|
|
if (ret < 0) {
|
|
|
fprintf(stderr, "Can't close PQ uart\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static td_s32 iapi_mdbg_send_uart_ack(td_u8 ack)
|
|
|
{
|
|
|
td_s32 ret_val;
|
|
|
|
|
|
ret_val = uapi_uart_write((td_char *)&ack, sizeof(td_u8));
|
|
|
if (ret_val < 0) {
|
|
|
fprintf(stderr, "send ack1 error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static td_s32 iapi_mdbg_get_uart_data(td_s32 read_size, td_u8 *buf)
|
|
|
{
|
|
|
td_s32 ret_val = 0;
|
|
|
td_u32 checksum = 0;
|
|
|
td_s32 read_total_byte = 0;
|
|
|
td_u32 tmp_val;
|
|
|
|
|
|
/* read data */
|
|
|
read_total_byte += read_size;
|
|
|
tmp_val = mdbg_get_value(buf, ext_mdbg_msg, length), read_size = (td_s32)tmp_val;
|
|
|
|
|
|
if ((read_size == 0) || (read_size > MDBG_CMDBUF_SIZE - read_total_byte - 4)) { // 读取数据最大size,4握手字节长度
|
|
|
fprintf(stderr, "read size is zero or out of range!\n");
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 100000 * 1000; // 100000 * 1000 ns = 10 ms
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
iapi_mdbg_uart_read_data(buf + read_total_byte, read_size, &ret_val);
|
|
|
if (ret_val < read_size) {
|
|
|
fprintf(stderr, "read data time out\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* read data checksum */
|
|
|
read_total_byte += read_size;
|
|
|
tmp_val = sizeof(td_u32), read_size = (td_s32)tmp_val;
|
|
|
iapi_mdbg_uart_read_data(buf + read_total_byte, read_size, &ret_val);
|
|
|
if (ret_val < (td_s32)sizeof(td_u32)) {
|
|
|
fprintf(stderr, "read CheckSum error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* verify data checksum */
|
|
|
if (memcpy_s(&checksum, sizeof(td_u32), buf + read_total_byte, sizeof(checksum)) != EOK) {
|
|
|
fprintf(stderr, "call memcpy_s failed!");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (iapi_mdbg_verify_data_checksum(buf, checksum) != TD_SUCCESS) {
|
|
|
fprintf(stderr, "check data checksum error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 iapi_mdbg_uart_read_msg(td_u8 *buf)
|
|
|
{
|
|
|
td_s32 read_size;
|
|
|
td_s32 ret_val = 0;
|
|
|
|
|
|
if (buf == TD_NULL) {
|
|
|
soc_err_print_null_pointer(buf);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
/* read msg magic number + cmd + len+headerchecsum */
|
|
|
read_size = (td_s32)mdbg_offset_of(ext_mdbg_msg, mdbg_data);
|
|
|
iapi_mdbg_uart_read_data(buf, read_size, &ret_val);
|
|
|
if (ret_val < read_size) {
|
|
|
if (ret_val > 0) {
|
|
|
fprintf(stderr, "read header error\n");
|
|
|
}
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* check Magic number is valid */
|
|
|
if (iapi_mdbg_is_valid_msg(((ext_mdbg_msg *)buf)->magic_num) != TD_TRUE) {
|
|
|
fprintf(stderr, "check magic number error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
/* check header checksum */
|
|
|
if (iapi_mdbg_verify_header_checksum((td_u8 *)buf) != TD_SUCCESS) {
|
|
|
fprintf(stderr, "check header checksum error\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (iapi_mdbg_send_uart_ack(0xA0) < 0) {
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
ret_val = (td_s32)mdbg_get_value(buf, ext_mdbg_msg, cmd);
|
|
|
if (ret_val == EXT_MDBG_CMD_UART_SWITCH) {
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* read data */
|
|
|
ret_val = iapi_mdbg_get_uart_data(read_size, buf);
|
|
|
if (ret_val != TD_SUCCESS) {
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* send ack */
|
|
|
if (iapi_mdbg_send_uart_ack(0xB0) < 0) {
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static td_void iapi_mdbg_uart_switch(td_void)
|
|
|
{
|
|
|
int ret;
|
|
|
td_u32 boardid = 0;
|
|
|
ret = ext_mpi_sys_get_board_id(&boardid);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_fatal_print_call_fun_err(uapi_sys_get_board_id, ret);
|
|
|
return;
|
|
|
}
|
|
|
boardid &= 0x2000;
|
|
|
/* switch to mdbg uart */
|
|
|
if (g_mdbg_chip == MDBG_CHIP_RESERVED5 || g_mdbg_chip == MDBG_CHIP_RESERVED19 ||
|
|
|
g_mdbg_chip == MDBG_CHIP_HI3751V811) {
|
|
|
uapi_uart_switch(1); /* reserved5 use uart1 to mdbg feature */
|
|
|
} else if (g_mdbg_chip == MDBG_CHIP_RESERVED9 || g_mdbg_chip == MDBG_CHIP_RESERVED13) {
|
|
|
if (boardid != 0x2000) {
|
|
|
uapi_uart_switch(2); /* reserved9 or reserved13 use uart2 to mdbg feature */
|
|
|
} else {
|
|
|
uapi_uart_switch(5); /* uart5 */
|
|
|
}
|
|
|
} else {
|
|
|
fprintf(stdout, "unkown chip version .... \n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
fprintf(stdout, "Start PQ TOOL DBG!\n");
|
|
|
g_uart_switch = TD_TRUE;
|
|
|
g_net_use = TD_FALSE;
|
|
|
g_debug_request = TD_TRUE;
|
|
|
mpi_pq_dbg_update_uart_status(g_uart_open_dev, g_pq_dbg, g_uart_switch, g_is_cts_enable);
|
|
|
|
|
|
if (g_debug_request == TD_TRUE) {
|
|
|
g_debug_mode = TD_TRUE;
|
|
|
g_debug_request = TD_FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* MDGB线程 */
|
|
|
td_void *iapi_mdbg_uart_thread(td_void *para)
|
|
|
{
|
|
|
td_s32 ret_val = TD_FAILURE;
|
|
|
|
|
|
if (para == TD_NULL) {
|
|
|
soc_log_err("para was null!\n");
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
g_delay.tv_sec = 0;
|
|
|
g_delay.tv_nsec = 400000 * 1000; // 400000 * 1000 ns = 40ms
|
|
|
|
|
|
while (1) {
|
|
|
if (g_exit_dbg == TD_TRUE) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (g_pq_dbg == TD_FALSE) {
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* Enter the debug mode */
|
|
|
if (g_debug_mode == TD_FALSE) {
|
|
|
iapi_mdbg_uart_read_data((td_u8 *)para, 15, &ret_val); // 读取数据的最大长度为15
|
|
|
if (iapi_mdbg_uart_is_open_flag(para) != TD_TRUE) {
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
iapi_mdbg_uart_switch();
|
|
|
nanosleep(&g_delay, TD_NULL);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* recive data */
|
|
|
if (iapi_mdbg_uart_read_msg((td_u8 *)para) != TD_SUCCESS) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* parser data */
|
|
|
if (iapi_mdbg_parser_msg((td_u8 *)para) != TD_SUCCESS) {
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return TD_NULL;
|
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
#if __cplusplus
|
|
|
}
|
|
|
#endif
|
|
|
#endif /* __cplusplus */
|