前文链接:(2条消息) 【轻量级开源ROS 的机器人设备(5)】--(2)拟议的框架——µROS节点
五、静态栈分析
在处理运行多个资源的严格受限平台时线程,重要的是将堆栈使用保持在最低限度。这甚至
在利用具有同质堆栈大小的线程池时更为重要,因为这个大小取决于它的任何一个达到的最大堆栈深度工作线程。一个静态堆栈分析工具可以方便地进行估算,如果准确地说,是一组感兴趣的函数的堆栈使用。堆栈分析µROSnode 提供的工具是 urosstan,由 urosstan.py 实现Python 脚本。
5.1 分析流程
编译流程的示意图如图 5.4 所示。用户供给配置文件(清单 B.12 中的实际示例)和静态分析
输出到工具。对于每个入口点,它构建调用图,并且它跟踪具有最大堆栈使用率的路径。该工具然后输出列表未解析的符号、每个入口点的报告和摘要。
5.2 配置
用户必须提供一个配置文件,其中指定了分析选项,以及入口点集、自定义终止符号和源文件映射。
5.3 入口点
对每个入口点进行分析(全局函数名称)在入口点集中列出。每个入口点都分配了一个值,该值表示进入前的堆栈深度。
5.4 终止符
用户可能想要切断一些调用图分支,或者手动定义未解析符号的堆栈使用。例如,外部无法分析库函数或汇编调用,但用户仍然可以提供由这些调用触发器分配的最大字节数。这个方式,调用图分析在到达任何终止符时停止用户提供的符号。
5.5 文件映射
堆栈分析器依赖于 GCC 工具链生成的静态分析。映射集将每个源文件映射到 .gkd、.su 和 .nm 输出;分别是 GCC RTL 转储、GCC 堆栈使用报告和 GNU nm 对象符号。
六、关于有效性的观察
尽管它很有用,但经常存在严重的障碍,这会降低静态分析的有效性。首先,它分析的输出文件GCC 工具链仅适用于 C/C++ 源文件。外部库和程序集GCC 静态分析无法跟踪代码,因此无法构建完整的调用图,或利用一些堆栈使用报告。
此外,在运行时分配的间接函数不能被静态跟踪分析工具。这就是为什么用户应该意识到提供一个有意义的入口点列表。
然而,递归是静态分析无法消除的障碍。工具可以在调用图中发现循环,因此鼓励用户分析他们的循环对运行时堆栈使用的影响。
无论如何,该工具对于发现堆栈上意外深度分配的路径,或者更好地了解所分析代码的整体堆栈使用情况仍然非常有用。这样,用户可以优化局部变量的分配,或尽可能协调堆栈分配。当可以完全访问完全用 C/C++ 编写的源代码时,该工具显示出它的最佳用途。顺便说一句,如果在配置文件中指定所有汇编程序和库函数的使用,仍然可以达到最大精度。如果某些信息丢失但已知被绑定,例如通过它们的全覆盖运行时分析数据,那么分析至少可以报告保守的结果。需要指出的是,urosstan 目前仅支持 C/C++ 代码库的 GCC 工具链,因为这是我们在整个项目开发过程中使用的工具链。如果用户只对整体堆栈分配感兴趣,那么可以使用 GCC 编译纯 C/C++ 代码库并且不进行任何优化,仍然提供粗略的保守分析。如果目标工具链不同,目标代码的等价性很粗糙,但对于初步分析仍然有效。
七、 示范工程
包中提供了一个turtlesim demo,几乎等同于turtlesim_node [7] 官方 ROS 节点。它支持其所有主题、服务和参数,利用了现实生活中 Node.js 所需的几乎所有功能。
海龟的最大数量受 MAX_TURTLES 常量限制。这海龟姿势以 1kHz 更新,并以 100Hz 流式传输。
消息类型和处理程序首先使用配置文件生成如清单 5.18 所示。由于 turtleX/* 主题和服务的名称随着海龟的变化,它们的创建和删除被移动到应用程序(应用程序)模块。该模块处理海龟生成和杀死操作,如以及 /rosout 消息的生成。
静态堆栈分析配置文件如清单 B.12 所示。
该演示分为两个端口:一个是仅使用 POSIX API 开发的,另一个是第二个使用 LWIP 网络堆栈在 ChibiOS/RT 下运行。包含 Eclipse 项目文件。
7.1 项目:turtlesim-posix演示
该演示的所有低级功能都遵循 POSIX 标准。它是在标准笔记本电脑上使用 Linux Mint 14 Nadia 和 Raspbian Wheezy 进行测试在具有 256 MB RAM 的 Raspberry Pi 模型 B 上(参见第 6.1.3节)。当 /turtlesim 节点关闭时,应用程序将退出。
1 # urosgen.py configuration file for turtlesim
2
3 [Options]
4 author = Andrea Zoppi <texzk@email.it>
5 licenseFile = ../../../COPYING
6 includeDir = ../include
7 sourceDir = ../src
8 nodeName = turtlesim
9 fieldComments = false
10
11 [PubTopics]
12 rosout = rosgraph_msgs/Log
13 turtleX/pose = turtlesim/Pose
14 turtleX/color_sensor = turtlesim/Color
15
16 [SubTopics]
17 turtleX/command_velocity = turtlesim/Velocity
18
19 [PubServices]
20 clear = std_srvs/Empty
21 kill = turtlesim/Kill
22 spawn = turtlesim/Spawn
23 turtleX/set_pen = turtlesim/SetPen
24 turtleX/teleport_absolute = turtlesim/TeleportAbsolute
25 turtleX/teleport_relative = turtlesim/TeleportRelative
26
27 [CallServices]
28 # none
Listing 5.18: Turtlesim configuration file for urosgen.py
7.2 项目:turtlesim-chibios+lwip
该演示结合使用了 ChibiOS/RT RTOS 和 LWIP 网络堆栈,并且可以在 ARM Cortex M4 内核上运行。具体是测试过的使用 ChibiOS/RT 2.5.2 和 LWIP 1.4.1。处理器是STM32F407具有以太网功能的定制板(参见第 6.1 节),通过使用 DP83848RM II 模式下的 PHY。 USB口作为串口终端/shell模拟器。当 /turtlesim 节点关闭时,只有 Node 停止运行,而董事会的其他功能继续运行。
八 与用户应用程序集成
µROSnode 被开发为以低的成本集成到用户应用程序中 努力。下面说明了一般的集成要求。
8.1 Makefile 脚本
µROSnode 包提供了一组 Makefile 脚本包含在根 Makefile 中;它们可以在 mk 文件夹中找到。这主脚本 uros.mk 定义了核心源文件和头文件的列表,其中是必要的。
此外,用户必须包含用于目标平台的脚本,这些脚本定义了低级驱动程序源文件和头文件的列表。如果目标平台的某个子系统还不支持,可以通过template/src/lld文件夹中的模板文件进行开发;标有 TODO 的注释给出了正确实施的说明。
8.2 配置 µROSnode
需要为用户应用程序进行配置。应用程序必须包含共享头文件 urosconf.h,并且为 µROSnode 子系统提供设置。模板可以在µROSnode 包的模板/包含文件夹。评论协助
用户调整所需的设置。
8.3 回调
用户模块(参见第 5.2.7 节)需要在 urosUser.c 应用程序源文件中定义一些回调函数。 template/src 中的模板文件有助于开发此类回调函数。
8.4 处理函数
用户应该创建消息类型和处理模块(参见第 5.2.8 节和第 5.2.9 节),以便 µROSnode 可以正确处理主题和服务的消息流。此任务由代码生成器工具协助完成,详见第 5.3.1 节。
8.5 初始化
µROSnode 框架必须通过调用初始化urosInit(),它初始化全局状态。这应该在什么时候完成平台已完全初始化。
实际用户应用程序一运行,节点就会启动。这是通过调用 urosNodeCreateThread() 创建节点线程来完成,它跟踪节点的生命周期;主题、服务和参数是由 Node 线程注册和注销。该线程退出时节点已关闭。