一、printf是不可重入函式
printf不能在中斷中被呼叫的原因是它是一個不可重入函式,而在中斷中要避免呼叫不可重入函式,首先我們先說說什么是不可重入函式,
簡單說來,區分一個函式是否可重入就是看這個函式能否在未回傳的時候再次被呼叫,而造成一個函式不可重入的原因往往是使用了全域變數,如果一個函式未回傳再執行一次會導致對全域變數的操作是不安全的,就例如我們常用的printf、malloc、free都是不可重入的函式,printf會參考全域變數stdout,malloc,free會參考全域的記憶體分配表,在多執行緒的環境下,如果沒有很好的處理資料保護和互斥訪問,就會發生錯誤,
二、ESP_LOGx日志
日志記錄庫提供了兩種設定日志詳細程度的方法:
-
在編譯時:在menuconfig中,使用選項設定詳細程度
CONFIG_LOG_DEFAULT_LEVEL,詳細程度高于的所有日志記錄陳述句CONFIG_LOG_DEFAULT_LEVEL將被前處理器洗掉, -
在運行時:詳細級別低于的所有日志
CONFIG_LOG_DEFAULT_LEVEL默認情況下啟用,該功能esp_log_level_set()可用于按模塊設定日志記錄級別,模塊由其標簽標識,這些標簽是可讀的ASCII零終止字串,
該功能
esp_log_level_set()無法將日志記錄級別設定為高于CONFIG_LOG_DEFAULT_LEVEL,要在編譯時增加特定檔案的日志級別,請使用宏LOG_LOCAL_LEVEL
有以下詳細級別:
ESP_LOGE-錯誤(最低)ESP_LOGW- 警告ESP_LOGI-資訊ESP_LOGD-除錯ESP_LOGV-詳細(最高)
此外,ESP_EARLY_LOGx每個宏都有相應的版本,例如ESP_EARLY_LOGE,在初始化堆分配器和syscalls之前,只能在早期啟動代碼中顯式使用這些版本,普通ESP_LOGx宏也可以在編譯引導加載程式時使用,但是它們將退回到與ESP_EARLY_LOGx宏相同的實作方式,
考慮到執行緒安全,在FreeRTOS中盡量使用ESP_LOGx來輸出除錯資訊和列印訊息,
ESP-IDF 編程指南——記錄庫
三、包含頭檔案
#include "esp_log.h"
四、如何使用這個庫
4.1 列印資訊
在每個使用日志記錄功能的C檔案中,定義TAG變數,如下所示:
static const char* TAG = "MyModule";
然后使用日志記錄宏之一生成輸出,例如:
uint16_t ap_count = 0;
ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);
4.2 更改詳細級別
要在檔案或組件范圍內覆寫默認的詳細級別,請定義LOG_LOCAL_LEVEL宏,
在檔案范圍內,在包含之前定義它esp_log.h,例如:
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"
在組件范圍內,在組件makefile中定義它:
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
要在運行時配置每個模塊的日志記錄輸出,請esp_log_level_set()按以下方式向函式添加呼叫:
esp_log_level_set("*", ESP_LOG_ERROR); // set all components to ERROR level
esp_log_level_set("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack
esp_log_level_set("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
4.3 通過JTAG登錄到主機
默認情況下,日志記錄庫使用類似于vprintf的函式將格式化的輸出寫入專用UART,通過呼叫一個簡單的API,所有日志輸出都可以路由到JTAG,從而使日志記錄速度提高了幾倍,有關詳細資訊,請參閱“登錄到主機”部分,
? 由 Leung 寫于 2021 年 4 月 20 日
? 參考:ESP32 開發筆記(三)原始碼示例 0、Hello Bug ESP_LOGX與printf
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278531.html
標籤:其他
上一篇:VMware虛擬化專案中經常使用的三種磁盤置備模式 vmware- vsphere- datastore-disk
