星標(biāo)公眾號,讓嵌入式知識 “投喂” 不停歇!
AppKit是一個專注于嵌入式Linux應(yīng)用開發(fā)的C++14框架,它的核心目標(biāo)是提升開發(fā)效率和應(yīng)用健壯性。AppKit提供了一套經(jīng)過驗證的工具集,覆蓋了線程管理、定時器、文件IO、串口通信、網(wǎng)絡(luò)通信、CAN總線、GPIO控制等嵌入式開發(fā)中的高頻需求。
https://gitee.com/newgolo/appkit
雙環(huán)境支持: 同時支持ROS和非ROS環(huán)境編譯,既能用于機(jī)器人項目,也能用于傳統(tǒng)嵌入式應(yīng)用
跨平臺構(gòu)建: 內(nèi)置zbuild編譯系統(tǒng),支持x86_64和aarch64平臺的本地編譯與交叉編譯
工程化實踐:
集成了fmt、spdlog、json、yaml-cpp等成熟的第三方庫,避免重復(fù)造輪子
AppKit的設(shè)計哲學(xué)是"分層解耦,按需組合"。整個項目分為三個核心層次:

項目采用了標(biāo)準(zhǔn)化的ROS工作空間布局,即使在非ROS環(huán)境下也保持了這種結(jié)構(gòu):
appkit/
├── environ/ # 環(huán)境配置中樞
│ ├── cmake/ # CMake工具集
│ │ ├── zbuild.cmake # zbuild函數(shù)定義
│ │ ├── finder.cmake # 依賴查找
│ │ └── common.cmake # 通用配置
│ ├── config/ # 平臺配置文件
│ │ ├── linux-amd64.sh # x64配置
│ │ └── linux-arm64.sh # ARM64配置
│ ├── zbuild/ # zbuild工具腳本
│ └── envsetup.sh # 環(huán)境初始化腳本
├── src/
│ ├── appkit/ # 核心庫源碼
│ │ ├── inc/ # 公共頭文件
│ │ └── src/ # 實現(xiàn)代碼
│ ├── third_party/ # 第三方依賴
│ ├── demos/ # 示例程序
│ └── include/ # 全局公共頭文件
├── prebuilt/ # 預(yù)編譯庫存放
│ ├── linux-amd64/
│ └── linux-arm64/
├── zbuild/ # 非ROS編譯入口
└── ws_output/ # ROS編譯輸出

關(guān)鍵設(shè)計點:
environ目錄:這是整個構(gòu)建系統(tǒng)的大腦。envsetup.sh通過source的方式注入環(huán)境變量,讓用戶在shell中就能調(diào)用zbuild_setup等函數(shù)。這種設(shè)計比傳統(tǒng)的Makefile更靈活,可以根據(jù)平臺動態(tài)配置。
setup.cmake:每個package的CMakeLists.txt都會include這個文件。它統(tǒng)一管理了編譯選項、依賴路徑、宏定義等,避免了各模塊的配置不一致。
prebuilt機(jī)制:交叉編譯時,先將庫安裝到prebuilt目錄,其他模塊再從這里鏈接。這避免了交叉編譯環(huán)境下的路徑混亂問題。
AppKit支持三種編譯模式:

zbuild的核心機(jī)制:
通過環(huán)境變量ZBUILD_ENABLE來區(qū)分編譯模式。當(dāng)ZBUILD_ENABLE=1時,所有package的CMakeLists.txt都會走非ROS的編譯分支:

這種設(shè)計的精妙之處在于:同一份CMakeLists.txt,通過環(huán)境變量控制就能適配兩種完全不同的構(gòu)建系統(tǒng)。避免了維護(hù)兩套構(gòu)建腳本的麻煩。
AppKit的線程設(shè)計采用了經(jīng)典的Runnable模式:

使用示例:

設(shè)計優(yōu)勢:
run()函數(shù)可以訪問Thread對象,方便檢查退出標(biāo)志嵌入式系統(tǒng)中常常需要管理大量定時器,如果每個定時器都開一個線程,資源消耗很大。AppKit采用了單線程集中調(diào)度的方式:

關(guān)鍵點:
AppKit提供了一個輕量級的應(yīng)用框架,類似于ROS的節(jié)點概念:

這種設(shè)計讓應(yīng)用的生命周期管理變得清晰:

優(yōu)勢:
#include <appkit/async.h>
#include <appkit/console.h>
#include <appkit/datetime.h>
#include <appkit/strutil.h>
#include <appkit/timer.h>
#include <appkit/tracer.h>
usingnamespace appkit;
void test_timer_manager() {
Timer t1(500, true);
Timer t2(1000, true);
TimerManager tm;
tm.registerTimer(t1, []() { TRACE_INFO("500 ms timer timeout!"); });
tm.registerTimer(t2, []() { TRACE_INFO("1000 ms timer timeout!"); });
while (1) {
TRACE_YELLOW("01. start.");
TRACE_YELLOW("02. stop.");
TRACE_YELLOW("input q to quit!");
ConsoleIn ci;
ci.waitInput();
if (ci.asString() == "01") {
tm.start();
} elseif (ci.asString() == "02") {
tm.stop();
} elseif (ci.asString() == "q" || ci.asString() == "quit") {
break;
}
}
tm.stop();
}
void test_timer() {
while (1) {
TRACE_YELLOW("----------timer test--------------");
TRACE_YELLOW("01. timer manager test.");
TRACE_YELLOW(" q. quit");
TRACE_YELLOW("please input selection:");
ConsoleIn ci;
ci.waitInput();
if (ci.asString() == "01") {
test_timer_manager();
} elseif (ci.asString() == "02") {
//
} elseif (ci.asString() == "q" || ci.asString() == "quit") {
break;
}
}
}


std::thread更符合OOP思想,線程邏輯可復(fù)用、可測試猜你喜歡:
一款基于FreeRTOS設(shè)計的手機(jī)操作系統(tǒng)!
嵌入式系統(tǒng)內(nèi)存泄漏檢測利器:MTrace
嵌入式模塊設(shè)計的工程實踐!
一份經(jīng)典的嵌入式面試題!
嵌入式系統(tǒng)模塊間幾種通信方式對比
在公眾號聊天界面回復(fù)1024,獲取嵌入式資源