找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1180

积分

1

好友

161

主题
发表于 12 小时前 | 查看: 2| 回复: 0

图片

来源:https://gitee.com/MacRsh/mr-library

MR-library(简称MR框架)是一款专为资源受限的嵌入式系统(尤其是MCU)设计的轻量级设备框架。它充分考虑了嵌入式开发在资源与性能上的特殊需求,通过提供一套标准化的设备管理层,将应用程序与底层硬件驱动解耦,从而显著降低了嵌入式应用开发的门槛与复杂度,帮助开发者高效构建稳定、可移植的应用程序。

该框架为开发者抽象出统一的设备操作接口,包括开启(open)、关闭(close)、控制(ioctl)、读(read)、写(write) 等。应用程序只需调用这些标准接口访问设备,无需关心底层驱动的具体实现细节,这有助于提升代码的整洁性与可维护性。更重要的是,当硬件平台更换时,开发者仅需为新硬件适配底层驱动,应用程序代码即可实现无缝迁移,极大地提升了软件的可重用性与项目的可扩展性。

图片

关键特性

  • 标准化的设备访问接口:统一的open/close/read/write/ioctl操作模型。
  • 应用程序与驱动解耦:应用层不依赖具体驱动实现,便于移植和维护。
  • 开发简化:同时简化了底层驱动开发和上层应用程序开发。
  • 轻量高效:核心框架代码精简,对ROM/RAM资源占用极低。
  • 模块化设计:各组件解耦,支持独立开发与功能裁剪,硬件迁移成本极低。
  • 环境兼容:支持在无操作系统的裸机环境和RTOS等操作系统环境下运行。

主要组成

  • 设备框架:提供标准设备访问接口。
  • 内存管理:提供动态内存管理模块。
  • 工具库:包含链表、队列、平衡二叉树等常用数据结构。
  • 功能组件:各类可选的软件组件。

标准化设备接口

所有设备操作均通过以下核心接口完成,这种设计思想与Linux设备驱动模型有异曲同工之妙,但在资源占用上做了极致优化,更适合单片机环境。

接口 描述
mr_dev_register 注册设备
mr_dev_open 打开设备
mr_dev_close 关闭设备
mr_dev_ioctl 控制设备
mr_dev_read 从设备读取数据
mr_dev_write 向设备写入数据

使用示例

struct mr_spi_dev spi_dev;

int main(void)
{
    /* 注册SPI10设备(CS低电平有效)到SPI1总线上 */
    mr_spi_dev_register(&spi_dev, "spi1/spi10", 0, MR_SPI_CS_ACTIVE_LOW);

    /* 打开SPI1总线下的SPI10设备 */
    int ds = mr_dev_open("spi1/spi10", MR_OFLAG_RDWR);

    /* 发送数据 */
    uint8_t wr_buf[] = {0x01, 0x02, 0x03, 0x04};
    mr_dev_write(ds, wr_buf, sizeof(wr_buf));

    /* 接收数据 */
    uint8_t rd_buf[4] = {0};
    mr_dev_read(ds, rd_buf, sizeof(rd_buf));

    /* 关闭设备 */
    mr_dev_close(ds);
}

配置工具

MR-library 集成了 Kconfig 可视化配置工具,开发者无需深入源码即可完成功能裁剪与参数配置,这对于复杂的嵌入式C语言工程项目管理尤为便捷。

Kconfig 会根据工程中的配置文件自动生成一个层级式的配置菜单界面。开发者通过方向键和回车键即可轻松选择需要启用的功能组件,并设置相关参数。

图片
图片

通过修改参数,可以快速裁剪出符合项目需求的轻量级库。配置完成后,运行配套的 Python 脚本即可自动生成最终的项目配置文件 mr_config.h

目录结构

名称 描述
bsp 板级支持包
components 组件
device 设备文件
document 文档
driver 驱动文件
include 库头文件
source 库源文件
Kconfig 配置文件
kconfig.py 自动配置脚本
LICENSE 许可证

开始使用

配置 Kconfig 环境

注:Kconfig 工具并非强制使用,但极力推荐,其安装配置快捷,且能极大提升开发效率。

  1. 检查Python环境:在命令行中运行 python --version 检查Python版本(Kconfig 依赖 python,若未安装请先行安装)。
  2. 安装Kconfiglib:在命令行中执行以下命令进行安装。
    python -m pip install windows-curses
    python -m pip install kconfiglib
  3. 验证安装:在命令行中运行 menuconfig -h,若显示帮助信息则表示安装成功。

将框架导入工程

  1. 获取源码:从 Gitee 或 Github 仓库下载最新版本源码。
  2. 放置源码:将源码解压并放置到您的工程目录中。以STM32工程为例:
    工程目录/
    ├── .mxproject
    ├── Core/
    ├── Drivers/
    ├── MDK-ARM/
    └── mr-library/  <-- 将源码放在这里
  3. BSP配置:如果使用的芯片已有适配的BSP,请参考对应BSP的教程完成配置。
  4. 精简目录:移除工程不需要的目录,如 bspdocumentmodule(若无需Git管理,也可删除 .git 文件夹)。精简后目录如下:
    工程目录/
    ├── .mxproject
    ├── Core/
    ├── Drivers/
    ├── MDK-ARM/
    └── mr-library/
        ├── device/
        ├── driver/
        ├── include/
        ├── source/
        └── ...
  5. 添加文件到IDE:将 sourcedevicedriver 目录下的所有源文件添加到IDE工程中(大部分IDE可自动识别)。

配置菜单选项

  1. mr-library 目录下打开命令行,运行 menuconfig 进入配置界面。

    注:添加对应芯片的驱动后,菜单中将显示 Device configureDriver configure 选项。

  2. 选中 Device configure 回车进入,根据需求配置功能模块。
  3. 配置完成后,按 Q 键退出,并按 Y 保存配置。

生成配置文件

  1. mr-library 目录下的命令行中,运行 python kconfig.py 脚本,自动生成 mr_config.h 配置文件。

添加包含路径与初始化

  1. 添加头文件路径:在编译器设置中添加 mr-libraryinclude 目录路径。
  2. 配置自动初始化(GCC):在工程的链接脚本文件(如 link.ld)中添加以下代码段:
    /* mr-library auto init */
    . = ALIGN(4);
    _mr_auto_init_start = .;
    KEEP(*(SORT(.auto_init*)))
    _mr_auto_init_end = .;

    注:Keil、IAR等IDE若自动生成链接脚本,通常可跳过此步。

  3. 启用GNU语法(非GCC编译器):例如在Keil中,对于AC5或AC6编译器,需在选项设置中启用GNU扩展语法。
  4. 包含头文件与初始化:在工程的 main.c 文件中:

    #include "include/mr_lib.h"
    
    int main(void)
    {
        mr_auto_init(); // 框架自动初始化
        // ... 用户代码
    }

实践:点亮一个LED

#include "include/mr_lib.h"

/* 定义LED引脚(以STM32的PC13为例) */
#define LED_PIN_NUMBER                  45

int main(void)
{
    /* 自动初始化 */
    mr_auto_init();

    /* 打开PIN设备 */
    int ds = mr_dev_open("pin", MR_OFLAG_RDWR);

    /* 设置要控制的引脚号 */
    mr_dev_ioctl(ds, MR_CTL_PIN_SET_NUMBER, mr_make_local(int, LED_PIN_NUMBER));
    /* 设置引脚为推挽输出模式 */
    mr_dev_ioctl(ds, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT));

    while(1)
    {
        /* 点亮LED(输出高电平) */
        mr_dev_write(ds, mr_make_local(uint8_t, MR_PIN_HIGH_LEVEL), sizeof(uint8_t));
        mr_delay_ms(500);
        /* 熄灭LED(输出低电平) */
        mr_dev_write(ds, mr_make_local(uint8_t, MR_PIN_LOW_LEVEL), sizeof(uint8_t));
        mr_delay_ms(500);
    }
}

实践:输出“Hello World”


#include "include/mr_lib.h"

int main(void)
{
    /* 自动初始化 */
    mr_auto_init();

    /* 打开Serial-1设备(假设为串口1) */
    int ds = mr_dev_open("serial1", MR_OFLAG_RDWR);

    /* 向串口输出 "Hello World" */
    mr_dev_write(ds, "Hello World\r\n", sizeof("Hello World\r\n") - 1); // 注意长度计算

    while(1);
}



上一篇:使用LlamaIndex与Python快速构建私有数据智能问答应用
下一篇:CMake 实战:一键分离 C++ 项目中的开发与生产编译环境
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 15:44 , Processed in 0.107681 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表