调试信息之网络打印

使用串口打印调试信息,通常设置为115200bps, N81,这种设置每秒打印10K+字节的调试信息。

比如打印信息:[I:ERROR][T:19/09/04 16:15:19:649][F:ca.c][C:ca_update_sys_mode][L:1979] Get CA status failed,有100+字节,打印这条信息耗时约为10ms。

目前应用,只打印关键信息,每次操作有120+条打印信息,这样打印调试信息就耗时1.2S。

在项目实施过程中增加了网络打印调试手段。

网络打印简单说就是将打印信息通过网口经过网络将调试信息传送到打印接收端。具体实施时考虑资源消耗,使用UDP协议。具体实施如下:

1.初始化网络设备

static u32 debug_init(phandle param)
{
    static bool b_is_inited = false;
    u32 error_code = SUCCESS;    
    os_thread_create_t create_t;
    bool ret = false;
    static u32 thread_handle=0;
    os_sem_create_t sem_create;

    if (b_is_inited)
    {
        return SUCCESS;
    }

    /*平台网络初始化*/
    ......

    /*创建信号量、线程*/
    sem_create.pshared=0;
    sem_create.sem_count=1;
    ret=os_create_sem(sem_create,&g_debug_sem);
    if(ret)
    {
        DEBUG_PRINTF_MONTAGE("os_create_sem failed,[p-err]=0x%x\n", ret);
        return PUBLIC_MODULE_PUBLIC_DEBUG;
    }  
    
    memset(&create_t,0,sizeof(create_t));
    create_t.attr_set=OS_CREATE_ATTR_SET;
    create_t.call_back = debug_net_send_thread;
    create_t.parm      = NULL;
    create_t.schedpolicy=THREAD_SCHED_OTHER;
    create_t.set_priority=THREAD_SET_PRIORITY_OFFSET;
    create_t.priority=OS_THREAD_PRIORITY_MID;
    create_t.detachstate=THREAD_CREATE_DETACHED;    
    create_t.stack_size = 0x10000;
    create_t.thread_name="debug_send_network";
    if (os_create_thread(create_t,&thread_handle))
    {
        DEBUG_PRINTF_MONTAGE("os_create_thread failed,[p-err]=0x%x\n", ret);
        os_destroy_sem(g_debug_sem);
        return PUBLIC_MODULE_PUBLIC_DEBUG;
    }

    return SUCCESS;

}

2.打印信息直接拷贝到内存buffer

static s32 debug_printf(const u32 level, const s8 *format, ...)
{    
    static s8 buffer[1024];
    u32 buffer_len = 0;
    
	va_list list;

va_start(list, format);
vsnprintf(buffer,sizeof(buffer), format, list);
va_end(list);

os_acquire_sem(g_debug_sem, OS_WAIT_TIMEOUT_MAX);
buffer_len = strlen(buffer);
if(b_is_client_inited)
{
    if( (g_net_log_pos + buffer_len) < DEBUG_DATABUF_LEN )
    {
        memcpy(g_net_log_buf+g_net_log_pos, buffer, buffer_len);
        g_net_log_pos += buffer_len;
    }
    else
    {
        DEBUG_PRINTF_MONTAGE("buffer_len:%d remain %d\n", buffer_len, DEBUG_DATABUF_LEN-g_net_log_pos);
    }
}    
os_release_sem(g_debug_sem);
   
return 0;

}

3.发送线程间隔一段时间发送一次打印buffer信息到接收端

static void *debug_net_send_thread(void * pvoid_parm)
{
    s32 sock = 0;
    s32 send_buf_len_total = 0;
    s32 send_len = 0;
    s32 actual_send_len = 0;
    s32 actual_send_len_total = 0;    
    
    sock = lwip_socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
    DEBUG_PRINTF_MONTAGE("create socket failed[%d]\n",sock);
    return NULL;
}

while(1)
{
    if ( b_is_client_inited && (g_net_log_pos > 0) )
    {
        os_acquire_sem(g_debug_sem,OS_WAIT_TIMEOUT_MAX);
        memcpy(g_send_buf, g_net_log_buf, g_net_log_pos);
        send_buf_len_total = g_net_log_pos;
        g_net_log_pos = 0;
        os_release_sem(g_debug_sem);
        
        actual_send_len_total = 0;
        while(send_buf_len_total > 0)
        {
            send_len = MIN(send_buf_len_total, DEBUG_SEND_PERTIME_MAX);
            actual_send_len = lwip_sendto(sock, (const void *)g_send_buf+actual_send_len_total, send_len, 0,(const struct sockaddr *)&g_client_addr, sizeof(g_client_addr));
            if (actual_send_len < send_len)
            {
                DEBUG_PRINTF_MONTAGE("actual_send_len:%d < send_len:%d\n", actual_send_len, send_len);
                os_msleep(10);
            }

            if (actual_send_len > 0)
            {
                actual_send_len_total += actual_send_len;
                send_buf_len_total -= actual_send_len;
            }
        }
    }

    os_msleep(50);
}

lwip_close(sock);
return NULL;

}

4.信息接收端运行在PC机上,使用python开发,核心代码如下:

def main():
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    port_num = 23456
    udp_socket.bind(('', port_num))

    time_str = time.strftime('%Y%m%

d_%H%M%S', time.localtime())
    file_name = "MT2211_log_" + time_str + ".log"
    f = open(file_name, 'w+')
    print("ip: " + get_host_ip() + " port: " + "".join("%d" % port_num) + " log save file: " + file_name)

while True:
    receive_data = udp_socket.recvfrom(65507)
    data_to_bytes = ''.join("%s" % receive_data[0].decode())
    print("%s" % receive_data[0].decode(), end="")

    f.write(data_to_bytes)
    file_size = os.path.getsize(file_name)
    if file_size >= (10 * 1024 * 1024):
        f.close()

        time_str = time.strftime('%Y%m%d_%H%M%S', time.localtime())
        file_name = "MT2211_log_" + time_str + ".log"
        f = open(file_name, 'w+')
        print("store log to new file: " + file_name)


f.close()

5.运行情况,信息接收端net_print打印以及每10M日志信息存储到一个新文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值