0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Ulog使用硬件RTC時間戳信號量鎖死分析

冬至子 ? 來源:Code_Monkey ? 作者:Code_Monkey ? 2023-08-10 17:00 ? 次閱讀

一、現(xiàn)象描述
在使能硬件RTC,初始化階段未設(shè)置時間的情況下【測試環(huán)境為4.1.0版本Env創(chuàng)建的Keil工程】
如果開啟Ulog時間戳,打印日志導(dǎo)致線程鎖死

根本原因為打印時間戳日志的過程中由于未設(shè)置時間,導(dǎo)致再次調(diào)用日志打印,在以下函數(shù)中掛起線程

/* 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()導(dǎo)致output_lock上鎖兩次
output_lock上鎖本質(zhì)為接收信號量ulog.output_locker
ulog初始化的信號量為1
第一次上鎖信號量減一
再次調(diào)用LOG_I導(dǎo)致第二次上鎖
第一次的鎖還沒有解開
第二次上鎖導(dǎo)致鎖死現(xiàn)象,直接掛起線程
Ulog無法輸出任何信息

二、對比分析
由于之前使用RT-Studio的4.0.3版本可以正常輸出提示

所以將4.1.0與4.0.3對比分析并排查問題

硬件平臺:STM32F407 正點原子探索者開發(fā)板

以下表格是在進入主線程之前為未設(shè)置時間的RTC初始化流程對比

1.jpg

三、臨時解決方案
方案一:避開初始化未設(shè)置時間的提示,增加RTC初始化函數(shù),在進入主線程之前設(shè)置時間

缺點:如果真的忘記設(shè)置時間,導(dǎo)致死鎖又要踩坑,花時間排查原因,影響開發(fā)進度

方案二:保留始化未設(shè)置時間的提示,避開第二次上鎖,將 LOG_I 修改為 rt_kprintf

缺點:無論是否開啟Ulog,依舊會有提示,其實影響不是很大,甚至在未開啟Ulog也會有提示

? 【前提條件是開啟了串口或者其他控制臺輸出,如果沒開啟控制臺輸出不知道會發(fā)生什么】

方案三:直接將未設(shè)置時間的提示注釋掉,由于不會第二次上鎖,所以日志打印正常

缺點:未設(shè)置時間不會提示

方案四:使用4.0.3版本

方案五:Ulog不使用時間戳格式

四、場景復(fù)現(xiàn)
理論上只要是STM32的單片機都會有這個問題,其他廠家的未測試過

以下測試平臺以正點原子的探索者開發(fā)板為參考,場景復(fù)現(xiàn)大同小異

據(jù)說該開發(fā)板的啟動電路的串口設(shè)置為控制臺打印會有一些沖突

如果發(fā)現(xiàn)不能正常打印最好換一個串口或者使用RTT作為控制臺輸出

(1)鎖死環(huán)境復(fù)現(xiàn)
打開 ···rt-threadbspstm32stm32f407-atk-explorer

右鍵打開Env 輸入scons —dist

打開dist文件夾中新生成的bsp工程

右鍵打開Env 輸入menuconfig

進入 RT-Thread Kernel -> Kernel Device Object 修改可以使用的控制臺設(shè)備【如: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,復(fù)制生成的時鐘配置,注釋掉msp文件的Error_Handler()已防止后續(xù)編譯錯誤

復(fù)制一下內(nèi)容到 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!");
}
}
編譯代碼并下載芯片,發(fā)現(xiàn)日志打印失敗,燈不閃爍,此時 main線程已經(jīng)掛起

(2)對比環(huán)境復(fù)現(xiàn)
測試平臺為RT-Studio 2.2.1【其實和Studio版本關(guān)系不大】

基于芯片創(chuàng)建的RT-Thread工程

本文就不詳細說明Studio的配置步驟了

以下圖片為Ulog配置

復(fù)制上面的main函數(shù),一切運行正常,并有未設(shè)置時間的提示

1.jpg

五、Ulog及RTC其它問題的吐槽
(1)部分設(shè)備注冊的日志信息無法打印
主要原因是初始化順序不可控,使用 INIT_BOARD_EXPORT(ulog_init);

不能保證在設(shè)備注冊之前初始化

使初始化階段部分打印之間 return

void ulog_voutput(······)
{
/* ······ /
if (!ulog.init_ok)
{
return;
}
/
······ */
}
例如以下打印在我的測試環(huán)境下就是直接 return

LOG_I("I2C bus [%s] registered", bus_name);
(2)STM32的LSE和LSI不能同時開啟
為什么需要同時開啟?

因為獨立看門狗的時鐘源是LSI

1.jpg

當使用LSE作為RTC的時鐘源

如果關(guān)閉LSI是否會導(dǎo)致獨立看門狗工作異常?【實際情況未測試,可能和初始化順序有關(guān)】

具體看以下代碼

/* 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;
}

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • RTC
    RTC
    +關(guān)注

    關(guān)注

    2

    文章

    519

    瀏覽量

    66133
  • STM32單片機
    +關(guān)注

    關(guān)注

    58

    文章

    549

    瀏覽量

    58561
  • STM32F407
    +關(guān)注

    關(guān)注

    15

    文章

    187

    瀏覽量

    29298
  • 獨立看門狗
    +關(guān)注

    關(guān)注

    0

    文章

    24

    瀏覽量

    3780
  • HAL庫
    +關(guān)注

    關(guān)注

    1

    文章

    114

    瀏覽量

    6115
收藏 人收藏

    評論

    相關(guān)推薦

    FreeRTOS信號量使用教程

    信號量是操作系統(tǒng)中重要的一部分,信號量一般用來進行資源管理和任務(wù)同步, FreeRTOS中信號量又分為二值信號量、 計數(shù)型信號量、互斥
    的頭像 發(fā)表于 12-19 09:22 ?2997次閱讀
    FreeRTOS<b class='flag-5'>信號量</b>使用教程

    Linux驅(qū)動開發(fā)筆記-自旋信號量

    :如果在寫代碼時,有以上的競態(tài)發(fā)生,一定要注意進行互斥訪問7.解決競態(tài)的方法:中斷屏蔽原子操作自旋信號量如何使用以上4個機制呢?1.中斷屏蔽解決哪些情況的競態(tài):進程和進程的搶占中斷和進程中斷和中斷
    發(fā)表于 08-30 18:08

    信號量、互斥、自旋

    信號量、互斥、自旋http://bbs.edu118.com/forum.php?mod=viewthread&tid=488&fromuid=231(出處: 信盈達IT技術(shù)社
    發(fā)表于 08-29 09:48

    信號量和互斥信號量的相關(guān)資料分享

    信號量簡介信號量就是一個上鎖的機制,代碼必須獲得鑰匙才能執(zhí)行,一旦獲得了信號量,就相當于該代碼具有了進入被代碼的權(quán)限。說白了,就和java多線程中常用的
    發(fā)表于 03-02 07:11

    Ulog使用硬件RTC時間信號量的原因及解決方案

    一、現(xiàn)象描述在使能硬件RTC,初始化階段未設(shè)置時間的情況下【測試環(huán)境為4.1.0版本Env創(chuàng)建的Keil工程】如果開啟Ulog時間
    發(fā)表于 03-14 14:28

    ulog里現(xiàn)在默認的時間是從哪里獲取的呢?

    我現(xiàn)在用的外部RTC,想在ulog里的時間顯示外部RTC時間,
    發(fā)表于 11-14 14:22

    ulog里用的時間是從哪里取的?

    我現(xiàn)在用的外部RTC,想在ulog里的時間顯示外部RTC時間,
    發(fā)表于 05-11 09:56

    你了解Linux 各類信號量?

    內(nèi)核信號量與用戶信號量,用戶信號量分為POXIS信號量和SYSTEMV信號量,POXIS信號量
    發(fā)表于 05-04 17:19 ?2469次閱讀
    你了解Linux 各類<b class='flag-5'>信號量</b>?

    信號量和自旋

    自旋不應(yīng)該被持有時間過長。如果需要長時間鎖定的話, 最好使用信號量。自旋的基本形式如下:??? spin_lock(&mr_lock);
    發(fā)表于 04-02 14:43 ?790次閱讀

    uCOS信號量源碼的詳細資料分析

    本文檔的主要內(nèi)容詳細介紹的是uCOS信號量源碼的詳細資料分析信號量相關(guān)的函數(shù) 創(chuàng)建一個信號量,參數(shù)是信號量的初始值,創(chuàng)建成功返回值是
    發(fā)表于 06-17 17:38 ?7次下載
    uCOS<b class='flag-5'>信號量</b>源碼的詳細資料<b class='flag-5'>分析</b>

    Linux信號量(2):POSIX 信號量

    上一章,講述了 SYSTEM V 信號量,主要運行于進程之間,本章主要介紹 POSIX 信號量:有名信號量、無名信號量。 POSIX 信號量
    的頭像 發(fā)表于 10-29 17:34 ?656次閱讀

    開源硬件信號量在行動

    電子發(fā)燒友網(wǎng)站提供《開源硬件信號量在行動.zip》資料免費下載
    發(fā)表于 11-16 10:22 ?0次下載
    開源<b class='flag-5'>硬件</b><b class='flag-5'>信號量</b>在行動

    FreeRTOS的二值信號量

    FreeRTOS中的信號量是一種任務(wù)間通信的方式,信號量包括:二值信號量、互斥信號量、計數(shù)信號量,本次實驗只使用二值
    的頭像 發(fā)表于 02-10 15:07 ?1333次閱讀

    Free RTOS的計數(shù)型信號量

    上篇講解了二值信號量,二值信號量只能判斷有無,而不能確定事件發(fā)生的次數(shù),因此我們?yōu)榱舜_定事件的次數(shù)引入了計數(shù)型信號量!
    的頭像 發(fā)表于 02-10 15:29 ?944次閱讀
    Free RTOS的計數(shù)型<b class='flag-5'>信號量</b>

    使用Linux信號量實現(xiàn)互斥點燈

    信號量常用于控制對共享資源的訪問,有計數(shù)型信號量和二值信號量之分。初始化時信號量值大于1的,就是計數(shù)型信號量,計數(shù)型
    的頭像 發(fā)表于 04-13 15:12 ?758次閱讀
    使用Linux<b class='flag-5'>信號量</b>實現(xiàn)互斥點燈