Petalinux自动化脚本:超越官方模板的自定义启动与系统钩子

PetaLinux内核定制深度剖析:从配置到编译完整指南 手把手带你走完PetaLinux内核定制关键步骤——从Kconfig图形化配置、设备树修改,到交叉编译与镜像生成。全程聚焦PetaLinux工具链特性,解决常见编译报错与BOOT.BIN联动问题,助你真正掌握嵌入式Linux系统级构建核心能力。 阅读详情

Petalinux自动化脚本:超越官方模板的自定义启动与系统钩子

在工业控制与边缘计算场景中,系统启动的可靠性与灵活性往往决定了整个设备的稳定性和可维护性。当我们面对成百上千台设备需要批量部署、远程更新或故障自恢复时,仅仅依赖Petalinux官方提供的标准启动机制显然不够。许多工程师可能已经熟悉了基础的autostart.sh脚本创建,但真正强大的自动化能力隐藏在系统初始化的深层机制中——那些被称为“钩子”(Hook)的拦截点,能够让我们在系统启动的关键阶段注入自定义逻辑,实现高度可控的启动流程。

本文将带你深入Petalinux的初始化系统内部,超越简单的脚本创建,探索如何利用INITSCRIPT机制、多设备兼容性处理以及故障恢复策略,构建一套适应工业环境的高可靠性启动方案。无论你是在设计一个需要自动识别外置存储并加载配置的边缘设备,还是希望实现系统状态监控与异常自愈的工控系统,这里的技巧与实践都能为你提供新的思路。

1. 理解Petalinux初始化系统与钩子机制

Petalinux基于Yocto项目构建,其初始化系统通常使用SysVinit或systemd(取决于版本配置)。在SysVinit体系中,启动过程被划分为多个运行级别(runlevel),每个级别对应一组特定的服务与脚本。这些脚本按照数字顺序执行,为我们提供了插入自定义逻辑的自然切入点。

INITSCRIPT机制是Petalinux中管理初始化脚本的核心框架。通过.bb文件(BitBake配方)中的INITSCRIPT_NAME、INITSCRIPT_PARAMS等变量,我们可以定义脚本的安装位置、执行顺序及运行级别。与简单地放置一个脚本在/etc/init.d不同,这种机制确保了脚本在构建时就被正确集成到根文件系统中,并且受到包管理系统的跟踪。

考虑以下典型的初始化脚本配方示例:

inherit update-rc.d

DESCRIPTION = "Custom autostart script for industrial devices"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

INITSCRIPT_NAME = "custom-autostart"
INITSCRIPT_PARAMS = "start 99 5 . stop 01 0 1 6 ."

SRC_URI = "file://custom-autostart"

do_install() {
    install -d ${D}${sysconfdir}/init.d
    install -m 0755 ${WORKDIR}/custom-autostart ${D}${sysconfdir}/init.d/custom-autostart
}

FILES_${PN} = "${sysconfdir}/init.d/custom-autostart"
RDEPENDS_${PN} = "bash"

这段代码不仅安装了初始化脚本,还通过INITSCRIPT_PARAMS定义了精确的执行顺序:在运行级别5(多用户图形模式)中以99的优先级启动,在运行级别0(停机)、1(单用户)和6(重启)中以01的优先级停止。这种细粒度控制是简单脚本放置无法实现的。

提示:在实际项目中,我通常会为关键服务设置比默认服务更高或更低的优先级数字,确保依赖关系得到正确处理。例如,网络服务应该在大多数自定义脚本之前启动,而日志收集服务可能需要在最后启动。

除了标准的初始化脚本,Petalinux还提供了多种钩子点供我们利用:

  • ${sysconfdir}/rc.local:最简单的前向兼容方式,适合快速测试
  • Systemd单元文件:在新版本中更为常见,提供更现代的依赖管理
  • BusyBox初始化脚本:在资源受限设备上的轻量级方案

理解这些机制的区别与适用场景,是构建可靠启动系统的第一步。

2. 构建安全可靠的自定义启动脚本

创建自定义启动脚本远不止于写几行Shell命令那么简单。在工业环境中,脚本必须具备容错能力、日志记录和超时控制,否则一个失败的启动项可能拖累整个系统。

安全注入用户脚本的最佳实践是从设计时就考虑错误处理。以下是一个增强了可靠性的autostart脚本框架:

#!/bin/sh

### 环境配置
LOG_FILE="/var/log/autostart.log"
MAX_RETRY=3
RETRY_DELAY=5

### 日志记录函数
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
    logger -t "autostart" "$1"
}

### 错误处理函数
run_with_retry() {
    local command=$1
    local description=$2
    local attempt=1
    local result=1
    
    while [ $attempt -le $MAX_RETRY ]; do
        log_message "尝试执行: $description (尝试: $attempt/$MAX_RETRY)"
        eval $command
        result=$?
        if [ $result -eq 0 ]; then
            log_message "成功: $description"
            return 0
        fi
        sleep $RETRY_DELAY
        attempt=$((attempt+1))
    done
    
    log_message "错误: $description 失败 after $MAX_RETRY 次尝试"
    return $result
}

### 主执行逻辑
log_message "开始执行自定义启动脚本"

# 示例:加载内核模块
run_with_retry "insmod /lib/modules/$(uname -r)/extra/custom-driver.ko" "加载自定义驱动模块"

# 示例:启动自定义应用
run_with_retry "/usr/bin/custom-app --daemonize" "启动自定义应用程序"

log_message "自定义启动脚本执行完成"

这个脚本框架提供了结构化日志记录、重试机制和错误报告,远比简单的命令序列可靠。在实际部署中,我还发现为关键操作添加超时控制非常有用,可以使用timeout命令包装可能挂起的操作:

# 启动可能挂起的服务,设置5分钟超时
timeout 300 /usr/bin/problematic-service || log_message "警告: 服务启动超时"

权限与安全考虑同样重要。在嵌入式系统中,我们常常需要以root权限运行脚本,但这带来了安全风险。对于不需要完全特权的操作,可以考虑使用capabilities机制或创建专用用户:

# 为需要部分特权的程序设置capabilities
setcap cap_net_raw+ep /usr/bin/network-monitor

# 创建专用系统用户
adduser --system --no-create-home --group appuser
chown appuser:appuser /usr/bin/custom-app

注意:在生产系统中,避免在启动脚本中使用硬编码的路径和参数。使用配置文件或环境变量可以提高脚本的灵活性和可维护性。我曾经维护过一个项目,其中启动参数被硬编码在几十个脚本中,当需求变化时,更新工作变得极其困难。

3. 实现多设备与多分区兼容性

工业环境中,设备多样性是常态。不同的存储设备(SD卡、eMMC、NVMe)可能在不同的硬件平台上表现出不同的设备命名规则。处理这种多样性是实现可靠自动化的关键挑战。

SD卡分区识别是一个经典问题。不同的控制器和驱动可能将相同的SD卡识别为mmcblk0、mmcblk1甚至sda。依赖于固定设备名的脚本在设备变更时就会失败。以下是更健壮的分区检测方法:

#!/bin/bash

# 查找所有可能的SD卡设备
find_sd_devices() {
    local devices=()
    for device in /dev/mmcblk* /dev/sd*; do
        # 排除设备本身(只包含分区)
        if [[ $device =~ [0-9]$ ]]; then
            # 检查是否为FAT或EXT4分区
            if blkid -t TYPE=vfat $device >/dev/null 2>&1 || blkid -t TYPE=ext4 $device >/dev/null 2>&1; then
                devices+=($device)
            fi
        fi
    done
    echo "${devices[@]}"
}

# 挂载并检查分区内容
mount_and_check() {
    local device=$1
    local mount_point="/mnt/autostart_tmp"
    local config_file="autostart.sh"
    local result=1
    
    mkdir -p $mount_point
    if mount $device $mount_point 2>/dev/null; then
        if [ -f "$mount_point/$config_file" ]; then
            echo "$mount_point/$config_file"
            result=0
        else
            umount $mount_point
        fi
    fi
    
    [ $result -ne 0 ] && rm -rf $mount_point
    return $result
}

# 主检测逻辑
detect_autostart_partition() {
    local devices=$(find_sd_devices)
    for device in $devices; do
        local config_path=$(mount_and_check $device)
        if [ $? -eq 0 ]; then
            echo $config_path
            return 0
        fi
    done
    return 1
}

# 使用示例
AUTOSTART_SCRIPT=$(detect_autostart_partition)
if [ $? -eq 0 ]; then
    echo "找到启动脚本: $AUTOSTART_SCRIPT"
    source $AUTOSTART_SCRIPT
else
    echo "未找到外部启动脚本,使用默认配置"
fi

这种方法不依赖于固定设备名,而是通过检查分区内容和文件系统类型来识别正确的分区。在实际项目中,我可以进一步通过检测分区标签来确认:

# 通过分区标签识别
if blkid -l -o device -t LABEL="CONFIG_PARTITION" >/dev/null 2>&1; then
    CONFIG_DEVICE=$(blkid -l -o device -t LABEL="CONFIG_PARTITION")
    # ...
fi

对于更复杂的场景,我们可能需要处理多种配置文件格式和版本兼容性。以下表格总结了几种常见配置方案的优缺点:

配置方案实现复杂度灵活性可靠性适用场景
固定设备名低低低开发测试
文件系统类型检测中中中单一类型存储
分区标签检测中高高多存储设备
内容特征识别高高高异构环境
网络配置获取高极高中云连接设备

提示:在最近的一个边缘计算项目中,我们结合使用了分区标签检测和内容验证:首先查找特定标签的分区,然后验证分区内的数字签名,最后才执行配置脚本。这种深度防御策略防止了恶意配置的注入。

4. 高级应用:系统监控与故障自恢复

真正的工业级解决方案不仅仅关注启动过程,还关注系统整个生命周期的健康状态。通过扩展启动钩子,我们可以实现丰富的监控和自愈功能。

系统状态监控可以在启动时初始化,并在后台持续运行。以下是一个简单的监控框架,可以集成到启动脚本中:

#!/bin/sh

# 监控系统服务状态
monitor_services() {
    local services=("custom-app" "network-manager" "data-logger")
    local check_interval=60
    
    while true; do
        for service in "${services[@]}"; do
            if ! systemctl is-active --quiet "$service"; then
                logger -t "monitor" "服务 $service 异常,尝试重启"
                systemctl restart "$service"
                
                # 记录重启事件
                echo "$(date '+%Y-%m-%d %H:%M:%S') - 重启服务 $service" >> /var/log/service-monitor.log
            fi
        done
        sleep $check_interval
    done
}

# 监控资源使用情况
monitor_resources() {
    local threshold_memory=90  # 内存使用率阈值%
    local threshold_disk=80    # 磁盘使用率阈值%
    local check_interval=300
    
    while true; do
        # 检查内存使用
        local mem_usage=$(free | awk '/Mem:/ {printf("%.0f"), $3/$2*100}')
        if [ $mem_usage -gt $threshold_memory ]; then
            logger -t "monitor" "内存使用率过高: $mem_usage%"
            # 执行清理操作...
        fi
        
        # 检查磁盘空间
        local disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
        if [ $disk_usage -gt $threshold_disk ]; then
            logger -t "monitor" "根分区使用率过高: $disk_usage%"
            # 清理旧日志文件...
        fi
        
        sleep $check_interval
    done
}

# 在后台启动监控进程
start_monitoring() {
    monitor_services &
    monitor_resources &
    
    # 记录监控进程PID,便于管理
    echo $! > /var/run/service-monitor.pid
    echo $! > /var/run/resource-monitor.pid
}

# 主执行逻辑
case "$1" in
    start)
        start_monitoring
        ;;
    stop)
        kill -TERM $(cat /var/run/*monitor.pid) 2>/dev/null
        ;;
    *)
        echo "用法: $0 {start|stop}"
        exit 1
        ;;
esac

故障自恢复是工业系统的关键需求。通过结合监控和智能恢复策略,我们可以减少现场维护需求。以下示例展示了如何实现分级恢复机制:

#!/bin/sh

# 尝试温和恢复
attempt_soft_recovery() {
    local service=$1
    logger -t "recovery" "尝试温和恢复服务: $service"
    
    systemctl restart $service
    sleep 5
    
    if systemctl is-active --quiet "$service"; then
        logger -t "recovery" "温和恢复成功: $service"
        return 0
    fi
    return 1
}

# 尝试强制恢复
attempt_hard_recovery() {
    local service=$1
    logger -t "recovery" "尝试强制恢复服务: $service"
    
    # 停止相关进程
    pkill -9 -f "$service"
    sleep 2
    
    # 清理可能的状态文件
    rm -f /var/run/$service.pid
    rm -f /var/lock/$service.lock
    
    # 重新启动
    systemctl start $service
    sleep 5
    
    if systemctl is-active --quiet "$service"; then
        logger -t "recovery" "强制恢复成功: $service"
        return 0
    fi
    return 1
}

# 尝试完全重置
attempt_full_reset() {
    local service=$1
    logger -t "recovery" "尝试完全重置服务: $service"
    
    # 停止服务
    systemctl stop $service
    
    # 重新安装包(如果适用)
    if which apt-get >/dev/null 2>&1; then
        apt-get install --reinstall -y $service
    fi
    
    # 恢复默认配置
    cp /etc/$service/default-config.conf /etc/$service/config.conf
    
    # 重新启动
    systemctl start $service
    sleep 10
    
    if systemctl is-active --quiet "$service"; then
        logger -t "recovery" "完全重置成功: $service"
        return 0
    fi
    return 1
}

# 主恢复逻辑
automated_recovery() {
    local service=$1
    local max_attempts=3
    
    for attempt in $(seq 1 $max_attempts); do
        case $attempt in
            1)
                attempt_soft_recovery $service && return 0
                ;;
            2)
                attempt_hard_recovery $service && return 0
                ;;
            3)
                attempt_full_reset $service && return 0
                ;;
        esac
    done
    
    logger -t "recovery" "错误: 无法恢复服务 $service,需要人工干预"
    # 触发告警通知...
    return 1
}

这种分级恢复策略确保了我们首先尝试最温和的干预,逐步升级到更激进的措施,最大程度减少对系统的影响。

在实际部署中,我发现将关键指标和事件发送到远程监控系统极为有价值。以下是一个集成远程监控的示例:

# 报告状态到监控服务器
report_to_monitoring() {
    local metric_name=$1
    local value=$2
    local tags=$3
    
    # 使用curl发送指标(示例)
    curl -s -X POST "https://monitoring.example.com/api/metrics" \
        -H "Authorization: Bearer $API_TOKEN" \
        -d "{
            \"metric\": \"$metric_name\",
            \"value\": $value,
            \"tags\": \"$tags\",
            \"timestamp\": $(date +%s)
        }" >/dev/null 2>&1 &
}

# 在恢复过程中报告
attempt_soft_recovery() {
    local service=$1
    report_to_monitoring "recovery.attempt" 1 "service:$service,type:soft"
    
    # ...恢复逻辑...
    
    if [ $? -eq 0 ]; then
        report_to_monitoring "recovery.success" 1 "service:$service,type:soft"
        return 0
    else
        report_to_monitoring "recovery.failure" 1 "service:$service,type:soft"
        return 1
    fi
}

通过将本地恢复操作与远程监控结合,我们创造了真正具有韧性的工业系统,能够在不需人工干预的情况下处理多种故障 scenario。

FMQL国产Zynq PS端裸机开发:IAR工具链选择与系列路线图 异构SoC芯片将ARM处理器与FPGA可编程逻辑集成于一体,在工业控制、边缘计算等领域广泛应用。理解其PS端与PL端的分工协作,是发挥芯片性能的关键。AXI总线作为PS与PL之间的高速通道,其中HP口支持PL直接读写DDR,实现高吞吐数据搬运,而GP口适合寄存器级控制,ACP口则提供缓存一致性加速。针对裸机开发场景,工具链的选择直接影响调试效率与代码可控性,IAR Embedded Workbench凭借对Cortex-A9的成熟支持及友好的调试体验,成为从MCU转型工程师的理想起点。本文以复旦微FMQL系 阅读详情

相关推荐

Zynq-7000多介质启动引导FSBL源码包(含QSPI/NOR/SD/NAND驱动与安全校验)

一套开箱即用的Xilinx Zynq-7000 SoC第一阶段启动代码,基于官方FSBL开源实现,直接支持QSPI Flash、NOR Flash、SD卡和NAND Flash四种启动介质,每种介质都配有独立驱动文件(qspi.c/nor.c/sd.c/nand.c)及对应头文件。内置图像搬运(image_mover)、RSA签名验证、MD5完整性校验、PCAP配置加载和PS端参数配置(ps7_parameters.xml)功能,所有模块通过main.c统一调度,最终由fsbl_handoff.S跳转至U-

prometheus5watch的博客 190

超越官方模板:Petalinux自动化启动脚本的深度定制与扩展应用

本文深入探讨了Petalinux自动化启动脚本的深度定制与扩展应用,重点介绍了如何通过修改.bb文件和设计Init脚本来实现驱动开发中的动态钩子注入与远程更新方案。文章提供了工业控制系统中的实战案例,展示了如何构建自适应启动机制以提升系统可靠性和现场可配置性,为嵌入式开发者提供了超越官方模板的高级定制方法。

pepsi的博客 1065

五子棋小游戏,可联机,单机

五子棋小游戏,可联机,单机

基于FreeRTOS与IPI机制的异构多核通信实战:从原理到KR260开发板实现

在嵌入式系统开发中,核间通信(IPC)是实现多核协同工作的核心技术,尤其在异构多核架构中,不同架构核心(如Cortex-A与Cortex-R)之间的高效、可靠数据交换是系统设计的关键。其原理通常基于共享内存、消息传递或硬件中断机制,旨在解决独立内存空间下的数据同步问题。该技术的核心价值在于能够充分发挥异构平台的优势,例如将实时任务部署于实时处理器(RPU),将富功能应用运行于应用处理器(APU),从而兼顾实时性与高性能。典型的应用场景包括工业控制、汽车电子和边缘计算设备。本文以Xilinx Zynq MPS

weixin_30847939的博客 459

基于蜣螂优化算法的多无人机安全航迹规划方法研究(Matlab代码实现)

内容概要:本文研究了基于多策略改进蜣螂优化算法(MSDBO)的多无人机协同三维安全航迹规划方法,旨在解决城市空中交通等复杂环境中多无人机集群飞行的路径规划与动态避障问题。通过引入多种优化策略对蜣螂算法进行改进,增强了算法的全局搜索能力与收敛精度,构建了以路径长度、飞行高度、威胁规避和转弯角度等为约束的综合成本最小化目标函数,实现了多无人机在三维空间中的高效协同避障与安全路径生成。该方法有效提升了飞行任务的安全性与执行效率,并通过Matlab仿真验证了其相较于传统算法在路径质量、避障能力和收敛性能方面的优越性。; 适合人群:具备一定智能优化算法基础和Matlab编程能力,从事无人机路径规划、群体智能算法、空中交通管理或相关工程应用研究的科研人员、高校研究生及自动化、航空航天领域的技术人员。; 使用场景及目标:①应用于城市巡检、应急救援、物流配送等多无人机协同任务中的三维路径规划;②为解决复杂动态环境下多机冲突消解、威胁规避与航迹优化问题提供高效算法支持;③推动蜣螂优化算法在多智能体系统与复杂工程优化中的实际落地与拓展应用。; 阅读建议:建议结合文中提供的Matlab代码进行仿真实践,深入理解MSDBO算法的设计机制与航迹规划模型的构建逻辑,可尝试调整环境参数、威胁分布或优化目标权重,观察算法在不同场景下的适应性与鲁棒性,进一步掌握智能优化算法在无人机系统中的应用方法与调参技巧。

音视频开发—H264相关概念和压缩原理详解(GOP、宏块、帧内压缩、帧间压缩)

本文讲述了H264相关概念和原理——GOP概念,SPS与PPS,帧内压缩原理,帧间压缩原理,解释了什么是运动补偿,什么运动矢量等等概念

weixin_46999174的博客 3982

ZYNQ7020双核通信实战:OpenAMP打通Linux与FreeRTOS

在嵌入式异构多核系统中,不同处理器核运行不同操作系统的场景越来越常见,而核间通信正是决定系统性能与可靠性的关键。共享内存配合中断通知是经典的核间通信机制,OpenAMP作为一套开源异构多核通信框架,将这种底层机制标准化,提供了远程处理器管理、消息传递和硬件抽象能力。它支持Linux与RTOS(如FreeRTOS)之间高效的数据交换,被广泛应用于ZYNQ等ARM+FPGA平台。围绕ZYNQ7020,深入讲解OpenAMP的工作原理、工程搭建、设备树配置、中断与缓存一致性处理,并总结了双核通信中的常见问题与调试

weixin_32770423的博客 307

Flutter 完整学习文档 - 从入门到精通

Widget 就像乐高积木,Flutter 中所有的东西都是 Widget。一个按钮是 Widget,一段文字是 Widget,甚至布局、边距、对齐方式也是 Widget!"万物皆 Widget"

zwjapple的专栏 2321

芯参谋(100):RT-Thread_驱动开发指南

本文档为Microchip PIC/AVR/SAM三族MCU的全流程开发指南,覆盖从选型、MCC配置、代码生成到量产烧录的完整链路。针对三族工具链差异大、生态复杂的问题,按“选型→配置→应用→烧录→调试”顺序组织,明确各环节官方出处与可复现命令。重点解决跨族迁移中的共性难题:MCC生成边界、PPS引脚映射失效、UPDI连接失败、内存溢出及量产固件一次性烧录等。通过机制-配置-排查三段式结构,结合速查表与读者路径,实现工程问题快速定位,提升开发效率与产品可靠性。

qq520131714的专栏 584

脑机接口(BCI)从原理到开发实战 09|SSVEP应用:通过视觉刺激控制设备

本文介绍了稳态视觉诱发电位(SSVEP)脑机接口技术。SSVEP是一种高效的非侵入式BCI范式,当用户注视特定频率闪烁的视觉刺激时,大脑枕叶会产生对应的节律性响应。文章详细阐述了SSVEP的神经机制、刺激范式设计、数据预处理方法,重点讲解了典型相关分析(CCA)这一核心识别算法。相比运动想象和P300范式,SSVEP具有信息传输率高(60-100 bits/min)、信号稳定、无需训练等优势,在高速拼写、设备控制等领域应用广泛。文章还提供了完整的电极选择、滤波、分段等预处理流程,以及CCA和滤波器组CCA的

小明的博客 1359

基于phpstudy搭建pikachu靶场

一、phpstudy下载安装配置 phpstudy介绍 简单介绍一下phpstudy,详细请参考百度解读。pikachu是基于PHP环境搭建的,需要数据库支持,所以装pikachu之前需要先安装它需要的环境,就像你养鱼需要给它提供水环境一样。安装phpstudy能满足pikachu的需求,所以先安装phpstudy。 phpStudy是一个PHP调试环境的程序集成包。该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是

ptxybird的博客 1万+

基于PIC32CX1025SG41128 USB CDC Dual-Bank Bootloader设计

本项目基于PIC32CX1025SG41128实现支持USB CDC虚拟串口的双Bank安全Bootloader,替代传统UART升级方式。通过抽象通信接口,实现固件分块传输、CRC校验与安全切换,确保升级中断时系统可回退。采用双Bank布局,预留failsafe区域记录版本与重试信息,支持RAM触发重启进入升级模式。配套上位机工具btl_host.py与打包脚本make_merged_bin.py,完成镜像生成与下载。工程结构清晰,兼容MPLAB X/VSCode开发环境,适用于高可靠性嵌入式设备远程升级

lindd911911的博客 275

MTK手机传感器驱动开发避坑指南:从SCP代码大小限制到Overlay加载流程详解

本文详细解析了MTK平台传感器驱动开发中的常见问题,包括SCP代码大小限制、Overlay加载流程及客制化传感器集成。通过实战案例和优化策略,帮助开发者高效解决MTK传感器驱动开发中的技术难题,提升开发效率。

weixin_42522374的博客 402

TMC2209步进电机驱动开发

TMC2209是两相步进电机驱动,最高峰值电流2A(有效值1.4A),供电电压4.75V~29V。开发时一定要注意电流的阈值,2A的电流可能不适配大扭矩的电机需求。通信接口:半双工UART(单数据线,共用一根线收发,必须控制收发方向)细分:最高 256 微步(UART 模式),引脚模式最高 16 细分控制方式:STEP + DIR 脉冲方向控制(主流用法,不是串口发脉冲)用法:引脚模式和UART配置模式,UART模式可实时改变寄存器状态MS1/MS2:引脚模式时用于改变细分;

weixin_44425713的博客 350

UE4逆向实战:如何快速定位UWorld和GName的5种实用技巧(含版本差异分析)

本文详细介绍了UE4逆向工程中快速定位UWorld和GName的5种实用技巧,包括特征码定位法、动态行为分析法、静态符号分析法等,并针对不同版本差异提供了适配方案。特别强调了UWorld作为游戏世界核心容器和GName作为名称管理系统的重要性,帮助开发者高效进行游戏逆向分析。

star的博客 900

【Coppeliasim|轨迹规划(三)】机械臂逆解

文章目录一些设置导航点设置添加连接用于碰撞的设置代码实现终端输出 一些设置 导航点设置 关于如何添加设置 dummy 的细节建议参考官方手册,这里不再赘述。 添加连接用于碰撞的设置 按照序号点击(一个是机械臂,一个是所有的物体除了机械臂): 代码实现 getMatrixShiftedAlongZ=function(matrix,localZShift) local m={} for i=1,12,1 do m[i]=matrix[i] end

【人工智障 | 计算鸡视觉 | 机器孩】 1万+

BcoreOS 系统制作实战:用一个升级包,让Rocky Linux10.1跑进Ubuntu 25.04

本节以 Rocky 10.1 作为系统母盘,演示如何根据内核校验和匹配 AOS 镜像,并最终生成可用的 BcoreOS 升级包。

xiaozhi@fslib.org的博客 235

YOLO11改进策略【独家融合改进】| RCSOSA + SPD + WFU

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。WFU模块通过小波变换的频率分解与跨尺度融合机制,解决了传统上采样过程中的混叠和细节丢失问题,实现了高效、高保真的面部细节重建。

Limiiiing的博客 453

京东双十一超级折扣 当当旗舰店驱动书

手把手教你学Linux设备驱动开发」点击链接直接打开 或者复制文案打开京东。

BeiJingXunWei的博客 184

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

AI 如何接进 LabVIEW:链路怎么搭、边界在哪、还差什么

这篇讨论的是:如果让 AI 真正连进 LabVIEW 开发环境,链路该怎么搭、边界在哪,以及从开源 demo 走到可交付系统还差哪些工程工作。阅读说明:本文基于公开开源项目与通用工程方法整理,用于技术选型讨论,不代表已完成的客户案例、已交付系统或实测性能指标。文中能力模块是常见需求分类,具体范围与指标需按实际工况沟通与验收确认。

bjcyck的博客 133

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Linux下i2c标准驱动开发流程

i2c_driver。

大道之行,始于足下 356

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

芯参谋(103):Zephyr 驱动开发指南

本文系统阐述Zephyr环境下存储器件驱动移植的核心方法论,聚焦“何时复用、何时自研”这一关键问题,通过分层架构解析(设备驱动层与框架层对接)、官方驱动可复用性判断(基于JEDEC ID表)及典型路径选择(SPINOR走MTD、NAND走坏块管理、eMMC走块设备),指导开发者高效完成SPINOR/SPINAND等器件的移植。内容涵盖驱动骨架搭建、binding设计、初始化等级配置、命令层实现、页边界处理、擦除超时管理及上板联调流程,强调参数表提取、时序校验与错误传播规范,最终形成可量产落地、可上游提交的高

qq520131714的专栏 100

【正点原子Linux连载】第十九章 设备树下的platform驱动编写 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南

第133~182行,platform下的 probe函数:led_probe,当设备树中的设备节点与驱动之间匹配成功会先去初始化pinctrl里面配置的IO,也就是根据示例代码19.1.1.1中的属性进行配置,然后再执行probe函数,第140行调用led_gpio_init函数时,将pdev->dev.of_node作为参数传递到函数中,platform_device结构体中内置了一个device结构体类型的成员变量dev。首先修改设备树文件,加上我们需要的设备信息,本章我们就使用到一个LED0。

weixin_55796564的博客 77

RS485半双工通信模块驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

本文详细分析了RK3568平台RS485串口在单板自发自收失败的常见原因,强调半双工特性下A/B悬空或无对端时RX为空属正常现象。重点指出:write成功仅表示数据进入UART FIFO,不代表信号已发送;需通过A/B短接回环验证链路通断;正确配置DE/RE控制(GPIO或硬件自动方向)、设备树、权限及串口参数;避免与RS232混淆。推荐使用uart_rs485.c工具进行完整测试,确保收发器供电、极性正确、tcdrain完成,最终以“发回显”作为过单板标准。

wanwuzhineng_01的博客 457

【正点原子Linux连载】 第十三章 Linux按键输入实验 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南

本章我们实现按键输入,在驱动程序中使用一个整形变量来表示按键值,应用程序通过read函数来读取按键值,判断按键有没有按下。也就是模拟按键按下,GPIO3_C5为高电平,松开按键为低电平。注意,本章例程只是为了演示Linux下GPIO输入驱动的编写,实际中的按键驱动并不会采用本章中所讲解的方法,Linux下的input子系统专门用于输入设备!第120~131行,key_open函数通过调用keyio_init函数来始化按键所使用的IO,应用程序每次打开按键驱动文件的时候都会初始化一次按键IO。

weixin_55796564的博客 209

Swarm-Rebuild-详细说明

一个 Chrome 扩展:点一下,当前网页会淡出成空白画布,然后一群"多人协作光标"像设计团队一样,把页面一格格重新画回来。纯视觉表演,不改动你的页面。

我的开源项目:https://gitee.com/derekgo/vue-cms_xg 444
上一篇: STM32N6 NPU加速YOLOv8人脸检测实战:从模型量化到边缘部署全解析
下一篇: Qt项目从x86 Ubuntu迁移至ARM树莓派:交叉编译避坑实践
sql99
博客等级 码龄19年 168粉丝 1905原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值