赞
踩
整理:付斌,转自嵌入式ARM,参考已标注至原文
01
嵌入式系统的概念 着重理解“嵌入”的概念
主要从三个方面上来理解:
1、从硬件上,将基于CPU的处围器件,整合到CPU芯片内部。
比如早期基于X86体系结构下的计算机,CPU只是有运算器和累加器的功能。
一切芯片要造外部桥路来扩展实现,像串口之类的都是靠外部的16C550/2的串口控制器芯片实现。
而目前的这种串口控制器芯片早已集成到CPU内部,还有PC机有显卡,而多数嵌入式处理器都带有LCD控制器,但其种意义上就相当于显卡。
比较高端的ARM类Intel Xscale架构下的IXP网络处理器CPU内部集成PCI控制器(可配成支持4个PCI从设备或配成自身为CPI从设备);还集成3个NPE网络处理器引擎,其中两个对应于两个MAC地址,可用于网关交换用,而另外一个NPE网络处理器引擎支持DSL,只要外面再加个PHY芯片即可以实现DSL上网功能。
IXP系列最高主频可以达到1.8G,支持2G内存,1G×10或10G×1的以太网口或Febre channel的光通道。
IXP系列应该是目标基于ARM体系统结构下由intel进行整合后成Xscale内核的最高的处理器了。
2、从软件上前,就是在定制操作系统内核里将应用一并选入,编译后将内核下载到ROM中。
而在定制操作系统内核时所选择的应用程序组件就是完成了软件的“嵌入”,比如WinCE在内核定制时,会有相应选择,其中就是Wordpad,PDF,MediaPlay等等选择,如果我们选择了,在CE启动后,就可以在界面中找到这些东西,如果是以前PC上将的windows操作系统,多半的东西都需要我们得新再装。
3、把软件内核或应用文件系统等东西烧到嵌入式系统硬件平台中的ROM中就实现了一个真正的“嵌入”。
以上的定义是我在6、7年前给嵌入式系统下自话侧重于理解型的定义,书上的定义也有很多,但在这个领域范围内,谁都不敢说自己的定义是十分确切的,包括那些专家学者们,历为毕竟嵌入式系统是计算机范畴下的一门综合性学科
02
嵌入式系统的分层与专业的分类
嵌入式的定义很模糊,尤其是这几年发展出众多的应用形式,让人摸不着头脑。对于想进入这个地方的新人,有种望而却步的感觉。
嵌入式系统分为4层,硬件层、驱动层、操作系统层和应用层。
1、硬件层,是整个嵌入式系统的根本,如果现在单片机及接口这块很熟悉,并且能用C和汇编语言来编程的话,从嵌入式系统的硬件层走起来相对容易,硬件层也是驱动层的基础。
一个优秀的驱动工程师是要能够看懂硬件的电路图和自行完成CPLD的逻辑设计的,同时还要对操作系统内核及其调度性相当的熟悉的。但硬件平台是基础,增值还要靠软件。
硬件层比较适合于,电子、通信、自动化、机电一体、信息工程类专业的人来搞,需要掌握的专业基础知识有,单片机原理及接口技术、微机原理及接口技术、C语言。
2、驱动层,这部分比较难。
驱动工程师不仅要能看懂电路图还要能对操作系统内核十分的精通,以便其所写的驱动程序在系统调用时,不会独占操作系统时间片,而导至其它任务不能动行,不懂操作系统内核架构和实时调度性,没有良好的驱动编写风格,按大多数书上所说添加的驱动的方式,很多人都能做到,但可能连个初级的驱动工程师的水平都达不到。
这样所写的驱动在应用调用时就如同windows下我们打开一个程序运行后,再打开一个程序时,要不就是中断以前的程序,要不就是等上一会才能运行后来打开的程序。
想做个好的驱动人员没有三、四年功底,操作系统内核不研究上几编,不是太容易成功的,但其工资在嵌入式系统四层中可是最高的。
驱动层比较适合于电子、通信、自动化、机电一体、信息工程类专业尤其是计算机偏体系结构类专业的人来搞,除硬件层所具备的基础学科外,还要对数据结构与算法、操作系统原理、编译原理都要十分精通了解。
3、操作系统层
对于操作系统层目前可能只能说是简单的移植,而很少有人来自已写操作系统,或者写出缺胳膊少腿的操作系统来,这部分工作大都由驱动工程师来完成。
操作系统是负责系统任务的调试、磁盘和文件的管理,而嵌入式系统的实时性十分重要。据说,XP操作系统是微软投入300人用两年时间才搞定的,总时工时是600人年,中科院软件所自己的女娲Hopen操作系统估计也得花遇几百人年才能搞定。因此这部分工作相对来讲没有太大意义。
4、应用层,相对来讲较为容易的。
如果会在windows下如何进行编程接口函数调用,到操作系统下只是编译和开发环境有相应的变化而已。如果涉及Jave方面的编程也是如此的。
嵌入式系统中涉及算法的由专业算法的人来处理的,不必归结到嵌入式系统范畴内。但如果涉及嵌入式系统下面嵌入式数据库、基于嵌入式系统的网络编程和基于某此应用层面的协议应用开发(比如基于SIP、H.323、Astrisk)方面又较为复杂,并且有难度了。
03
嵌入式领域分工的变化
著名嵌入式专家火哥曾经说过,有很多所谓有经验的人认为,嵌入式底层软件和硬件技术是不怎么变化的,经验越多越值钱,越老越吃香。其实这是一种主观机械而又狭隘的经验主义,缺乏全局视野,只看到自己所在领域的一些基础性技术,看不到整个行业和相关学科领域的变化,一叶障目。
其实就拿现代足球和篮球运动作为类比,也是同样的道理。现代足球和篮球的发展历史比什么嵌入式软件,硬件等高科技的发展史还要长久,那种机械经验主义狭隘的观点肯定会认为,打篮球就是学运球,突破,传球,投篮,踢足球就是学传球,停球,带球,铲球,射门,跑位,这都是50年前甚至100年前就有的东西,和现在一样是不变的。然后他们没有看到的是,篮球和足球的战术和位置分工,每隔5-10年就会发生很大的变化。
比如篮球领域从之前的强内线,肌肉棒子的中锋时代演变成小球三分射手时代,内线球员对中远投和三分球能力要求越来越高,以前那种没有射程的大个内线越来越不吃香。
足球领域的分工和战术变化就更多了,从远古一点巴西群星的424 WM阵型个人技术流到意大利链式防守,从经典442阵型,双前锋一高一快或者双高的英式长传冲吊,到第一代433全攻全守的踢法。从4231传统的边锋加经典10号位前腰和扫荡防守型后腰再到西班牙式Tiki-Taka传控足球短传渗透的盛行,再到现在高位逼抢,经典前腰和防守型后腰的消失,全能型B2B中场的吃香。其它位置的球员,例如,逆足边锋内切踢法,伪9号无锋阵,边后卫对助攻能力要求越来越高,而不只是防守对方边锋,中后卫对出球能力要求越高,不只是会防守抢断。而过去那些有了很多成绩和荣誉但是位置单一,不符合现代高位逼抢,灵活换位要求的球员,越来越没有市场。
像现代足球,篮球这种发展了50年到100年的体育运动,看似不变,实际上都经历了如此多的战术和位置分工变化,不同时代对不同位置球员的要求都不一样,更何况近二三十年经历了高速发展的电子信息和嵌入式技术呢?回到正题,分析一下硬件工程师和嵌入式软件工程师的分工和技能要求变迁。
1. 硬件工程师
一开始没有集成电路和数字芯片,要设计一个系统需要用三极管,电阻,电容,电感等分立器件来搭,那时候硬件工程师对模拟电路设计的要求是非常高的,既要精通应用业务逻辑,也要精通模拟电路设计,大家可以看看模电书上经典uC741放大器里面的模拟电路图的复杂程度。
后来有了小规模的模拟和数字芯片(比如uc741放大器,74LS04数字门电路,ne555时钟发生器),硬件工程师就可以使用这些芯片加上一些外围电路来搭建自己的系统,硬件设计门槛有所降低,做出的产品也更加丰富,但是自己还是要精通应用业务逻辑。
再到后来,ASIC和大规模集成电路以及嵌入式编程芯片的出现,很多算法和逻辑控制功能都集成在ASIC芯片里面或者在嵌入式处理器中用编程软件实现。硬件工程师对业务应用业务逻辑的要求大大降低,同时所做的外围电路设计也越来越少,比如电源方面,可以买TI的开关电源芯片加上少量的外围电路,就能实现自己高性能开关电源,无需精通里面各种复杂的控制算法和功率因素补偿等技术。这个时候,有些硬件工程师开始往单片机编程技能方面发展,还有一些硬件工程师往EMC,PCIE,WIFI,USB,DDR等数字和模拟等接口标准认证方面发展,硬件的分工开始细化专业化。
再到当前,芯片原厂提供的不再仅仅提供单独的芯片让硬件工程师设计电路,而是提供现成的基于芯片设计的模块或者turn key解决方案,即插即用,不需要自走PCB打板的流程,就能快速验证自己想法和产品方案。并且原厂提供的这些模块和解决方案,已经做好了安规,车规与EMC等标准认证,更加降低了硬件开发的门槛,提高了开发效率,很多硬件工程师的工作也变成在原厂方案板上修改,验证,抠掉一些冗余器件节约成本,或者剩余的时间要负责供应链和生产管理相关的工作。而从前那些高深的数字,模拟混合电路,分立器件电路设计技术和经验显得无太大用武之地(除了少数芯片设计场合)。
2. 嵌入式软件工程师
20多年前的嵌入式工程师大部分都是用C语言和汇编在8位单片机上开发驱动程序和相对简单的控制和通信系统。那时候单片机功能没有现在这么高级,里面甚至没有ADC, PWM等常用模块,需要搭建很多外围或者电路来丰富产品的功能。那时候的单片机嵌入式开发除了要会编程,对硬件也相对较高,要自己设计通用的硬件原理图,甚至画2层左右的PCB板,只有碰到电源,射频,EMC专业硬件问题的时候,才会需要雇佣专门的硬件工程师来处理。
后来使用复杂一些的32位MCU开发,MCU功能开始变得强大,系统需求也开始复杂化,嵌入式工程师需要开发多个平台驱动乃至上位机应用程序,这个时候,公司一般会雇佣专门的硬件工程师做PCB layout和部分原理图设计工作。嵌入式软件工程师只需要设计硬件原理图的核心功能I/O部分,看懂芯片手册,对嵌入式工程师硬件能力的要求开始降低,大部分精力用于软件开发上。
再后来的嵌入式开发使用DSP处理器和RTOS实时操作系统,硬件部分也变得集成度更高更复杂,嵌入式工程师对硬件方面的掌控和要求也越来越低,仅限于看原理图,配置一些I/O引脚和寄存器,原理图设计基本都交给专门的硬件工程师。但是嵌入式软件这块,做DSP的需要熟悉一些业务算法,做RTOS的要懂得数据结构,操作系统、计算机网络方面的知识。驱动开发也开始变得框架化,模块化而不仅仅限于裸机开发,配置寄存器和简单的业务逻辑。
再到当前,嵌入式大规模使用SOC,跑Linux/Android等复杂操作系统,DSP等专用CPU核也可以集成在SOC中,通过驱动进行调用。嵌入式工程师基本不用参与硬件原理图设计,硬件能力基本不是啥门槛,只要学过电路,模电,数电等教科书知识,看得懂别人I/O部分的原理图就行了。读数据手册配置修改寄存器的活也只有偶尔会用上,因为芯片原厂和Linux开源社区为了推广生态,已经将很多产品级的芯片的驱动程序集成到Linux内核,配置好了寄存器,降低了系统底层软件的使用门槛(这其中有少数嵌入式工程师在原厂从事门槛较高的专业领域驱动开发,比如音视频,GPU,Display,Security等),使得嵌入式工程师把更多的精力集中在具体应用和业务逻辑开发上。
通过上述的一次次技术领域分工的变化,使得嵌入式工程师入行门槛和工作重点也发生了变化,从硬件到原理图I/O设计,到驱动开发到应用业务逻辑。可以说每个部分都有它的技术难点,没有哪个技术比其它技术高尚,我们应该关注当下的重点,善于从各种矛盾中抓主要矛盾,有的放矢地学习提高自己,善于思考主流技术的发展趋势和变化,千万不要被过去的教条所束缚。
04
当前阶段嵌入式技术的重难点
著名嵌入式专家火哥认为,当前阶段嵌入式技术的重难点有三个方面:
1. 以C/C++语言为主的编程能力。
原本C语言编程也不是啥门槛性的大问题,但是因为国内大部分电子信息专业都是以C语言入门,然后选用的国产教材质量参差不齐,代码风格不规范,这就人为地给入门菜鸟创造了门槛。但是只要肯花时间下功夫,学习豆瓣上推荐的几本国外经典的C语言教材,进而学习数据结构,面向对象等计算机基础知识,多练习多写代码来熟练编程技巧,火哥相信这个不会是大问题。
C++方面,以前做单片机,做RTOS的老嵌入式工程师可能基本上都是写C程序,用不上C++。但是现在基于Linux系统的嵌入式开发,重点将会聚焦在复杂业务逻辑应用编程上。在大规模复杂业务逻辑和GUI编程中,使用纯C语言已经力不从心,使用C++开发的嵌入式应用程序的地方将会越来越多。但是C++这个语言本身比较复杂,不能强求像C语言那样掌握95%以上的特性,C++总会有很多语言特性用不上或者不熟练,需要找到合适的项目,在实践中反复练习再回头看书巩固,循序渐进。熟练掌握C++会需要较长的时间,目前一般的要求是掌握基本的面向过程,面向对象编程的编程方法,多用智能指针,复杂的模板编程能看懂就行,不要求掌握所有奇巧淫技。
2. 对计算机体系结构和操作系统相关问题的掌控能力
这一块知识算是计算机基础理论上的难点,虽然相关书籍资料已经汗牛充栋,商业级的Linux内核源代码也能从网上下载,但是要啃下它还是需要耐心。很多做单片机裸机,RTOS开发的嵌入式工程师无法进入Linux开发的世界,多半也是因为Linux操作系统确实有一定难度。对这一块知识,其实并不要求你掌握Linux内核每行源码(这是不可能的),也不要求你能够独立写出一个复杂的产品化的操作系统(也不现实),但是操作系统底层和计算机体系结构基本的工作原理和机制还是要搞清楚,要知道操作系统大概做了什么,是如何处理你的API调用的。
火哥知道这是一块硬骨头,但事在人为,有了这么多资料和实验资料的今天,肯花时间,有耐心,也不应该是大问题。
3. 业务应用能力
为什么我们需要做嵌入式计算机系统,因为嵌入式计算机系统可以根据不同业务场景需求进行裁剪和定制。说到底,业务才是嵌入式系统真正的命根子,不同业务方向嵌入式工程师薪资差异可能会比较大(当然在少数公司,开发操作系统也属于他们的业务)。在企业有话语权有地位的嵌入式工程师所掌握的业务技能一定和企业当前盈利的业务方向高度匹配,充分满足企业的业务需求。
当前嵌入式软件工程师要想提高收入,一定要跟着主流有盈利能力的业务走,提升相关的业务应用技能。当然很多细分业务,不去相关的企业是根本没有机会接触的,热门业务相关的高级资料也不是能够通过网络和入门培训视频轻易获得。所以说当前阶段的业务门槛才是嵌入式在不同领域的真正门槛。学会自己分析,把握当前主流前沿的业务方向,有的放矢地学习提升自己,让自己掌握的知识发挥最大的“钱”力。
05
如何调整自己的学习和职业发展方向
著名嵌入式专家火哥分析了嵌入式领域的现状和重难点之后,那么嵌入式工程师调整自己的学习和职业方向,有以下三点:
1. 不用过于纠结硬件门槛与寄存器配置
毛选《矛盾论》告诉我们事物的背后要搞清楚哪些是主要矛盾,哪些是次要矛盾,处理问题要善于抓主要矛盾。
同理,在当前的嵌入式学习和开发中,硬件门槛与寄存器配置已经不再是主要矛盾,而是影响你解决问题众多次要矛盾之一。真正的主要矛盾是应用业务开发,是对操作系统工作流程的掌控,让操作系统能够很好地支持和配合应用业务实现系统的功能。
那么对待硬件和寄存器配置,固然还是要以客观严谨的态度分析和解决相关的问题,但是不要把太多时间花在硬件原理和数据手册寄存器的学习上,否则这将是一个高投入,低产出的工作。火哥认为硬件相关问题,嵌入式工程师能把大概定位出来,交给专业的硬件工程师处理就行。这点对硬件知识的要求只需要懂得教科书上基本模拟和数字电路知识就行,相对于自己独立设计硬件电路,通过各种标准认证的要求完全不是一个层次的。
2. 不能把编程仅限于嵌入式端
目前的嵌入式复杂业务应用编程和PC端,服务器应用编程的界限其实越来越模糊。嵌入式端应用编程除了某些时候需要利用一些平台特有的硬件和驱动特性,来提升和优化程序性能之外,大部分的工作也是堆业务逻辑代码,只是在不同平台上堆业务代码,用不同的编译器编译而已。
从编程的角度考虑,就不要把编程范围仅仅限制在嵌入式端,在以应用业务为中心的前提下,可以主动尝试开发PC端,服务器端甚至web端的应用程序,还可以把在PC端,服务器端编程用到的新技术因地制宜地移植部署到嵌入式端,做到取长补短的作用,同时也把自己的职业道路越走越宽。
目前,嵌入式端也引入了python编程搭建整套自动化测试系统,很多嵌入式端的测试用例也是用python编写的。很多做STM32, RTOS开发的嵌入式工程师,也不仅限于嵌入式端编程了,因为他们开发的产品很多需要通过物联网接入到云端服务器,有时候他们也要兼顾一些云服务器的应用业务逻辑以及云端和嵌入式端通信协议开发的工作,不再是以前传统意义上的嵌入式开发工程师。
按照这个发展潮流和趋势,火哥可以预言,未来的对嵌入式工程师的技能要求将会弱化硬件技能,在有扎实的操作系统基本功前提下,以业务导向的应用编程为核心,有云端服务器到嵌入式终端的端到端垂直开发能力。
3. 跳槽的时候要有业务升级意识
最后就是要有目的地跳槽,不只是考虑薪资问题,更要考虑下一份工作能接触到的业务知识是不是主流赚钱的业务,未来有没有赚钱的盈利模式,能不能让自己的路越走越宽?平时多关注招聘网站的需要,看看什么样的公司,什么样的业务提供的招聘需求是最多的,要敢于和打价格战,不赚钱的业务和公司说再见,及时跳坑。不要把时间耗在了重复性基础性工作(比如火哥鄙视的万年嵌入式点灯,spi,i2c开发)和不盈利的业务上。
06
嵌入式er要有“一技之长”
有这样一个问题:扫大街重不重要?毫无疑问对于一个城市,这是份至关重要的工作。想想看,如果北京上海纽约东京这样的大城市一个月没有人清扫,试想想会出现什么后果。试想想会有多少瘟疫流行,又会有多少人会死于非命。遗憾的是,对于这么重要的一份工作,许多国家都没有给出一个好的报酬,城市的保洁员往往只能得到最低的薪水。
你可以说一万个“不合理”,但还是解决不了问题。你也可以争取做国会议员,建立新的法案去改变这种这种不合理,但最后你会发现自己无功而返。
“就这么多钱,你干不干;你不干,大把的人干。”简单的说:是因为保洁工作所需要的技能太容易被替代。
做工程师也一样,不仅是IT领域,其他任何领域都一样。如果咱们不具备特殊的技能,就是说,没有一技之长,那么我们怎么能够梦想得到和别人不一样的待遇呢?同样一件事,我请个月薪3000元的新毕业生就能够做,我为什么要花1W5, 2W去请一个七八年工作经验的人呢?我傻吗?我钱没地方烧吗?
有许多朋友,大学毕业六七年了,面试的时候问他的技术特长是什么,有的理直气壮,有的甚至还犹豫了半天,才说出来:“C语言”、“Java语言”!试想想,“xx语言”好的人这个世界上有多少,在北大青鸟培训个十七八个月,是不是“xx语言”会足够强,咱们和他们比有什么优势?
对于自己的优势,这些朋友表达不出来,或者不准确。说白了,就是平时在这方面思考得太少了,因此,自己给自己引导得太少了,几年的功夫,一直随波逐流了。
要搞技术,从走出大学的第一天起,甚至在大学毕业之前,就要清楚,自己的“一技之长”究竟应该建立在哪里。只有这样,才能明确奋斗和努力的方向,进而才有机会把握自己命运,主张自己的价值。
仅仅就嵌入式开发而言,咱们来看看怎么做这个选择。
首先,我们宏观上看看这个领域一般是怎么划分职责的。
产品经理:公司做什么样的产品、在什么时间能够赚多少钱,产品经理必须准确定位出来,否则整个公司都在瞎忙乎。产品经理的核心价值在于准确的产品定义。
项目经理:整个产品的QCT。产品定义与产品的商业计划确定以后,关键就在于产品的实现。项目经理的职责在于控制、协调、执行好产品的开发,使产品准时上市(T),同时满足公司的质量标准(Q)和成本要求(C)。
技术专家:产品需要某个功能,它属于自己负责的领域,技术专家必须给出技术方案,指导该功能的实现,保证该功能的实现满足产品的QCT。
系统构架师:负责产品整个系统的构架和实现方式。保证产品的质量和产品开发的效率。构架师往往还必须考虑开发成果的复用。
软件工程师:交付功能块的代码,保证质量、工期和效率。保证自己交付的代码有效的实现了要求的功能,bug少,容易维护。
接口工程师:协调软件部门与其他部门、以及外包单位之间的互动,保证产品开发的QCT。
开发环境工程师:保证开发工具、纠错工具等开发环境的质量,保证团队的效率。
开发流程改善专员:紧盯组织内外部的协作、保证开发流程的顺利实施、领导开发流程的改善,改善组织的开发效率。
测试工程师:负责产品的验证。开发出来的产品是否符合产品的定义,是否符合业界的标准,保证产品的质量,并且不断提高测试的效率、缩短测试周期。
质量专员:负责产品的质量和流程的质量,应对与总结产品出厂后的质量问题,并通过流程改善来杜绝同类性质问题的重复发生。
部门经理:调配部门的资源保证公司所有产品的QCT;招聘、培养员工以保证部门具备足够的能力满足公司不断变化的需求。
这里罗列了一大堆堆教科书里头写了一万遍的角色。可是,咱们自己到底想成为什么样的角色?要成为这样的角色,到底需要一些什么样的技能,或者“一技之长”,咱们仔细的研究过吗?仔细的研究了以后,针对咱们自己仔细的规划过吗?仔细的规划过了,咱们随机应变的执行过吗?
如果都没有,那么,老不给咱们涨工资,咱们有次没次的跳槽,能跳好吗?
搞技术,人生无非是如下的五条出路:
一、做技术专家,做到李政道、钱伟长或者Linus Torvalds的水平;
二、技术管理,瞄准Ray Ozzie那样的角色,当公司的高管;
三、自己创业;
四、技术市场、技术营销:虽然不搞技术了,但是懂得如何推销技术;
五、改行。
在达到这些位置之前,我们要经历上一篇所列的形形色色的角色。
本篇就是要仔细挖掘一下,一个嵌入式的从业者所需要的技术和技能,看看应该从什么样的角度来建立“一技之长”。
我们先抛开个人素质和商业素养,以后找机会谈。
做为一名技术人员,应该怎样选择“技术专长”的成长之路?非常容易迷惑,这是一个事实。发达国家把它做为一项国家工程,各自研究了一套技能体系,并结合资格认定,引导工程师自我成长。就我所知道的范围来说,英国、美国、日本等国政府都有一套体系。这里我想把这些国家现有的分类体系,结合我自己的体会,介绍给大家。
首先,我们可以把技术分成三大类:
一、开发技术
二、领域技术
三、管理技术
在这里先罗列一下这三大类的分法。
开发技术指的是完成一个大规模的软件开发工程所必备的技术,比如系统需求分析、系统设计、软件需求分析、软件模式设计、软件详细设计、代码编写与测试、代码集成(Integration)、软件检验(Validation)、系统集成、系统检验等各个环节所需要的工具、模式、流程和知识。
管理技术指的是项目管理和流程管理所必备的技术,比如分工管理、时间管理、成本管理、质量管理、沟通管理、采购管理、风险管理、人员与组织管理等等属于项目管理技术;而变更管理、配置管理、开发环境管理、开发流程选定、知识产权管理等等则属于流程管理的范畴。
领域技术指的是平台技术、界面技术、通信技术、多媒体技术、存储技术、传感与控制技术、信息处理技术、应用技术等等。
从这样的分法我们得到的启发是,不管自己将来要成为专家还是高管,开发技术和管理技术大部分都是必须掌握的。“我”的“不可替代性”一定是在领域技术中去找的。如果某一项领域技术在公司里能够做到数一数二,咱们在那个公司才是不可替代,因为把握替代掉要花更大的代价。如果咱某项技术能够在行业中能够做到数一数二,那么你就具备了成为“Ray Ozzie”的基本条件。
能够做到数一数二的,做到不可替代,一个公司里就那么多。如果退而求其次,就是做个“牛人”。上面罗列了不同角色,咱们可以成为这些角色的“牛人”。成为各种“牛人”分别需要在哪些方面牛呢?以后有机会再说吧。今天先把领域技术分解一下:
一、平台技术包括
1. 特定的处理器,比如对ARM处理器、TI的DSP或者NVidia的GPU等等的全面掌握
2. 特定的操作系统,比如对Nucleus,Rex OS, Linux等等内核的掌控。
3. 特定的软件框架,比如Java VM等VM,特定的应用框架比如GNOME、KDE的掌控(太大了 :-( )
二、界面技术
1.输入处理:通过人类的动作产生的输入处理比如按键、触屏、气味、声波、G-Sensor、 GPS信号等等信息输入的处理技术。
2.输出处理:显示、声音、振动、气味、光亮。由于GUI通常涉及到输入输出,我们把GUI技术划在界面技术当中,比如透彻掌控X-Windows,GTK+, Match box, mini-GUI等等。严格讲的,界面技术指的是针对一个特定的功能,用软件去设计、实现一整套操作、反馈流程,使用户既容易学、又容易记。从这种意义上看,GUI应该属于平台技术,因为GUI是实现用户操作流程的平台。
三、通信技术
1. ISO 1~7 层通信模型某几个层面的设计、实现和维护。由于无线通信涉及物理层到网络层的变化,通常分有线、无线通信技术。GSM协议栈、TCP/IP协议栈、TD-SCDMA协议栈都是通信技术范畴。
2. 无线广播技术:DVB-T/H, T-DMB, CMMB等等都是无线广播技术
3. 互联网技术:这里指的是TCP层以上通信协议,比如HTTP, IMAP, POP3, SMTP,FTP等等技术。
四、多媒体技术
1. 声音压缩与解压缩技术:MP3, AAC, AMR等等
2. 图片压缩与解压缩技术: PNG, GIF, JPEG等等
3. 影视压缩与解压缩技术:H.263, H.264, MPEG4等等
五、存储技术
1.文件系统:FAT32, EXT3,JFFS等等
2.媒体技术:内存、闪存、磁盘等等物理媒体特性的掌控
3.存储接口技术:热插拔、冷插拔设备的接口技术
六、传感与控制技术
1.物理化学量输入技术:电位、电流、振动、光、压力等物理化学量的计量技术
2.物理化学量输出与控制技术:电磁、光、热、速度、振动、坐标等物理化学量输出技术
七、信息处理技术
1. 信息输入技术:数据输入、声音输入等等信息输入技术
2. 信息安全技术:加密、解密技术
3. 数据处理技术:数据压缩与解压缩技术、嵌入式数据库技术
4. 信息输出技术:Postscript语言,XML语言,SVG等等通用信息格式输出技术
八、应用技术,特定目的的应用软件的实现,它们往往是如上七类技术的综合应用,比如
1. 浏览器
2. 消息类应用:e-mail, IMPS, MMS, SMS等等
3. VoIP应用
4. 视频通话
5. 媒体播放器
以上八大方面,每一个方面都够咱们干一辈子的。罗列了这么多,希望能够给各位有志于加入嵌入式软件开发的朋友,大学毕业后刚刚走上社会的朋友,毕业后做了许多年软件觉得不知道自己该怎么发展的朋友,或者自以为嵌入式就那么回事的朋友,提供一个思考的线索。参考这个分类,理出自己发展的路子。
大学毕业后五年内,我们通常是“干一行爱一行”。
大学毕业五年以后,希望自己能够做到“爱一行干一行”!
07
嵌入式Linux进阶流程
一、练好基本功
嵌入式系统专业是综合了计算机硬件技术,计算机软件技术以及电子电路技术的一门综合学科,所涉及的内涵和知识非常广泛,包括:数字电路,模拟电路,计算机组成原理,单片机基础,C语言基础,操作系统,数据结构,编译原理,计算机控制,计算机网络等知识。
在真正学习嵌入式开发之前,首先要打好基础。其中最重要的是C语言基础、数字电路、计算机组成原理三门课程。对于C语言,至少能单独编写调试一个3 ~ 500行的程序,能够了解C语言的基本语法规则,基本语句的使用,理解指针概念并能灵活使用各种指针。
计算机组成原理要能理解组成一个计算机系统的几大部件,计算机系统的结构,理解系统总线,理解处理器和计算机外部设备的关系,处理器和计算机外设是如何协调工作完成某一项功能的,计算机软件和硬件是如何分工协作完成某一项任务的,理解软件是通过寄存器来控制硬件的。
数字电路,模拟电路要了解其基本原理个概念,能看懂简单模拟、数字电路原理图。理解数字电路中的寄存器,时序的概念,能看懂芯片手册和时序图。对于其他基础课程,重点要理解其中的一些基本概念,如何使用等等。
对于电子,自动化,通信,计算机类专业的学生,在大二、大三开设的专业基础或专业课程中基本包含了以上的大部分课程。因为缺乏实践,可能学得不是很深入,但是一些基本的概念和基本知识应该还是有所了解,针对一些薄弱环节,自己稍微加强学习一下,基本上已经具备了学习嵌入式开发的基础。
在嵌入式基本功学习阶段,最重要的是C语言和单片机基础,最好是能用C语言开发一个小的单片机程序,例如用C语言实现单片机和PC的串口通信,用C语言控制LED等显示,用C语言控制数码管显示等小程序。在这个期间需要的学习工具就是单片机51学习开发板。推荐飞凌的OK-51学习开发板。详情参考:
二、嵌入式linux应用开发
嵌入式开发基础知识学习完后,这时候你已经有了一定的嵌入式开发基础了,可以进行基于单片机的嵌入式系统设计了。
单片机编程本身也是属于嵌入式编程,但是在这里我们只是把单片机开发当作嵌入式系统开发的基础,不把单片机开发作为真正的嵌入式系统开发,在这里我们的嵌入式系统开发是指在带有操作系统的嵌入式平台上的应用和驱动开发,特别指在嵌入式linux平台上的开发。
单片机开发在很早以前是非常热门的,现在在一些比较简单的系统上单片机也用的非常广泛,随着硬件的成本不断降低,在一些比较复杂的嵌入式设备一般都采用嵌入式linux操作系统,在嵌入式linux平台上进行开发,这样可以极大的提高嵌入式开发效率,提高系统的稳定性和可靠性,降低开发成本。
由于linux是一个开源的操作系统,你可以通过阅读linux内核来理解内核的实现机制,如果有需要,你甚至可以通过修改内核源码来提高系统的性能;同时,全球参与linux开发的队伍非常庞大,网上有大量的嵌入式linux开发资料和源代码,很多你需要实现的功能在网上基本都能找到相关源码,参考一下别人写的源码,这样可以极大的提高自己的工作效率和技术能力。
近几年,随着参与linux开发的人越来越多,linux系统的稳定性、实时性有了很大的提高,linux系统无论在服务器上还是嵌入式设备平台上都应用越来越广泛,现在包括华为、中兴、朗讯的各大通信巨头都开始把自己设备的底层平台从vxworks操作系统迁移到linux系统,可以说嵌入式linux是嵌入式技术发展一个方向,是嵌入式技术的一面旗帜。
基于以上原因,我的建议是学嵌入式开发,就学嵌入式linux开发,相对于wince等其他的嵌入式平台,你可以真正学到更多的东西,学到嵌入式技术的精髓,同时他又符合嵌入式产业发展的方向,不容易被日新月异的技术发展所淘汰。
有了嵌入式开发的基础,又知道了我们为什么要学习嵌入式linux开发,那我们就要开始动手开始学习了,那如何开始学习嵌入式linux开发,从哪里开始着手呢?
做任何事情都有一个循序渐进的过程,学习嵌入式linux也一样。在有了一定的嵌入式开发基础后,学习嵌入式linux开发比较适合的切入点是从嵌入式linux应用程序开发开始,即暂时先不去关心嵌入式硬件平台,不去关心linux的底层驱动,先把精力集中在现有的嵌入式linux平台上进行嵌入式linux应用程序设计开发。
学习嵌入式linux开发绝不是看看书就可以学好的,需要多实践,编程调试;因为嵌入式开发不同于普通的基于PC机或服务器的应用程序开发,嵌入式开发的应用程序是要烧写到嵌入式板卡或开发板上运行的,所以首先你要给自己购买一块开发板。
有了开发板后,先后开始学习嵌入式linux开发环境搭建、嵌入式linux开发模型、linux内核移植和文件系统、嵌入式linux应用程序移植、嵌入式linux多进程,多线程应用程序设计、嵌入式linux网络编程,如果对嵌入式数据库或图形软件开发有兴趣的,可以进一步学习嵌入式linux数据库开发或基于QT的嵌入式linux图形应用软件设计。
每学一章节都要通过相关实验来来验证你从书上学到的东西,同时提高自己编写代码,调试程序的能力。这个过程根据不同学员的基础不同,大概要花上1 ~ 2个月时间。
学完这些课程后,你就有了再现有的嵌入式linux平台上进行应用程式设计开发的能力,到一些嵌入式软件公司去,能够胜任在现有的嵌入式linux平台上进行上层的应用程序开发工作。但是目前你还不能进行嵌入式linux系统和驱动的开发,也就是说,你现在只能在一个已经构建好的嵌入式linux平台上进行应用程序开发,而自己还没有能力根据实际需要去重新构建一个嵌入式linux平台。
要让自己有能力根据实际需要重新构建一个嵌入式linux软硬件平台,这时候就需要进行下一阶段的学习了,即嵌入式linux系统和驱动开发。
三、嵌入式Linux系统和驱动开发
有了嵌入式linux平台上开发应用程序的基础,你已经对linux的功能、linux对应用程序提供的接口和系统调用有了一定的了解,知道如何利用linux提供的功能来进行应用程序开发,知道如何来使用设备驱动来进行应用程序设计,有了这些知识后,你就可以更深入的去学习Linux系统原理和基于Linux驱动的开发,Linux内核的裁剪,文件系统构,bootloader等等底层的知识了。
想要更深入学习嵌入式Linux系统和驱动开发,要学的内容非常多包括计算机软件、硬件、操作系统知识。这时候你可以参照以下的学习思路,因为嵌入式Linux系统和驱动的开发,和底层硬件联系非常紧密,所以首先我们从学习了解嵌入式硬件开始,包括:ARM体系架构、S3C2440微处理器接口设计、时钟系统、LCD屏接口、存储控制器及系统的存储空间分配、NAND FLASH接口和NOR FLASH接口等。
对嵌入式系统硬件有了一定的了解后,接下来就可以开始学习bootloader了,理解bootloader的概念,功能,和原理,重点掌握U-BOOT的使用和移植。接下来就开始学习嵌入式linux内核机制,分析嵌入式Linux源码组成、内核的模块机制、内核进程管理、内存管理机制、linux的中断系统、Linux内核的移植等。有了内核的基础,就可以学习嵌入式Linux设备驱动开发了,重点掌握字符设备驱动开发,LCD屏设备驱动开发、触摸屏设备驱动开发、USB设备驱动开发,网卡设备驱动开发。
学完这些知识点并通过相关实验验证后,嵌入式Linux系统和驱动的开发就算掌握了差不多了,能够胜任绝大部分基于linux平台的驱动开发工作了。学完这些知识点,根据学员的不同情况,一般需要花三个月到半年时间。通过这一阶段的学习,你在嵌入式Linux开发领域已经算是有了一定的功底,已经不再被人称为菜鸟了,已经进入嵌入式linux开发高手行列了。
四、更上一层楼
深入理解了嵌入式内核和驱动开发,这时候写个什么驱动对你已经没有什么问题了,开发过程中一些基本问题都难不倒你了。这是你可能想优化一下系统的性能,比如实时性,提高系统的启动速度,或者优化系统的内存管理机制,要达到修改内核核心机制的境界,你就需要去深入去研读linux内核源码了,参考《linux源码深度分析》、《linux情景分析等》等linux源码分析的书籍,深入理解linux各部分的实现机制和原理,以及可能存在的问题。
你只有在深入理解现有代码和实现机制的基础上,才能提出更好的改进方案。如果你能达到这个境界,那你已经是高手中的高手,可以笑傲群雄了。
五、误区
1、全身投入学习桌面或服务器版本linux系统
Linux桌面环境只是嵌入式linux的一个开发工具,开发环境而已。我们的目标不是学习linux服务器的配置和使用,linux服务器的高级配置和使用那是另外一个领域,不属于嵌入式linux讨论的范畴。
我们进行嵌入式linux开发,只是把linux桌面环境当作一个工具,在linux桌面环境下运行嵌入式linux开发工具,例如gcc 编译器,make工具来开发我们的嵌入式linux应用程序而已,对于嵌入式开发工程师来说,没有必要花费那么多的精力和时间去研究linux桌面版和服务器的应用,只要能了解最基本的操作即可。现在的桌面linux系统的图形化界面做的也相当好,跟window具有相同的易用性能,例如ubuntu很多操作都可以在图形界面下完成,就没有必要去记每个linux命令了。熟悉linux桌面系统的使用和基本操作命令,安排1~2天时间学习基本就可以掌握了。
2、直接阅读linux内核源代码
很多想学linux,在连linux是什么东西,一点都还不会使用的情况下去就阅读linux内核源代码,花了大量时间去阅读《linux源码深度分析》、《linux情景分析等》等书。这样的结果很可能就是看的头昏眼花,不知所云,最后只能放弃了。
这也是同学们学习嵌入式linux的一个误区,在有一定嵌入式linux开发基础后,带着一定的目的去阅读linux源代码,这样可以极大的提高你的技术能力,但是你在没有任何基础,对linux一点都不了解的情况下就去阅读linux内核源代码,无异于以卵击石,最后只能是撞个头破血流。
3、对于初学者来讲,要量力而行。
不要认为驱动层工资高就把它当成方向了,要结合自身特点,嵌入式系统四个层面上那个层面上来讲都是有高人存在,当然高人也对应的高工资,我是做硬件层的,以前每月工资中个人所得税要被扣上近3千大元,当然我一方面充当工程师的角色,一方面充当主管及人物的角色,两个职位我一个人干,但上班时间就那些。硬件这方面上可能与我PK的人很少了,才让我拿到那么多的工资
4、开发系统选择。
很多ARM初学者都希望有一套自己能用的系统,但他们住住会产生一种错误认识就是认为处理器版本越高、性能越高越好,就象很多人认为ARM9与ARM7好,我想对于初学者在此方面以此入门还应该理智,开发系统的选择最终要看自己往嵌入式系统的那个方向上走,是做驱动开发还是应用,还是做嵌入式系统硬件层设计与板级测试。
如果想从操作系统层面或应用层面上走,不管是驱动还是应用,那当然处理器性能越高越好了,但这个东西自学,有十分大的困难,不是几个月或半年或是一年二年能搞定的事。
从关注上游半导体公司的角度,来说一下对嵌入式行业的预测:
当前的主流可以按照两个类型进行分割:裸机系列和有系统系列。第一种,裸机系列很容易理解,比如C51、MSP430、PIC这样的品种繁多的单片机,开发过程和方法基本相同,使用半导体厂商提供的BSP包,按照手册进行寄存器配置,对周围数字芯片的各个协议工作方式了解,就能解决一些功能单一的需求;跑系统系列基本上就是Linux、Android这样的非实时操作系统和一些实时操作系统,操作系统的多任务、完善管理机制就开始谈及芯片的架构和指令,PowerPC、ARM,MIPS等等等,这些处理器芯片常常用于解决复杂的需求,并将需求定制交给熟悉业务和技术的嵌入式应用工程师或者CS行业工程师,这样就可以完美和计算机开发者相结合制造出多种多样的功能设备。这样看的话,操作系统可以说是在嵌入式行业和计算机行业打通的一个桥梁。
传统的嵌入式基本上就是这样的,稍微的预测一下呢?
C51、MSP430、PIC这类的开发必定会淘汰,不是说它们不够锋利,而是由半导体行业的特性所决定的。半导体器件生产成本是按照规生产模数量所摊薄的,生产的越多,需求越多,成本越低,未来基于MSP430、C51的这样的实时性稍微有松弛的场景,也会可能选择一个ARM的以Cortex-M为核心的处理器(arm的授权费真的低到不行了,真算是业界良心),生产规模上升,成本则下降,且方便日后扩展,再然后Cortex-M核心arm公司也是在不断投入成本优化,上上的选择。
从裸机的发展上我们就可以看到一个发展方向,SoC模式的思想。核心架构交给专业的公司去做,自己公司做擅长的一块,然后这些功能部件全部都集成在一个芯片里。比如,今年参加的arm公司关于芯片IP的培训,也认真听了一些新的创业半导体公司的介绍,学习到了很多,也打开了我另一个世界的大门。其中在一个物联网案例中,有一个公司他们是做NB无线传输的,处理器核心采用的是arm公司的,他还特意感谢了arm公司,arm公司在提供demo评估自己芯片到流片的时候是不收费用的,量产后才交费用,这大大的降低了做企业的风险。
这个公司选择arm公司成熟的cortex-a系列处理器的核心的方案,自己专注做NB无线基带,调制解调算法MAC层,最后融合成一个芯片,然后流片,回片测试。这是一个物联网的芯片的案例,用的就是SoC模式。SoC模式将一整套系统做成一个芯片,就好像曾经把复杂的巨大模电数电的放大电路做成芯片一样。在物联网的应用上,嵌入式SoC,未来必然成趋势,嵌入式和物联网的关系实际上大家都清楚,很不负责任和不准确的说,嵌入式+CS+互联网,上中下组成的大规模网络可叫物联网,嵌入式在物联网布局中处于底层的地位,大规模布局这就有体积小、寿命长、低功耗这些基本要求,SoC模式肯定是首选,缺不了处理器,缺不了无线,做进一个芯片不刚刚好麽。
谈到SoC 模式,很多人都觉得大部分工作量其实在半导体上,嵌入式软件开发似乎没有用武之地,其实不然,反而对于嵌入式软件开发的要求又更上了一层楼。就说一个例子,多核、多层的SoC早在零几年的时候有这样成型的产品,比如TI公司的OMAPL138,DSP(C6748)+ARM(ARM9)架构的,在嵌入式软件上,面临的难以解决的问题就是核间通信,DSP和ARM如何通信,包括现在有名的ZYNQ,FPGA+ARM的多核异构平台,多核心之间通信如何解决,这始终需要去解决,还有,英伟达的TX2,SoC级上面ARM Cortex-A5x系列+自己的GPU。很多人采用的是Linux内核里面一个模型,IPC,常常用在裸机上。如果上操作系统,Linux系统对于多核异构的通信,TI使用syslink驱动级的组件,zynq采用ram内存读取的方法反包装出接口。这些开发对于多核通信应用级的都很难,更别说开发出这样的BSP支持的了。
未来嵌入式,不单单是对于传统的CPU+外设模块,通过外设总线驱动读取外部数据,而是打入到芯片内部,一块芯片,即一个系统。而开发的重点,也不单单是传统的那些嵌入式的知识,还要包含半导体SoC的知识。驱动开发需求会加大,嵌入式将越来越集成化,越来越脱离周边硬件,且深度整合,由外向内发展,SoC将是主流。
应对上面SoC的发展趋势,一个单纯的嵌入式软件工程师已经满足不了需求,也随着技术迭代,这些名称的定义又赋予新的意义,这些传统的技能已跟不上潮流,身为行业人也要跟着风头做出转变。嵌入式是一个要不断学习不断反思的路线,个人的技术树上还要不断的开枝散叶,越来越集成化的开发平台过时的很快,就要求我们开出的技能枝叶更多,所以不能拘泥于某个公司的某个产品上,不能以C语言为天,但也应该注重基础。
Linux内核好厚的一本书,翻开第一页的前言那个作者告诉我们这还不是全部,如果把内核全部都写成书是不可能,只能去学习介绍最核心的东西。对于Linux内核,可以毫无遮掩的说这是全天下最好的工程师编写的最好的代码,一手的好学习资料。我们学习内核不是要学习内核怎么编写,而是要掌握里面的模型和机制,分页、内核调度和内存管理、死锁等等,这些机制模型可以嵌套在我们的任何解决方案中,就比如上面异构多核通信的机制,使用的IPC概念反复在Linux内核中出现,在某些场景下就可以抽象成一些模型。当然了,以上说的只是内核的附带的好处,最重要的就是,Linux内核和处理器核心深深绑定,Linux驱动和SoC周边绑定。从这句话中,你是否能体会到,现在的嵌入式开发是,物理上用外设总线和外设相连,然后编写C语言程序,然后烧写到FLASH里,然后去驱动外设传感器实现某一个功能;而未来的嵌入式开发在SoC上都是一个芯片内,即将依托操作系统,开发将要不断的深入内核中和修改Linux驱动去实现功能,留出接口,高度集成之后那些应用层的开发东西交由CS去做,实现业务层面的黏连,出现了不同以往的分工。
所以所谓的嵌入式应用工程师,这个职位很可能在未来会消失不见,这就是高级程度的体现后的变化。
嵌入式开发的门槛即将越来越高,阶级也将割裂,产生一个泾渭分明的分水岭,嵌入式和CS那些模糊不清的界限也会逐渐清晰。我举个例子,我真的很久很久没用STM32了,有幸参加了意法半导体组织的全国巡回一个会议,意法的工程师给我们展示了他们公司可视化开发的操作,鼠标一点那个引脚,时钟多少,用了什么外设,启动多少定时器,哪个会冲突,然后生成代码,这样向导式生成的代码又好用又标准。那一刻感慨道,还要嵌入式应用工程师做什么呢?点点鼠标钱就赚到了。可这件事情怎么可能,当意法开发出这样的工具时候,自己的芯片好卖了,一部分人乐了,一部分人也哭了。甄嬛传里面,姐姐杀了姐姐,这个也一样,程序员让程序员失业,挺搞笑的,也挺残酷的。是的,意法半导体这个已经能体现出对于裸机开发的风气,TI的网页版配置方法都不需要你下载任何软件。因此你也可以看到,处于上游公司的职位一定程度上可以决定下游公司职位的命运。
嵌入式进程不断的进化,学习量也会迅猛增加,既然SoC前景这么好,直接从SoC学起可否?可要知道,在这个混沌不清的嵌入式年代,都要一步步学上来,硬件还是从电阻电容,然后到数字电路、单片机;软件还是要从printf hello world,到指针结构体,甚至要学C++;理论还是要数据结构到一些常规算法;Linux系统还是要从熟练应用到研究它的内核。一步都不能少。这也正是嵌入式所谓坑的一点原因吧,但还是中国老祖宗那种辩证思想,塞翁失马焉知非福,学这么多门槛也高,将来分水岭一形成,你来决定别人的命运,而学习少且赚钱的维持不了几年肯定人也是膨胀,寻常人不走的路才有好风景呀,相信你总有怡然自得和庆幸的时段。还有对于嵌入式行业把脉的人,预测其药丸,实际上还不如说他们看到的是静态的嵌入式,怎么说,就好比蛇脱皮,留下干涸的一层蛇形的皮,真身早跑了。嵌入式的概念也会随着时代迁移且与时俱进,形式也会变换,它是活的,不是固定的。
我们通过观察最上游的半导体公司,就能看出未来发展的路径,而看现在刚需的那些一列列职位看不出什么的。忘记谁跟我说的了,上游决定下游,且有一定的延迟,这个延迟时间正是给你的时间,否则就会被无情的淘汰掉。
所以给的建议是在下游公司做嵌入式应用的人做好应对,能上系统就上系统。
我可以大言不惭的说自己是一个比较刻苦的人吧,学业时段基本上没有什么娱乐项目,都是敲代码焊板子看看行业趋势这类的,就希望有朝一日进入职场里面能“笨鸟先飞”。其实这样或多或少的产生了一种思维定式,包括进入职场,我无法忘记曾经那些努力,不希望那些努力白费去从事一个完全陌生还有些许相关的职位,这样就会错过很多的机会。这种把持着的安全感实际上也不是很好,也非常希望那些刻苦的职场新人能够大胆的去尝试,open自己,毕竟在学校的眼界是狭窄的,我们也只是按照自己的路子和道听途书的路子再走,可实际面对自己的道路是不尽相同,机会也不尽相同。放弃自己所学是艰难的,可有的时候真的需要勇敢迈出这一步,去体验新的平台的知识,其实到最后发现,学习能力是关键的,自己曾经学的到后来都是相通的,没有白不白学一说。可能,我在学校学习的是嵌入式软件开发,可公司要求我学习半导体里面的ip知识,是有些许关联,但不应该去拒绝,而应该大胆尝试,毕竟公司平台要高于当时你的眼界,当时也是怀揣着对现在生活的猜想去努力的,现在到了这个平台上就该接受一切现实,努力踏实工作,而不是放不下过去。
-END-
免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除
添加极客助手微信,加入技术交流群
长按,扫码,关注公众号
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。