zlog是一个高可靠性、高性能、线程安全、灵活、概念清晰的纯C日志函数库。
zlog在效率、功能、安全性上大大超过了log4c,并且是用c写成的,具有比较好的通用性。
zlog有这些特性:
syslog分类模型,比log4j模型更加直接了当日志格式定制,类似于log4j的pattern layout多种输出,包括动态文件、静态文件、stdout、stderr、syslog、用户自定义输出函数运行时手动、自动刷新配置文件(同时保证安全)高性能,在作者的笔记本上达到25万条日志每秒, 大概是syslog(3)配合rsyslogd的1000倍速度用户自定义等级多线程和多进程环境下保证安全转档精确到微秒简单调用包装dzlog(一个程序默认只用一个分类)MDC,线程键-值对的表,可以扩展用户自定义的字段自诊断,可以在运行时输出zlog自己的日志和配置状态不依赖其他库,只要是个POSIX系统就成(当然还要一个C99兼容的vsnprintf)zlog仓库链接:
https://github.com/HardySimpson/zlog
zlog使用手册:
http://hardysimpson.github.io/zlog/UsersGuide-CN.html
test.c:
#include <stdio.h>#include "zlog.h"int main(int argc, char** argv){ int rc; zlog_category_t *zc; rc = zlog_init("test.conf"); if (rc) { printf("init failed\n"); return -1; } zc = zlog_get_category("my_cat"); if (!zc) { printf("get cat fail\n"); zlog_fini(); return -2; } zlog_info(zc, "嵌入式大杂烩"); zlog_info(zc, "hello, zlog"); zlog_fini(); return 0;}test.conf:
xmakexmake是一个跨平台的安装(编译)工具。
xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
xmake官网:
https://xmake.io/
1、支持的平台Windows (x86, x64)macOS (i386, x86_64, arm64)Linux (i386, x86_64, cross-toolchains ..)*BSD (i386, x86_64)Android (x86, x86_64, armeabi, armeabi-v7a, arm64-v8a)iOS (armv7, armv7s, arm64, i386, x86_64)WatchOS (armv7k, i386)MSYS (i386, x86_64)MinGW (i386, x86_64, arm, arm64)Cygwin (i386, x86_64)Wasm (wasm32)Cross (cross-toolchains ..)2、支持的工具链3、支持的语言C/C++Objc/Objc++SwiftAssemblyGolangRustDlangFortranCudaZig (Experimental)4、编译测试多任务并行编译测试:
单任务编译测试:
官网上的内容很丰富,对xmake做了很详细的介绍,感兴趣的小伙伴可以自己去了解学习。
gear-libgear-lib是一组通用的C基础库。
全部用POSIX C实现,目标是为了跨平台兼容linux, windows, android, ios。适用于物联网,嵌入式,以及网络服务开发等场景。包含如下内容:
gear-lib使用起来很方便,可以作为我们日常开发中的工具库。
gear-lib地址:
https://github.com/gozfree/gear-lib
inihinih是一个C 语言编写的 INI 文件解析器。
ini 文件是 Initialization File 的缩写,即初始化文件。INI文件由节、键、值组成,注解使用分号表示(;)
例子:
[ip] ;Section1ip_addr = 192.168.1.103[test] ;Section2name = ZhengN num = 66 #include <stdio.h>#include <stdlib.h>#include <string.h>#include "ini.h"typedef struct{ const char* ip_addr; const char* name; int num;} configuration;static int handler(void* user, const char* section, const char* name, const char* value){ configuration* pconfig = (configuration*)user; #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 if (MATCH("ip", "ip_addr")) { pconfig->ip_addr = strdup(value); } else if (MATCH("test", "name")) { pconfig->name = strdup(value); } else if (MATCH("test", "num")) { pconfig->num = atoi(value); } else { return 0; /* unknown section/name, error */ } return 1;}int main(int argc, char* argv[]){ configuration config; config.ip_addr = NULL; /* set defaults */ config.name = NULL; config.num = 0; if (ini_parse("ip.ini", handler, &config) < 0) { printf("Can't load 'ip.ini'\n"); return 1; } printf("Config loaded from 'ip.ini': ip_addr = %s, name = %s, num = %d\n", config.ip_addr, config.name, config.num); if (config.ip_addr) free((void*)config.ip_addr); if (config.name) free((void*)config.name); return 0;}queuequeue.h是Linux、FreeBSD中的一个很实用的头文件。这个头文件里全是宏定义操作,所以其不仅可以使用在Linux/嵌入式Linux项目中,也可以使用在单片机项目中。
它使用宏实现了如下数据结构:
SLIST:单向无尾链表LIST:双向无尾链表STAILQ:单向有尾链表(可作队列使用)TAILQ:双向有尾链表(可作队列使用)所有的数据结构都支持如下功能:
在链表头插入节点在任意节点后插入节点删除节点遍历节点我们可以在Linux系统的如下路径中找到这个头文件:
/usr/include/sys/queue.h
也可以通过如下网址查看:
https://code.woboq.org/userspace/glibc/misc/sys/queue.h.html
/* * Singly-linked List definitions. */#define SLIST_HEAD(name, type) \struct name { \ struct type *slh_first; /* first element */ \}#define SLIST_HEAD_INITIALIZER(head) \ { NULL }#define SLIST_ENTRY(type) \struct { \ struct type *sle_next; /* next element */ \}/* * Singly-linked List functions. */#define SLIST_INIT(head) do { \ (head)->slh_first = NULL; \} while (/*CONSTCOND*/0)#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ (elm)->field.sle_next = (slistelm)->field.sle_next; \ (slistelm)->field.sle_next = (elm); \} while (/*CONSTCOND*/0)#define SLIST_INSERT_HEAD(head, elm, field) do { \ (elm)->field.sle_next = (head)->slh_first; \ (head)->slh_first = (elm); \} while (/*CONSTCOND*/0)#define SLIST_REMOVE_HEAD(head, field) do { \ (head)->slh_first = (head)->slh_first->field.sle_next; \} while (/*CONSTCOND*/0)#define SLIST_REMOVE(head, elm, type, field) do { \ if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ struct type *curelm = (head)->slh_first; \ while(curelm->field.sle_next != (elm)) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = \ curelm->field.sle_next->field.sle_next; \ } \} while (/*CONSTCOND*/0)#define SLIST_FOREACH(var, head, field) \ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)/* * Singly-linked List access methods. */#define SLIST_EMPTY(head) ((head)->slh_first == NULL)#define SLIST_FIRST(head) ((head)->slh_first)#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)cJSONhttps://github.com/DaveGamble/cJSON.git
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
cJSON是C语言编写的用于解析与组包JSON数据的一个库。
protobufhttps://github.com/protocolbuffers/protobuf
Protocol Buffers,是Google公司开发的一种数据格式,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。
JSON类型数据可读性很好,但是整个数据包中会带有一些无用的数据,自然会在一定程度上带来通信负担。protobuf是一种相对JSON来说更为轻量的数据格式。
protobuf的优点:
可扩展性强。消息格式升级和兼容性好支持跨平台多语言序列化反序列化速度很快序列化后体积相比Json和XML很小,适合网络传输如果文章对你有帮助,麻烦帮忙点赞、收藏、转发,谢谢!
私信回复【嵌入式书籍】,可获取博主精心整理的嵌入式电子书一份