软件开发相关技术与经验分享
1. 构建路径与脚本
在软件开发构建过程中,可使用由环境变量指定基础路径的绝对路径进行构建。例如,当
ARDUINO_TOOLS=c:\Progra~2\Ardunio
时,构建路径如下:
$ARDUINO_TOOLS$/hardware/arduino/cores/arduino
同时,还指定了特定于
'cpp1'
变体的目录:
[cpp11] src/Cpl/System/_cpp11
并且会构建以下文件中指定的所有目录(相对于构建目录):
../../../libdirs.b
此外,NQBP 提供了一些额外脚本,用于支持或利用 NQBP 引擎,如下表所示:
| 脚本 | 描述 |
| — | — |
| bob.py | 递归构建多个项目或测试的工具,只能在
projects/
和
tests/
目录树中运行,可通过选项过滤和指定要构建的项目或测试。例如,
c:\work\pim\tests>bob.py vc12 -gt
仅构建使用 Visual Studio 编译器的测试,并将
-gt
选项传递给
nqbp.py
构建脚本。 |
| chuck.py | 递归运行可执行文件或脚本的工具,只能在
projects/
和
tests/
目录中运行,同样可通过选项过滤和指定要运行的可执行文件或脚本。例如,
c:\work\pim\tests>chuck.py --match a.exe --dir vc12 --loop 10
将执行所有使用 Visual Studio 编译器构建的
a.exe
单元测试十次。 |
| tca.py | 用于调用
gcovr
工具生成代码覆盖率报告和指标的包装脚本。例如,
tca.py rpt --filter .*Cpl/Container.*
为
Cpl::Container
模块或命名空间生成覆盖率指标。该脚本需在单元测试可执行文件至少运行一次后执行。在 PIM 仓库中,只有
mingw_w64 32-bit
构建配置为可生成代码覆盖率指标。 |
在 PIM 仓库中,
env.bat
和
env.sh
脚本为
bob.py
和
chuck.py
脚本创建宏(或别名),允许在不指定路径或不将其路径添加到系统命令路径的情况下调用这些脚本。
2. Colony 相关库
-
Colony.core :是一个 C++ 类库,提供基本系统服务和操作系统抽象层(OSAL),是温控器示例的基础。它在 GitHub 上有自己的仓库(https://github.com/johnttaylor/colony.core),并已直接集成到 PIM 仓库中。其提供的功能如下表所示:
| 服务 | 描述 |
| — | — |
| Cpl::Checksum | 包含校验和、CRC 和哈希类的集合。 |
| Cpl::Container | 各种类型容器的类,所有容器使用侵入式列表机制。即放入容器的每个项都包含在容器中所需的内存和字段,插入项时不分配内存,所有容器在有足够 RAM 的情况下可包含无限数量的项。但侵入式容器有两个主要副作用:所有放入容器的项或类必须继承自基类Cpl::Container::Item;给定项最多只能在一个容器中。 |
| Cpl::Dm | 数据模型框架,提供多线程的数据模型架构模式框架,具有类型安全、原子操作、变更通知、独立的有效/无效状态、支持应用特定的无效代码、数据可持久存储、支持序列化、命令行调试 shell 支持、锁定、关联静态数据和类型信息等特性,该框架也可用于裸机应用。 |
| Cpl::Io | 用于从流和文件读写数据的通用接口,本质上提供了与 POSIX 文件描述符或 Windows 文件句柄通常执行的操作的平台无关接口。 |
| Cpl::Itc | 用于基于消息的线程间通信(ITC)以及事件标志的类。ITC 消息机制是客户端 - 服务器模型,消息可异步或同步发送,数据通过有效负载共享,使用所有权约定提供线程安全访问,不使用动态内存,消息和有效负载类型安全。ITC 事件标志机制中,每个线程支持最多 N 个唯一事件标志,事件标志在线程间不唯一,可将单个事件标志视为二进制信号量,线程可等待至少一个事件被信号,信号触发后,处于“信号”状态的所有事件将被清除。 |
| Cpl::Json | JSON 解析器和格式化器,是用于序列化和反序列化 JSON 字符串的第三方文件,针对 Arduino 平台,但可在任何平台上工作,具有无malloc选项。 |
| Cpl::Math | 与数值操作相关的类和实用程序。 |
| Cpl::Memory | 允许应用程序手动管理动态内存而不依赖实际堆的接口。 |
| Cpl::Persistent | 非易失性数据的基本持久存储机制,将持久数据组织成记录,应用程序负责定义记录的数据内容,启动时读取记录,所有持久存储的数据都进行校验和以检测数据损坏,记录实例负责在检测到数据损坏时默认其数据并更新持久介质,该子系统独立于物理持久存储介质,记录服务器可处理无限数量的记录,也可有多个记录服务器实例。 |
| Cpl::System | 与程序执行相关的抽象和类的平台无关基础,是基本的操作系统抽象层(OSAL)接口,设计用于支持多线程应用程序,也提供了裸机、无需线程的实现。 |
| Cpl::Text | 提供另一个字符串类和额外文本处理的实用程序,Cpl::Text::String类与其他字符串类的不同之处在于它支持“零动态内存分配”接口和实现,也有在不需要严格内存管理时使用的动态内存实现。 |
| Cpl::TShell | 可用于与应用程序交互的基于文本的命令 shell 框架,如调试 shell 可提供对运行应用程序的白盒访问,但它只是一个框架,应用程序需负责将其连接到应用程序并提供特定于应用程序的命令。 | -
Colony.Apps :是温控器示例的原生 GitHub 仓库(https://github.com/johnttaylor/colony.apps),已集成到 PIM 仓库以简化示例代码的使用。最初,该仓库旨在包含基于其他
Colony.*仓库构建的多个示例应用程序,目前唯一的示例应用程序是温控器示例。 -
Colony.Arduino :是另一个在 GitHub 上的
Colony.*仓库(https://github.com/johnttaylor/colony.arduino),已集成到 PIM 仓库。它为Colony.*生态系统提供对多个 Arduino 板和库的支持,在 PIM 中,为 Grand Central M4 板提供 BSP,并为与 Grand Central M4 板一起使用的 LED 盾牌提供 NeoPixel 库。
3. RATT 自动化测试工具
RATT 是基于 Python 的自动化测试工具,构建于 Python
pexpect
包之上,也是一个 GitHub 仓库(https://github.com/johnttaylor/ratt)。PIM 仓库使用 RATT 工具在模拟时间内运行自动化集成测试,以测试控制算法。RATT 专为支持命令行界面的被测单元(UUT)进行自动化测试而创建,但也可用于任何与启动它的父进程支持交互行为(如
stdio
)的应用程序。其特点如下:
- 是纯 Python 模块,可在 Windows 和 Linux 上运行。
- 除运行脚本外,还有交互式模式。
- 可列出所有可用脚本并为每个脚本提供帮助。
- 测试脚本用 Python 编写。
- 测试脚本可位于任何位置和多个位置。
- 可与通过以下方式连接的 UUT 一起工作:
- 串口
-
stdio
(即控制台应用程序)
- Telnet/SSH(需要 Telnet 客户端应用程序)
4. 软件开发规则
在软件开发过程中,有一些经验总结出的规则值得遵循:
1.
Never trust the software guys
:软件开发者的代码总会有 bug,他们不擅长估算工作量,优先级可能与项目经理不一致,要么过于认真追求完美,要么不够认真不重视测试。使用此规则提醒大家软件开发者也是人,工作存在不完美之处。
2.
Software is not soft, it’s hard
:软件复杂、具有挑战性且耗时,需要专业技能。在嵌入式领域,软件开发常被视为次要活动,许多利益相关者不理解软件开发过程,因此开发者除了开发软件,还需花费时间和精力向他人解释为何开发耗时比预期长。
3.
“Similar but different” is still different
:软件开发中,不要因为有了某个工具或框架就用它处理所有类似但不同的事情,如不能将正方形和矩形同等对待,应遵循里氏替换原则(LSP)。
4.
The hardware is always late
:硬件开发困难,交货时间长,印刷电路板组件(PCBA)成本高。
5.
There are always new requirements
:软件需求总是在变化,应接受变化并设计出“容忍变化”的方案。同时,80% 的代码通常不会改变,但 20% 可能会意外改变,因此可假设所有代码都会改变来应对未来的变化。
6.
Don’t ask open - ended questions
:客户往往不知道自己想要什么,询问开放式问题会导致需求不断变化,项目难以完成。因此,只提供选项 A 或选项 B 供客户选择,不要提供选项 C。
7.
Testers are your friends
:测试团队和开发团队之间存在紧张关系,但友好的测试人员可提前告知问题,让开发者有机会在问题公开前解决或找出根本原因,而疏远的测试人员会给开发者带来麻烦。
8.
Just move the cursor to the right
:大多数软件开发人员在编写文档时会感到困难,可先不考虑格式、语法和逻辑顺序,直接开始输入内容,之后再进行组织、格式化和润色。
9.
They only remember the number, never the preconditions
:在向管理层汇报时,即使说明了时间等数字的前提条件,他们往往只记住数字。因此,即使经理要求非约束性的工作完成时间预估,给出的答案也会被视为具有约束力。
10.
Money is always an issue
:在项目规划中,不要假设超出当前预算分配的额外资金会可用,因为即使计划通过投入资金解决问题,但实际可能无法获得资金,而利益相关者对项目进度的期望不会改变。
11.
Never believe never
:不要相信利益相关者、营销人员等所说的“产品永远不需要做 X”,很多时候原本认为不需要的功能后来会变成必须具备的功能。
12.
All developers are not created equal
:开发者是个体,在经验、兴趣、能力和技能(包括技术和个人方面)上存在差异,不要假设同事和自己一样,要做好应对人员差异的准备。
13.
If you can’t write it down, you can’t code it
:如果不能用自然语言和图表描述设计,就无法正确编码,也难以让他人理解。设计功能时,如果难以编写设计文档或注释,可能需要更深入思考问题。如果说出来都不合理,就应该重新开始设计。
综上所述,在软件开发中,合理运用相关工具和技术,遵循经验规则,有助于提高开发效率和软件质量。
软件开发相关技术与经验分享(续)
5. 规则的应用与影响分析
为了更清晰地理解这些软件开发规则的实际应用和影响,我们可以通过一些具体的流程图和进一步的分析来探讨。
5.1 需求变更处理流程
graph LR
A[接收需求] --> B{是否有新需求?}
B -- 是 --> C[评估变更影响]
B -- 否 --> D[按原计划开发]
C --> E{是否接受变更?}
E -- 是 --> F[调整设计以适应变化]
E -- 否 --> G[与客户沟通协商]
F --> H[重新规划进度]
G --> B
H --> D
在这个流程图中,体现了“ There are always new requirements ”规则的应用。当有新需求出现时,需要评估其对项目的影响,决定是否接受变更。如果接受,就要调整设计并重新规划进度;如果不接受,则需要与客户沟通协商。这一流程有助于在需求不断变化的情况下,保持项目的有序进行。
5.2 提问策略对项目的影响
| 提问方式 | 结果 | 原因 |
|---|---|---|
| 开放式问题 | 需求不断变化,项目周期延长 | 客户往往不清楚自己的需求,开放式问题会引出更多不确定的需求 |
| 封闭式问题(A 或 B) | 需求相对明确,项目进度可控 | 限制了客户的选择,减少了需求的不确定性 |
这张表格说明了“ Don’t ask open - ended questions ”规则的重要性。通过合理的提问方式,可以有效控制项目的需求范围,提高项目的成功率。
6. 工具与库的协同使用
在软件开发中,NQBP 脚本、Colony 相关库和 RATT 测试工具并不是孤立使用的,它们可以相互协同,提高开发效率和软件质量。
6.1 开发流程示例
graph LR
A[项目初始化] --> B[使用 bob.py 构建项目]
B --> C[使用 Colony.core 进行开发]
C --> D[使用 chuck.py 运行测试]
D --> E{测试是否通过?}
E -- 是 --> F[使用 tca.py 生成代码覆盖率报告]
E -- 否 --> C
F --> G[使用 RATT 进行自动化集成测试]
G --> H{集成测试是否通过?}
H -- 是 --> I[项目完成]
H -- 否 --> C
这个流程图展示了如何将 NQBP 脚本、Colony 相关库和 RATT 测试工具结合使用。首先使用
bob.py
构建项目,然后基于
Colony.core
进行开发。开发过程中使用
chuck.py
运行单元测试,通过后使用
tca.py
生成代码覆盖率报告。最后使用 RATT 进行自动化集成测试,确保软件的整体质量。
6.2 各工具和库的优势互补
| 工具/库 | 优势 | 与其他工具/库的互补点 |
|---|---|---|
| NQBP 脚本 | 方便项目构建和测试管理 | 为 Colony 相关库的开发和测试提供构建和执行环境 |
| Colony.core | 提供丰富的系统服务和抽象层 | 为 RATT 测试提供稳定的软件基础,便于编写测试用例 |
| RATT 测试工具 | 自动化测试能力强 | 验证 Colony 相关库开发的软件的功能和性能,确保 NQBP 脚本构建的项目质量 |
通过这种优势互补,开发者可以更高效地完成软件开发项目,减少错误和提高软件的可靠性。
7. 开发者个人成长与团队协作
软件开发不仅仅是技术的运用,还涉及到开发者的个人成长和团队协作。
7.1 开发者个人成长
开发者应该根据“ All developers are not created equal ”规则,认识到自己的优势和不足,有针对性地进行学习和成长。例如,如果在文档编写方面存在困难,可以遵循“ Just move the cursor to the right ”规则,多练习写作,提高文档编写能力。同时,要不断学习新的技术和知识,提升自己在软件开发各个方面的能力。
7.2 团队协作
在团队协作中,要充分理解和运用这些规则。例如,“ Testers are your friends ”规则提醒开发者要与测试人员建立良好的合作关系,积极沟通,共同解决问题。“ They only remember the number, never the preconditions ”规则则要求开发者在与管理层沟通时,更加清晰地表达自己的观点和前提条件,避免误解。
8. 总结与建议
在软件开发过程中,合理运用各种工具和技术,遵循经过实践总结的规则,对于提高开发效率、保证软件质量和促进团队协作都具有重要意义。以下是一些具体的建议:
-
工具使用
:熟练掌握 NQBP 脚本、Colony 相关库和 RATT 测试工具的使用方法,根据项目需求合理选择和组合使用这些工具。
-
规则遵循
:在项目的各个阶段,严格遵循软件开发规则,如在需求获取阶段采用封闭式提问,在开发过程中注重文档编写等。
-
团队协作
:加强团队成员之间的沟通和协作,充分发挥每个成员的优势,共同应对软件开发中的各种挑战。
通过不断地实践和总结,开发者可以更好地应对软件开发中的各种问题,推动项目的顺利进行。
超级会员免费看

被折叠的 条评论
为什么被折叠?



