Buildroot 增加系统启动项并解决后台无法获取输入(串口)

news2025/3/31 5:18:43

在这里插入图片描述

Buildroot 增加自启动项

  • 概述
  • 增加模块
  • 源码结构
  • 编写测试程序
  • 编译测试
  • 增加系统自启动
  • 一个问题
    • 解决方案:显式指定输入设备
  • 其他
    • /etc/init.d 目录下的 SXXxxx 文件作用解析‌

概述

Buildroot 是一款轻量级、高度可定制的开源工具集,专为嵌入式系统打造。它通过自动化构建流程(交叉编译工具链、Linux内核、根文件系统、引导程序),将复杂的嵌入式开发简化为“菜单配置”(make menuconfig)。开发者无需手动处理依赖与兼容性问题,只需勾选所需软件包,即可生成完整的可烧录镜像。在嵌入式场景中,服务进程的自动加载是刚需, 通常将启动脚本置于/etc/init.d/(SysV init)或编写systemd单元文件,实现服务的全自动托管。

增加模块

参考: Buildroot 添加自定义模块-内置文件到文件系统

–本文不再复述–

源码结构

package/auto_run/
├── CMakeLists.txt
├── Config.in
├── dumpsys.cpp
├── auto_run.mk
└── S99dumpsys

编写测试程序

dumpsys.cpp

#include <stdio.h>
#include <string.h>
#include <sys/statvfs.h>
#include <unistd.h>

void print_memory() {
    FILE *meminfo = fopen("/proc/meminfo", "r");
    if (!meminfo) {
        printf("无法读取内存信息\n");
        return;
    }

    char line[256];
    unsigned long total_mem = 0, free_mem = 0;

    while (fgets(line, sizeof(line), meminfo)) {
        if (strncmp(line, "MemTotal:", 9) == 0) {
            sscanf(line + 9, "%lu", &total_mem);
        } else if (strncmp(line, "MemFree:", 8) == 0) {
            sscanf(line + 8, "%lu", &free_mem);
        }
    }
    fclose(meminfo);

    printf("可用内存: %lu MB / 最大内存: %lu MB\n", free_mem / 1024, total_mem / 1024);
}

void print_disk() {
    struct statvfs stat;
    if (statvfs("/", &stat) != 0) {
        printf("无法读取磁盘信息\n");
        return;
    }

    unsigned long free_space = (stat.f_bfree * stat.f_frsize) / (1024 * 1024);
    unsigned long total_space = (stat.f_blocks * stat.f_frsize) / (1024 * 1024);

    printf("可用空间: %lu MB / 最大空间: %lu MB\n", free_space, total_space);
}

int main() {
    char input[10];

    while (1) {
        printf("输入命令 (mem/disk/exit): ");
        if (!fgets(input, sizeof(input), stdin)) {
            continue;
        }

        // 移除换行符
        input[strcspn(input, "\n")] = 0;

        if (strcmp(input, "mem") == 0) {
            print_memory();
        } else if (strcmp(input, "disk") == 0) {
            print_disk();
        } else if (strcmp(input, "exit") == 0) {
            break;
        } else {
            printf("无效命令\n");
        }
    }
    return 0;
}

编译测试

编译完成后, 可以直接将dumpsys 程序拷贝到/usr/data/dumpsys运行测试:

# /usr/data/dumpsys 
输入命令 (mem/disk/exit): mem
可用内存: 397 MB / 最大内存: 447 MB
输入命令 (mem/disk/exit): exit

增加系统自启动

auto_run.mk

AUTO_RUN_SITE = $(TOPDIR)/package/auto_run
AUTO_RUN_SITE_METHOD = local
AUTO_RUN_INSTALL_STAGING = YES

# dumpsys
define AUTO_RUN_INSTALL_INIT_SYSV
    $(INSTALL) -D -m 0755 $(AUTO_RUN_SITE)/S99dumpsys $(TARGET_DIR)/etc/init.d/S99dumpsys
endef

AUTO_RUN_POST_INSTALL_TARGET_HOOKS += AUTO_RUN_INSTALL_INIT_SYSV

$(eval $(cmake-package))

S99dumpsys

#!/bin/sh

check_run(){
    local file="/usr/data/dumpsys"
    local max_attempts=10
    local attempt=1

    while [ $attempt -le $max_attempts ]; do
        if [ -f "$file" ]; then
            echo "File $file found, starting dumpsys..."
            /usr/data/dumpsys &
            return 0
        else
            echo "Attempt $attempt: File $file not found, waiting..."
            sleep 1
            attempt=$((attempt + 1))
        fi
    done

    echo "file not found and exit"
    return 1
}

case "$1" in
    start)
        echo "Starting dumpsys..."
        check_run || exit 1
        ;;
    stop)
        echo "Stopping dumpsys..."
        killall dumpsys
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac

exit 0

一切准备就绪! 打包烧录!

一个问题

为了方便测试, 默认/usr/data/目录下没有dumpsys, 通过命令拷贝并重启.
意外出现:

输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): 输入命令 (mem/disk/exit): ...

循环输出LOG: 输入命令 (mem/disk/exit):
调试发现问题出在

if (!fgets(input, sizeof(input), stdin))

原因是从stdin读取输入出现了问题.

在Buildroot环境中,fgets()在通过init脚本启动时失败但在手动启动时正常,这通常与标准输入(stdin)的环境差异有关。

由于 后台运行(&)的影响

  • &使程序在后台运行,可能导致stdin被关闭或重定向
  • init系统可能进一步处理了标准流

解决方案:显式指定输入设备

修改程序代码:

FILE *input_stream = fopen("/dev/console", "r");
if (!input_stream) {
    input_stream = fopen("/dev/tty", "r");
}
if (!input_stream) {
    input_stream = stdin;
}

if (!fgets(input, sizeof(input), input_stream)) {
    // 错误处理
}

根本原因是初始化环境和交互式shell环境的差异。在系统启动时,标准输入可能没有绑定到有效的终端设备,而手动启动时则会有完整的终端环境。

其他

/etc/init.d 目录下的 SXXxxx 文件作用解析‌

文件命名规则与核心作用‌

  • S 前缀‌:表示 ‌启动(Start)‌ 服务,与之对应的 K 前缀表示 ‌停止(Kill)‌ 服务‌。
    XX 数字‌:决定脚本执行顺序,数值小的优先执行(如 S10network 先于 S20apache 执行),用于解决服务间的依赖关系(例如网络接口需先于 Web 服务启动)‌。
    xxx 服务名‌:标识具体服务(如 S50ssh 表示 SSH 服务)。

  • SXXxxx 文件是 SysVinit/BusyBox 初始化系统中,通过数字排序和符号链接机制实现服务按需启动的核心配置单元,直接影响嵌入式设备或服务器在特定运行级别的服务状态‌。

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

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

相关文章

数据库取证分析

目录 一.多表关联 1.一对多联结 2.子查询 二.数据库示例分析 1.多表关联 三.选择SQL分析的原因 四.数据库概述 五.SQL语言 一.多表关联 1.一对多联结 2.子查询 二.数据库示例分析 1.多表关联 三.选择SQL分析的原因 四.数据库概述 五.SQL语言 1.select 字段

【深度技术揭秘】 Android SystemUI锁屏界面动态布局重构:横竖屏智能适配指南

1. 问题背景与需求拆解 在Android 13系统定制中&#xff0c;发现平板横屏锁屏界面存在两大视觉问题&#xff1a; 时钟控件尺寸过大&#xff0c;与竖屏样式不统一 解锁图标位置异常&#xff0c;横向居中而非顶部居中&#xff08;如图示&#xff09; 需实现&#xff1a; 横竖屏…

制作PaddleOCR/PaddleHub的Docker镜像

背景 在落地RAG知识库过程中&#xff0c;遇到了图文识别、图片表格内容识别的需求。但那时&#xff08;2024年4月&#xff09;各开源RAG项目还没有集成成熟的解决方案&#xff0c;经调研我选择了百度开源的PaddleOCR。支持国产&#xff01; 概念梳理 PaddleOCR 百度飞桨的OCR…

Ubuntu部署Docker搭建靶场

前言 我们需要部署Docker来搭建靶场题目&#xff0c;他可以提供一个隔离的环境&#xff0c;方便在不同的机器上部署&#xff0c;接下来&#xff0c;我会记录我的操作过程&#xff0c;简单的部署一道题目 Docker安装 不推荐在物理机上部署&#xff0c;可能会遇到一些问题&…

【DFS】羌笛何须怨杨柳,春风不度玉门关 - 4. 二叉树中的深搜

本篇博客给大家带来的是二叉树深度优先搜索的解法技巧,在后面的文章中题目会涉及到回溯和剪枝,遇到了一并讲清楚. &#x1f40e;文章专栏: DFS &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的…

搭建Redis主从集群

主从集群说明 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 主从结构 这是一个简单的Redis主从集群结构 集群中有一个master节点、两个slave节点&#xff08;现在叫replica&#xff09;…

WSL2增加memory问题

我装的是Ubuntu24-04版本&#xff0c;所有的WSL2子系统默认memory为主存的一半&#xff08;我的电脑是16GB&#xff0c;wsl是8GB&#xff09;&#xff0c;可以通过命令查看&#xff1a; free -h #查看ubuntu的memory和swap &#xff08;改过的11GB&#xff09; 前几天由于配置E…

git 合并多次提交 commit

在工作中&#xff0c;有时候在反复修改代码中&#xff08;比如处理MR的检视意见&#xff0c;或者为了推送到测试环境&#xff0c;先 commit到自己的远程分支上&#xff09;不免会有多次 commit&#xff0c;这样发起 MR 的时候&#xff0c;就会有一堆 commit 信息&#xff0c;看…

如何分析和解决服务器的僵尸进程问题

### 如何分析和解决服务器的僵尸进程问题 #### **一、僵尸进程的定义与影响** **僵尸进程&#xff08;Zombie Process&#xff09;** 是已终止但未被父进程回收资源的进程。其特点&#xff1a; - **状态标识**&#xff1a;在进程列表&#xff08;如 ps 或 top&#xff09;中标…

XXL-Job 二次分片是怎么做的?有什么问题?怎么去优化的?

XXL-JOB二次分片机制及优化策略 二次分片实现原理 XXL-JOB的二次分片是在分片广播策略的基础上&#xff0c;由开发者自行实现的更细粒度数据拆分。核心流程如下&#xff1a; 初次分片&#xff1a;调度中心根据执行器实例数量&#xff08;总分片数n&#xff09;分配分片索引i&…

java版嘎嘎快充玉阳软件互联互通中电联云快充协议充电桩铁塔协议汽车单车一体充电系统源码uniapp

演示&#xff1a; 微信小程序&#xff1a;嘎嘎快充 http://server.s34.cn:1888/ 系统管理员 admin/123456 运营管理员 yyadmin/Yyadmin2024 运营商 operator/operator2024 系统特色&#xff1a; 多商户、汽车单车一体、互联互通、移动管理端&#xff08;开发中&#xff09; 另…

Spatial Multiplexing Power Save

802.11n中添加的PSMP&#xff0c;SMPS机制。 SM 节能功能可让 STA 在大部分时间内仅通过一条活动接收链运行&#xff0c;从而达到节能目的。 空间复用省电(Spatial Multiplexing Power Save&#xff09;模式下&#xff0c;节点会关闭多余的天线&#xff0c;仅仅使用一根天线进…

2025年渗透测试面试题总结-某360-企业蓝军面试复盘 (题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 360-企业蓝军 一、Shiro绕WAF实战方案 二、WebLogic遭遇WAF拦截后的渗透路径 三、JBoss/WebLogic反序…

C语言基础—函数指针与指针函数

函数指针 定义 函数指针本质上是指针&#xff0c;它是函数的指针&#xff08;定义了一个指针变量&#xff0c;变量中存储了函数的地址&#xff09;。函数都有一个入口地址&#xff0c;所谓指向函数的指针&#xff0c;就是指向函数的入口地址。这里函数名就代表入口地址。 函…

用DrissionPage升级网易云音乐爬虫:更稳定高效地获取歌单音乐(附原码)

一、传统爬虫的痛点分析 原代码使用requests re的方案存在以下局限性&#xff1a; 动态内容缺失&#xff1a;无法获取JavaScript渲染后的页面内容 维护成本高&#xff1a;网页结构变化需频繁调整正则表达式 反爬易触发&#xff1a;简单请求头伪造容易被识别 资源消耗大&am…

OpenCV图像拼接(5)构建图像的拉普拉斯金字塔 (Laplacian Pyramid)

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::detail::createLaplacePyr 是 OpenCV 中的一个函数&#xff0c;用于构建图像的拉普拉斯金字塔 (Laplacian Pyramid)。拉普拉斯金字塔是一种多…

通俗一点介绍什么是场外期权交易 ?

场外期权是交易所以外的市场进行交易的期权&#xff0c;主要由期货公司、证券公司等金融机构根据客户具体要求进行设计&#xff0c;最终由期货公司等机构与客户签订协议的形式进行&#xff0c;通俗一点理解场外期权就是股票做多的玩法交易&#xff0c;下文为大家科普通俗一点介…

蓝桥杯备考:图的遍历

这道题乍一看好像没什么不对的&#xff0c;但是&#xff01;但是&#xff01;结点最大可以到10的5次方&#xff01;&#xff01;&#xff01;我们递归的时间复杂度是很高的&#xff0c;我们正常遍历是肯定通过不了的&#xff0c;不信的话我们试一下 #include <iostream>…

IIS漏洞攻略

一&#xff0c;PUT漏洞 1&#xff0c;在windows server 2003 中开启 WebDAV 和写权限&#xff0c;然后访问并使用BP抓包 2&#xff0c;使用PUT上传一个木马文件&#xff0c;后缀要改成其他格式 3&#xff0c;将上传的木马文件的内容写入到asp文件中&#xff0c;然后进行连接即…

C++《红黑树》

在之前的篇章当中我们已经了解了基于二叉搜索树的AVL树&#xff0c;那么接下来在本篇当中将继续来学习另一种基于二叉搜索树的树状结构——红黑树&#xff0c;在此和之前学习AVL树类似还是通过先了解红黑树是什么以及红黑树的结构特点&#xff0c;接下来在试着实现红黑树的结构…