如何在OpenWrt软路由中增加一个新功能

为了在OpenWrt中增加一个新的功能,并使其支持 UCI 配置,我们可以创建一个简单的C语言服务,例如一个简单的日志服务。此服务将记录到日志文件中,并支持通过 UCI 配置启用或禁用日志功能。以下是详细的步骤和代码示例。

1 创建服务代码

1.1 创建服务的源代码 (logservice.c)

这个服务将检查 UCI 配置,根据配置决定是否写入日志:

c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <uci.h>void log_message(const char *message) {FILE *file = fopen("/tmp/logservice.log", "a");if (file) {fprintf(file, "%s\n", message);fclose(file);}
}int main(void) {struct uci_context *c;struct uci_ptr ptr;char *enabled;c = uci_alloc_context();if (uci_lookup_ptr(c, &ptr, "logservice.global.enabled", true) == UCI_OK) {enabled = ptr.o->v.string;if (strcmp(enabled, "1") == 0) {while (1) {log_message("Log service is active.");sleep(60);  // Log every minute}}}uci_free_context(c);return 0;
}

1.2 创建 Makefile来编译这个服务

makefile
CC=gcc
CFLAGS=-I.
DEPS = uci.h
OBJ = logservice.o%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)logservice: $(OBJ)$(CC) -o $@ $^ $(CFLAGS) -luciclean:rm -f *.o logservice

2 为 OpenWrt 创建软件包

2.1 创建 OpenWrt 包目录结构

在 OpenWrt 构建环境中的 package 目录下创建一个新目录 logservice。

mkdir -p package/logservice
cd package/logservice

2.2 创建控制文件(Makefile)

这个文件定义了包的元数据和如何编译和安装它:

makefile
include $(TOPDIR)/rules.mkPKG_NAME:=logservice
PKG_RELEASE:=1
PKG_VERSION:=1.0.0include $(INCLUDE_DIR)/package.mkdefine Package/logserviceSECTION:=utilsCATEGORY:=UtilitiesTITLE:=Simple Log ServiceDEPENDS:=+libuci
endefdefine Package/logservice/descriptionA simple service that logs messages to a file based on UCI configuration.
endefdefine Build/Preparemkdir -p $(PKG_BUILD_DIR)$(CP) ./src/* $(PKG_BUILD_DIR)/
endefdefine Build/Compile$(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS)
endefdefine Package/logservice/install$(INSTALL_DIR) $(1)/usr/sbin$(INSTALL_BIN) $(PKG_BUILD_DIR)/logservice $(1)/usr/sbin/$(INSTALL_DIR) $(1)/etc/init.d$(INSTALL_BIN) ./files/logservice.init $(1)/etc/init.d/logservice$(INSTALL_DIR) $(1)/etc/config$(INSTALL_DATA) ./files/logservice.config $(1)/etc/config/logservice
endef$(eval $(call BuildPackage,logservice))

控制文件通常指的是用于描述和控制软件包编译和安装过程的 Makefile。这个 Makefile 与传统的 Linux/Unix 系统中用于编译程序的 Makefile 相似,但它专门为 OpenWrt 的包管理系统设计,用来定义软件包的元数据、构建和安装行为。通常包含以下部分:

包的定义和元数据

  • PKG_NAME:定义软件包的名称。
  • PKG_VERSION:定义软件包的版本号。
  • PKG_RELEASE:软件包的发布次数,通常用于修订号或当相同版本号的包被修改时递增。
  • PKG_SOURCE、PKG_SOURCE_URL、PKG_HASH:(可选)定义软件包源代码的位置、下载 URL 和源码的哈希值(用于验证)。

包含 OpenWrt 构建系统的规则和宏定义

  • include $(TOPDIR)/rules.mk:包含了 OpenWrt 主目录下的通用规则文件。
  • include $(INCLUDE_DIR)/package.mk:包含处理软件包的核心功能和定义的文件。

软件包定义区域

  • define Package/:开始定义一个软件包,其中 是软件包的名称,通常与 PKG_NAME 相同。
    • SECTION、CATEGORY:软件包的分类和子分类。
    • TITLE:软件包的简短描述或标题。
    • DEPENDS:定义软件包的依赖,如依赖其他库或软件包。

包描述

  • define Package//description:提供软件包的详细描述。

准备构建环境

  • define Build/Prepare:准备构建目录,通常包括解压源码、应用补丁等步骤。

配置软件包

  • define Build/Configure:(可选)如果软件包需要特殊的配置步骤,可以在这里定义。

编译软件包

  • define Build/Compile:定义编译软件包的命令和步骤。

安装软件包

  • define Package//install:定义如何安装编译后的软件到目标目录,通常包括拷贝可执行文件、配置文件等到相应的安装目录。

注册软件包

  • $(eval $(call BuildPackage,)):这是一个宏调用,用于注册软件包,使得构建系统能够识别和处理它。

2.3 创建 UCI 配置文件和初始化脚本

  • UCI 配置 (logservice.config):

      config logservice 'global'option enabled '1'
    
  • 初始化脚本 (logservice.init):

     #!/bin/sh /etc/rc.commonSTART=99start() {/usr/sbin/logservice &}stop() {killall logservice}
    

在 OpenWrt 或其他使用 init.d 脚本的 Unix-like 系统中,logservice.init 脚本的作用是控制 logservice 服务的启动、停止以及其他管理操作。这个脚本通常被称为 init 脚本或服务脚本,并且是服务管理的核心组成部分。logservice.init 脚本主要提供以下功能:

  1. 启动服务(start)

    • 当系统启动或手动启动服务时,该脚本将被调用以启动 logservice 程序。通常,这涉及到运行主服务程序,并可能还包括设置必要的环境或运行前的配置。
  2. 停止服务(stop)

    • 当系统关闭或需要手动停止服务时,该脚本用于安全地停止 logservice 程序。这通常涉及到发送终止信号给服务进程或执行其他清理步骤。
  3. 重启服务(restart)

    • 这通常是通过停止后再启动服务来实现,有时是为了应用新的配置更改或恢复服务的正常状态。
  4. 查看服务状态(status)

    • 尽管在给出的脚本示例中没有直接实现,但许多服务脚本还支持检查并报告服务是否正在运行以及运行状态。
  5. 启动顺序(START)

    • 在 logservice.init 脚本中定义的 START=99 表示此服务在系统启动过程中的启动顺序。数值越大,启动越晚,允许它在其他服务之后启动。

logservice.init 脚本是服务生命周期管理的关键工具,它允许系统管理员和系统本身在适当的时间以适当的方式启动和停止服务。在 OpenWrt 这样的嵌入式系统中,这种脚本是管理后台服务不可或缺的部分,确保了服务的可控性和稳定性。

3 编译和安装

  1. 将软件包添加到 OpenWrt 构建系统

    返回到 OpenWrt 的根目录并运行 make menuconfig。在 Utilities 菜单下选择 logservice 包进行编译。

  2. 编译 OpenWrt 镜像

    make package/logservice/compile V=s
    make V=s

  3. 刷写固件并测试服务

    安装生成的固件到你的设备上,并测试 logservice 是否根据 UCI 配置正确运行。

这个例子展示了如何为 OpenWrt 添加一个简单的 C 语言编写的服务,使其支持 UCI 配置。

4 OpenWrt NFC功能的例子

代码包括两个部分:一个是 OpenWrt 的启动脚本,用于管理 NFC 服务的启动和停止;另一个是 Makefile,用于编译 NFC 相关的 C 代码。

4.1 启动脚本init.d解释

#!/bin/sh /etc/rc.common
USE_PROCD=1
START=46
STOP=99
SERVICE_USE_PID=1
USE_PROCD=1
PROG=/usr/bin/topsw_nfc
  • 这是一个 shell 脚本,用于控制 NFC 服务 (topsw_nfc) 的启动和停止。
  • USE_PROCD=1:启用 procd 支持,procd 是 OpenWrt 的进程管理守护程序。
  • START=46STOP=99:定义了服务启动和停止的优先级。数字越小,启动优先级越高;停止时则相反。
  • SERVICE_USE_PID=1:表明该服务使用 PID 文件。
  • PROG=/usr/bin/topsw_nfc:定义了 NFC 程序的路径。
start_service() {procd_open_instanceprocd_set_param stdout 1procd_set_param stderr 1procd_set_param command "$PROG"procd_set_param respawnprocd_close_instance
}
  • start_service 函数用于配置和启动服务。
    • procd_open_instance:开启一个新的服务实例。
    • procd_set_param:设置服务参数,如标准输出、错误输出、启动命令和重启参数。
    • procd_close_instance:关闭实例配置,启动服务。
reload_service() {restart
}
  • reload_service:定义重启服务的功能,使用 restart 命令重启服务。

4.2 Makefile解释

PROGS = topsw_nfc
  • 定义要编译的程序名称。
SOURCES = $(wildcard ./src/*.c)
OBJS = $(patsubst %.c,%.o,$(SOURCES))
  • SOURCES 获取 src 目录下所有的 .c 文件。
  • OBJS 将源文件名从 .c 转换为 .o
$(OBJS): %.o : %.c
$(CC) -c $(CFLAGS) $(CFLAGS) $^ -o $@
  • 规则,说明如何从 .c 文件生成 .o 文件。
$(PROGS): $(OBJS)
  • 最终链接生成可执行文件的规则。

4.3 NFC添加到系统中的步骤

  1. 编译:使用 Makefile 编译 NFC 相关的 C 代码生成可执行文件 topsw_nfc
  2. 部署:将编译好的程序部署到 /usr/bin/topsw_nfc 路径下。
  3. 服务管理:通过 OpenWrt 的启动脚本管理 NFC 服务的启动、停止和重启
  4. 配置启动:配置脚本确保在系统启动时,NFC 服务按指定的优先级启动,并在停止时按相反的优先级停止。

在 OpenWrt 及类似的构建系统中,系统能够知道存在 topsw_nfc 这个包,并允许在图形界面中进行选择,主要是通过以下几个关键步骤实现的:

  1. 包定义文件(Makefile)

每个可选的软件包在 OpenWrt 的源代码目录中通常都有一个对应的包定义文件,即一个 Makefile。这个 Makefile 不仅定义了如何下载、配置、编译、安装、清理该软件包,还包含了软件包的描述、依赖关系和配置选项等元数据。

  • 包目录结构:在 OpenWrt 的源代码中,通常有一个 package 目录,其中每个子目录或文件夹代表一个包。例如,topsw_nfc 包可能位于 package/network/services/topsw_nfc 目录下。
  • Makefile 内容:此 Makefile 将包含如下关键信息:
    • Package 定义,用于设置包名和描述。
    • define Package/topsw_nfc,其中包括描述、版本、分类等。
    • 编译和安装指令,指明如何构建和安装包。
    • 可能还包括 Config.inconfig 段落,用于定义配置界面中的选项。
  1. 配置系统集成

OpenWrt 使用 Kconfig 系统,这是从 Linux 内核借鉴的配置工具,用于在图形界面 (make menuconfig) 中显示和选择配置选项。

  • Kconfig 与 Makefile:包的 Makefile 中通常包括指向 Kconfig 文件的引用,这使得构建系统在运行 make menuconfig 时可以解析并显示所有可用的包选项。
  • 配置选项:在 Kconfig 文件或 Makefile 中定义的配置选项决定了包是否可以被选中,以及它依赖哪些条件。
  1. 图形界面中的显示

当运行 make menuconfig 时,OpenWrt 的构建系统会扫描所有包的 Makefile 和 Kconfig 文件,将它们的信息汇总到配置界面中。

  • 用户交互:在图形界面中,用户可以浏览各种类别的软件包,选择需要编译进固件的包。
  • 依赖解析:如果 topsw_nfc 包依赖其他库或包,这些依赖也会在图形界面中显示,用户必须先解决依赖问题,才能启用该包。
  1. 系统的响应

选择了 topsw_nfc 包并保存配置后,这些选择被写入 .config 文件,这是构建系统在后续构建过程中读取的配置文件。

总结来说,系统通过预定义的包描述文件(Makefile)、Kconfig 集成以及图形配置界面(menuconfig)相结合的方式,使得用户可以选择特定的软件包,如 topsw_nfc,进行编译和安装。这种方法保证了构建系统的灵活性和可扩展性,允许用户根据需要定制自己的固件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9967.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S三 K8S部署微服务应用

一 用k8s部署微服务应用 以我们之前用docker部署过的eureka应用为例&#xff0c;首先添加配置文件eureka-app-deployment.yaml用于创建Deployment apiVersion: apps/v1 kind: Deployment metadata:name: eureka-app-deployment # deployment名字labels:app: eureka-app spec:…

【C++】CentOS环境搭建-升级CMAKE

【C】CentOS环境搭建-升级CMAKE CMAKE报错CMake 3.12 or higher is required. You are running version 2.8.12.2升级步骤1.移除当前的cmake2.安装必要的构建工具和库3.下载最新的cmake源码并解压5.编译和安装6.验证安装 CMAKE报错CMake 3.12 or higher is required. You are r…

oraclesql中删除表中重复行的方法

在Oracle SQL中&#xff0c;删除表中的重复行有几种常见的方法。以下是其中的三种&#xff1a; 使用ROWID: 通过比较ROWID&#xff0c;你可以找到并删除重复的行。这是因为ROWID是Oracle数据库为每一行数据分配的唯一标识符。 sql DELETE FROM persons p1 WHERE ROWID NOT…

MySQL存储引擎详解

存储引擎 MySQL体系结构 连接层&#xff1a;与客户端连接&#xff0c;权限校验、连接池服务层&#xff1a;SQL接口和解析、查询优化、缓存、函数引擎层&#xff1a;索引、存储引擎存储层&#xff1a;系统文件、日志&#xff08;Redo、Undo等&#xff09; 存储引擎介绍 不同的…

SSH:安全远程访问的基石

SSH&#xff1a;安全远程访问的基石 一、引言 在当今这个数字化、网络化的时代&#xff0c;远程访问和管理计算机资源已成为日常工作的重要组成部分。然而&#xff0c;如何在不安全的网络环境中确保数据传输的机密性、完整性和可靠性&#xff0c;成为了一个亟待解决的问题。S…

前端测试策略与实践:单元测试、E2E测试与可访问性审计

前端测试策略是确保Web应用程序质量、性能和用户体验的关键组成部分。有效的测试策略通常包括单元测试、端到端&#xff08;E2E&#xff09;测试以及可访问性审计等多个层面。以下是关于这三类测试的策略与实践建议&#xff1a; 单元测试 定义与目的&#xff1a; 单元测试是针…

P2622 关灯问题

小小注解&#xff1a; 1. vis&#xff1a;表示到达该状态的步数&#xff08;min&#xff09;1&#xff0c; 因为我们是从开始状态 穷举&#xff0c;所以每次到一个新状态&#xff08;之前没有到过的状态&#xff09;就是最小步数。 如何判断是否是一个新状态呢&#xff0c…

axios常用配置

Axios 是一个基于 promise 的 HTTP 库&#xff0c;广泛用于浏览器和 node.js 中。以下是一些 Axios 常用的配置选项&#xff1a; url: 字符串&#xff0c;请求的服务器URL&#xff0c;是必填项。method: 请求方法&#xff0c;如 ‘get’, ‘post’, ‘put’, ‘delete’ 等&am…

免费远程控制软件哪个好用

免费远程控制软件哪个好用 在现今高度信息化的社会&#xff0c;远程控制软件已成为许多用户进行远程办公、技术支持和教育培训的重要工具。市面上有许多免费的远程控制软件&#xff0c;但哪款才是最好用的呢&#xff1f;本文将为您介绍几款热门的免费远程控制软件&#xff0c;…

Tab菜单与下拉式菜单

Tab菜单 利用CSS隐藏或显示栏目中的部分内容&#xff0c;实际Tab面板包含的全部内容都已下载到客户端浏览器当中。一般Tab面板仅显示一个Tab菜单项&#xff0c;当用户点选对应的菜单选项之后&#xff0c;才会显示对应的内容。 <!DOCTYPE html> <html><head>…

Matlab: ode45解微分方程——以弹簧振子模型为例

简介&#xff1a; 在科学和工程中&#xff0c;我们经常遇到描述事物变化的微分方程。这些方程可以帮助我们理解从行星运动到药物在体内的扩散等各种现象。但是&#xff0c;很多微分方程非常复杂&#xff0c;手动求解几乎不可能。这时&#xff0c;我们就可以使用像 ode45这样的…

【DL】FocalLoss的PyTorch实现

【DL】FocalLoss的PyTorch实现 此篇不介绍FocalLoss的原理&#xff0c;仅展示PyTorch实现FocalLoss的两种方式。个人认为相关原理已在文章《FocalLoss原理通俗解释及其二分类和多分类场景下的原理与实现》中讲得很清晰&#xff0c;故此篇不再介绍。 方式一 同时计算一个batc…

【iOS】frame与bounds区别

文章目录 前言framebounds两者区别size的区别总结 前言 在学习响应者链的过程中用到了frame与bounds的混用&#xff0c;这两个属性经常出现在我们的开发中&#xff0c;特别撰写一篇博客分析区别 首先&#xff0c;我们来看一下iOS特有的坐标系&#xff0c;在iOS坐标系中以左上…

C语言如何查看进程中环境变量中所有的值

示例代码&#xff1a;查看进程中环境变量中所有的值。 #include <stdio.h>int main(){extern char** environ;for (char** pp environ; *pp; pp){printf("%s\n", *pp);}return 0; }输出结果&#xff1a; SHELL/bin/bash WSL2_GUI_APPS_ENABLED1 WSL_DISTRO_…

【debug】如何使用pycharm对代码调试

后续会将所有debug中遇到的知识放入&#xff0c;建议关注收藏 本站友情链接&#xff1a; 基本理论专栏&#xff08;当前更新好的debug所有内容都在这里&#xff09; 【debug】报错解决方法&#xff08;CondaHTTPError&#xff1a;HTTP 000 connection failed for url&#xff…

【回溯 状态压缩 深度优先】37. 解数独

本文涉及知识点 回溯 状态压缩 深度优先 LeetCode37. 解数独 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只…

leetCode刷题记录4-面试经典150题-2

文章目录 不要摆&#xff0c;没事干就刷题&#xff0c;只有好处&#xff0c;没有坏处&#xff0c;实在不行&#xff0c;看看竞赛题面试经典 150 题 - 2210. 课程表 II 不要摆&#xff0c;没事干就刷题&#xff0c;只有好处&#xff0c;没有坏处&#xff0c;实在不行&#xff0c…

[C++核心编程-06]----C++类和对象之对象模型和this指针

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Microsoft 365 for Mac v16.84 office365全套办公软件

Microsoft 365 for Mac是一款功能丰富的办公软件套件&#xff0c;为Mac用户提供了丰富的功能和工具&#xff0c;提高了工作效率和协作能力。Microsoft 365 for Mac是一款专为Mac用户设计的订阅式办公软件套件&#xff0c;旨在提高生产力和效率。 Microsoft 365 for Mac v16.84正…

数据赋能(83)——数据要素:数据要素管理与数据管理

数据要素管理则更关注数据作为生产性资源在创造经济价值中的作用&#xff1b;数据管理更侧重于数据在整个生命周期中的控制、保护和价值提升。 数据要素管理是对数据作为关键生产要素进行系统性管理的过程。它聚焦于数据在经济和社会活动中的价值创造和贡献&#xff0c;将数据…