IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【开源】libinimini:适用于单片机的极简 ini 解析库 -> 正文阅读

[嵌入式]【开源】libinimini:适用于单片机的极简 ini 解析库

介绍说明

最近自己基于 XR872 在做一个小作品练习练习,具备可以配置的功能,选择了使用 ini 作为配置文件。我调研了网上常见的 ini 解析库,几乎都涉及到了 fopen()/fgets().. 以及 malloc()。

说明这些开源库都仅适用于支持完整 C语言标准库的系统,并不适用于 RTOS 或裸跑的单片机。因为前者虽是 C 语言的标准文件操作函数,但在单片机中基本上使用的都是简化版的 fatfs 接口,要想引入单片机使用,意味着需要对该接口库进行修改。后者更是涉及到内存管理,ram 的占用会随着 ini 配置文件的内容而变化,意味着 ram 的使用不可控,极易受外部因素影响,这对 ram 资源极为稀有的单片机来说,是不可接受的。

本着学习的态度,就自己设计了一个非常简单的 ini 配置文件解析库(libinimini),具有以下几种特点:

1. 内存空间占用可控,libinimini 只使用用户指定的一段内存空间进行解析和返回结果。
2. 不关心数据的来源,libinimini 会通过回调用户的接口来获取每一行文本,不关心文本来自于文件还是其它通信接口。
3. 使用方便简单易上手,用户只需要实现以行为单位的文本数据的回调接口,之后只需要等待 libinimini 解析结果即可。

注意:接口本身会将键值作为字符串传递出来,如果需要转换为数字,调用类似 atoi() 的函数转换即可。

源码仓库位置:

https://github.com/lovemengx/libinimini

https://gitee.com/lovemengx/libinimini

示例代码

sys_config.ini(部分内容)

单片机版本(xr872@FreeRtos)

/**
******************************************************************************
* @文件		main.c
* @版本		V1.0.0
* @日期
* @概要		用于举例说明 libinimini 如何在单片机中应用
* @作者		lmx
******************************************************************************
* @注意
******************************************************************************
*/

#include <stdio.h>
#include <string.h>
#include "fs/fatfs/ff.h"
#include "kernel/os/os.h"
#include "../src/libinimini.h"
#include "common/framework/fs_ctrl.h"
#include "common/framework/platform_init.h"

// 由 libinimini 回调,用于将解析的结果返回
// 返回值: LIB_INIMINI_STOP:停止解析  LIB_INIMINI_KEEP:继续解析
static int inimini_result_cb(libinimini_data_t* data, void* context)
{
	printf("section:%-20s keyname:%-30s strval:%-30s\n", data->section, data->keyname, data->strval);
	if (strcmp(data->section, "compass_para") == 0 && strcmp(data->keyname, "compass_int") == 0) {
		printf("-------------------------------------------------\n");
		printf("[%s]\n", data->section);
		printf("%s = %s\n", data->keyname, data->strval);
		printf("-------------------------------------------------\n");
		return LIB_INIMINI_STOP;
	}
	return LIB_INIMINI_KEEP;
}

// 由 libinimini 回调,用于获取每一行的原始文本数据
// 返回值: 0: 已无数据可以提供  >0: 字符串数据的长度 
static unsigned int inimini_getline_cb(char* buf, unsigned int size, void* context)
{
	FIL* fp = (FIL*)context;
	if (f_gets(buf, size, fp) == NULL) {
		return LIB_INIMINI_STOP;
	}
	return (unsigned int)strlen(buf);
}

int main(void)
{
	FIL file;
	static char cache[512] = { 0 };
	libinimini_parameter_t para;

	platform_init();
	
	if(fs_ctrl_mount(FS_MNT_DEV_TYPE_SDCARD, 0) != FS_MNT_STATUS_MOUNT_OK){
		printf("fs mount failed\n");
		while(1) OS_Sleep(1);
	}
	
	if(f_open(&file, "sys_config.ini", FA_READ | FA_OPEN_EXISTING) != FR_OK){
		printf("open file failed\n");
		while(1) OS_Sleep(1);
	}

	memset(&para, 0x00, sizeof(libinimini_parameter_t));
	para.contex = &file;
	para.result = inimini_result_cb;
	para.ops.getline_cb = inimini_getline_cb;
	libinimini_foreach(&para, cache, sizeof(cache));
	f_close(&file);
	
	printf("libinimini_foreach done...\n");
	while(1) OS_Sleep(1);
	return 0;
}

Windows/Linux 版本

#include <stdio.h>
#include <string.h>
#include "libinimini.h"

// 由 libinimini 回调,用于将解析的结果返回
// 返回值: LIB_INIMINI_STOP:停止解析  LIB_INIMINI_KEEP:继续解析
static int inimini_result_cb(libinimini_data_t* data, void* context)
{
	printf("section:%-20s keyname:%-30s strval:%-30s\n", data->section, data->keyname, data->strval);
	if (strcmp(data->section, "compass_para") == 0 && strcmp(data->keyname, "compass_int") == 0) {
		printf("-------------------------------------------------\n");
		printf("[%s]\n", data->section);
		printf("%s = %s\n", data->keyname, data->strval);
		printf("-------------------------------------------------\n");
		return LIB_INIMINI_STOP;
	}
	return LIB_INIMINI_KEEP;
}

// 由 libinimini 回调,用于获取每一行的原始文本数据
// 返回值: 0: 已无数据可以提供  >0: 字符串数据的长度 
static unsigned int inimini_getline_cb(char* buf, unsigned int size, void* contex)
{
	FILE* fp = (FILE*)contex;
	if (fgets(buf, size, fp) == NULL) {
		return LIB_INIMINI_STOP;
	}
	return strlen(buf);
}

int main(void)
{
	char inimini_cache[1024] = { 0 };
	libinimini_parameter_t para;

	FILE* fp = fopen("F:/sys_config.ini", "r");
	if (NULL == fp) {
		printf("open file failed\n");
		return 0;
	}

	memset(&para, 0x00, sizeof(libinimini_parameter_t));
	para.contex = fp;
	para.result = inimini_result_cb;
	para.ops.getline_cb = inimini_getline_cb;
	int cnt = libinimini_foreach(&para, inimini_cache, sizeof(inimini_cache));
	fclose(fp);

	printf("libinimini_foreach done...\n");
	return 0;
}

??

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:31:24  更:2022-03-03 16:35:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:35:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码