嵌入式软件开发流程(个人心得)

一 背景刚从学校出来实习那会儿,在深圳南山某龙电控公司上班,职位是售后维修,用伺服电机控制绣花机,有个显示终端应该用的是桌面系统。一进公司就开始修板子,在经过一番培训之后就出去驻场服务,看到软件开发工程师来支持我们的工作,他们没什么头发,大部分都戴着眼镜,看上去很厉害的样子,他们拿着示波器的探头,拿着万用表打到二极管档位,测量线路的通断,当时真的很想成为这样的人。二 毕业后换工作 来到我人生中最重要的一家公司,有个老同事真的很热心,手把手教我怎么看原理图,为什么控制这个IO为高电平,三极管就输出低电平,为什么电磁阀可以动起来,怎么控制继电器,怎么写代码怎么画原理图,怎么画PCB板,一条龙服务毫无保留地非常耐心地指导我,部门经理在下班后,等我们吃完饭手把手教我们怎么用java与下位机通信,怎么创建线程,那段时光真的很美好,把我带进了软件开发行业。三 感谢非常感谢过去帮助过我的人,这个社会真的需要你们这样的人,特别是刚毕业的学生,进到这样一家公司真的是很不错的选择。四 嵌入式软件开发流程因为大部分做的是嵌入式开发,所以是按照这个话题来开展4.1 好的软件深受4个人的喜爱和1个人的无奈4.1.1 老板通常老板都喜欢又快又好,交期快,订单量大。前期应该达不到,但有了良好的框架后理论上是可以达到这种效果的。

4.1.2 多个用户傻瓜式操作、操作一步到位、快速上手、大量通俗易懂的手册、查阅文档自助解决问题、视频教程、技术支持快速响应(客服机器人)、稳定可靠不会崩溃满足一个用户是比较简单的,但是同时满足不同的用户就比较困难了,在技术支持方面我们需要引导用户自助解决问题、提供通俗易懂的用户手册。

4.1.3 同事代码风格和编程思想良好、命名方式通俗易懂、有注释、良好的设计架构、阅读代码不会难受、有丰富的通俗易懂的技术文档,易于更新维护、易于跨平台移植、没有潜在的BUG。

4.1.4 自己钱多事少,更新、维护、扩展、移植时只需更改少量代码、或不用改代码,软件测试、领导签字一次性通过,用户使用过程中体验良好,没有收到任何BUG反馈,深受用户喜爱。

4.1.5 软件测试测了半天没有发现一个BUG,功能全部正常,一个版本都没有升,感觉太无聊,没有一点成就感,完全没有发挥他的价值,他会感到很迷茫,甚至开始怀疑人生但是没办法,只能委屈一下他了

五 具体实施方法5.1 现场考察用户需求在开发之前,如果有现成的产品,最好去客户现场了解一下,就像做生意先要踩点记录一下人流量,人均消费水平,房租之类的同样的道理,我们需要知道:5.1.1 用户使用现有产品体验是否良好,操作是否方便,如何改进5.1.2 用户将来会遇到哪些问题5.1.3 用户遇到问题时,如何通过我们提供的资源,他自己独立解决问题用户能够使用文档或者现有功能来自己解决问题,可结合公众号,服务器,数据库5.1.4 总结哪些尚未被满足的、而又被广泛渴望的需求(用户痛点)5.1.5 将以上用户需求转换成规范的开发计划、开发文档(硬件系统框架图、软件功能定义等)

5.2 设计原则5.2.1 开闭原则软件设计应该在满足功能需求的基础上增加一些东西当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求视觉反馈、触感反馈,为什么要有反馈,可能是一个很深奥的话题了,可能跟人体分泌的多巴胺有关系,我不确定。以不变应万变(无论用户需求有什么变化,我们都不用改固件),用户的可变动需求,还可以通过(GPIO)(拨码开关)或者其他通信接口来配置,把配置权交给硬件或者通信接口,交给用户5.2.2 有软件框架和设计模式5.2.3 有分层,做框架之前有个前提条件,要拿到功能定义、硬件系统框架图

分好层之后,分别编译成库文件,后续独立维护相应的库文件即可,便于移植减少维护时地相互影响,改动时不影响其他功能

5.2.4 稳定可靠不出错,不崩溃(访问了空地址、内存溢出、内存泄露、数组越界、堆栈溢出等)

5.2.5 参数检查有输入参数的函数,要有参数检查(排除所有可能的非法值)、错误处理、返回值用户输入是一个非常危险的事情,需要谨慎处理

5.2.6 自定义malloc-不使用库函数malloc动态申请或释放内存创建内存池(静态),自己实现申请和释放的函数-多任务时,需要对公共资源进行原子性访问,防止数据出错

5.2.7 重试机制为了保证数据的有效传输,可能需要加入重试机制

5.2.8 易扩展、易维护更新软件时,更改代码量较少或无需更改代码

5.2.9 抽象变动部分-改宏定义,或者类、静态链表、集合、数组等的定义,不更改过程将未来可能会变的部分抽象出来,定义成数组、静态链表、集合等,使用通用的过程来处理可变的部分-不支持编程语法的将未来可能会变的部分抽象到外部文件(xml,bin),创建动态链表或者动态数组等再触发遍历

-支持编程语法的增加脚本解释器,将未来可能会变的部分抽象到外部脚本文件(asm,lua,js,html,php),创建动态链表或者动态数组等再触发遍历

5.2.10 有使用设计模式,例如工厂模式、创造者模式等

5.2.11 易维护,能够快速定位异常(追溯)

5.2.12 JAVA、VB.NET、C#,不确定C++有这种方法增加全局异常捕捉事件,抛出异常时将具体文件名和行号追加写入日志文件

5.2.13 有调试打印功能单片机可通过串口/LCD/并口(电脑主板)/PCI(电脑主板)来打印,串口/LCD/并口(电脑主板)/PCI(电脑主板)的读写字节函数映射到printf的相关读写字节函数上位机可通过控制台打印,输出到文件或者控制台窗口

5.2.14 软件层级之间通用的接口函数,便于移植跨平台-write2.7.2 read-control(cmd,data,void*parameter)可以不断地扩展新功能-接口函数中void *作为输入参数,可以传递任意类型任意长度的参数5.2.15 必要的错误码帮助客户自主解决问题,依赖于函数有返回值

5.2.16 有自检功能(硬件电路自检)、上电自检(通过指示灯来显示,用于检查IC,硬件电路等)3.1 当出现故障时,可通过系统自检来锁定问题,提示用户排除原因,解决问题能够便于移植(跨平台)的原因

5.2.17 分层设计抽象出通用的类,通用的接口函数,除非资源太少,不能支持面向对象编程思想例如GPIO类有什么属性,有什么接口函数,要兼容所有的平台,就要按照拥有最多的属性来做GPIO类

六 可实施步骤嵌入式软件开发可以遵循一定的流程来执行:6.1 总结用户需求,兼容多个用户的需求6.2 了解现有方案,总结用户痛点(尚未被满足的、而又被广泛渴望的需求)6.3 总结用户可能会遇到的困难6.4 总结如何引导用户解决困难6.4.1 将以上总结转换成规范的开发计划及技术文档6.5 输出功能定义及设计要点(文档)6.6 输出软件框架图(文档)6.7 输出软件流程图(文档)6.8 确认以上文档OK,开始写代码6.8.1 确认好软件测试计划6.9 软件测试(自己)6.10 软件测试(正式),输出测试报告6.11 更新改善6.12 稳定性测试、可靠性测试、极端环境下测试6.13 客户验收6.14 客户现场跟踪,总结已知缺陷6.15 持续改善6.16 项目资料存档,输出测试文档七 总结以上是我以个人工作经验做的总结,不过我们的能力再好也要先提高自己的沟通能力,良好的沟通能力能够让我们打开彼此的心扉,让家庭更加和谐,让我们与朋友同事相处的更加融洽,让我们更好地开展工作,最大限度的发挥我们的工作经验和个人能力。

心有多大舞台就有多大,我现在也成了嵌入式软件工程师,但我还有更大的梦想,希望大家大胆去想象,大胆去挑战,一起努力去做到心想事成。

PHP 扩展开发初探

什么是 PHP 扩展

通俗说,PHP 扩展是增强 PHP 语言功能的插件。PHP 提供了编程语言的语法,比如分支、循环、函数、类等,这些是 PHP 本身所提供的。在某些情况下需要在 PHP 语言的基础上进行扩展,那么就需要通过 PHP 底层提供的数据结构和接口来开发 PHP 扩展,从而来补充或扩展 PHP 语言,使之更加的强大。当然了,PHP 本身就已经集成了一些基本的、强大的、优秀的 PHP 扩展。

PHP 扩展的好处

从上面的了解得知,PHP 扩展可以在 PHP 原有的基础上来扩展 PHP 的功能,使之更为的强大。另一方面,PHP 扩展可以通过“插件式”的方式来管理和维护 PHP 的功能,如果将全部的功能整合到 PHP 语言中,PHP 想必会过于臃肿,且又不够灵活。而有了扩展,就解决了这样的问题。

PHP 扩展的存在形式

在 Linux 系统下,PHP 扩展以 .so 文件存在,在 Windows 下以 .dll 文件存在。

什么时候使用 PHP 扩展

单独的使用 PHP 语言并不能满足所有的开发,比如在项目中使用 Redis 或 MongoDB 时,就需要相应的 PHP 扩展,来增强 PHP 语言,让 PHP 可以来操作 Redis 或者 MongoDB,以完成更加功能强大的项目。

什么时候开发自己的 PHP 扩展

开发自己的 PHP 扩展是必须的么?其实不是。通常情况下,作为一个 PHPer 是不需要自己开发 PHP 扩展的,但是某些情况下可能是必须要开发 PHP 扩展的。比如,我就遇到了这样的问题。合作的第三方提供了 Windows 下的动态链接库文件(.dll 文件,非 COM 的 DLL 文件),而我又没有找到如何在 PHP 下加载调用 DLL 文件的方式,因此我需要写 PHP 扩展,通过 PHP 的扩展来加载和调用第三方提供的 DLL 文件。

开发自己的 PHP 扩展

在前面我已经提到了我遇到的问题,合作的第三方提供了 Windows 下的动态链接库文件,而我又没有找到 PHP 下加载和调用 DLL 文件的方式,因此决定自己编写 PHP 扩展来加载和调用第三方提供的 DLL 文件中的导出函数。以下,就是我对于搭建开发 PHP 扩展环境和编译 PHP 扩展源码的记录。

准备工具

首先说明一点,DLL 文件只能在 Windows 系统上运行,Linux 系统上是无法进行运行的。那么,我们这个扩展是不考虑 Linux 系统的,只考虑 Windows 系统即可。因此,准备的开发工具是 VS2015。起初,我在网上查找了一些资料,很多资料中都写到,在 Windows 下开发 PHP 扩展需要安装 CygWin,经过我自己的学习,可以告诉大家“不需要”。当然了,我们的扩展只在 Windows 系统上运行,如果需要在 Linux 系统上运行,是否需要 Cygwin 我就不得而知了。当然了,其他版本的 VS 也应该是可以的,只是我只测试了 VS2015 罢了。

下载 PHP 的源代码

除了需要安装 VS2015 以外,还需要下载 PHP 的源码,我下载的源码是 PHP 7.2 的源码。

下载 PHP 源码的地址是:https://windows.php.net/download/

打开该地址后,下载如下图所示的源代码:

在这里,下载 PHP 7.2 的源码,并注意在源码下面有一个 VC15 x64 的字样。

下载完的的文件为:php-7.2.20-src.zip

下载完源码进行解压,解压后的目录为:php-7.2.20-src

下载源码并不是一件复杂的事情,但是页面中有多个版本的源码可供下载,选择哪个有时也是比较纠结的问题,这里就下载 php7.2 的源码,因为我本地使用的就是 php7.2 的环境。

创建扩展

进入 php-7.2.20-src\\ext 目录下,在该目录下有一个名为 ext_skel_win32.php 的文件,在命令行中执行:

其中,loaddll 是要创建的扩展的名称。想要成功执行该命令,需要将 PHP 的可执行程序添加到环境变量中。

执行情况如下:

看到如上的输出提示,则说明我们创建的 PHP 扩展生成成功了。以上输出如下所示:

此时,在 \\ext 目录下生成了 loaddll 的目录,该目录是生成出的 PHP 的扩展模板,可以在模板的基础上进行开发。

使用 VS2015 创建扩展项目

打开 VS2015,我这里使用的是 VS2015,其他开发环境没有进行测试。

在 VS2015 中选择 “文件” -> “新建” -> “从现有代码创建项目”,来创建 PHP 扩展的解决方案,如下图:

选择了 “从现有代码创建项目” 后,会出现创建项目的向导,如下图:

直接点击 “下一步”,到如下图:

在此步骤,选择刚才生成的扩展模板的目录,然后填入项目名称,这里是“loaddll”,点击“下一步”,到达如下图:

此步骤选择DLL项目,点击下一步,到达如下图:

直接点击“下一步”,到达如下图:

点击“完成”,等待 VS2015 开始创建项目。

配置编译选项并编译项目

在 VS2015 生成项目完毕后,切换项目为 “Release”和“x64”的选项,如下图:

切换完成后,在项目上右键选择“属性”,如下图:

修改配置类型为 DLL,这样生成的目标文件扩展名自动变为 .dll,如下图所示:

选择“配置属性” -> “C/C++” -> “常规”,在“附加包含目录”中点击“编辑”来添加相关的目录,如下图:

这里需要包含的目录包括如下图的几个目录:

这里主要是添加了 PHP 源码的几个目录,因为编译 PHP 扩展的源码时需要 PHP 的底层内核数据结构进行支持,因此需要包含以上的目录。

选择“配置属性” -> “C/C++” -> “预处理器”,在“预处理器定义”中点击“编辑”来添加相关预处理指令,如下图:

在预处理中,HAVE_LOADDLL 中的 LOADDLL 是扩展的名称,COMPILE_DL_LOADDLL 中的 LOADDLL 同样也是扩展的名称,这个名称与最开始生成扩展模板时的名称应该一致。

编译源代码

把 php-7.2.20-src\\win32\\build\\ 目录下的 config.w32.h.in 复制到 php-7.2.20-src\\main\\ 目录下,并重命名为 config.w32.h,这个 .h 文件在编译时是需要的,但是在 php-7.2.20-src\\main\\ 下并没有该文件,因此需要自己手动进行复制。

在 config.w32.h 中增加如下代码

注意这里的 VC15 ,在下载源代码的时候,我们已经见到过这个标识了。

接着,从 PHP 的安装目录中复制 php7ts.lib 文件到 loaddll 目录下,注意,是从PHP 的安装目录中,而不是 PHP 源代码的目录中。

php7ts.lib 在目录 php7.2.10\\dev 目录下,我使用的是 wamp64 下的 php7.2.10,大家自己使用对应的 .lib 文件即可,当然,这个 .lib 文件也必须是 php7.2 的,因为我们下载的是 php7.2 的源码。

在项目的 resource Files 下添加 php7ts.lib 文件,添加该文件就比较简单了,同样是右键添加即可。

按下 F7 生成解决方案,如图:

看到“成功 1 个”文件以后,在目录 \\php-7.2.20-src\\ext\\loaddll\\x64\\Release 下会生成一个 loaddll.dll 文件,这个文件就是我们的 PHP 扩展文件。

PHP 扩展的安装与测试

将VS2015 生成 loaddll.dll 重命名为 php_loaddll.dll ,将其拷贝到 PHP 环境的扩展中,我的路径是 php\\php7.2.10\\ext,想必熟悉 PHP 的应该都会添加 PHP 扩展。如下图:

在 php.ini 文件中增加配置,如下图:

使用 php -m 来查看是否有 loaddll.dll 模块,如下图:

phpinfo 查看,如下图:

通过上面可以看出,我们的 PHP 扩展已经正常安装了,接下来就需要测试我们的扩展是否可以运行了。

在 PHP 源码目录下 php-7.2.20-src\\ext\\loaddll\\ 有一个 loaddll.php 的测试文件,在命令行下进行执行该命令:

输出内容如下:

如下图:

看到如上输出,说明该扩展的模板编译成功,可以继续开发实际的扩展模块了。

总结

很多时候,学习编程的第一步就是搭建环境,而往往搭建环境的过程中由于步骤过于复杂,而资料又没有傻瓜化的详细步骤,导致很多想要学习或入门的程序员连第一步都无法踏出。对于开发 PHP 扩展而言也是一样的。

如何通过 PHP 扩展来让 PHP 程序可以直接调用 DLL 中的函数,除了需要掌握 C 语言的知识以外,还需要掌握 Windows 程序设计的知识,本文就不再讨论了,因为有 C 语言的知识和 Windows 程序设计的知识,在 PHP 扩展中调用 DLL 并非难事。

希望本文对大家有所帮助!

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。