CmBacktrace (Cortex Microcontroller Backtrace)是一款針對 ARM Cortex-M 系列 MCU 的錯誤代碼自動追蹤、定位,錯誤原因自動分析的開源庫。支持裸機、ucos rh-thread,freertos.適配 Cortex-M0/M3/M4/M7 MCU;支持中英文輸出。
ulog:與開源easy log很像,可將程序運行過程中的一些狀態信息分標簽、級別輸出到不同的后端(控制台、文件、網絡),逐步取代RTT早期的elog/rt_dbg。資源占用小(ROM<1K, RAM<0.2K),分同步模式(為避免影響線程只能輸出到控制台)、異步模式(支持在中斷、hardfault下使用(CmBacktrace已經做了適配),需要bug和專門的日志處理線程),用用好主要是注意日志的標簽、級別、過濾。
#define LOG_E(...) ulog_e(LOG_TAG, __VA_ARGS__) #define LOG_W(...) ulog_w(LOG_TAG, __VA_ARGS__) #define LOG_I(...) ulog_i(LOG_TAG, __VA_ARGS__) #define LOG_D(...) ulog_d(LOG_TAG, __VA_ARGS__) #define LOG_RAW(...) ulog_raw(__VA_ARGS__) #define LOG_HEX(name, width, buf, size) ulog_hex(name, width, buf, size)

utest簡介
utest的初衷是方便RT-Thread開發者使用統一的框架接口編寫測試程序,實現單元測試,覆蓋測試以及集成測試的目的,utest測試框架依賴ULOG模塊日志進行日志輸出,utest的斷言宏uassert 僅記錄通過和失敗的數量,不會產生斷言並終止程序運行。其功能不等同於 RT_ASSERT。

GSM/GPRS等模組一般都通過AT命令通訊,RTT的AT組件對客戶端(也支持多客戶端)和服務器都可適配,除了發送命令,解析返回數據(第幾行,關鍵字),還能處理URC數據(自己設計URC數據表:收到的前綴,前綴匹配后的響應函數)
DFS:設備的虛擬文件系統,以文件夾為容器,以文件為單位的抽象數據類型。可實現了數據的存儲、分級組織、訪問和獲取等操作。
-
FatFS 是專為小型嵌入式設備開發的一個兼容微軟 FAT(文件名都大寫,最多8個字符,后綴最多3個) 格式的文件系統,采用 ANSI C 編寫,具有良好的硬件無關性以及可移植性,是 RT-Thread 中最常用的文件系統類型。
-
傳統型的 RomFS 文件系統是一種簡單的、緊湊的、只讀的文件系統,不支持動態擦寫保存,按順序存放數據,因而支持應用程序以 XIP(execute In Place,片內運行) 方式運行,在系統運行時, 節省 RAM 空間。
-
Jffs2 文件系統是一種日志閃存文件系統。主要用於 NOR 型閃存,基於 MTD 驅動層,特點是:可讀寫的、支持數據壓縮的、基於哈希表的日志型文件系統,並提供了崩潰 / 掉電安全保護,提供寫平衡支持等。
-
DevFS 即設備文件系統,在 RT-Thread 操作系統中開啟該功能后,可以將系統中的設備在 /dev 文件夾下虛擬成文件,使得設備可以按照文件的操作方式使用 read、write 等接口進行操作。
-
NFS 網絡文件系統(Network File System)是一項在不同機器、不同操作系統之間通過網絡共享文件的技術。在操作系統的開發調試階段,可以利用該技術在主機上建立基於 NFS 的根文件系統,掛載到嵌入式設備上,可以很方便地修改根文件系統的內容。
-
UFFS 是 Ultra-low-cost Flash File System(超低功耗的閃存文件系統)的簡稱。它是國人開發的、專為嵌入式設備等小內存環境中使用 Nand Flash 的開源文件系統。與嵌入式中常使用的 Yaffs 文件系統相比具有資源占用少、啟動速度快、免費等優勢。
只有塊設備才可以掛在文件系統,所以需要在指定的外設(SPI/SD)上創塊設備。然后格式化文件系統dfs_mkfs()(特定的文件系統),然后掛載文件系統(int dfs_mount(),即)將一個存儲設備掛接到一個已存在的路徑上(我們對該路徑上的文件進行操作))。用完后卸載文件系統dfs_unmount。
文件的常用操作:以/為根路徑,以fd文件操作符為基本單位,進行文件的open()打開/創建、讀、寫、添加、查找、重命名、關閉,同步文件到存儲設備int fsync(int fildes)等操作。
目錄的操作:創建mkdir、打開opendir、讀取opendir、關閉closedir。
文件系統操作常用的 FinSH 命令如下表所示:
| FinSH 命令 | 描述 |
|---|---|
| ls | 顯示文件和目錄的信息 |
| cd | 進入指定目錄 |
| cp | 復制文件 |
| rm | 刪除文件或目錄 |
| mv | 將文件移動位置或改名 |
| echo | 將指定內容寫入指定文件,當文件存在時,就寫入該文件,當文件不存在時就新創建一個文件並寫入 |
| cat | 展示文件的內容 |
| pwd | 打印出當前目錄地址 |
| mkdir | 創建文件夾 |
| mkfs | 格式化文件系統 |
注意:
RT-Thread/FatFs 默認使用 437 編碼(美國英語)。如果需要存儲中文文件名,可以使用 936 編碼(GBK編碼)。936 編碼需要一個大約 180KB 的字庫
NetDev:即網絡接口設備,又稱網卡,主要作用是解決設備多網卡連接時網絡連接問題(比如同時有網口和4G,設定網口為缺省,4G備用),用於統一管理各個網卡信息與網絡連接狀態,並且提供統一的網卡調試命令接口,RT-Thread 系統中目前支持三種協議棧類型: lwIP 協議棧、AT Socket 協議棧、WIZnet TCP/IP硬件協議棧.網卡的統一操作接口
- up/down: 底層網卡初始化完成之后置為 up 狀態,用於判斷網卡開啟還是禁用。
- link_up/link_down: 用於判斷網卡設備是否具有有效的鏈路連接,連接后可以與其他網絡設備進行通信。該狀態一般由網卡底層驅動設置。
- internet_up/internet_down: 用於判斷設備是否連接到因特網,接入后可以與外網設備進行通信。
- dhcp_enable/dhcp_disable: 用於判斷當前網卡設備是否開啟 DHCP 功能支持。
統一的調試接口:ping、ifconfig(設置 IP地址、網關和子網掩碼時應確保dhcp_disable)、netstat、dns 等命令
SAL:RT-Thread 系統提供了一套 SAL(套接字抽象層)組件,該組件完成對不同網絡協議棧或網絡實現接口的抽象並對上層提供一組標准的 BSD Socket API.SAL在netDev之上。TLS(Transport Layer Security,傳輸層安全協議從SSL發展而來) 是建立在傳輸層 TCP 協議之上的協議,目前常用的 TLS 的實現方式:MbedTLS、OpenSSL、s2n

/* 通過函數入口參數url獲得host地址(如果是域名,會做域名解析) */ host = gethostbyname(SAL_TLS_HOST); * 創建一個socket,類型是SOCKET_STREAM,TCP 協議, TLS 類型 */ sock = socket(AF_INET, SOCK_STREAM, ROTOCOL_TLS); /* 初始化預連接的服務端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SAL_TLS_PORT); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 初始化預連接的服務端地址 */ connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); /* 發送數據到 socket 連接 */ ret = send(sock, send_data, strlen(send_data), 0); /* 接收並打印響應的數據,使用加密數據傳輸 */ bytes_received = recv(sock, recv_data, SAL_TLS_BUFSZ - 1, 0);
//綁定套接字(bind) int bind(int s, const struct sockaddr *name, socklen_t namelen); //監聽套接字(listen) int listen(int s, int backlog); //接收連接(accept) int accept(int s, struct sockaddr *addr, socklen_t *addrlen); //建立連接(connect) int connect(int s, const struct sockaddr *name, socklen_t namelen); //TCP 數據發送(send) int send(int s, const void *dataptr, size_t size, int flags); //UDP 數據發送(sendto) int sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); //UDP 數據接收(recvfrom) int recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); //關閉套接字(closesocket) int closesocket(int s); //獲取遠端地址信息(getpeername) int getpeername(int s, struct sockaddr *name, socklen_t *namelen); //獲取本地地址信息(getsockname) int getsockname(int s, struct sockaddr *name, socklen_t *namelen); //配置套接字參數(ioctlsocket) int ioctlsocket(int s, long cmd, void *arg); //獲取套接字選項(getsockopt) int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); //設置套接字選項(setsockopt) int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); //關閉套接字(closesocket) int closesocket(int s);
低功耗的通常策略:主控時鍾頻率的調整、工作電壓的改變、總線頻率的調整甚至關閉、外圍設備工作時鍾的關閉,外設電源的關閉,單片機的低功耗模式與喚醒(時鍾頻率、工作模式),需要注意的是進入低功耗模式時有2個問題:1是os_tick的補償,以內進入低功耗模式后系統時鍾停止,此時要切換低功耗定時器(RTC)計算出喚醒時間或者其它中斷的喚醒源,並在喚醒后對os_tick進行補償;2對於低功耗敏感的功能模式要考慮進出低功耗模式時的狀態保持、恢復、和狀態改變相關的(如周期延時的時基改變,串口的波特率改變)這些通過注冊PM設備,設置掛起和恢復時的回調函數。


