【项目笔记:HT46】串口驱动操作应用缓存导致的缓存异常

问题描述

在新的版本 v1.0.8_b3 上测试出来,发现出现有时候开机之后音量会比较大,但是根据调试信息来看发现这个实际是哪个音量是有返回的。

[1155853]: s_uart1: vol_set:0
[1156854]: s_uart1: vol_set:0
add:537050748, wpos:0D/HEX rbuf: 0000-0010: 55 AA 00 01 F0 21 00 A0 31 00 U....!..1. 
[1156869]: r_uart1: dfu_s:0 vol:0
[1156869]: p_UART1: vol set seq: 49, vol:[ 0/0] 
[1156869]: h_UART1: hw_ver:2, uart power off 
[1159128]: h_UART1: hw_ver:2, uart power on 
[1159428]: r_PORT0: uID[ 0]: 1988828526 line0:0 line1:3, flg:1
add:537051783, wpos:1D/HEX rbuf: 0000-0010: 55 AA 00 01 F0 21 09 31 18 00 U....!.1.. 
[1159796]: r_uart1: dfu_s:0 vol:9
[1159796]: p_UART1: vol set seq: 4a, vol:[ 0/3] 
add:537050748, wpos:0D/HEX rbuf: 0000-0010: 55 AA 00 01 F0 28 01 0A 88 00 U....(.... 

问题分析

发现这个问题之后,我们同客户端调试发现,他们反馈没有收到这个数据,于是

  • 增加调试信息
/* 处理数据 */
if (r_crc == crc)
{
  if (port == 1)
  {
	log_raw("cmd addr:%u, wpos:%d", rpac, uart_tcb[port].rbuf_tcb.wpos);
	LOG_HEX("rbuf", 16, (uint8_t *)rpac, 10);
  }
  rt_enter_critical();
  uart_tcb[port].rbuf_tcb.wpos = (uart_tcb[port].rbuf_tcb.wpos + 1) % 2;
  if (uart_tcb[port].rbuf_tcb.cnt < 2)
	uart_tcb[port].rbuf_tcb.cnt++;
  rt_exit_critical();
}	
/* 从驱动读取串口数据 */
if (rlen > 0)
{
	log_raw("irq addr:%u, wpos:%d", rbuf, uart_tcb[port].rbuf_tcb.wpos);
	LOG_HEX("rbuf", 16, (uint8_t *)rbuf, rlen);
	ret = uart_rbuf_decode(port, pdata, rlen);
	/* 一旦校验出错则实现下行滑动缓存 */
	if (ret == 1)
	{
	  pdata = rbuf + 1;
	  rlen--;
	}
}

在这里插入图片描述
此处发现中断读取的数据与送的数据缓存存在异常,于是继续修改调试信息

/* 设置缓存 */
void uart_rbuf_set_idel(uint8_t port)
{
  uart_tcb[port].pdata = (uint8_t *)&(uart_tcb[port].rpac[uart_tcb[port].rbuf_tcb.wpos]);
  if (port == 1)
    LOG_D("next buf addr:%u, wpos:%d ", uart_tcb[port].pdata, uart_tcb[port].rbuf_tcb.wpos);
  uart_tcb[port].r_cnt = UART_HEAD_LEN;
  uart_tcb[port].uart_s = VOC_IDLE;
  uart_tcb[port].w_pos = 0;
}

/* 缓存写入数据 */
void uart_rbuf_add(uint8_t port, uint8_t dat)
{
  if (uart_tcb[port].w_pos < 1027)
  {
    uart_tcb[port].pdata[uart_tcb[port].w_pos] = dat;
    if (uart_tcb[port].r_cnt > 0)
      uart_tcb[port].r_cnt--;
    uart_tcb[port].w_pos = (uart_tcb[port].w_pos + 1) % 1027;
    if (port == 1)
    {
      log_raw("[%d]: buf addr:%u, wpos:%d, ",  HAL_GetTick(), uart_tcb[port].pdata,
              uart_tcb[port].rbuf_tcb.wpos);
      LOG_HEX("rbuf", 16, (uint8_t *)uart_tcb[port].pdata, uart_tcb[port].w_pos);
    }
  }
  else
  {
    uart_rbuf_set_idel(port);
    LOG_E("r_uart%d: rbuf is full!", port);
  }
}

于是又调试信息:
在这里插入图片描述
看到数据在写入 BUF 的地址 uart_tcb[port].pdata (port = 1) 发生了突变,于是在BUF操作的时候检查数据:

    if (port == 1)
      LOG_D("[%d]: point check s0 addr:%u, wpos:%d ", HAL_GetTick(), 
        uart_tcb[port].pdata, uart_tcb[port].rbuf_tcb.wpos);
    uart_rbuf_add(port, rbuf[i]);
    if (port == 1)
      LOG_D("[%d]: point check s1 addr:%u, wpos:%d ", HAL_GetTick(), 
        uart_tcb[port].pdata, uart_tcb[port].rbuf_tcb.wpos);

在这里插入图片描述
此处发现这个在修改缓存之前这个地址就突变了,于是怀疑硬件的附带的缓存操作导致数据被修改:

void rt_hw_uart_power_rst(uart_port_t *uart_port)
{
  /* RP555 1号硬件:2个芯片公用同一块供电管脚: port1的 pwr */
  if (sys_tcb_val.hw_ver == 1)
    uart_port = &rp555_hw_uart_port[1];

  /* 复位 */
  HAL_GPIO_WritePin(uart_port->power.GPIOx,
      uart_port->power.GPIO_Pin, GPIO_PIN_RESET);
  rt_thread_mdelay(100);
  HAL_GPIO_WritePin(uart_port->power.GPIOx,
      uart_port->power.GPIO_Pin, GPIO_PIN_SET);
  /* 芯片启动时间 */
  LOG_W("h_UART%d: hw_ver:%d, uart power rst", uart_port->idx, sys_tcb_val.hw_ver);
  rt_thread_mdelay(300);
  /* 清空 UART 缓存数据 */
- uart_tcb[uart_port->idx].pdata = (uint8_t *)&uart_tcb[uart_port->idx].rpac;
  uart_tcb[uart_port->idx].r_cnt = UART_HEAD_LEN;
  uart_tcb[uart_port->idx].uart_s = VOC_IDLE;
- uart_tcb[uart_port->idx].w_pos = 0;
  uart_port->power_s = 1;
  /* 清除错误等待错误的记录时间 */
  uart_tcb[uart_port->idx].hw_cnt = 0;
  /* 清空状态记录 */
  uart_tcb[uart_port->idx].dfu_s = UART_DFU_IDEL;
}

void rt_hw_uart_power_off(uart_port_t *uart_port)
{
  /* RP555 1号硬件:2个芯片公用同一块供电管脚:port1的 pwr */
  if (sys_tcb_val.hw_ver == 1)
    uart_port = &rp555_hw_uart_port[1];

  if((sys_tcb_val.work_mode != HT46_ZJ_MODE) && (uart_port->power_s == 1))
  {
    /* RP555 1号硬件:2个芯片公用同一块供电管脚:port1的 pwr */
    if (sys_tcb_val.hw_ver == 1)
      uart_port = &rp555_hw_uart_port[1];

    HAL_GPIO_WritePin(uart_port->power.GPIOx,
                    uart_port->power.GPIO_Pin, GPIO_PIN_RESET);
    LOG_W("h_UART%d: hw_ver:%d, uart power off", uart_port->idx, sys_tcb_val.hw_ver);
    /* 清空 UART 缓存数据 */
-   uart_tcb[uart_port->idx].pdata = (uint8_t *)&uart_tcb[uart_port->idx].rpac;
    uart_tcb[uart_port->idx].r_cnt = UART_HEAD_LEN;
    uart_tcb[uart_port->idx].uart_s = VOC_IDLE;
-   uart_tcb[uart_port->idx].w_pos = 0;
    uart_port->power_s = 0;
  }
}

void rt_hw_uart_power_on(uart_port_t *uart_port)
{
  /* RP555 1号硬件:2个芯片公用同一块供电管脚:port1的 pwr */
  if (sys_tcb_val.hw_ver == 1)
    uart_port = &rp555_hw_uart_port[1];

  /* RP555 1号硬件:2个芯片公用同一块供电管脚:port1的 pwr */
  if (uart_port->power_s == 0)
  {
    HAL_GPIO_WritePin(uart_port->power.GPIOx,
                      uart_port->power.GPIO_Pin, GPIO_PIN_SET);
    LOG_W("h_UART%d: hw_ver:%d, uart power on", uart_port->idx, sys_tcb_val.hw_ver);
    /* 芯片启动时间 */
    rt_thread_mdelay(300);
    /* 清空 UART 缓存数据 */
-   uart_tcb[uart_port->idx].pdata = (uint8_t *)&uart_tcb[uart_port->idx].rpac;
    uart_tcb[uart_port->idx].r_cnt = UART_HEAD_LEN;
    uart_tcb[uart_port->idx].uart_s = VOC_IDLE;
-   uart_tcb[uart_port->idx].w_pos = 0;
    uart_port->power_s = 1;
  }
}

于是剔除驱动中对串口缓存地址的修改,再次测试
在这里插入图片描述
之后的数据就都一样了,至此问题算是解决了。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值