news 2026/9/29 22:16:07

20 嵌入式操作系统 | ubus:把自己的程序状态暴露出去

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
20 嵌入式操作系统 | ubus:把自己的程序状态暴露出去

嵌入式操作系统 | ubus:把自己的程序状态暴露出去

本课程开源地址(Gitee):https://gitee.com/fujianxinxi/qianrushixitongyingyongkaifa.git
课件、示例代码与验收脚本都在该仓库,可直接git clone或下载 ZIP 使用。

模块六 · 2 学时 · 环境:VMware + Ubuntu 20.04

一句话概述:讲清 ubus 的对象/方法模型:先启动 ubusd,再写一个注册 sensordata 对象的 C 程序,把运行状态(设备名、运行时长、被查询次数、传感器读数)用 blobmsg 返回去,最后用 ubus list 和 ubus call 一条命令一条命令地查询,配套课堂练习与课后作业。

本节目标

  1. 能说出 ubus 是干什么的,以及 ubusd 和 socket 文件的作用
  2. 会写一个注册对象和方法、返回程序状态的 C 程序(blobmsg 组返回值)
  3. 会先起 ubusd、再跑自己的程序、最后用ubus list/ubus call查询

一、讲解内容

1.1 知识讲解

ubus 是什么。它是 OpenWrt 里的进程间通信(IPC)机制:一个程序把自己的"能力"注册成一个对象,对象里可以有若干方法;别的程序(或命令行的ubus)通过名字就能调用它、拿回数据。路由器上执行ubus call network.interface.lan status查询网络状态,用的就是这套机制。
两个关键东西:

名字是什么
ubusd一个守护进程(相当于"总机"),所有程序都连它
/var/run/ubus/ubus.sock通信用的 unix socket 文件;程序启动时先ls -l看它一眼,就知道 ubusd 在不在

(这个路径是课时 15 编译时钉死在库里的默认值,ubusd启动时会自动创建所在的目录。)

写一个 ubus 服务端就三步:

步骤函数干什么
① 连上总机ubus_connect(NULL)连接 ubusd,并ubus_add_uloop(ctx)让它的消息走 uloop
② 注册对象ubus_add_object(ctx, &obj)把自己登记成sensordata,方法是status
③ 等人调用方法回调别人ubus call时,回调被调用,用blobmsg组装返回值发回去

blobmsg 是什么。它是 libubox 提供的一套"键值对表"接口:先用blob_buf_init开一个空表,再用blobmsg_add_string / add_u32 / add_double往里放字段,最后通过ubus_send_reply发回去。命令行那边看到的就是一段 JSON(正好接上下一课)。

1.2 操作步骤(一条命令一步,看现象)

第 1 步:编译(注意要链接 4 个库)

cd~/lab/课时20-ubus状态查询 gcc-Wall-Wextra-oubus_status ubus_status.c-lubus-lubox-lblobmsg_json-ljson-c

为什么这么多-l:程序用了 ubus 的接口(-lubus)、uloop 和 blobmsg(-lubox)、blobmsg 与 JSON 互转(-lblobmsg_json -ljson-c)。少一个就会看到undefined reference to ...。

第 2 步:先启动 ubusd(终端 A)

sudoubusd&ls-l/var/run/ubus/ubus.sock

现象(出现 socket 文件说明总机已经开机):

srw-rw-rw- 1 root root 0 Sep 25 08:15 /var/run/ubus/ubus.sock

第 3 步:运行我们的程序(终端 A,会让出提示符前先打印三行)

sudo./ubus_status

现象(程序注册完就不动了,正等别人来查):

① 连接 ubusd… 已连接 ② 已注册对象: sensordata(方法: status) ③ 现在到另一个终端执行: ubus list ; ubus call sensordata status

第 4 步:另开一个终端 B,先看有哪些对象

ubus list

现象(能看到我们刚注册的对象):

sensordata

第 5 步:查询状态(这就是"让程序把状态说出来")

ubus call sensordata status

现象(返回一段 JSON;多查几次query_count会加 1):

{ "device": "ubuntu-gateway", "uptime_s": 49321, "query_count": 1, "sensor": "温度", "value": 25.500000, "status": "ok" }

再执行一次同样的命令:

{ "device": "ubuntu-gateway", "uptime_s": 49321, "query_count": 2, "sensor": "温度", "value": 26.000000, "status": "ok" }

第 6 步:回到终端 A 看程序那边的现象

← 收到第 1 次 ubus 查询 ← 收到第 2 次 ubus 查询

两边对应上了:终端 B 每执行一次ubus call,终端 A 的程序回调就被调用一次——这就是"查询程序状态"的完整链路。
第 7 步:收工

# 终端 A 按 Ctrl+C 停掉 ubus_status,然后:sudopkill-xubusd# 关掉总机

1.3 常见错误与排查

现象原因解决
程序打印"连不上 ubusd"ubusd 没启动先sudo ubusd &,再ls -l /var/run/ubus/ubus.sock确认
ubus list是空的自己的程序没在运行(或刚退出)先把./ubus_status跑起来(它会一直等)
ubus call ... : Object not found对象名写错,或程序没注册成功对象名必须是sensordata;先ubus list看一眼
ubus call没反应程序卡住了(比如注册后没进 uloop)检查是否调用了uloop_run()
编译报undefined reference to ubus_...链接参数少写了四条都要写:-lubus -lubox -lblobmsg_json -ljson-c
ubusd: command not found课时 15 没装好 ubus回课时 15 检查,which ubusd应为/usr/local/sbin/ubusd

二、学生练习

本节命令速查表:

命令作用示例
gcc … -lubus -lubox -lblobmsg_json -ljson-c编译 ubus 程序见第 1 步
sudo ubusd &启动总机sudo ubusd &
ls -l /var/run/ubus/ubus.sock确认总机在ls -l /var/run/ubus/ubus.sock
sudo ./ubus_status运行自己的服务程序sudo ./ubus_status
ubus list看有哪些对象ubus list
ubus call 对象 方法调用方法查询ubus call sensordata status
sudo pkill -x ubusd关掉总机sudo pkill -x ubusd
编号任务提示预期结果
L20.1按步骤跑通查询先 ubusd → 再程序 → 再 callubus list有 sensordata,call 返回 JSON
L20.2连查 3 次连续执行ubus callquery_count依次 1、2、3
L20.3加一个字段在handle_status里加blobmsg_add_u32(&b, "heartbeat", 42)call 结果里多一项
L20.4加第二个方法仿照status加一个ping方法(返回{"pong":true})ubus call sensordata ping能调通
L20.5不启动 ubusd 就运行程序先sudo pkill -x ubusd程序打印"连不上 ubusd"并退出
L20.6观察"程序退出后"的现象停掉 ubus_status 后再ubus list对象消失,ubus call报 Object not found

三、作业

  • 必做:完成 L20.1、L20.2,提交两个终端截图(程序端 + ubus call 的 JSON 输出),并回答:① ubusd 是什么,socket 文件有什么用?② 我们的程序是怎么"把状态交出去"的?③ 为什么ubus call的输出是 JSON?
  • 选做:把课时 18 的采集程序和新知识合起来——在 ubus 对象里返回"最后一次采集的温度",让查询能拿到实时值(提示:把采集结果存到全局变量,回调里读它)
  • 提交:截图 + 文字回答,命名课时20-作业截图.png

四、本节小结与下节预告

本节把程序状态暴露给了别人:启动 ubusd、注册sensordata对象、用 blobmsg 返回字段,再用ubus list/ubus call查询。你注意到没有——ubus call打出来的就是 JSON。下节课我们就专门学 JSON:怎么用它生成和解析数据。

附录:怎么运行 + 完整代码

一个课件就够用:先按附录 A 的顺序敲命令(服务端/对端先开,自己的程序后开),再按附录 B 抄代码。行尾请用 LF。

附录 A|怎么运行(注意先后顺序)

gcc-Wall-Wextra-oubus_status ubus_status.c-lubus-lubox-lblobmsg_json-ljson-csudoubusd&# 终端A:先启动 ubusdls-l/var/run/ubus/ubus.sock# 确认 socket 在sudo./ubus_status# 再运行自己的程序(前台等着被查)ubus list# 终端B:看对象ubus call sensordata status# 查询状态(返回 JSON)sudopkill-xubusd# 收工

附录 B|文件ubus_status.c

/* * ubus_status.c —— 课时 20:注册一个 ubus 对象,把程序状态暴露出去 * * 编译:gcc -Wall -Wextra -o ubus_status ubus_status.c -lubus -lubox -lblobmsg_json -ljson-c * 运行:sudo ./ubus_status # 需要先启动 ubusd(见 ubus_check.sh start) * * 做法三步: * ① 连上 ubusd(ubus_connect) * ② 注册一个对象 sensordata,里面有一个方法 status * ③ 别人执行 ubus call sensordata status 时,我们的回调被调用, * 用 blobmsg 组一个表返回去(ubus 命令行会把它打成 JSON) */#include<stdio.h>#include<signal.h>#include<time.h>#include<unistd.h>#include<libubox/blobmsg.h>#include<libubox/uloop.h>#include<libubus.h>staticstructubus_context*ctx;staticunsignedintquery_count=0;/* 被查询了几次 *//* 方法回调:有人 ubus call sensordata status 时,uloop 会走到这里 */staticinthandle_status(structubus_context*c,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){structblob_bufb={0};(void)c;(void)obj;(void)method;(void)msg;query_count++;blob_buf_init(&b,0);/* 准备一个空表 */blobmsg_add_string(&b,"device","ubuntu-gateway");/* 字符串字段 */blobmsg_add_u32(&b,"uptime_s",(uint32_t)(time(NULL)%100000));blobmsg_add_u32(&b,"query_count",query_count);/* 自己被查了几次 */blobmsg_add_string(&b,"sensor","温度");blobmsg_add_double(&b,"value",25.0+query_count*0.5);/* 假装最新读数 */blobmsg_add_string(&b,"status","ok");ubus_send_reply(c,req,b.head);/* 把表发回去 */blob_buf_free(&b);printf("← 收到第 %u 次 ubus 查询\n",query_count);fflush(stdout);return0;}/* 方法表:本对象只有 status 一个方法,不用参数 */staticconststructubus_methodstatus_methods[]={UBUS_METHOD_NOARG("status",handle_status),};staticstructubus_object_typestatus_type=UBUS_OBJECT_TYPE("sensordata",status_methods);staticstructubus_objectstatus_obj={.name="sensordata",/* ubus call 时用的对象名 */.type=&status_type,.methods=status_methods,.n_methods=ARRAY_SIZE(status_methods),};staticvoidon_signal(intsig){(void)sig;uloop_end();}intmain(void){uloop_init();signal(SIGINT,on_signal);signal(SIGTERM,on_signal);printf("① 连接 ubusd…\n");ctx=ubus_connect(NULL);/* NULL = 用默认 socket /var/run/ubus/ubus.sock */if(!ctx){printf(" 连不上 ubusd:先执行 ./ubus_check.sh start 把 ubusd 起起来\n");return1;}printf(" 已连接\n");ubus_add_uloop(ctx);/* 让 ubus 的消息也走 uloop 事件循环 */if(ubus_add_object(ctx,&status_obj)!=0){printf("② 注册对象失败\n");return1;}printf("② 已注册对象: sensordata(方法: status)\n");printf("③ 现在到另一个终端执行: ubus list ; ubus call sensordata status\n");fflush(stdout);uloop_run();/* 事件循环:等别人来调用 */ubus_free(ctx);uloop_done();printf("\n④ 程序退出(共被查询 %u 次)\n",query_count);return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 22:13:52

大语言模型技术 step by step 第15章 提示工程与上下文学习

第15章 提示工程与上下文学习 学习目标 理解上下文学习&#xff08;ICL&#xff09;的原理与机制掌握少样本提示与思维链等提示技术理解指令遵循与提示敏感性了解提示工程的最佳实践前面几章讨论如何训练和对齐模型。本章转向如何使用模型。大模型有一个革命性特性&#xff1a;…

作者头像 李华
网站建设 2026/9/29 22:13:24

Kong 插件,解决2.5.1不支持原生暴露url

lua脚本 建目录custom-latency&#xff0c;编辑文件&#xff0c;打zip包为file schema.lualocal typedefs require "kong.db.schema.typedefs"return {name "custom-latency",fields {{ consumer typedefs.no_consumer },{ protocols typedefs.protoc…

作者头像 李华
网站建设 2026/9/29 22:12:59

AI论文降重工具实战:从查重原理到高效降重的完整流程指南

又到一年毕业季&#xff0c;群里哀嚎一片的不是论文写不出来&#xff0c;而是查重报告上那个刺眼的红字。我见过太多人卡在最后一步&#xff1a;学校的查重系统结果一出来&#xff0c;重复率35%&#xff0c;距离合格线还差一大截&#xff0c;留给自己的时间却只剩两三天。说实话…

作者头像 李华
网站建设 2026/9/29 22:12:06

告别无效读论文!从零搞定文献阅读与实验复现完整流程

做机器学习相关课程作业或课题预研&#xff0c;相信很多人都有同样的困扰&#xff1a;认真读完一篇论文&#xff0c;看懂了理论思路&#xff0c;却完全没法落地实操。要么找不到配套数据集和源码&#xff0c;要么实验设计晦涩难懂&#xff0c;手动搭环境、调参耗时费力&#xf…

作者头像 李华
网站建设 2026/9/29 22:10:39

OpenClaw 3.1.0 上手教程,支持键鼠模拟、网页采集、文档批量处理

&#x1f4d6; 前言 本文面向 Windows 系统用户&#xff0c;系统梳理 OpenClaw 的标准化部署流程。全程无需输入任何命令行&#xff0c;所有操作均依托可视化向导完成&#xff0c;即便是零基础用户也能独立走完整套部署。文中同时汇总了高频报错的对应解决方案&#xff0c;力求…

作者头像 李华
网站建设 2026/9/29 22:09:20

2026年GEO服务商怎么选?主流方案全维度拆解与优选推荐

AI大模型正在重塑信息分发规则。当越来越多用户开始习惯向豆包、DeepSeek、千问、元宝等平台提问&#xff0c;品牌能否出现在AI的回答里、排在第几位、以什么形象被描述&#xff0c;已经成为决定流量走向的关键变量。GEO&#xff08;生成引擎优化&#xff09;由此成为企业营销的…

作者头像 李华