www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]嵌入式開源項目精選專欄 本專欄由Mculover666創(chuàng)建,主要內(nèi)容為尋找嵌入式領(lǐng)域內(nèi)的優(yōu)質(zhì)開源項目,一是幫助開發(fā)者使用開源項目實現(xiàn)更多的功能,二是通過這些開源項目,學(xué)習(xí)大佬的代碼及背后的實現(xiàn)思想,提升自己的代碼水平,和其它專欄相比,本專欄的優(yōu)勢在于:


嵌入式開源項目精選專欄

本專欄由Mculover666創(chuàng)建,主要內(nèi)容為尋找嵌入式領(lǐng)域內(nèi)的優(yōu)質(zhì)開源項目,一是幫助開發(fā)者使用開源項目實現(xiàn)更多的功能,二是通過這些開源項目,學(xué)習(xí)大佬的代碼及背后的實現(xiàn)思想,提升自己的代碼水平,和其它專欄相比,本專欄的優(yōu)勢在于:

不會單純的介紹分享項目,還會包含作者親自實踐的過程分享,甚至還會有對它背后的設(shè)計思想解讀。

目前本專欄包含的開源項目有:

  • SFUD | 一個簡潔實用的開源項目,幫你輕松搞定SPI Flash
  • cJSON | 一個輕量級C語言JSON解析器
  • paho | 支持10種語言編寫mqtt客戶端,總有一款適合你!
  • MultiButton | 一個小巧簡單易用的事件驅(qū)動型按鍵驅(qū)動模塊
  • letter-shell | 一個功能強大的嵌入式shell

如果您自己編寫或者發(fā)現(xiàn)的開源項目不錯,歡迎留言或者私信投稿到本專欄,分享獲得雙倍的快樂!

1. EasyLogger

本期給大家?guī)淼拈_源項目是 EasyLogger,一款輕量級且高性能的日志庫,作者armink,目前收獲 1.1K 個 star,遵循 MIT 開源許可協(xié)議。

EasyLogger 是一款超輕量級、高性能的 C/C++ 日志庫,非常適合對資源敏感的軟件項目,相比之下, EasyLogger 的功能更加簡單,提供給用戶的接口更少,上手會更快,更多實用功能支持以插件形式進行動態(tài)擴展。

目前EasyLogger支持以下功能:

  • 日志輸出方式支持串口、Flash、文件等;
  • 日志內(nèi)容可包含級別、時間戳、線程信息、進程信息等;
  • 支持多種操作系統(tǒng),支持裸機;
  • 各級別日志支持不同顏色顯示;

項目地址:https://github.com/armink/EasyLogger

2. 移植EasyLogger

2.1. 移植思路

在移植過程中主要參考兩個資料:項目的readme文檔和demo工程。

對于這些開源項目,其實移植起來也就兩步:

  • ① 添加源碼到裸機工程中;
  • ② 實現(xiàn)需要的接口即可;

2.2. 準備裸機工程

本文中我使用的是小熊派IoT開發(fā)套件,主控芯片為STM32L431RCT6:移植之前需要準備一份裸機工程,我使用STM32CubeMX生成,使用USART1的查詢方式發(fā)送數(shù)據(jù),并將printf重定向到USART1,具體過程請參考:

  • STM32CubeMX_06 | 使用USART發(fā)送和接收數(shù)據(jù)(查詢模式)
  • STM32CubeMX_09 | 重定向printf函數(shù)到串口輸出的多種方法

串口USART1配置如下:生成工程后printf重定向代碼如下:

#include <stdio.h>

int fputc(int ch, FILE *stream)
{
    /* 堵塞判斷串口是否發(fā)送完成 */
    while((USART1->ISR & 0X40) == 0);

    /* 串口發(fā)送完成,將該字符發(fā)送 */
    USART1->TDR = (uint8_t) ch;

    return ch;
}

裸機工程準備好之后開始移植easylogger。

2.3. 添加elog到工程中

① 復(fù)制源碼到工程中:② 在keil中添加easylogger組件的源碼文件:

  • port/elog_port.c:elog移植接口文件;
  • src/elog.c:elog核心功能源碼;
  • src/elog_utils.c:elog所用到的一些c庫工具函數(shù)實現(xiàn);
  • src/elog_buf.c(可選添加):elog緩沖輸出模式源碼;
  • src/elog_async.c(可選添加):elog異步輸出模式源碼;

③ 將easylogger/inc頭文件路徑添加到keil中:

2.4. 實現(xiàn)elog移植接口

elog的移植接口都已經(jīng)寫好了,在elog_port.c文件中,只需要在函數(shù)體中添加代碼即可。

① elog初始化接口

ElogErrCode elog_port_init(void);

如果涉及到后續(xù)elog使用資源的初始化,比如動態(tài)申請分配緩沖區(qū)內(nèi)存,可以放在此接口中,本文中保持默認。

② elog日志輸出接口(重點)

//開頭添加
#include <stdio.h>

……

//接口實現(xiàn)
void elog_port_output(const char *logsize_t size) {
 //日志使用printf輸出,printf已經(jīng)重定向到串口USART1
 printf("%.*s", size, log);
}

這兒有個小知識點,%s表示字符串輸出,.<十進制數(shù)>是精度控制格式符,輸出字符時表示輸出字符的位數(shù),在精度控制時,小數(shù)點后的十進制數(shù)可以使用*來占位,在后面提供一個變量作為精度控制的具體值。

③ 日志輸出上鎖/解鎖接口

該接口可以對日志輸出接口進行上鎖/解鎖,以保證日志在并發(fā)輸出時的正確性,本文中使用的是裸機程序,所以在此使用關(guān)閉全局中斷來加鎖,打開全局中斷來解鎖:

//開頭添加
#include <stm32l4xx_hal.h>

……

//接口實現(xiàn)
void elog_port_output_lock(void) {
    
    //關(guān)閉全局中斷
 __set_PRIMASK(1);
  
}
void elog_port_output_unlock(void) {
    
    //開啟全局中斷
 __set_PRIMASK(0);
    
}

STM32開關(guān)全局中斷的方式很多,本文中直接操作 PRIMASK 寄存器來快速的屏蔽/打開全局中斷,參考文章:

https://blog.csdn.net/working24hours/article/details/88323241

④ 系統(tǒng)信息獲取接口

elog提供了三個接口用來獲取當前時間、獲取進程號、獲取線程號,因為本文中移植到裸機工程中,并且沒有提供時間支持,所以這三個接口都返回空字符串,如下:

const char *elog_port_get_time(void) {
    
 return "";
    
}
const char *elog_port_get_p_info(void) {

 return "";
    
}
const char *elog_port_get_t_info(void) {

 return "";
    
}

2.5. 配置elog

elog的核心功能開啟宏定義和核心參數(shù)宏定義都在配置文件elog_cfg.h中,在本文中只講述其中重要的宏定義。

日志輸出總開關(guān):

/* enable log output. */
#define ELOG_OUTPUT_ENABLE

換行符宏定義修改如下:

/* output newline sign */
#define ELOG_NEWLINE_SIGN                        "\r\n"

帶有顏色的日志輸出開關(guān):

/* enable log color */
#define ELOG_COLOR_ENABLE

移植時并沒有添加異步輸出和緩沖區(qū)輸出的源碼,所以將這兩個功能關(guān)掉:至此,移植配置完成,接下來可以開始愉快的使用啦!

3. 使用easylogger

3.1. 初始化elog

elog使用之前需要初始化,過程有三步:① 初始化elog

ElogErrCode elog_init(void);

② 設(shè)置日志輸出格式

void elog_set_fmt(uint8_t level, size_t set);

其中第一個參數(shù)表示設(shè)置哪個日志輸出級別對應(yīng)的輸出格式,從以下宏定義中選擇一個:

/* output log's level */
#define ELOG_LVL_ASSERT                      0
#define ELOG_LVL_ERROR                       1
#define ELOG_LVL_WARN                        2
#define ELOG_LVL_INFO                        3
#define ELOG_LVL_DEBUG                       4
#define ELOG_LVL_VERBOSE                     5

其二個參數(shù)是日志輸出格式,枚舉給出,可以自由組合搭配:

/* all formats index */
typedef enum {
    ELOG_FMT_LVL    = 1 << 0/**< level */
    ELOG_FMT_TAG    = 1 << 1/**< tag */
    ELOG_FMT_TIME   = 1 << 2/**< current time */
    ELOG_FMT_P_INFO = 1 << 3/**< process info */
    ELOG_FMT_T_INFO = 1 << 4/**< thread info */
    ELOG_FMT_DIR    = 1 << 5/**< file directory and name */
    ELOG_FMT_FUNC   = 1 << 6/**< function name */
    ELOG_FMT_LINE   = 1 << 7/**< line number */
} ElogFmtIndex;

/* macro definition for all formats */
#define ELOG_FMT_ALL    (ELOG_FMT_LVL|ELOG_FMT_TAG|ELOG_FMT_TIME|ELOG_FMT_P_INFO|ELOG_FMT_T_INFO| ELOG_FMT_DIR|ELOG_FMT_FUNC|ELOG_FMT_LINE)

③ 啟動elog

void elog_start(void);

接下來在main函數(shù)中的usart1初始化函數(shù)之后,while(1)之前編寫elog初始化代碼:

/* USER CODE BEGIN 2 */
/* 初始化elog */
elog_init();

/* 設(shè)置每個級別的日志輸出格式 */
//輸出所有內(nèi)容
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
//輸出日志級別信息和日志TAG
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG);
//除了時間、進程信息、線程信息之外,其余全部輸出
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_TIME | ELOG_FMT_P_INFO | ELOG_FMT_T_INFO));
//輸出所有內(nèi)容
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL);

/* 啟動elog */
elog_start();

/* USER CODE END 2 */

3.2. elog日志輸出

elog中每種級別都有一種完整方式,兩種簡化方式,使用時自行選擇:

#define elog_assert(tag, ...) 
#define elog_a(tag, ...) //簡化方式1,每次需填寫 LOG_TAG
#define log_a(...)       //簡化方式2,LOG_TAG 在文件頂部定義,使用前無需填寫 LOG_TAG

#define elog_error(tag, ...)
#define elog_e(tag, ...)
#define log_e(...)

#define elog_warn(tag, ...)
#define elog_w(tag, ...)
#define log_w(...)

#define elog_info(tag, ...)
#define elog_i(tag, ...)
#define log_i(...)

#define elog_debug(tag, ...)
#define elog_d(tag, ...)
#define log_d(...)

#define elog_verbose(tag, ...)
#define elog_v(tag, ...)
#define log_v(...)

前兩種在使用的時候只需要包含<elog.h>頭文件即可,第三種方式除了包含頭文件之外,還需要在文件開始定義TAG宏定義,使用起來和printf相同,所以這里我使用第三種方法演示。

首先在main.c文件開始定義TAG宏,包含頭文件:

/* USER CODE BEGIN Includes */
#define LOG_TAG    "main"

#include <elog.h>

/* USER CODE END Includes */

然后在main函數(shù)中編寫的elog初始化代碼之后,繼續(xù)添加代碼,測試elog的使用:

log_a("Hello EasyLogger!");
log_e("Hello EasyLogger!");
log_w("Hello EasyLogger!");
log_i("Hello EasyLogger!");
log_d("Hello EasyLogger!");
log_v("Hello EasyLogger!");

編譯,燒寫,使用串口終端(Mobaxterm)查看串口輸出:

3.3. 五彩繽紛的輸出

要想五彩繽紛的日志,僅在elog_cfg.h中使能顏色輸出還不夠,還需要使用API開啟輸出:

void elog_set_text_color_enabled(bool enabled);

在初始化elog的時候使能文字顏色輸出:再次編譯、下載、查看輸出:每個級別日志的前景色、背景色、字體都可以在elog_cfg.h中修改宏定義,宏定義的值在elog.c中給出,可自行查看,比如這里我將ERROR級別的日志修改為閃爍字體:編譯、下載、查看輸出:

3.4. 移植前后內(nèi)存占用情況

移植前的裸機工程只具有usart1收發(fā)功能,移植easylogger之后兩者內(nèi)存對比如下:

3.5. elog的高級功能

elog除了基本的日志功能之外,還提供了一些高級功能,比如:

  • 日志輸出過濾功能:可以按級別、TAG、關(guān)鍵詞過濾日志;
  • 緩沖輸出模式;
  • 異步輸出模式;

這些功能如何使用,在項目的readme文檔中講述的很詳細,本文限于篇幅,這些高級功能不詳細講述,如有興趣深入,可以自行研究。

4. 設(shè)計思想解讀

4.1. 數(shù)據(jù)加工

使用日志打印組件與使用printf最基本的區(qū)別在于:輸出了更多有利于調(diào)試的信息,可以理解為對輸出數(shù)據(jù)進行了一次加工。

打印語句所在文件、函數(shù)名、行號這些信息是利用了編譯器內(nèi)置宏的功能:

  • __FILE__:文件名
  • __FUNCTION__:函數(shù)名
  • __LINE__:行號

而在終端中輸出有顏色的字符則是利用了ANSI escape code,即Escape 序列屏幕控制碼,關(guān)于這兩個知識點詳細的解釋和示例請閱讀:

  • 編譯器宏詳解
  • ANSI escape code詳解

在elog中對輸出內(nèi)容進行加工處理的函數(shù)為:

/**
 * output the log
 *
 * @param level level
 * @param tag tag
 * @param file file name
 * @param func function name
 * @param line line number
 * @param format output format
 * @param ... args
 *
 */

void elog_output(uint8_t level, const char *tag, const char *file, const char *func,const long line, const char *format, ...) ;

4.2. 日志輸出模式

俗話說,師傅領(lǐng)進門,修行在個人,本文所講述的只是日志打印組件的基本功能,使用printf直接實現(xiàn)日志輸出接口,所以在日志輸出模式上和使用printf輸出沒有區(qū)別,只不過多了些信息。

elog支持異步輸出模式,開啟異步輸出模式后,將會提升用戶應(yīng)用程序的執(zhí)行效率。應(yīng)用程序在進行日志輸出時,無需等待日志徹底輸出完成,即可直接返回。

elog也支持緩沖輸出模式,開啟緩沖輸出模式后,如果緩沖區(qū)不滿,用戶線程在進行日志輸出時,無需等待日志徹底輸出完成,即可直接返回。但當日志緩沖區(qū)滿以后,將會占用用戶線程,自動將緩沖區(qū)中的日志全部輸出干凈。

這兩種無需等待,直接返回的日志輸出模式,在打印大量日志信息的時候非常重要,打印日志的代碼對正常應(yīng)用程序的影響越小越好,本文不再講述,還請讀者自行研究。

5. 項目工程源碼獲取和問題交流

目前我將Easylogger源碼、我移植到小熊派STM32L431RCT6開發(fā)板的工程源碼上傳到了QQ群里(包含好幾份HAL庫,QQ相對速度快點),可以在QQ群里下載,有問題也可以在群里交流,當然也歡迎大家分享出來自己移植的工程到QQ群里

放上QQ群二維碼:

接收更多精彩文章及資源推送,歡迎訂閱我的微信公眾號:『mculover666』。

免責聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉