芯片设计上的BUG

近期白嫖君在使用gd32这款芯片时候,发现了一个大概率是芯片设计上的bug,贴出来和大家分享一下。
我们在使用串口发送数据时,无非是使用两种方法,一种是逐字节发送,另一种是dma发送。
一般串口发送数据前,我们需要先查看tbe标志位,判断缓存区内是不是已经空了,如果空了我们才会往里填数据。
但是当发送缓存区为空时,并不代表我们的数据已经实际发完了,只是代表缓存区内的数据空了,这时物理意义上的发送可能还在进行中,如果你使用rs485器件,这时候把发送使能关断的话,就会丢失一个字节的数据。
因此,一般发送完成后,需要检查tc标志是不是已经被拉高了,以此来判断数据线上的数据是不是确实已经发结束了。
void usart_sendbuf(uint32_t usart_periph, uint8_t *buffer , uint16_t ucsend_num){ unsigned int i; usart_flag_clear(usart_periph, usart_flag_tc); //在发送前要先清除tc for(i = 0; i < ucsend_num; i++) { while(usart_flag_get(usart_periph, usart_flag_tbe) == reset); usart_data_transmit(usart_periph, buffer[i]); }    while(usart_flag_get(usart_periph, usart_flag_tc) == reset);      } 这次白嫖君的程序就是还按照这个套路来写的,串口发送数据量比较大,在运行一段时间后,程序突然就死机了,查看一下,是死在了最后一行等待tc标志位这里。查看寄存器列表,tc始终为0。
下面是官方库函数手册上给出的说明:
tc标识是受单片机硬件控制的,并不受程序影响,这里无法拉高九成九就是芯片bug了,于是白嫖君谷歌了一下,发现也有人遇到类似问题:
针对这种情况,硬件上无法做出改善,只能从软件上规避了:
void usart_sendbuf(uint32_t usart_periph, uint8_t *buffer , uint16_t ucsend_num){ uint32_t i; uint32_t j = 0; usart_flag_clear(usart_periph, usart_flag_tc); //为了使用tc,在发送前要先清除tc for(i = 0; i= 0xffff) //在这里加超时机制 { break; } } } 引入超时机制,当等待时间超过设定阈值,则不再等待tc置位,以此来避免程序阻塞假死。
特别注意:出现这种情况目前来说可能gd全系都有可能存在这个问题,且不区分是usart0还是usartx,同时似乎只在数据量较大时会出现此种情况。我以前用gd的片子也不少,从没遇见过这种情况。特此说明,避免抬杠嘛~


怎么在数据可视化报表上展现车辆行驶轨迹
奥迪首次引入安卓9.0系统
MF51单端玻封型热敏电阻
什么是智慧用电设备_电猫猫_西安闽泰科技
英飞凌助力新能源汽车充电设施全球标准化
芯片设计上的BUG
2019两会5G提案最全汇总!Facebook或将于今年推出企业版Oculus Go和Quest
RF2903的原理及在扩频通信中的应用
MOVIPRO:电机初始化Starting up the motor encoder
超多维d1手机怎么样 一个可以随身携带的迷你电影院
超五类网线传输距离只能100米内的原因
桁架机器人厂家在设计机器人时有什么要求?
蚂蚁回应约谈:严格遵从监管要求
谷歌透露:在2021年的Android 12系统上允许更容易地安装第三方APP
LT1937-采用SC70和ThinSOT封装的白光LED升
如何看待波卡和以太坊的区别
半导体市场的疯狂结束后
Intel新CEO:7nm芯片用于2023年销售芯片 可能扩大芯片制造外包
晶圆对晶圆的3D IC技术
《无人驾驶航空器飞行管理暂行条例》正式施行 低空经济发展将更规范有序