当前位置: 首页 > news >正文

如何在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,进行编译和安装。这种方法保证了构建系统的灵活性和可扩展性,允许用户根据需要定制自己的固件。

相关文章:

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

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

【linux】vmtouch文件缓存管理工具

目录 vmtouch简介 用法 例子 统计文件或者目录在缓存中的记录 缓存文件到内存 其他类似工具 vmtouch简介 vmtouch是用c语言编写的文件缓存管理工具&#xff0c;适用用于所有类Unix系统。 作用&#xff1a; 1&#xff0c;查看文件系统缓存情况 2&#xff0c;将文件或目…...

论文阅读:The Unreasonable Ineffectiveness of the Deeper Layers 层剪枝与模型嫁接的“双生花”

作者实证研究了针对流行的开放式预训练 LLM 系列的简单层修剪策略&#xff0c;发现在不同的 QA 基准上&#xff0c;直到去掉一大部分&#xff08;最多一半&#xff09;层&#xff08;Transformer 架构&#xff09;后&#xff0c;性能的下降才会降到最低。为了修剪这些模型&…...

Python批量备份华为设备配置到FTP服务器

Excel表格存放交换机信息&#xff1a; 备份文件夹效果图&#xff1a; Windows系统配置计划任务定时执行python脚本&#xff1a; Program/script&#xff1a;C:\Python\python.exe Add arguments (optional)&#xff1a; D:\Python_PycharmProjects\JunLan_pythonProje…...

Java虚拟机(JVM)中确保资源及时释放的策略

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;内存管理主要是通过垃圾回收&#xff08;Garbage Collection, GC&#xff09;来自动处理的。Java开发者通常不需要&#xff08;也不应该&#xff09;显式地释放对象内存&#xff0c;因为JVM的垃圾回收器会自动处理不再使…...

04-Fortran基础--Fortran数组和矩阵运算

04-Fortran基础--Fortran数组和矩阵运算 fortarn中对数组和矩阵的主要操作和内置运算包括&#xff1a; 数组的声明和初始化&#xff1a;fortarn中可以通过声明和初始化来创建数组。例如&#xff1a; integer :: my_array(3) [1, 2, 3] ! 声明一个包含3个整数的数组并初始化数…...

el-select选项框内容过长

利用popper-class实现选项框内容过长&#xff0c;截取显示功能&#xff1a; <el-select popper-class"popper-class" :popper-append-to-body"false" v-model"value" placeholder"请选择"><el-optionv-for"item in opt…...

K8S面试题学习5

参考K8S面试题&#xff08;史上最全 持续更新&#xff09;_kubernetes常见面试题-CSDN博客做的个人总结&#xff0c;规划是每天看10题&#xff0c;thx&#xff01; 1. 请详述kube-proxy原理? 每个node节点都会运行一个kube-proxy的进程&#xff0c;核心功能是将service的访问…...

字符以及字符串函数

字符以及字符串函数 求字符串长度strlen 长度不受限制的字符串函数strcpystrcatstrcmp 长度受限制的字符串函数strncpystrncatstrncmp 字符串查找strstrstrtok 错误信息报告strerror 字符分类函数字符转换函数tolowertoupper 内存操作函数memcpymemmovememcmpmemset 这篇文章注…...

记录解决问题--redis ssl连接

1.问题场景 springboot连接redis启动报错&#xff0c;感觉是没连上redis&#xff0c;本地是正常启动的&#xff0c;但是本地不是ssl连接。 2.redis ssl连接知识 ①一般不开启ssl的连接&#xff0c;直接连接即可&#xff0c;有密码输密码。 ②不受信的ssl连接&#xff0c;也就…...

买卖股票的最佳时机

dp[i][0] 表示第i天持有股票所得最多现金&#xff0c;相当于买的价格最低&#xff0c;卖的价格最高 持有股票状态为0&#xff0c;不持有为1 用二维数组表示天数和是否持有&#xff0c; i-1天就持有&#xff0c;或者第i天买入 class Solution {public int maxProfit(int[] p…...

Linux部署安装

Linux部署安装 Linux中有两种软件安装包 一、源码包 软件的源代码是软件的原始数据&#xff0c;但是源代码不能直接在计算机中直接运行安装。 需要通过编译将源代码转换为计算机可以识别的机器语言&#xff0c;之后才可以进行安装。 源码包安装的方式可以在安装过程中发根据…...

docker搭建mysql集群实现主从复制

前言 随着业务的增长&#xff0c;一台数据服务器已经满足不了需求了&#xff0c;负载过重。这个时候就需要减压了&#xff0c;实现负载均衡和读写分离&#xff0c;一主一丛或一主多从。 主服务器只负责写&#xff0c;而从服务器只负责读&#xff0c;从而提高了效率减轻压力。 …...

Neo4j 之安装和 CQL 基本命令学习

正常使用结构化的查询语言 SQL&#xff08;Structured Query Language&#xff09;较多一些&#xff0c;但是像 Neo4j 这种非结构化的图形数据库来说&#xff0c;就不得不学习下 CQL&#xff08;Cypher Query Language&#xff09;语言了。如果你之前学过 《离散数学》或《图论…...

【全开源】JAVA台球助教台球教练多端系统源码支持微信小程序+微信公众号+H5+APP

功能介绍 球厅端&#xff1a;球厅认证、教练人数、教练的位置记录、助教申请、我的项目、签到记录、我的钱包、数据统计 教练端&#xff1a;我的页面&#xff0c;数据统计、订单详情、保证金、实名认证、服务管理、紧急求助、签到功能 用户端&#xff1a;精准分类、我的助教…...

机器学习-如何为模型选择评估指标?

为机器学习模型选择评估指标是一个关键步骤&#xff0c;因为它直接关联到如何衡量模型的性能。以下是选择评估指标的一些建议&#xff1a; 1、理解问题类型&#xff1a; 分类问题&#xff1a;对于二分类问题&#xff0c;常见的评估指标包括准确率、精确率、召回率、F1分数、R…...

【AutoGPT】踩坑帖(follow李鱼皮)

本文写于2024年5月7日 参考视频&#xff1a;AutoGPT傻瓜式使用教程真实体验&#xff01; 对应文章&#xff1a;炸裂的AutoGPT&#xff0c;帮我做了个网站&#xff01; 平台&#xff1a;GitPod 云托管服务 原仓库已经改动很大&#xff0c;应使用的Repo为&#xff1a;Auto-GPT-ZH…...

机器学习-L1正则/L2正则

机器学习-L1正则/L2正则 目录 1.L1正则 2.L2正则 3.结合 1.L1正则 L1正则是一种用来约束模型参数的技术&#xff0c;常用于机器学习和统计建模中&#xff0c;特别是在处理特征选择问题时非常有用。 想象一下&#xff0c;你在装备行囊准备去旅行&#xff0c;但你的行囊有一…...

Linux——socket编程之tcp通信

前言 前面我们学习socket的udp通信&#xff0c;了解到了socket的概念与udp的实现方法&#xff0c;今天我们来学习一下面向连接的tcp通信。 一、tcp套接字创建 UDP和TCP都是通过套接字&#xff08;socket&#xff09;来实现通信的&#xff0c;因此TCP也得使用socket()接口创建…...

HTTP协议介绍

文章目录 http协议http协议格式GET请求POST请求http客户端实现 http协议 http协议是应用层协议&#xff0c;一般建立在tcp协议的基础之上&#xff08;当然你的实现非要基于udp也是可以的&#xff09;&#xff0c;也就是说http协议的数据收发是通过tcp协议的。 http协议也分为h…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...