一、现象描述
在使能硬件rtc,初始化阶段未设置时间的情况下【测试环境为4.1.0版本env创建的keil工程】
如果开启ulog时间戳,打印日志导致线程锁死
根本原因为打印时间戳日志的过程中由于未设置时间,导致再次调用日志打印,在以下函数中挂起线程
/* drv_rtc.c 文件 /
if (hal_rtcex_bkupread(&rtc_handler, rtc_bkp_dr1) != bkup_reg_data)
{
log_i(rtc hasn't been configured, please use command to config.);
/ 其他代码省略 */
}
在log_i()中再次运行log_i()导致output_lock上锁两次
output_lock上锁本质为接收信号量ulog.output_locker
ulog初始化的信号量为1
第一次上锁信号量减一
再次调用log_i导致第二次上锁
第一次的锁还没有解开
第二次上锁导致锁死现象,直接挂起线程
ulog无法输出任何信息
二、对比分析
由于之前使用rt-studio的4.0.3版本可以正常输出提示
所以将4.1.0与4.0.3对比分析并排查问题
硬件平台:stm32f407 正点原子探索者开发板
以下表格是在进入主线程之前为未设置时间的rtc初始化流程对比
三、临时解决方案
方案一:避开初始化未设置时间的提示,增加rtc初始化函数,在进入主线程之前设置时间
缺点:如果真的忘记设置时间,导致死锁又要踩坑,花时间排查原因,影响开发进度
方案二:保留始化未设置时间的提示,避开第二次上锁,将 log_i 修改为 rt_kprintf
缺点:无论是否开启ulog,依旧会有提示,其实影响不是很大,甚至在未开启ulog也会有提示
【前提条件是开启了串口或者其他控制台输出,如果没开启控制台输出不知道会发生什么】
方案三:直接将未设置时间的提示注释掉,由于不会第二次上锁,所以日志打印正常
缺点:未设置时间不会提示
方案四:使用4.0.3版本
方案五:ulog不使用时间戳格式
四、场景复现
理论上只要是stm32的单片机都会有这个问题,其他厂家的未测试过
以下测试平台以正点原子的探索者开发板为参考,场景复现大同小异
据说该开发板的启动电路的串口设置为控制台打印会有一些冲突
如果发现不能正常打印最好换一个串口或者使用rtt作为控制台输出
(1)锁死环境复现
打开 ···rt-threadbspstm32stm32f407-atk-explorer
右键打开env 输入scons —dist
打开dist文件夹中新生成的bsp工程
右键打开env 输入menuconfig
进入 rt-thread kernel -> kernel device object 修改可以使用的控制台设备【如:uart1,jlinkrtt】
rt-thread comonents -> device drivers using rtc device drivers
rt-thread comonents -> utilities enable ulog
log format -> enbale timestamp format for time
hardware drivers config -> on-chip peripheral drivers enablertc rtc_using_lse
esc 然后选择yes保存配置
打开 ···boardcubemx_config文件夹,配置cubemx
打开keil,复制生成的时钟配置,注释掉msp文件的error_handler()已防止后续编译错误
复制一下内容到 main.c 仅供参考
#include
#include
#include
#define dbg_tag main
#define dbg_lvl dbg_log
#include
/* defined the led0 pin: pf9 /
#define led0_pin get_pin(f, 9)
int main(void)
{
/ set led0 pin mode to output */
rt_pin_mode(led0_pin, pin_mode_output);
while (1)
{
rt_pin_write(led0_pin, pin_high);
rt_thread_mdelay(500);
rt_pin_write(led0_pin, pin_low);
rt_thread_mdelay(500);
log_d(hello rt-thread!);
}
}
编译代码并下载到芯片,发现日志打印失败,灯不闪烁,此时 main线程已经挂起
(2)对比环境复现
测试平台为rt-studio 2.2.1【其实和studio版本关系不大】
基于芯片创建的rt-thread工程
本文就不详细说明studio的配置步骤了
以下图片为ulog配置
复制上面的main函数,一切运行正常,并有未设置时间的提示
五、ulog及rtc其它问题的吐槽
(1)部分设备注册的日志信息无法打印
主要原因是初始化顺序不可控,使用 init_board_export(ulog_init);
不能保证在设备注册之前初始化
使初始化阶段部分打印之间 return
void ulog_voutput(······)
{
/* ······ /
if (!ulog.init_ok)
{
return;
}
/ ······ */
}
例如以下打印在我的测试环境下就是直接 return
log_i(i2c bus [%s] registered, bus_name);
(2)stm32的lse和lsi不能同时开启
为什么需要同时开启?
因为独立看门狗的时钟源是lsi
当使用lse作为rtc的时钟源
如果关闭lsi是否会导致独立看门狗工作异常?【实际情况未测试,可能和初始化顺序有关】
具体看以下代码
/* drv_rtc.c */
static rt_err_t stm32_rtc_init(void)
{
__hal_rcc_pwr_clk_enable();
rcc_oscinittypedef rcc_oscinitstruct = {0};
#ifdef bsp_rtc_using_lsi
rcc_oscinitstruct.oscillatortype = rcc_oscillatortype_lsi;
rcc_oscinitstruct.pll.pllstate = rcc_pll_none;
rcc_oscinitstruct.lsestate = rcc_lse_off;
rcc_oscinitstruct.lsistate = rcc_lsi_on;
#else
rcc_oscinitstruct.oscillatortype = rcc_oscillatortype_lse;
rcc_oscinitstruct.pll.pllstate = rcc_pll_none;
rcc_oscinitstruct.lsestate = rcc_lse_on;
rcc_oscinitstruct.lsistate = rcc_lsi_off;
#endif
hal_rcc_oscconfig(&rcc_oscinitstruct);
if (rt_rtc_config() != rt_eok)
{
log_e(rtc init failed.);
return -rt_error;
}
return rt_eok;
}
华为荣耀Magic这部未来之机,最大特点就是搭载了智慧系统
华为麒麟990将支持哪些新功能
基于IEEE 1588时钟同步技术改善和提高系统的同步精度
博世推出人工智能驱动的遮阳板 汽车零件发展获重大突破
三星利用5G改进芯片制造
Ulog使用硬件RTC时间戳信号量锁死分析
未来的女性更容易被人工智能抢掉饭碗吗
手机芯片正在处于「全面缺货」状态
加油加气站实现多功能的安防管理体系管理,防患于未然
高光谱相机评估植被健康状况的方法有哪些?
LT3753在异步闭环设计中的应用
小米6抢先首发高通骁龙835处理器有必要吗?
功率损耗是功率放大器驱动喷墨打印头设计中的关键考虑因素吗?
语者与电子系统及其设计有何关系呢
EDA企业概伦电子拟科创板上市
双芯技术加持vivo X80系列,自研V1+与天玑9000、骁龙8 Gen1擦出怎样的火花?
喜报丨软通动力荣获“2023开放AIGC开发者大赛”一等奖
2022年模拟集成电路将实现两位数增长
芯动力携RPP系列产品亮相ELEXCON 2023,引领计算硬件新革命
华为携手鞍钢和恩菲联合发布智能矿山融合IP工业网解决方案,加速非煤矿山智能化进程