(图片来源网络,侵删)
一 背景刚从学校出来实习那会儿,在深圳南山某龙电控公司上班,职位是售后维修,用伺服电机控制绣花机,有个显示终端应该用的是桌面系统一进公司就开始修板子,在经过一番培训之后就出去驻场服务,看到软件开发工程师来支持我们的工作,他们没什么头发,大部分都戴着眼镜,看上去很厉害的样子,他们拿着示波器的探头,拿着万用表打到二极管档位,测量线路的通断,当时真的很想成为这样的人二 毕业后换工作 来到我人生中最重要的一家公司,有个老同事真的很热心,手把手教我怎么看原理图,为什么控制这个IO为高电平,三极管就输出低电平,为什么电磁阀可以动起来,怎么控制继电器,怎么写代码怎么画原理图,怎么画PCB板,一条龙服务毫无保留地非常耐心地指导我,部门经理在下班后,等我们吃完饭手把手教我们怎么用java与下位机通信,怎么创建线程,那段时光真的很美好,把我带进了软件开发行业三 感谢非常感谢过去帮助过我的人,这个社会真的需要你们这样的人,特别是刚毕业的学生,进到这样一家公司真的是很不错的选择四 嵌入式软件开发流程因为大部分做的是嵌入式开发,所以是按照这个话题来开展4.1 好的软件深受4个人的喜爱和1个人的无奈4.1.1 老板通常老板都喜欢又快又好,交期快,订单量大前期应该达不到,但有了良好的框架后理论上是可以达到这种效果的4.1.2 多个用户傻瓜式操作、操作一步到位、快速上手、大量通俗易懂的手册、查阅文档自助解决问题、视频教程、技术支持快速响应(客服机器人)、稳定可靠不会崩溃满足一个用户是比较简单的,但是同时满足不同的用户就比较困难了,在技术支持方面我们需要引导用户自助解决问题、提供通俗易懂的用户手册4.1.3 同事代码风格和编程思想良好、命名方式通俗易懂、有注释、良好的设计架构、阅读代码不会难受、有丰富的通俗易懂的技术文档,易于更新维护、易于跨平台移植、没有潜在的BUG4.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,voidparameter)可以不断地扩展新功能-接口函数中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 项目资料存档,输出测试文档七 总结以上是我以个人工作经验做的总结,不过我们的能力再好也要先提高自己的沟通能力,良好的沟通能力能够让我们打开彼此的心扉,让家庭更加和谐,让我们与朋友同事相处的更加融洽,让我们更好地开展工作,最大限度的发挥我们的工作经验和个人能力心有多大舞台就有多大,我现在也成了嵌入式软件工程师,但我还有更大的梦想,希望大家大胆去想象,大胆去挑战,一起努力去做到心想事成
0 评论