lhdjply/f1c200s_library

Uart里My_Printf死机问题

Closed this issue · 6 comments

STM32G commented

软件版本

  • 软件已更新到最新版本

您使用的场景?

用的F1C100S芯片,windows平台,vscode

您做了什么操作?

在‘UART_IDLE_task(void * p)’函数内打印串口接收到的内容

static void UART_IDLE_task(void * p)
{
  while(1)
  {
    uart_idle(&uart_Data);

    if(uart_Data.receive_complete_flag == 1)
    {
      uart_Data.receive_complete_flag = 0;

      My_Printf("rxlen=%d,%s",uart_Data.len,uart_Data.RXD_BUF);
    }

    rt_thread_mdelay(1);
  }
}

您遇到了什么问题?

在原有的void My_Printf(char * fmt, ...)函数里使用了'uart_Data.TXD_BUF'作为vsprintf的格式化字符串缓存区,但在实际使用过程中,会造成死机现象。尝试定位问题,最后在函数内部创建一个局部数组作为缓存,就不会死机。我修改后的函数如下:

void My_Printf(char * fmt, ...)
{
  uint32_t i,len;
  va_list p;
  char buf[500];

  rt_enter_critical();
  va_start(p, fmt);
  len = vsnprintf(buf,499,fmt, p);
  va_end(p);

  for(i = 0; i < len; i++)
  {
    UART_SendData(UART1, buf[i]);
    while(UART_Get_Status(UART1, UART_USR_TFNF) != SET);
  }

  rt_exit_critical();
}

您期望的结果是怎样的?

麻烦有时间看下具体原因。

你好,放年假了,家里没有板子,没法测试诶。等我放完假在看看吧,抱歉啊😅 。差不多要2月底左右

对了,你修改了static void UART_IDLE_task(void * p)后,是在哪个界面测试的。如果是在串口界面测试的话,可能会有冲突。因为串口界面有下面代码。

static void my_timer(lv_timer_t * timer)
{
if(uart_Data.receive_complete_flag == 1)
{
lv_textarea_add_text(pageuarttest.receive_data, (char *)uart_Data.RXD_BUF);
uart_Data.receive_complete_flag = 0;
}
}

STM32G commented

您好,您说的这个地方我已经注意到了,没有在串口界面测试,只是在LCD启动后的功能选择界面测试的。
刚才又发现了新的问题,之前为了定位问题把其他线程全部关闭,只保留了串口进程,用了修改后的函数测试没有问题。当我再次把其他线程打开后,My_Printf()函数依旧会造成死机,或者有时候单片机会自动复位。

你把这个线程堆栈改大一点看看,比如300改成1000。如果不行的话,只能等我放完假回去在看了

rt_thread_t uart_idle = rt_thread_create("uart_idle",
UART_IDLE_task,
NULL,
300,
2,
20);

STM32G commented

线程堆栈改大就好了,非常感谢,祝春节快乐!

没事,好了就行。新年快乐,那我就关闭这个issue了。