PX4模块设计之十六:Hardfault模块

2023-05-16

PX4模块设计之十六:Hardfault模块

  • 1. Hardfault模块初始化
  • 2. Hardfault模块主程序
  • 3. Hardfault命令
    • 3.1 hardfault_check_status
    • 3.2 hardfault_rearm
    • 3.3 genfault
    • 3.4 hardfault_commit
    • 3.5 hardfault_increment_reboot
  • 4. BBSRAM设备
  • 5. 总结
  • 6. 参考资料

1. Hardfault模块初始化

nsh_main之前的启动过程可参考:PX4模块设计之十:PX4启动过程。Hardfault是通过启动脚本进行启动的。

注:这个模块主要使用了电池供电情况下SRAM持续保持数据的特性,从而保证系统异常宕机后,再次重启仍能获取宕机时的异常情况(通常这种临界异常无法保存在日志中)。

nsh_main
 └──> nsh_initialize
     └──> boardctl(BOARDIOC_INIT, 0)
         └──> board_app_initialize
             └──> board_hardfault_init
                 └──> stm32_bbsraminitialize(BBSRAM_PATH, filesizes);  // "/fs/bbr", The path to the Battery Backed up SRAM
                     └──> stm32_bbsram_probe
                         └──> register_driver(devname, &stm32_bbsram_fops, 0666, &g_bbsram[i]);


static const struct file_operations stm32_bbsram_fops =
{
  .open   = stm32_bbsram_open,
  .close  = stm32_bbsram_close,
  .read   = stm32_bbsram_read,
  .write  = stm32_bbsram_write,
  .seek   = stm32_bbsram_seek,
  .ioctl  = stm32_bbsram_ioctl,
  .poll   = stm32_bbsram_poll,
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
  .unlink = stm32_bbsram_unlink,
#endif
};

启动脚本类似如下:

if [ $SDCARD_AVAILABLE = yes ]
then
	if hardfault_log check
	then
		set STARTUP_TUNE 2 # tune 2 = ERROR_TUNE
		if hardfault_log commit
		then
			hardfault_log reset
		fi
	fi
fi

2. Hardfault模块主程序

hardfault_log_main
 ├──> <command:check>
 │   └──> hardfault_check_status
 ├──> <command:rearm>
 │   └──> hardfault_rearm
 ├──> <command:fault>
 │   └──> genfault
 ├──> <command:commit>
 │   └──> hardfault_commit
 ├──> <command:count>
 │   └──> hardfault_increment_reboot false
 └──> <command:reset>
     └──> hardfault_increment_reboot true

3. Hardfault命令

hardfault_log <command> [arguments...]
 Commands:
   check         Check if there's an uncommitted hardfault

   rearm         Drop an uncommitted hardfault

   fault         Generate a hardfault (this command crashes the system :)
     [0|1]       Hardfault type: 0=divide by 0, 1=Assertion (default=0)

   commit        Write uncommitted hardfault to /fs/microsd/fault_%i.txt (and
                 rearm, but don't reset)

   count         Read the reboot counter, counts the number of reboots of an
                 uncommitted hardfault (returned as the exit code of the
                 program)

   reset         Reset the reboot counter

3.1 hardfault_check_status

检查是否有未提交的hardfault记录,如果有就打印输出。

hardfault_check_status
 ├──> int fd = hardfault_get_desc(caller, &desc, true);
 ├──> <fd == -ENOENT>
 │   └──> hfsyslog(LOG_INFO, "Failed to open Fault Log file [%s] (%d)\n", HARDFAULT_PATH, ret);
 ├──> <fd == -EIO>
 │   └──> hfsyslog(LOG_INFO, "Fault Log is Armed\n");
 └──> <else>
     ├──> int rv = close(fd);
     ├──> <rv < 0>
     │   └──> hfsyslog(LOG_INFO, "Failed to Close Fault Log (%d)\n", rv);
     └──> <else>
         ├──> hfsyslog(LOG_INFO, "Fault Log info File No %" PRIu8 " Length %" PRIu16 " flags:0x%02" PRIx16 " state:%d\n", desc.fileno, desc.len, desc.flags, state);
         ├──> <state == OK>
         │   ├──> format_fault_time(HEADER_TIME_FMT, &desc.lastwrite, buf, arraySize(buf));
         │   ├──> identify(caller);
         │   ├──> hfsyslog(LOG_INFO, "Fault Logged on %s - Valid\n", buf);
         └──> <else>
             └──> rv = hardfault_rearm(caller);

3.2 hardfault_rearm

删除内存中的hardfault数据。

hardfault_rearm
 ├──> int rv = unlink(HARDFAULT_PATH);
 ├──> <rv < 0>
 │   └──> hfsyslog(LOG_INFO, "Failed to re arming Fault Log (%d)\n", rv);
 └──> <else>
     └──> syslog(LOG_INFO, "Fault Log is Armed\n");

3.3 genfault

略,模拟产生一个除以0的异常,导致系统宕机。

3.4 hardfault_commit

将电池供电持续保持内存中的异常数据转存到crashdump文件和ULog文件。

hardfault_commit
 ├──> ret = hardfault_get_desc(caller, &desc, false);
 ├──> <ret < 0>
 │   └──> return
 ├──> state = (desc.lastwrite.tv_sec || desc.lastwrite.tv_nsec) ?  OK : 1;
 ├──> int rv = close(fd);
 ├──> <rv < 0>
 │   ├──> hfsyslog(LOG_INFO, "Failed to Close Fault Log (%d)\n", rv);
 │   └──> return
 ├──> <state != OK>
 │   ├──> hfsyslog(LOG_INFO, "Nothing to save\n");
 │   ├──> ret = -ENOENT;
 │   └──> return
 ├──> format_fault_file_name(&desc.lastwrite, path, arraySize(path));
 ├──> hardfault_write(caller, fdout, HARDFAULT_FILE_FORMAT, true);  //该函数内部将会unlink hardfault文件
 └──> hardfault_append_to_ulog(caller, fdout);

3.5 hardfault_increment_reboot

重启计数

hardfault_increment_reboot
 ├──> int fd = open(HARDFAULT_REBOOT_PATH, O_RDWR | O_CREAT);
 ├──> <fd < 0>
 │   ├──> hfsyslog(LOG_INFO, "Failed to open Fault reboot count file [%s] (%d)\n", HARDFAULT_REBOOT_PATH, ret);
 │   └──> return
 ├──> <reboot false>
 │   └──> [count++,并写入BBSRAM设备0]
 └──> <reboot true>
     └──> [count重置0,并写入BBSRAM设备0]

4. BBSRAM设备

总共是5个BBSRAM设备,使用用途如下:

  1. 【4字节】计数
  2. 【384字节】当前飞行参数拷贝A
  3. 【384字节】当前飞行参数拷贝B
  4. 【64字节】当前ULog全路径文件名
  5. 【剩余字节】宕机日志

注:STM32F7设备默认是4K字节(STM32F7_BBSRAM_SIZE 4096)。

#define HARDFAULT_REBOOT_FILENO 0
#define HARDFAULT_REBOOT_PATH BBSRAM_PATH "" STRINGIFY(HARDFAULT_REBOOT_FILENO)
#define HARDFAULT_ULOG_FILENO 3
#define HARDFAULT_ULOG_PATH BBSRAM_PATH "" STRINGIFY(HARDFAULT_ULOG_FILENO)
#define HARDFAULT_FILENO 4
#define HARDFAULT_PATH BBSRAM_PATH "" STRINGIFY(HARDFAULT_FILENO)


#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) || \
    defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
#  define STM32F7_BBSRAM_SIZE 4096
#else
#  error "No backup SRAM on this STM32 Device"
#endif

#define HARDFAULT_MAX_ULOG_FILE_LEN 64 /* must be large enough to store the full path to the log file */

#define BBSRAM_SIZE_FN0 (sizeof(int))
#define BBSRAM_SIZE_FN1 384     /* greater then 2.5 times the size of vehicle_status_s */
#define BBSRAM_SIZE_FN2 384     /* greater then 2.5 times the size of vehicle_status_s */
#define BBSRAM_SIZE_FN3 HARDFAULT_MAX_ULOG_FILE_LEN
#define BBSRAM_SIZE_FN4 -1


/* The path to the Battery Backed up SRAM */
#define BBSRAM_PATH "/fs/bbr"
/* The sizes of the files to create (-1) use rest of BBSRAM memory */
#define BSRAM_FILE_SIZES { \
		BBSRAM_SIZE_FN0,   /* For Time stamp only */                  \
		BBSRAM_SIZE_FN1,   /* For Current Flight Parameters Copy A */ \
		BBSRAM_SIZE_FN2,   /* For Current Flight Parameters Copy B */ \
		BBSRAM_SIZE_FN3,   /* For the latest ULog file path */        \
		BBSRAM_SIZE_FN4,   /* For the Panic Log use rest of space */  \
		0                  /* End of table marker */                  \
	}

5. 总结

总体上看,这个BBSRAM设备主要用途就是记录coredump数据,类似系统的一个黑匣子。

注:配合ULog日志和之前做基站固件的时候所做的【基站软件Linux技术验证和分析:黑匣子技术】非常接近,只不过当时有多级Boot和版本管理回退等底层考虑。

6. 参考资料

【1】PX4开源软件框架简明简介
【2】PX4 Hardfault模块

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4模块设计之十六:Hardfault模块 的相关文章

随机推荐

  • BetaFlight开源工程结构简明介绍

    BetaFlight开源工程结构简明介绍 Step1 获取开源代码开源代码版本克隆开源代码 Step2 了解工程情况支持模型类型 xff1a 多旋翼 amp 固定翼支持特性 amp 功能安装 amp 文档链接配置工具下载其他介绍 xff08
  • 四轴FPV无人机手动操作简明介绍

    四轴FPV无人机手动操作简明介绍 通常航拍机都是有自稳算法 43 GPS导航 43 辅助功能 避障 的支持 xff0c 从而保证飞手能够相对容易且稳定的操作模型飞机 xff0c 通常通过阅读说明书都能很快上手 xff0c 这里就不在赘述 本
  • BetaFlight模块设计之三十:Cli模块分析

    BetaFlight模块设计之三十 xff1a Cli模块分析 Cli模块Cli接口Cli框架Cli命令结构主要函数分析cliProcess函数processCharacterInteractive函数processCharacter函数
  • PX4开发环境搭建--模拟器编译及QGroundControl & RC遥控模拟配置

    PX4开发环境搭建 模拟器编译 1 PX4开发环境介绍2 PX4开发环境搭建2 1代码下载2 2 国内环境调整2 3 建立ubuntu开发环境2 4 构建jMAVSim仿真2 5 补充版本信息 3 jmavsim仿真环境3 1 仿真命令集3
  • Android中的枚举

    在ARouter源码中发现使用到了枚举 xff0c 说明枚举并不是不常见的 xff0c 刚好枚举在我的视野中处于盲区 xff0c 于是打算周末加班给拿下 xff0c 扩展视野 了解枚举之前首先说一下什么是常量和变量 常量 声明后无法改变的量
  • PX4开源工程结构简明介绍

    PX4开源工程结构简明介绍 Step1 获取开源代码1 1 开源代码版本1 2 克隆开源代码 Step2 了解工程情况2 1 支持模型类型2 2 支持特性 amp 功能2 3 安装 amp 文档链接2 4 配置工具下载2 5 其他介绍 xf
  • PX4开源软件框架简明简介

    PX4开源软件框架简明简介 1 PX4系统构架1 1 飞控 43 地面站 RC控制1 2 飞控 43 伴飞电脑 43 地面站 集成RC控制 2 PX4软件构架2 1 设计概念2 2 软件构架2 1 中间件2 2 飞控代码 3 PX4运行环境
  • PX4模块设计之一:SITL & HITL模拟框架

    PX4模块设计之一 xff1a SITL amp HITL模拟框架 1 模拟框架1 1 SITL模拟框架1 2 HITL模拟框架 2 模拟器类型3 MAVLink API4 总结 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分
  • PX4模块设计之二:uORB消息代理

    PX4模块设计之二 xff1a uORB消息代理 1 uORB模块接口1 1 uORB服务接口1 2 uORB消息注册 去注册接口1 3 uORB消息发布接口1 4 uORB消息订阅 去订阅接口1 5 uORB辅助功能接口2 Hello W
  • PX4模块设计之三:自定义uORB消息

    PX4模块设计之三 xff1a 自定义uORB消息 1 新增自定义uORB消息步骤2 应用ext hello world消息示例3 编译执行结果4 参考资料 基于PX4开源软件框架简明简介和PX4模块设计之二 xff1a uORB消息代理
  • PX4模块设计之四:MAVLink简介

    PX4模块设计之四 xff1a MAVLink简介 1 MAVLink PX4 应用简介2 MAVLink v2 0新特性3 MAVLink协议版本4 MAVLink通信协议帧4 1 MAVLink v1 0 帧格式4 2 MAVLink
  • PX4模块设计之五:自定义MAVLink消息

    PX4模块设计之五 xff1a 自定义MAVLink消息 1 MAVLink Dialects1 1 PX4 Dialects1 2 Paprazzi Dialects1 3 MAVLink XML File Format 2 添加自定义M
  • PX4模块设计之六:PX4-Fast RTPS(DDS)简介

    64 TOC PX4模块设计之六 xff1a PX4 Fast RTPS DDS 简介 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分析内部模块功能设计 PX4 Fast RTPS DDS 具有实时发布 订阅uORB消息接口
  • PX4模块设计之九:PX4飞行模式简介

    PX4模块设计之九 xff1a PX4飞行模式简介 关于模式的探讨1 需求角度1 1 多旋翼 MC multi copter 1 1 1 RC控制模式1 1 1 1 Position Mode1 1 1 2 Altitude Mode1 1
  • PX4模块设计之十:PX4启动过程

    PX4模块设计之十 xff1a PX4启动过程 1 硬件 飞控硬件上电2 硬件 飞控硬件初始化3 硬件 43 软件 飞控bootloader初始化4 硬件 43 软件 飞控系统初始化5 软件 飞控应用初始化6 配置 SD卡配置文件6 1 e
  • atop安装和使用

    atop就是一款用于监控Linux系统资源与进程的工具 xff0c 它以一定的频率记录系统的运行状态 xff0c 所采集的数据包含系统资源 CPU 内存 磁盘和网络 使用情况和进程运行情况 xff0c 并能以日志文件的方式保存在磁盘中 at
  • PX4模块设计之十一:Built-In框架

    PX4模块设计之十一 xff1a Built In框架 1 Nuttx Built In框架2 PX4 Built In框架2 1 NSH Built In关联文件2 2 NSH Built In关联文件生成2 3 NSH Built In
  • PX4模块设计之十二:High Resolution Timer设计

    PX4模块设计之十二 xff1a High Resolution Timer设计 1 HRT模块特性2 HRT模块基本功能2 1 循环触发接口2 2 延迟触发接口2 3 定时触发接口2 4 其他功能 3 HRT模块精度3 1 精度粒度3 2
  • PX4模块设计之十三:WorkQueue设计

    PX4模块设计之十三 xff1a WorkQueue设计 1 WorkQueue启动2 WorkQueue接口2 1 基本接口2 2 辅助接口2 3 WorkQueue任务函数2 3 1 Flat Build2 3 2 Protected
  • PX4模块设计之十六:Hardfault模块

    PX4模块设计之十六 xff1a Hardfault模块 1 Hardfault模块初始化2 Hardfault模块主程序3 Hardfault命令3 1 hardfault check status3 2 hardfault rearm3