当前位置:首页 > 软件开发
  • 利用Sub-1 GHz Linux Gateway软件开发套件设计楼宇安保系统

    利用Sub-1 GHz Linux Gateway软件开发套件设计楼宇安保系统

    楼宇安保系统在许多系统拓扑结构中都有应用,从简易警报系统到复杂的传感器网络,所有这些都报告给作为枢纽的主安全面板。根据其部署模式,这些系统可能是有线的,也可能是无线的;无线系统会利用不同类型的连接模式以实现特定的应用。一些应用程序(如摄像头)使用Wi-Fi®进行与云的本地连接,而某些智能应用程序(例如门锁)使用低功耗蓝牙(Bluetooth® Low Energy)连接到手机和平板电脑。基于传感器网络的安保系统,例如烟雾探测器、运动探测器、门/窗传感器、温度/湿度传感器和玻璃破碎探测器,可从Sub-1 GHz网络中受益。 Sub-1 Ghz技术在设计楼宇安保系统时具有诸多优势,如实现比2.4 Ghz技术更长的距离和更好的墙壁穿透力。这可以实现全楼宇覆盖,无需中继器,也无需复杂的多跳网络拓扑。Sub-1 Ghz的功率也极低,使远程传感器可依靠一粒纽扣电池工作10年。此优势使系统无需在天花板和墙内布线,从而使设计具有灵活性。 设计楼宇安保系统时,一个基本要点是通信必须可靠。Sub-1 Ghz系统通过利用比2.4 Ghz频段更空闲的Sub-1 GHz频段,提供了高鲁棒性。 很明显,Sub-1 Ghz在构建安保设计方面具有许多关键优势,但安保系统和传感器通常必须具有云连接或需要Wi-Fi和低功耗蓝牙(Bluetooth® Low Energy)的智能设备接口。但是,设计一个通过Sub-1 GHz星形网络发送和接收传感器数据、连接到云并提供智能设备接口的系统非常复杂。借助双频段功能以及CC1352P无线微控制器(MCU)和Sub-1GHz Linux网关解决方案的灵活无线电功能,您可轻松开发可无缝连接到智能设备和云的产品,同时仍可在更长的距离中利用Sub-1 GHz技术集成的低功率20dBm Pa的优势。 Sub-1 GHzLinux网关软件开发包可扩展到许多不同的应用程序。例如,假设要设计一个楼宇安保系统,包括覆盖整个楼宇的烟雾探测器、运动探测器、门/传感器以及玻璃破碎探测器,并且所有这些都与中央安全面板进行通信。系统设计要求消费者能够在互联网或智能设备上查看传感器数据。Sub-1 GHzLinux网关解决方案可帮助实现这一案例,同时支持快速上市,并能灵活地启用各类解决方案体系结构。 图 1:家庭安保系统示例 如图1所示,外围传感器(烟雾探测器、运动探测器、门/窗传感器和玻璃破碎探测器)都通过Sub-1 Ghz星型网络与中央安全面板通话。该安保系统充分利用了Sub-1 GHz的远距离和墙壁穿透能力,可覆盖整个楼宇。此外,您可将无法接入交流电源的传感器(如门/窗传感器)远程放置;它们可依靠一粒纽扣电池运行10年。使用CC13152P双频MCU的烟雾探测器可通过低功耗蓝牙(Bluetooth® Low Energy)连接到手机或平板电脑,并在这些智能设备上向用户发送警报。 这些警报可报告电池寿命或检测到的任何危险,而烟雾探测器则通过Sub-1 GHz网络与主安全面板通信。安全面板可从所有传感器收集数据,并使用Wi-Fi连接到云以向安保公司报告或使互联网数据可视化。用户还可通过低功耗蓝牙(Bluetooth® Low Energy)连接到面板或从云中接收更新信息来更新系统固件。面板可随后将这些更新推送到外围设备,并通过Sub-1 GHz网络更新每个节点的固件。 该楼宇安保系统示例只是德州仪器Sub-1 GHz网关解决方案支持的一个用例。网关体系结构灵活,可连接到多个云供应商,其设计也基于SimpleLink MCU平台上成熟的硬件和软件,从而缩短了产品的开发时间和上市时间。利用这一解决方案的优势,现在就开始你的设计吧。

    时间:2020-05-11 关键词: 德州仪器 传感器 软件开发 烟雾探测器 智能安保系统

  • 从全栈工程师到数据科学家,入职第一年我都做了些什么?

    从全栈工程师到数据科学家,入职第一年我都做了些什么?

    万事开头难,从一个软件开发程序员转型为数据科学家,第一年该怎么做?一位博主就记录了自己从全栈工程师转行数据科学家第一年的心路历程,包括好的方面和不好的方面,希望能帮助到同样处境的人。我觉得自己非常幸运,雇主给了我一个机会,让我从一个全栈软件开发人员转型变成数据科学家,和内部数据团队一起工作。入职一年,我很享受这份工作给我带来的全新挑战,完全不同于以前做开发。我想写这篇文章,首先是为了回顾过去一年所做的事情:我经历的改变,我做得好的地方,我可以改进的地方。第二,通过记录我曾经遇到过的问题和挑战,我希望能帮助到和我处境相似的人。在开始之前,我先介绍一下我的背景:我之前不是做软件开发的,我拥有计算机科学的硕士学位和博士学位。因此,我不算冷启动,我有工具、模型和分析方法方面的相关经验。我从事开发工作将近8年。自从我的论文发表以后,我经历了很多变动。本文将分为两部分。进展顺利的部分和进展不佳的部分。对于那些只对结果感兴趣的人,也可以拉到底直接看最后的结论。进展顺利的方面Python 和 R刚开始,我不确定在项目中该使用Python或R。所以一开始我对这两种语言均作了研究学习,并在项目中结合使用了这两种语言。R经常让我想起Matlab,两者在用来编写和执行代码的界面非常像(我尝试了R Studio和Visual Studio的R插件),同时写代码和处理数据的方法也很像。但我只在硕士论文中用了R,还在博士学位论文中用了一些。除此之外,R和其他编程语言相比(这些年来,我在软件开发中经常使用C#)就没什么共性了。R这个工具极度以数据为中心,与数据进行交互的方法也很不一样。在R里有:列表,矩阵,向量,数组和数据帧。每个都有不同的使用场景,你需要学会什么时候使用。R与C#的语法很不一样,所以刚开始学R我遇到了不小的困难。我并不是说R不好,只是我使用Matlab10年,并且作为开发我的脑子已经习惯了某种思维方式,所以比较难转变。所以我刚开始的时候觉得R很难上手。作为一名有8年C#开发经验的程序员,我觉得Python比R更容易起步。很可能是因为我的大脑已经习惯了C#的思维方式。python比R更接近于C#,所以我学Python比R快很多。在使用这两个语言时,我没觉得两者有明显区别,尤其是对于可用的库,两者在我想做的工作的实现方面有差不多的处理能力,我也会得到相同的结果。但在摸索过程中,我对两个工具分别都有些困惑。总的来说,编程编久了,Python对于我的程序员思维更友好。所以我很快放弃了学习R,转而专注Python。这有助于我更快地进步,不必再花时间阅读新语法,事情变得简单许多,我一直觉得简单才是王道。这对我应对角色的许多其他变化也是有帮助的,因此,这样做可以最大程度地减少更改。关于使用哪种以及何时使用,我敢肯定大家定对此有很多意见,但是对我来说,从开发人员过渡到数据科学家后,我发现Python变得更容易掌握和使用,尤其是在我担任新职位后想快速发展并取得成果的初期。所以与R相比,使用Python让我更快进入状态,在输出方面,我没有发现两者有任何明显区别。所以我把这个归类为进展顺利,因为我很早做出了决定,且至今没有遇到任何情况让我觉得自己选错了Python,相反我节省了不少时间,所以我能更快地开始工作。文档记录记录一切,我定义的一切是从模型超参数到从何处以及如何获得训练数据,到在整个项目中做出选择的理由。另外,以有序的逻辑方式编写文档,实现这一目标的一个秘诀是,哪怕你只是写给自己看(例如,在我的情况下,我是唯一的数据科学家),你应该想象有人会读这份文档。此外,记录时要对自己有一定的约束,不要拖拉,不要走捷径。不然等你开始写的时候,你可能已经忘记一些需要注意的细节。因此一定要及时写下来。在完成文档之前,我觉得工作就还没做完。我从一开始就遵循这种方法,我觉得至关重要。我发现一件事是,即使在一个中型企业,等到一个项目的研究成果在公司开始推广已经是一段时间以后了,利益相关方因为有其他事要忙,所以不会立刻作出回应。有时候在我完成一个项目几个月后,有人跑来问我问题,我一时想不起来,但如果我翻看我之前做的文档记录就能马上提供详尽答案。例如,有一次我与另一位经理聊起几个月前做的一个项目,我向他展示了我已经完成的工作,他问我训练集的大小是多少,以及我用来获取数据的日期区间。我并记不得那些数据,但我记得自己已经写下过,而且我也记得写在了哪里。所以我能马上把文档拿给他们看。我发现自己遇到的另一种情况是当业务优先级发生变化,你可能会需要停下手头还没完成的项目去做另一个项目。当你再回到之前开始的项目时,完整的文档可以让你从之前停下的地方继续进行下去。不顺利的一面数据存储回顾前一年,进展不顺利的一个原因是我处理数据的方式(对于数据科学家而言这非常关键)。当我没有使用数据库的经验时,我基本上复用了在博士期间使用数据的方式。使用平面文件(特别是CSV)来存储数据。我把从生产环境中提取的初始数据,清洗后的中间过程数据,分析后的数据和结果都存在了CSV里。我工作流程中的每一步骤都需要通过Python脚本读取上一步创建的文件,并创建新的文件。这种把内容存储在硬盘上,并通过Python脚本与数据交互的原始办法,很快就出现了一些问题:有时很难在大量文件中找到我要找的那个文件。即使我记录了文件的内容和位置,但有时还是很难找到我想要的确切文件,因为文件实在太多了。我似乎总是在忙着用Python把从文件中读取数据或者将数据写入文件。我写了很多文件访问的命令,但其实是在做重复劳动,写这些代码对我要做的工作并没什么帮助。想快速地将数据总结一下似乎都有点费力:读取数据,汇总统计,输出统计,查看统计结果。有些文件很大,用起来很困难(在notepad中打开10GB以上的文件很麻烦)。第一年,我花了很长时间才意识到SQL是我的解药。在从事数据科学家工作之前我使用过SQL,但是我一开始没有意识到它对我的价值。当我意识到SQL就是我的解决方案后,我花了很多时间来学习更多有关SQL的知识,因为我在做程序员的时候稍微学了一点SQL。具体来说,我学习了如何查询数据(特别是我以前没接触过的高级语句)以及搭建和维护数据库的基础知识。我甚至通过了两个Microsoft SQL的考试。我现在主张尽可能用SQL。我把所有项目的数据都存在了SQL数据库中,尽量在SQL中做数据查询和操作。我的原则是:能在SQL中完成的处理,就在SQL中做。SQL处理不了的任务再用Python(例如,模型训练和执行)这里延伸出一个问题:你需要学会使用Python库,例如 SQLAlchemy,从 SQL读取数据到Python里。现在我的后SQL生活变得容易很多:所有项目数据存储在一个容易找到的地方。没有重复代码用于读写文件。我能快速查询数据并从数据中轻松得到统计结果。我能够很容易地查看大量数据,特别是前几行的数据。额外的好处是现在很容易把不同的数据联系起来,因为数据都已经在关系数据库中了,现在安全性也提高了:把数据存在本地磁盘上有潜在的风险。数据都在服务器里,安全很多。因此,我强烈推荐学好SQL并用起来。如何展示成果?还有一个进展不顺利的地方是我做的一些展示。从开发人员到数据科学家的一个变化是,我做演示的场合变多。展示的内容各种各样,有面向技术人员的demo演示,有面向业务相关人员的项目报告,再到与公司内部其他部门讨论项目工作,甚至向公司外部的第三方合作方展示工作。对于这些人我觉得我没有做好的一点是我没有根据受众来调整自己的展示方法。有些展示我做得还不错,比如对开发人员的技术演示我觉得我做得还不错。因为我跟技术人员拥有差不多的背景所以说技术的内容彼此也听得懂,交流起来会更容易一些。其他类型的演示更难一些,不幸地是很多时候我在展示的时候才意识到听众对我讲的内容不是很在意。我的受众分为四类,从展示的难易程度来分如下:从最简单的(最左边)开始,到最难的(最右边):开发人员,业务方,其他部门以及外部人员。我还可以将最左边的那些受众标记为最技术性的,将右边的那些受众标记为更“销售型”的,当从左向右移动时,两者之间会有一个过渡。我发现针对左边受众的展示是最容易准备的——他们对我正在使用的技术或所从事的业务领域有深刻的了解。针对外部人员的演示是最难的,因为他们往往相关知识最少。过去,我与这些听众进行交流的时候会直接进入到技术细节,就像我和左边听众交流时一样,但是结果很不好,因为他们不一定具有任何数据科学或机器学习的背景,所以我谈论许多概念对他们没有多大意义,他们不知道我在说什么。对这些受众来说,如果我花点时间介绍一下我正在做的工作以及更多的背景知识,效果会更好。甚至对某些受众来说,向他们介绍机器学习的概念,为什么我们要使用它以及它的好处。有时候,对我来说,不过多讨论技术细节反而是好事,给他们一些大概的框架概念就好。在反思了这一点之后,我现在在准备演示材料时,会更多地考虑我的目标受众。具体来说,我会考虑听众可能知道或不知道的内容,以及需要向他们呈现的内容,以帮助我准备需要讨论的内容和专业程度。这样他们就可以更好地理解我正在谈论什么=,并从演示中得到一些收获。为此,在准备演示文稿时我为自己准备了一些有用的问题,如下:听众对于数据科学领域了解多少?听众对于我试图解决的问题了解多少?听众知道我在使用的技术吗?听众对于我采用的技术细节或者结果感兴趣吗?计划与做程序员时相比,做数据数据家的工作计划更有挑战。作为开发人员,工作相对比较直接,所以也更好估算和排期。你通常知道你要实现的目标以及如何实现。当我还是一名开发人员的时候,我使用敏捷开发工具。因此,工作内容可以先评估、计划,然后排好优先级就开始做。在敏捷的方法论指导下,如果工作没什么意义,或者你不清楚如何做,你就不会把它排进工作计划。因为无法评估,因为未知,你要等到所有不明确的地方明确后才开展工作。数据科学的工作并不像这样简单,对于给定的问题你不会总是提前知道什么会起作用。也不会总是知道哪种类型的模型最准确。类似这样的情况与刚才提出的观点出现矛盾,当你是开发人员时,只有问题明确后,你才会把他们放入你的工作列表中。作为数据科学家,未知是你工作的一部分,因为你的工作就是要回答这些问题。或者你正在处理的问题可能会随着项目进展而改变。因此,有时候你提前做的几周计划可能很快要重新考虑。在计划方面,我喜欢将开发工作视为线性的——你知道自己在做什么以及如何做。数据科学工作我觉得是分叉树,可能需要试不同的道路,可能会碰到死胡同。数据科学家做短期工作计划还是可行的,比如你正在训练和测试的模型之类的——接下来一两周的工作,但是,长期计划很难做。你不可能总是提前知道什么会起作用,什么不会。所以我们才要进行实验和测试,这是数据科学家工作的核心价值。最后,花点时间去做不一定会有成果的工作,即使不起作用,也没什么大不了的。回答正确的问题在过去一年中(这让我栽过很多跟头),我发现数据科学工作的关键部分是回答问题,但更重要的是回答正确的问题。正如我所说,我栽过几次跟头,当时我正在回答一个问题,但并没有回答业务方实际想要回答的问题,之所以发生这种情况,是因为业务方使用的业务语言跟我用的的技术语言有差异,有时候我们用一样的词但要表达的意思却不同。针对这问题我的解决方法是在做项目的实际工作(现在称为“项目前”工作)之前先做准备性工作,在这个阶段,我会从业务方那里收集初始需求和信息。做一些初步分析,然后给业务方展示。运用敏捷的工作思路,我希望在每个sprint实现一个可交付的成功,并向业务方展示该成果。这样,我与业务方建立了一个有效的循环反馈机制,向他们展示一些东西并询问他们的意见,这可以建立一个有效对话,从而更清晰地定义真正要解决的问题。这个方法在项目各个阶段都有效,不仅仅是初始阶段。当你向业务方展示你的工作结果时,可能会激发他们不同的想法以及他们之前没有考虑过的思路。从而你能找到他们真正的痛点。所以过去一年来我发展的一项关键技能是与业务方的互动交流,深入挖掘他们真正想要的东西。总结Python比R更容易学习,因为对于程序员来说python与其他编程语言更接近。边执行边做文档学习如何使用关系数据库,比如SQL,用数据库来查询,操纵和存储数据。你需要准备很多展示,不仅是向项目业务方的报告,还要向公司其他同事报告,甚至是公司外面的人。你需要提高演讲能力以满足不同受众(技术或非技术)的需求。工作计划不是一帆风顺的,因为你无法预知什么起作用什么无效,要有心理准备有时候花了时间不一定取得预想的结果。花时间找你真正要解决的问题,不要不加思考就埋头开始做,与业务方建立反馈闭环是很有必要的。

    时间:2020-05-01 关键词: 软件开发 程序员

  • 盘点人工智能影响软件开发的几种重要方式

    盘点人工智能影响软件开发的几种重要方式

    (文章来源:教育新闻网) 根据专家的说法,人工智能可以简化我们几乎从日常任务到复杂的大型项目的所有工作,从而改善我们的生活。来自KommandoTech的人工智能统计数据显示,需要AI技能的工作比例是2013年的4.5倍。进一步告诉我们,自2000年以来,使用AI技术的初创公司的数量增加了14倍。 如今,大约五分之一的公司已经在使用人工智能,全球超过50%的大公司都有专门用于AI战略的预算。2018年进行的一项调查显示,到2025年,人工智能企业应用程序的全球收入应从2018年的16.2亿美元增长到312亿美元。已经从人工智能中受益的行业之一是“软件开发”行业。 软件开发是如此繁琐且耗时的工作的日子已经一去不复返了。今天,人工智能简化了软件测试过程。来自CrunchBase的统计数据进一步告诉我们,现在有10,000多名开发人员正在为Facebook Messenger构建聊天机器人。的确,人工智能简化了软件开发过程,但是以什么方式呢? 软件设计,过去,设计过程很棘手,容易出错,需要设计人员进行调整,直到获得所需的结果。但是,AI在设计过程中的应用使一切变得容易。AI工具旨在从设计师输入的输入数据中学习。他们能够从此类数据中提取和建模模式,这将有助于他们成为特定任务的专家。 自然语言处理(NLP)技术,机器学习和深度学习的应用使设计人员可以使用自然语言将其思想输入计算机,并使计算机提出适合于所描述内容的基础设计。 AI设计助手(AiDA)是一个很好的例子,它使用AI根据用户提供的信息为其用户设计网站。AIDA可以根据收集到的信息了解用户的需求和愿望。然后,它通过数百万种组合在网上搜索,以形成定制的设计,该设计将成为设计师正在寻找的基础。此后,设计人员可以进行调整以实现最终包装。 软件测试是软件开发过程中最关键的阶段之一,因为它有助于确保产品质量在发布之前。由于源代码的不断修改,如果测试必须重复多次,这是一个耗时的过程,并且可能会非常昂贵。因此,现在使用AI来自动化整个测试过程。AI能够减少标准的手动测试,从而为创建具有复杂功能的更多自动化软件测试提供了空间。 AI可以创建测试信息,探索信息的真实性,并得出数据范围,以实现更好的测试管理。

    时间:2020-04-27 关键词: 软件开发 人工智能

  • Arm Development Studio 最新版本2020.0 发布!附下载方式

    Arm Development Studio 最新版本2020.0 发布!附下载方式

    Arm Development Studio支持从架构探索到实时应用程序开发以及边缘设备编码的所有类型的软件开发项目。它加快了系统设计和软件开发的速度,使合作伙伴和客户能够更快,更经济地将更高质量的产品推向市场。 近日,Arm发布了Arm Development Studio最新版本2020.0,新增了最新的处理器的支持,增加支持STLINK和FDTI调试探测器等,产品具体的更新信息如下: 1. 不同版本都加了对更高级芯片的支持: Bronze版本添加了Cortex-M55和star 处理器的支持。 Gold版本的编译器支持Cortex-A34,Cortex-A77和Neoverse N1的处理器的程序编译,而Sliver版本支持上述核的调试和性能分析。 2. ARM 调试和调试探测器 软件增加支持STLINK和FDTI调试探测器; 所有版本均支持Arm自定义指令; 虚拟样机已支持lris 调试追踪接口; 已验证的新平台用于支持汽车、嵌入式开箱调试等关键领域。 包括以下产品: ·NVIDIA Xavier ·Renesas R-Car D3, R-Car V3M,R-Car E3 ·Rasberry Pi 4 ·Cortex-M33(SEE-200 Subsystem) MPS2 , MPS3 FPGA 3. Arm Compiler编译器 Arm 编译器6.14 新增加支持Cortex-A34,以及采用了Armv8-M架构以及可选M-profile Vector Extension(MVE)的Cortex-M55,同时对Armv8.6-A、Armv8-M和Armv8.1-M的架构进行进一步优化。 4. Arm Streamline线性性能分析器 增加了Cortex-A34,Cortex-A77系列CPU的支持以及Mali-G57,Mali-G77系列GPU的支持。 5. Graphic Analyzer图形分析器 支持Android 10以上设备,包括支持使用OpenGL ES层驱动程序。

    时间:2020-04-08 关键词: 芯片 ARM 软件开发

  • 最吸引流量的苹果WWDC

    最吸引流量的苹果WWDC

    每年的三大开发者大会,苹果WWDC通常是最晚召开,但却是最吸引流量的。在常规四大系统(iOS、macOS、watchOS和tvOS)之外,果粉们总是期待着One More Things,期盼着有新硬件发布。但这一次,没有更新MacBook,没有发布新iPad Pro,更没有传说中的iPhone SE 2。今年的WWDC是一次纯粹的软件发布会,是真正面向开发者的大会。这才是回归WWDC的初心。 尽管不忘初心这个词,已经被国内科技营销用到了泛滥;但做出好用的、出色的产品,从来都是科技公司的第一要事。首先是好用稳定,其次才是炫酷出色。 平心而论,今年的WWDC发布的新版软件并没有太多惊喜,而是从小处着手、从细微修补,着重于完善上一代产品的体验缺失。iOS 12的很多新功能要么在预期之内,比如iOS上的诸多应用覆盖到macOS,要么是竞争对手的升级改进,比如照片自动标签、手机使用管理和卡通形象都可以在Android手机上找到先行者。 不过,苹果用户如今对WWDC的最大期望,或许并不是各种炫酷全新功能发布高潮迭起,而是软件产品稳定好用。毕竟大家都理解,黑科技不是每年都有,革命颠覆也无法源源不断,稳定人性的体验才是用户每天相处面对的。 为什么这么说?因为过去两年,苹果的各种软硬件系统Bug实在是有点对不住苹果的金字招牌,也对不住乔布斯定下的追求完美的初心。毫不客气地说,iOS 11或许是用户吐槽最多的一代系统,对于以软件稳定流畅著称的苹果来说,这实在有点蒙羞。在面对iOS 11的诸多bug时,库克也是态度尴尬。 所以,看到WWDC上苹果自称“iOS 11用户满意度高达95%”的时候,微博和Twitter上都是“呵呵”,海内外一片尴尬而不失礼貌的微笑。据《华尔街日报》统计,自去年9月正式上线以来,iOS 11共有14次软件更新,解决了67个软件问题,比iOS 10增加了46%;而过去一年苹果的各种Bug问题超过了73个,较四年前的17个几乎翻了四倍。 这几年到底发生了什么?从2012年开始,苹果每年WWDC统一发布新版iOS和macOS系统,而之前macOS则是每两年升级一次。产品周期缩短,使得软件工程师没有足够的时间进行测试和Debug。另一方面,适配设备增加也增加了软件Debug的难度。现在苹果的在售设备已经达到了40款,比五年前多了10款。而现在iOS 12的支持设备上溯到2013年,甚至比iOS 11还要长久一年。 不过,最根本的问题或许还是企业文化上。2015年,Tumblr前CTO、Instapaper创始人曾经抨击苹果过于追求每年发布新系统的市场效果,而失去了追求产品尽善的完美主义,把营销优先置于产品优先之上。三年时间过去了,最核心系统iOS的bug不减反增,甚至出现了去年12月出现的iOS 11因为通知时间限定错误,导致iPhone大量闪退的低级错误。 尽管苹果市值高达9400亿美元,iPhone年销量高达2.23亿部,但在潮流不断变化的科技行业,苹果远远不能说是高枕无忧,尤其是在已经饱和的智能手机行业。IDC的数据显示,2017年全球智能手机市场首次出现增长停滞,同比仅增长0.5%,较2016年的2%增幅近一步放缓;去年第四季度,美国和中国这两大智能手机市场更双双出现了下滑。 实际上,在全球市值最高的五大科技公司当中,虽然苹果是市值和营收最高的,但也是竞争形势最严峻的。亚马逊、谷歌、微软、Facebook都在各自领域占据着不可撼动的绝对优势(分别是电商与云计算、搜索与移动平台、桌面平台与生产力、社交网络),只有苹果是仅近以少数市场份额成就了霸业。多年以来,iOS在全球智能手机市场的份额一直徘徊在15%左右,2017年仅有14.7%(IDC数据),与2014年相比基本持平。 虽然苹果主要靠卖硬件挣钱,软件系统大多是随机附送的,但软硬件一体的体验才是苹果产品的核心竞争力。即便过去两年苹果一直在努力推进产品与营收多元化,不断提升服务业务营收,近期更关注移动广告营收,但iPhone过去现在未来都会是苹果的不变基石。iOS生态系统是苹果的护城河,也是苹果的核心竞争力。 在WWDC开幕致词上,库克再次强调了这一优势——目前全球共有2000万苹果开发者。经营了十年的App Store每周都会迎来5亿用户。苹果平台累计为开发者带来了超过1000亿美元的营收。10多亿苹果设备用户是苹果拓展任何新领域的基石,虽然ARKit发布仅有一年,但苹果已然成为拥有上亿设备的全球最大AR平台。 多年以前乔布斯确定了苹果的商业模式——作出伟大的产品和服务,消费者自然愿意为这样的产品付出高价。在乔布斯离世之后,库克在他打下的平台基础上继续巩固、深耕、推进、扩张,成就了现在接近万亿美元的苹果霸业。但如果苹果不珍惜自己曾经追求完美的品牌形象,那么用户迟早会逐渐流失;iOS的大坝或许不会顿然倒塌,也会出现一个个蚁穴。 如果说看完今年的WWDC发布会,有什么期待的话,我希望9月份发布的正式版软件系统能够稳定与成熟,改变过去两年苹果新版系统粗枝大叶漏洞频出的形象。不求惊喜迭起,但求少Bug。

    时间:2019-08-16 关键词: 软件开发 iOS wwdc 电源新品

  • 解读任正非的新年公开信

    解读任正非的新年公开信

    近日任正非的公开信《全面提升软件工程能力与实践,打造可信的高质量产品》刷屏了,作为一个软件工程专业科班出身的软件开发从业者,自然是引起了我的好奇。仔细阅读之下确实让我大吃一惊,看似八股官方文,但细看之下是作者对于软件工程的理解确实非常深刻,各种专业术语信手拈来,比喻恰到好处。我对华为的研发其实一直挺好奇的,从传统的硬件公司,到现在软硬件齐头并进,华为手机销量都已经超过了苹果,可见华为的软硬件研发实力早已是全球领先了。公开信中的这一句:二十年前的 IPD 变革,重构了我们的研发模式,实现了从依赖个人、偶然性推出成功产品,到制度化、持续地推出高质量产品的转变。也揭示了华为的软件研发能做到领先水平的原因。华为是在 1999 年开始从 IBM 引进 IPD 的,到今年 2019 年正好 20 年,在过去的 20 年里,IPD 帮助华为从游击队变成了正规军,研发队伍从几千人到几万人,软件产品也覆盖到手机操作系统、应用、云服务。我对 IPD 是不甚了解的,只知道 IPD(Integrated Product Development,集成产品开发)是一种产品开发方法,但如果说软件产品的开发方法,我是比较熟悉的,那就是软件工程么!任正非发出的这封信的大背景也很特殊,2018 年中美贸易战开始,中兴、华为首当其冲成为美国开刀的对象,跟风站队的澳大利亚、新西兰、英国也跳出来抵制华为,说华为不安全,可能含有间谍软件,窃听国家机密,这帽子一扣是很难扯清的!这就是为什么整封信从标题开始,一共 17 次提到两个关键字:“可信”。只有让客户觉得华为的产品“可信”,华为才能尽快走出这场危机,那么怎么才能做到可信?如果你是餐厅老板,有人造谣你的厨房脏乱差,员工上完厕所不洗手,你怎么办?最好的办法自然是用先进的管理流程,并且让整个做菜的过程尽可能公开透明。所以信中有这样一句话:我们要转变观念,追求打造可信的高质量产品,不仅仅是功能、特性的高质量,也包括产品开发到交付过程的高质量。要转变观念,不再只认结果的质量,还要追求过程质量了!而如何追求过程质量呢?那就是要:“全面提升软件工程能力和实践”如果信到此为止,也就是个普通官方八股文了。领导们么,可不就是喜欢指个大方向,说你们要用软件工程,要实施软件工程,至于怎么用,那是你们的事情,毕竟做领导的哪有几个真的懂软件工程的,难得的是这封信居然有很多具体怎么做的内容。软件项目管理金三角先看这一句:我们各级管理者和全体员工都不得以进度、功能、特性等为理由来降低可信的要求,确保可信的要求在执行过程中不变形。振聋发聩呀同志们,热泪盈眶呀!生活中多少次:三个月的项目老板说你一个月就要给我做完;做到一半的项目,PM 说这个功能很重要,我们要加上去。最终怎么办?牺牲质量呗!又想要马儿跑得快又想要马儿不吃草,天底下哪有那么好的事情!软件工程里面早就告诉我们了:时间、范围、成本这三个要素直接决定了产品的质量! 希望各位老板别光学乔布斯,也学学任正非!程序开发2018年底程序员被裁的不少,很多程序员开始担忧起前景来,其实如果你能做到这下面要求的应该是不担心被裁的!我们要从最基础的编码质量做起,视高质量代码为尊严和个人声誉。代码就像是高楼大厦的一砖一瓦,没有高质量的代码,可信的产品就是空中楼阁。我们要优化并遵循公司各种编程规范,遵从架构与设计原则,熟练使用各种编程库和API,编写出简洁、规范、可读性强、健壮安全的代码。这一段是说给我们程序员看的,这其实也是对程序员的基本要求,大家看看自己,看看身边,真能做到的有多少?像我一样觉得自己还做的不够好的,咱还是努力学习吧,多练练,多用点心肯定更没问题的。架构说完程序员开始说架构师了:我们要深刻理解架构的核心要素,基于可信导向来进行架构与设计。看到没有,又提到可信了,架构设计的时候,别再天马行空,啥新酷用啥,啥流行用啥,一定要“可信导向”,架构设计目标先搞清楚!再是细节:在确保可信的前提下,要在性能、功能、扩展性等方面做好权衡;慎重地定义我们的模块与接口,真正做到高内聚与低耦合;我们要遵循权限和攻击面最小化等安全设计原则,科学设计模块之间的隔离与接口,提升安全性;低阶架构与设计要遵循高阶的架构与设计原则,在充分理解原有架构与设计的情况下,持续优化;我们要熟悉各种设计模式,重用公共成熟组件和服务,避免重复劳动。“高内聚与低耦合”,“权限和攻击面最小化”,“模块之间的隔离与接口”,“重用公共成熟组件和服务”……道理我都明白,做到可不容易!技术债务华为这些年高速发展,早些年为了追求速度肯定也没少走捷径,这些年下来也肯定没少欠技术债务,现在也是一个从追求速度到追求质量转型的契机。所以信中说完架构开始讲技术债务了:我们要重构腐化的架构及不符合软件工程规范和质量要求的历史代码。我们知道,再好的架构,其生命力也是有限的。随着时间的推移、环境的变化以及新技术、新功能特性的引入,架构也会腐化。面对腐化了的架构,要毫不犹豫地去重构它。同时主动以可信设计原则为导向,去重构不符合软件工程规范和质量要求的历史代码,提升软件架构的生命力。我们都知道,没有万能的架构,只有适合当时需求,当时技术条件和人员的架构,时间推移了很多架构就满足不了要求了,就需要重构了!作为80后,小时候其实生活挺艰苦的,那时候我们穿衣服都讲究的是:“新三年,旧三年,缝缝补补又三年”,架构也一样嘛,不满足需求我们先修修补补,真要重构挑战还是不小的,但是不去做它会一直成为发展的一个障碍,这封信也算是推了一把:“面对腐化了的架构,要毫不犹豫地去重构它。”,当然你重构,也不要忘记“可信”这个根本目标:“同时主动以可信设计原则为导向”。其实Google在这方面已经走在前面了,一直鼓励重写代码,任何软件每隔几年就重写一遍,这样可以优化代码,采用最新技术,去掉一些没有价值的功能,最重要的是让新员工得到锻炼,保持高昂的斗志。不知道这点是不是华为在像Google学习!安全这些年,互联网发展很快,但是安全事故却层出不穷:开房记录被泄漏、密码被泄漏、比特币被盗……这暴露出业界其实对安全是不够重视的,所以信中也不止一次提到安全问题:公司已经明确,把网络安全和隐私保护作为公司的最高纲领。”“我们要深入钻研软件技术,尤其是安全技术。”“我们要遵循权限和攻击面最小化等安全设计原则,科学设计模块之间的隔离与接口,提升安全性”“编写出简洁、规范、可读性强、健壮安全的代码。要打造一个“安全”的软件,就是首先要有安全意识,然后要懂安全技术,在整个开发过程中要从架构设计、代码方方面面去注意。技术是工具这些年开发界一直有些不好的风气,就是都认为自己的技术是最牛的,写后端的看不上前端的,用angular的看不上vue,写PHP的认为自己的语言是全世界最好的,开发的还看不上测试的。但是信中这一句话不要忽视呀:“软件技术是我们打造产品的基本工具”,技术只是工具,只是我们用来打造产品的工具!“技术是否先进,技术选择是否合理,将决定我们软件的高度;”,技术的选型,不仅看的是不是先进,还要看是不是适合当前产品项目,并不是什么什么新酷就用什么!“我们要深入学习架构与设计、编码、测试、安全、可用性、性能、维护性、体验等技术,并科学运用这些技术。”,既然技术只是工具,那么我们就没必要给自己设置各种技术壁垒障碍。如果开发就只学编码,测试就只学测试,认为安全那应该是搞安全的事,这样的话是非常不利于团体协作的,每个人都在一个领域能有深入的钻研,同时对其他领域有一定了解,对个人,对团队是非常有利的一件事。这样也不需要DevOps这种为了兼顾开发、测试、运维三种角色而存在的工种!一致性我们做软件开发的都知道,也看过很多段子:从客户的需求,到最终的实现,总是差别很大;我们在项目初始的时候制定了很多规范,却总是不了了之,难以执行;我们良好的设计,在编码实现的时候,因为赶进度、开发人员偷懒等各种原因绕开设计,抄近路,最后设计和编码无法一致……一致性在软件开发领域一直都是理想美好而现实却很残酷,信中也提到:我们要遵守过程的一致性。遵守适用的法律法规、遵循业界共识的标准、规范,确保规范到实现的一致性、代码到二进制的一致性。架构要符合架构原则,设计要遵循设计模式,代码要符合编程规范,最终做到需求与实现一致,达成各项对客户的承诺。我们只有脚踏实地做好每一步,才能真正打造出可信的高质量产品。无论这个目标有多难,但是从“遵守过程的一致性”开始,在每个阶段都去做到一致性,“脚踏实地做好每一步”,还是有希望做到,“真正打造出可信的高质量产品”。改变习惯在实施软件工程的过程中,有两个难题,一个就是转变思想,另一个就是改变习惯了,这种改变的过程也一定是很痛苦的。为此,我们要改变行为习惯,追求精品。我们要开放透明、积极和勇于揭示问题并主动推动改进。软件开发是一种创造性和艺术性的工作,需要充分发挥我们的聪明才智和潜力。我们要改变只重视功能结果、不重视代码质量的行为习惯,要严格遵守软件工程规范;改变被动的修修补补;改变碎片化知识获取,主动去学习提升并贡献经验、代码,形成共享知识库。我们需要改变的行为和习惯还有很多,对绝大多数人来讲都将是一个痛苦的转变过程,会脱一层皮,但我相信大家能够迎接这种挑战。从事软件开发工作越久,恐怕养成的坏习惯就越多,信中列的几条都很有代表性:“只重视功能结果、不重视代码质量”“功能实现完了就完事了,质量那是QA的事”,这种坏习惯不改质量是很难有保障的“不遵守软件工程规范”软件工程的各种规范不是约束,也不是摆设,而是实实在在为了团队整体更好的协作。对于定好的规范,要严格执行,不合理的规范,也要提出来一起改进。“被动的修修补补”为了能继续凑合,继续修修补补,而没有考虑重构改进,也是一个不好的习惯。“碎片化知识获取,不主动去学习提升”在现在的信息时代,碎片化的知识获取是容易的,但是像软件工程这种知识,仅仅通过碎片化的学习还是不够的,必须的主动的,系统的去学习,虽然这个过程会很辛苦,但是是非常有必要的。“不愿意贡献经验、代码,不去形成共享知识库”很多人不愿意去分享知识和经验,有的是因为太懒,有的是觉得没什么好处。但是分享本身就是一个学习和提升的最好手段!知识库这种事不仅是对别人,对自己也是一个特别好的过程。想象下你新加入一个团队,如果这个团队有很好的知识库,你可以通过知识库很快的上手工作,同样的,如果你把你的经验写到知识库,后面的新人也可以受益你的贡献!“软件工程”和“质量工程”需要依靠架构技术“软件工程”和“质量工程”需要依靠架构技术,而不是依靠CMM和QA管理流程。一切工程问题,首先要思考能否通过技术解决,当前技术无法解决的问题,暂时由管理手段代劳,同时不停止寻找技术手段。所有的涉及到人的管理最终都要归结到人管理还是制度管理的问题上,软件项目管理也不例外,如果过多的依赖于人的管理,那么项目经理的职责就太重了,优秀的项目经理本身就是稀缺资源,最终会变成一个瓶颈。所以通过架构技术和工具,把管理流程落实下来是一个非常好的方式。有两个例子可以很好的说明这点。早些年软件项目团队是非常庞大的,各个服务庞大模块紧密,所以管理成本很高,后来微服务这种架构提出后,将大的服务拆成小的服务,整个组织也从大项目部门拆分成各个小组,各小组可以独立更新维护。另一个例子是以前单元测试和代码审查还有自动部署很难执行,后来借助源代码管理工具和CI(Continuous integration,持续集成)工具,就可以很容易的进行代码审查、并且可以确保单元测试测试跑通过后才进行部署。这一点其实信中也有体现:我们将全面强化以Committer角色为核心的代码审核和提交机制,代码经过更加严格和系统的审核才能合入版本。为此我们将建立一支更高水平的Committer角色群体,负责软件架构的看护、代码的审核和提交,整体保障合入代码的高质量。我们要变革考核机制,要让架构设计好、代码写得好的人脱颖而出,对编程能力不满足要求的人给予帮助和培训。但任何人如果编写的代码长时间不能合入版本,将会被团队抛弃。软件工程就像一个国家的农业软件工程就像一个国家的农业,是最基础的设施!很感动,这些年软件工程被提起的其实不多,大家关注的更多是各种新酷的技术,而对于这种软件开发最基础的理论视而不见。还有人一提到软件工程,就马上说软件工程不是银弹。软件工程从来不说自己是银弹,就像现代医学,也不会号称自己包治百病,只会不断改进,对症下药!

    时间:2019-01-19 关键词: 任正非 软件开发

  • 谈一谈我在软件开发中的最佳实践

    谈一谈我在软件开发中的最佳实践

    “描述一个事物,唯有一个名词定义它的概念,唯有一个动词揭露它的行为,唯有一个形容词表现它的特征。要做的,就是用心去寻找那个名词、那个动词、那个形容词……”—— 福楼拜 (Gustave Flaubert)我想讲个故事。很久很久以前(一般讲故事都是这样开头吧), 两个老工程师在一起聊天,谈各自生涯中最自豪的工程。其中一个先讲述了他的杰作:“ 我们建造的桥,横跨一个峡谷,峡谷很宽很深。我们花了两年时间研究地质,选择材料。聘请了最好的工程师团队来设计方案,而这又花了五年时间。 我们签下了最大的工程队,委托他们建造基础结构、塔墩、收费亭,以及用于连接桥梁和高速公路的道路。桥面下层是铁路,我们甚至还修了自行车道。 那座桥花费了我数年的心血。”另外一个听完之后,陷入了沉思,过了一会儿,说到:“ 有一天晚上,我和一个朋友喝了点伏特加,然后我俩扔了一根绳子,越过一个河谷。呃…… 就是一根绳子,两头系在两颗树上。 河谷两边各有一个村庄,起初,有人加了个滑轮,用来传递包裹。然后,有人拉起了第二根绳子,勉强可以走走,虽然很危险,但小伙子们很喜欢。 后来,一群人重新修建了一下,使得更牢固。于是,女人们也开始从上面走,每天带着她们的农产品过桥。 就这样,在桥的另一边形成了一个市场。因为地方开阔,造了很多房子,慢慢地发展成了一个镇子。 绳索桥被木桥替代,这样就可以走马车了。 后来,镇上的人们修了一座真正的石桥。再然后,人们又把石料改成了钢材。 如今,那座钢构悬索桥依然伫立在那里。”前一个工程师沉默良久,说到:“ 有意思。我那座桥建成大约十年后,被拆除了。事实证明我们选错了地点,建好的桥没人用。据说有几个野路子的家伙,在下游几英里处,拉了一根绳子,所有人都从那走。”金门大桥(旧金山)我很喜欢这个故事。故事的出处,在一款消息队列产品—— ZeroMQ 的官方指南第6章里。说完故事,我想聊聊软件开发中,常常可以听到的一个概念 —— Best Practice :最佳实践。Wikipedia 上对其解释为:A best practice is a method or technique that has been generally accepted as superior to any alternatives because it produces results that are superior to those achieved by other means or because it has become a standard way of doing things.(最佳实践是一种:因其产生的结果优于其它选择下的结果,或其已经成为一种做事的标准,从而被普遍认可优于任何替代方案的方法或技术。)这个概念源于管理学,然后在 IT 界泛滥。简而言之,就是所谓“正确的做法”。最佳实践本身是美好的存在,犹如夜空中的一轮明月,照亮黑暗中的方向,指引着摸索前行的凡人。但凡事有度,子曰:“过犹不及。”我今天想说的,就是这月亮的背面。(传说中,月球背面隐藏着…… 嘘~)潮汐锁定导致月球永远以同一面朝向地球首先,最佳实践容易带来思想包袱,让人无法专注于解决问题本身。总是希望采用最好的技术方法,不愿意在不正确的做法上浪费时间,导致瞻前顾后,甚至裹足不前。此时的最佳实践,已然成为了一种毒药,一旦偏离了问题本身这个出发点,就会不知不觉走进“宏大构想”的思维陷阱。把简单的问题复杂化,阻碍了迈出第一步,直到能规划出“包罗万象”的解决方案后才肯动手,拖延症就这样来了,时间却走了。你想好了未来每一天怎么过吗…… 没想好? 那……不活了?其次,对最佳实践的执念容易让人钻牛角尖,将目标的重心带偏。过度关注实施过程是否符合标准化,忽视了项目中其它重要的东西,比如用户体验,比如实际需求。就像故事里讲的那样:第一座大桥,几乎是教科书般的标准化路数,可产品落地后和客户需求却差了好几英里;第二个看上去很野路子,但精准地解决了痛点,从始自终都是紧紧围绕实际需求迭代,每一次的进步都可以产生效用,这才叫杀手级应用。这让我想起了 Plan-9 的传说。你听说过 Plan-9 OS 吗? 一款由贝尔实验室的极客们打造的用于完善 UNIX 不足的操作系统。什么不足?在 UNIX 的哲学中,有一条叫做 “一切皆文件” ,但实际上UNIX本身并没有严格遵从这一条。于是,Plan-9 OS 完美实现了这一点。然后呢……? 没有然后了。它从没进过市场,所以如果你没听说过它,一点也不奇怪。Plan-9 OS 没有解决任何现实问题,没人在乎 “一切皆不皆文件”。这种执念的另一种表现就是工程师思维,沉迷于奇技淫巧中无法自拔,程序员尤其容易中招。比如性能优化。“优秀的程序员应该榨干每一字节内存”,听起来很熟悉,不是吗?但经济学上来讲,边际效应决定了一次项目中,越优化性价比越低。有一个很容易被忽略的事实:硬件其实比程序员要便宜。再比如对设计模式的崇拜。设计模式当然是好东西,但如果像强迫症一样使用它们,坚持用上它们才是正确的编程,就会导致按图索骥,强行让问题去适应设计模式,而不是让解决方案针对问题,这就本末倒置了。我有个基友,C++ 极客。毕业后入了腾讯,积累了巨额财富后,自己创业了。当然,当老板可比写 C++ 难多了,于是现在又去积累巨额财富了。想当年和那厮聊天,言必出设计模式,没事侃正则,再没事就研究 GC 策略 (好像玩 C++ 的普遍这德性) 。前不久看他代码,差点没认出来,这家伙画风一转,现在连接口都懒得多用(估计看到这,某些狂热分子肯定在破口大骂:你什么意思,你说你没用面向接口编程?)那位兄台甚至都懒得多聊,轻描淡写来一句,“没心思,以后有需要再加。”顺便扯一句,那哥们最近负责开发一款手游,他跟老板汇报的时候,预估的研发周期要12个月,然后老板跟他说:“好,12月出公测。” (哈~ 估计他肯定舌头打结把“12个月”说成了“12月”)。看到这的你,是否回忆起了你的老板?这也是我接下来想说的关于最佳实践的另一个问题:项目实施。工作数年,大小项目经历若干,慢慢体会到,一个项目的开发顺利与否,并不在于技术选型是否为最佳实践,更多的时候,取决于开发方案和技术储备之间的平衡。做项目毕竟是要讲方案落地的,如果最佳实践中的技术成本,超出了开发者的落实能力,那就是坑,这时盲从最佳实践无异于挖坟。如果是一个人的项目,抽时间恶补一通,兴许能填填坑,这取决于IQ。但要是一个团队,那就不是什么 IQ,EQ,QQ 的问题了,这中间产生的学习成本,集体培训成本,反复沟通成本,大量的初级错误,千奇百怪的代码,互相冲突引发的焦躁情绪,等等。这些负面的东西如果不能妥善的处理,足以抵消掉最佳实践带来的好处。别忘了,deadline 正在迫近。我自己曾经在一个项目组里,强行推行 Git 做源代码管理,当时组里共9人,有7人只会 SVN,但我坚持 Git 是 “最佳实践”。要不说年少无知少不更事呢,罢了,后来的事情我不想回忆了…… 那次项目之后,我再也不在一群只会 SVN 的队伍里提 Git 了。一个人做软件已经很难,比这更难的,是一群人做软件。当尘埃落定,蓦然回首,最佳实践很可能没你想象中那么重要。它更多的是一种精神层面的求道,并非物质世界的必要。扎克伯格 ( Mark Zuckerberg ) 于2004年在哈佛柯克兰公寓 ( Kirkland House ) 里写出 TheFacebook 的时候 ( 次年更名为Facebook ) ,用的是 “世界上最好的编程语言” PHP。这门可能是业界被吐槽次数最多的语言一直支撑着FB帝国的诞生,直到席卷全球。Stack Overflow 的联合创始人 Jeff Atwood 曾公开揶揄 Facebook 是一家 “召集全球顶级程序员在 Windows XP 上写 PHP ” 的公司。但这无所谓,24年前的马克也不纠结。一直等到需要的时候 (2010年),Facebook自己动手研发了一个编程语言 —— Hack,来解决 PHP 带来的危机。《社交网络》最佳实践,关键在时机(Timing)。如果说用 Facebook 这个 “根本不存在” 的网站来举例,纯属虚构的话,那我们来说点真实的例子,Web 技术的基石——HTML。由20世纪最重要的100人之一的 Tim Berners-Lee 创造的 HTML,其发明之伟大,足以单独开篇博文来赞美了,这里就不赘述了。这样一个造福全人类的神作,本身的设计结构绝非完美,甚至可以用混乱不堪来形容。没有严格统一的约束,形同虚设的规范,标准化进程的难产。以至于在很长一段时间内,连自身元素的定义,都可以向浏览器厂商妥协。但是,种种被人诟病的存在,丝毫不影响 HTML 改变世界的脚步。你我今天能相会于园,皆仰赖它的诞生。同样的例子还发生在 Web 世界另一个巨擎上——JavaScript。当今世界,Web 前端技术已经水银泻地般肆虐整个开发界,前端框架百花齐放、JS 衍生品鳞次栉比。所有这一切的背后,全都源于上世纪90年代横空出世的 JavaScript。那么,JavaScript是最佳实践吗?别逗了,如果有什么语言可以和刚才说到的 PHP 竞争一下谁被骂的次数更多,那非 JavaScript 莫属。这个仅花了十天设计出来的语言,打一出身就被贴上了怪胎的标签。混乱的标准,多样的实现,安全漏洞,语法随意,反人类…… 总之,JavaScript 和最佳实践半毛钱关系都扯不上,但它却是撑起当今互联网半壁江山的擎天柱。所以,用最接地气地话来说,不管黑猫白猫,逮着耗子就是最佳实践猫。彼之蜜糖,吾之砒霜。所谓最佳实践,其定义本身往往也是分歧的源头。什么是最佳?这个最佳是独一无二的吗?世界上有很多很多现实问题,可能根本就没有所谓的最佳实践。请听题,世界上最好的编程语言是哪个?第二题,世界上最好的文本编辑器是哪个?朋友,这天还聊得下去吗……最后,说一个我自己的故事。很久很久以前,为了找一款满意的文本编辑器,我干了一件可能是前无古人,后不知道有没有来者的蠢事 —— 我打开 Wikipedia,搜索 “ text editor ” ,然后转到一个叫做 “ List of text editors ” 的页面,接下来的一个月,我几乎把当时那个页面上,所有我能下载安装的文本编辑器,全部试用了一遍……嗯?你问我为什么这么做?呵呵,不把全世界的文本编辑器遍历一遍,我怎么知道哪个是最好的?这事细节我不想再提了,我也不想回忆了。要不说年少无知少不更事呢,时至今日,我想不出比这更愚蠢的事了。WTF~~这个页面上的表格行数逐年增多如今,再有人问我最好的编程语言或者最好的文本编辑器的问题的话,我会说:“朋友,要打架吗?”这两个问题的最佳实践,唯有暴力。

    时间:2019-01-17 关键词: 软件开发

  • 软件开发之路

    0.引言 软件开发之路是充满荆棘与挑战之路,也是充满希望之路。Java学习也是如此,没有捷径可走。梦想像《天龙八部》中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力,是很不现实的。每天仰天大叫"天神啊,请赐给我一本葵花宝典吧",殊不知即使你获得了葵花宝典,除了受自宫其身之苦外,你也不一定成得了"东方不败",倒是成"西方失败"的几率高一点。 "不走弯路,就是捷径",佛经说的不无道理。 1.如何学习程序设计? Java是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于Java,对C++等其他程序设计语言也一样管用。有编程高手认为,Java也好C也好没什么分别,拿来就用。为什么他们能达到如此境界?我想是因为编程语言之间有共通之处,领会了编程的精髓,自然能够做到一通百通。如何学习程序设计理所当然也有许多共通的地方。 1.1 培养兴趣 兴趣是能够让你坚持下去的动力。如果只是把写程序作为谋生的手段的话,你会活的很累,也太对不起自己了。多关心一些行业趣事,多想想盖茨。不是提倡天天做白日梦,但人要是没有了梦想,你觉得有味道吗?可能像许多深圳本地农民一样,打打麻将,喝喝功夫茶,拜拜财神爷;每个月就有几万十几万甚至更多的进帐,凭空多出个"食利阶层"。你认为,这样有味道吗?有空多到一些程序员论坛转转,你会发现,他们其实很乐观幽默,时不时会冒出智慧的火花。 1.2 慎选程序设计语言 男怕入错行,女怕嫁错郎。初学者选择程序设计语言需要谨慎对待。软件开发不仅仅是掌握一门编程语言了事,它还需要其他很多方面的背景知识。软件开发也不仅仅局限于某几个领域,而是已经渗透到了各行各业几乎每一个角落。 如果你对硬件比较感兴趣,你可以学习C语言/汇编语言,进入硬件开发领域。如果你对电信的行业知识及网络比较熟悉,你可以在C/C++等之上多花时间,以期进入电信软件开发领域。如果你对操作系统比较熟悉,你可以学习C/Linux等等,为Linux内核开发/驱动程序开发/嵌入式开发打基础。 如果你想介入到应用范围最广泛的应用软件开发(包括电子商务电子政务系统)的话,你可以选择J2EE或.NET,甚至LAMP组合。每个领域要求的背景知识不一样。做应用软件需要对数据库等很熟悉。总之,你需要根据自己的特点来选择合适你的编程语言。 1.3 要脚踏实地,快餐式的学习不可取 先分享一个故事。 有一个小朋友,他很喜欢研究生物学,很想知道那些蝴蝶如何从蛹壳里出来,变成蝴蝶便会飞。有一次,他走到草原上面看见一个蛹,便取了回家,然后看着,过了几天以后,这个蛹出了一条裂痕,看见里面的蝴蝶开始挣扎,想抓破蛹壳飞出来。 这个过程达数小时之久,蝴蝶在蛹里面很辛苦地拼命挣扎,怎么也没法子走出来。这个小孩看着看着不忍心,就想不如让我帮帮它吧,便随手拿起剪刀在蛹上剪开,使蝴蝶破蛹而出。 但蝴蝶出来以后,因为翅膀不够力,变得很臃肿,飞不起来。 这个故事给我们的启示是:欲速则不达。 浮躁是现代人最普遍的心态,能怪谁?也许是贫穷落后了这么多年的缘故,就像当年的大跃进一样,都想大步跨入***主义社会。现在的软件公司、客户、政府、学校、培训机构等等到处弥漫着浮躁之气。就拿我比较熟悉的大连大工IT职业培训来说吧,居然打广告宣称"20多年的计算机职业教育,辽宁省十佳学校",殊不知中国计算机发展才几年,软件发展才几年,居然去报名的学生不少,简直是藐视天下程序员。培训出来的“程序员”大多不知道OO,OP为何物?社会环境如是,我们不能改变,只能改变自己,闹市中的安宁,弥足珍贵。许多初学者C++/Java没开始学,立马使用VC/JBuilder,会使用VC/JBuilder开发一个Hello World程序,就忙不迭的向世界宣告,"我会软件开发了",简历上也大言不惭地写上"精通VC/Java"。结果到软件公司面试时要么被三两下打发走了,要么被驳的体无完肤,无地自容。到处碰壁之后才知道捧起《C++编程思想》《Java编程思想》仔细钻研,早知如此何必当初呀。 "你现在讲究简单方便,你以后的路就长了",好象也是佛经中的劝戒。 1.4 多实践,快实践 彭端淑的《为学一首示子侄》中有穷和尚与富和尚的故事。 从前,四川边境有两个和尚,一个贫穷,一个有钱。一天,穷和尚对富和尚说:"我打算去南海朝圣,你看怎么样?"富和尚说:"这里离南海有几千里远,你靠什么去呢?"穷和尚说:"我只要一个水钵,一个饭碗就够了。"富和尚为难地说:"几年前我就打算买条船去南海,可至今没去成,你还是别去吧!" 一年以后,富和尚还在为租赁船只筹钱,穷和尚却已经从南海朝圣回来了。 这个故事可解读为:任何事情,一旦考虑好了,就要马上上路,不要等到准备周全之后,再去干事情。假如事情准备考虑周全了再上路的话,别人恐怕捷足先登了。软件开发是一门工程学科,注重的就是实践,"君子动口不动手"对软件开发人员来讲根本就是错误的,他们提倡"动手至上",但别害怕,他们大多温文尔雅,没有暴力倾向,虽然有时候蓬头垢面的一副"比尔盖茨"样。有前辈高人认为,学习编程的秘诀是:编程、编程、再编程,笔者深表赞同。不仅要多实践,而且要快实践。我们在看书的时候,不要等到你完全理解了才动手敲代码,而是应该在看书的同时敲代码,程序运行的各种情况可以让你更快更牢固的掌握知识点。 1.5 多参考程序代码 程序代码是软件开发最重要的成果之一,其中渗透了程序员的思想与灵魂。许多人被《仙剑奇侠传》中凄美的爱情故事感动,悲剧的结局更有一种缺憾美。为什么要以悲剧结尾?据说是因为写《仙剑奇侠传》的程序员失恋而安排了这样的结局,他把自己的感觉融入到游戏中,却让众多的仙剑迷扼腕叹息。 多多参考代码例子,对Java而言有参考文献[4.3],有API类的源代码(JDK安装目录下的src.zip文件),也可以研究一些开源的软件或框架。 1.6 加强英文阅读能力 对学习编程来说,不要求英语, 但不能一点不会,。最起码像Java API文档(参考文献[4.4])这些东西还是要能看懂的,连猜带懵都可以;旁边再开启一个"金山词霸"。看多了就会越来越熟练。在学Java的同时学习英文,一箭双雕多好。另外好多软件需要到英文网站下载,你要能够找到它们,这些是最基本的要求。英语好对你学习有很大的帮助。口语好的话更有机会进入管理层,进而可以成为剥削程序员的"周扒皮"。 1.7 万不得已才请教别人 笔者在Martix与Java论坛的在线辅导系统中解决学生问题时发现,大部分的问题学生稍做思考就可以解决。请教别人之前,你应该先回答如下几个问题。 你是否在google中搜索了问题的解决办法? 你是否查看了Java API文档? 你是否查找过相关书籍? 你是否写代码测试过? 如果回答都是"是"的话,而且还没有找到解决办法,再问别人不迟。要知道独立思考的能力对你很重要。要知道程序员的时间是很宝贵的。 1.8 多读好书 书中自有颜如玉。比尔盖茨是一个饱读群书的人。虽然没有读完大学,但九岁的时候比尔盖茨就已经读完了所有的百科全书,所以他精通天文、历史、地理等等各类学科,可以说比尔?茨不仅是当今世界上金钱的首富,而且也可以称得上是知识的巨富。 笔者在给学生上课的时候经常会给他们推荐书籍,到后来学生实在忍无可忍开始抱怨,"天呐,这么多书到什么时候才能看完了","学软件开发,感觉上了贼船"。这时候,我的回答一般是,"别着急,什么时候带你们去看看我的书房,到现在每月花在技术书籍上的钱400元,这在软件开发人员之中还只能够算是中等的",学生当场晕倒。(注:这一部分学生是刚学软件开发的) 1.9 使用合适的工具 工欲善其事必先利其器。软件开发包含各种各样的活动,需求收集分析、建立用例模型、建立分析设计模型、编程实现、调试程序、自动化测试、持续集成等等,没有工具帮忙可以说是寸步难行。工具可以提高开发效率,使软件的质量更高BUG更少。组合称手的武器。到飞花摘叶皆可伤人的境界就很高了,无招胜有招,手中无剑心中有剑这样的境界几乎不可企及。 2.软件开发学习路线 两千多年的儒家思想孔孟之道,中庸的思想透入骨髓,既不冒进也不保守并非中庸之道,而是找寻学习软件开发的正确路线与规律。 从软件开发人员的生涯规划来讲,我们可以大致分为三个阶段,软件工程师→软件设计师→架构设计师或项目管理师。不想当元帅的士兵不是好士兵,不想当架构设计师或项目管理师的程序员也不是好的程序员。我们应该努力往上走。让我们先整理一下开发应用软件需要学习的主要技术。 A.基础理论知识,如操作系统、编译原理、数据结构与算法、计算机原理等,它们并非不重要。如不想成为计算机科学家的话,可以采取"用到的时候再来学"的原则。 B.一门编程语言,现在基本上都是面向对象的语言,Java/C++/C#等等。如果做WEB开发的话还要学习HTML/JavaScript等等。 C.一种方法学或者说思想,现在基本都是面向对象思想(OOA/OOD/设计模式)。由此而衍生的基于组件开发CBD/面向方面编程AOP等等。 D.一种关系型数据库,ORACLE/SqlServer/DB2/MySQL等等 E.一种提高生产率的IDE集成开发环境JBuilder/Eclipse/VS.NET等。 F.一种UML建模工具,用ROSE/VISIO/钢笔进行建模。 G.一种软件过程,RUP/XP/CMM等等,通过软件过程来组织软件开发的众多活动,使开发流程专业化规范化。当然还有其他的一些软件工程知识。 H.项目管理、体系结构、框架知识。 正确的路线应该是:B→C→E→F→G→H。 还需要补充几点: 1).对于A与C要补充的是,我们应该在实践中逐步领悟编程理论与编程思想。新技术虽然不断涌现,更新速度令人眼花燎乱雾里看花;但万变不离其宗,编程理论与编程思想的变化却很慢。掌握了编程理论与编程思想你就会有拨云见日之感。面向对象的思想在目前来讲是相当关键的,是强势技术之一,在上面需要多投入时间,给你的回报也会让你惊喜。 2).对于数据库来说是独立学习的,这个时机就由你来决定吧。 3).编程语言作为学习软件开发的主线,而其余的作为辅线。 4).软件工程师着重于B、C、E、D;软件设计师着重于B、C、E、D、F;架构设计师着重于C、F、H。 3.如何学习Java? 3.1 Java学习路线 3.1.1 基础语法及Java原理 基础语法和Java原理是地基,地基不牢靠,犹如沙地上建摩天大厦,是相当危险的。学习Java也是如此,必须要有扎实的基础,你才能在J2EE、J2ME领域游刃有余。参加SCJP(SUN公司认证的Java程序员)考试不失为一个好方法,原因之一是为了对得起你交的1200大洋考试费,你会更努力学习,原因之二是SCJP考试能够让你把基础打得很牢靠,它要求你跟JDK一样熟悉Java基础知识;但是你千万不要认为考过了SCJP就有多了不起,就能够获得软件公司的青睐,就能够获取高薪,这样的想法也是很危险的。获得"真正"的SCJP只能证明你的基础还过得去,但离实际开发还有很长的一段路要走。 3.1.2 OO思想的领悟 掌握了基础语法和Java程序运行原理后,我们就可以用Java语言实现面向对象的思想了。面向对象,是一种方法学;是独立于语言之外的编程思想;是CBD基于组件开发的基础;属于强势技术之一。当以后因工作需要转到别的面向对象语言的时候,你会感到特别的熟悉亲切,学起来像喝凉水这么简单。 使用面向对象的思想进行开发的基本过程是: ●调查收集需求。 ●建立用例模型。 ●从用例模型中识别分析类及类与类之间的静态动态关系,从而建立分析模型。 ●细化分析模型到设计模型。 ●用具体的技术去实现。 ●测试、部署、总结。 3.1.3 基本API的学习 进行软件开发的时候,并不是什么功能都需要我们去实现,也就是经典名言所说的"不需要重新发明轮子"。我们可以利用现成的类、组件、框架来搭建我们的应用,如SUN公司编写好了众多类实现一些底层功能,以及我们下载过来的JAR文件中包含的类,我们可以调用类中的方法来完成某些功能或继承它。那么这些类中究竟提供了哪些方法给我们使用?方法的参数个数及类型是?类的构造器需不需要参数?总不可能SUN公司的工程师打国际长途甚至飘洋过海来告诉你他编写的类该如何使用吧。他们只能提供文档给我们查看,Java DOC文档(参考文献4.4)就是这样的文档,它可以说是程序员与程序员交流的文档。 基本API指的是实现了一些底层功能的类,通用性较强的API,如字符串处理/输入输出等等。我们又把它成为类库。熟悉API的方法一是多查Java DOC文档(参考文献4.4),二是使用JBuilder/Eclipse等IDE的代码提示功能。 3.1.4 特定API的学习 Java介入的领域很广泛,不同的领域有不同的API,没有人熟悉所有的API,对一般人而言只是熟悉工作中要用到的API。如果你做界面开发,那么你需要学习Swing/AWT/SWT等API;如果你进行网络游戏开发,你需要深入了解网络API/多媒体API/2D3D等;如果你做WEB开发,就需要熟悉Servlet等API啦。总之,需要根据工作的需要或你的兴趣发展方向去选择学习特定的API。 3.1.5 开发工具的用法 在学习基础语法与基本的面向对象概念时,从锻炼语言熟练程度的角度考虑,我们推荐使用的工具是Editplus/JCreator+JDK,这时候不要急于上手JBuilder/Eclipse等集成开发环境,以免过于关注IDE的强大功能而分散对Java技术本身的注意力。过了这一阶段你就可以开始熟悉IDE了。 程序员日常工作包括很多活动,编辑、编译及构建、调试、单元测试、版本控制、维持模型与代码同步、文档的更新等等,几乎每一项活动都有专门的工具,如果独立使用这些工具的话,你将会很痛苦,你需要在堆满工具的任务栏上不断的切换,效率很低下,也很容易出错。在JBuilder、Eclipse等IDE中已经自动集成编辑器、编译器、调试器、单元测试工具JUnit、自动构建工具ANT、版本控制工具CVS、DOC文档生成与更新等等,甚至可以把UML建模工具也集成进去,又提供了丰富的向导帮助生成框架代码,让我们的开发变得更轻松。应该说IDE发展的趋势就是集成软件开发中要用到的几乎所有工具。 从开发效率的角度考虑,使用IDE是必经之路,也是从一个学生到一个职业程序员转变的里程碑。 Java开发使用的IDE主要有Eclipse、JBuilder、JDeveloper、NetBeans等几种;而Eclipse、JBuilder占有的市场份额是最大的。JBuilder在近几年来一直是Java集成开发环境中的霸主,它是由备受程序员尊敬的Borland公司开发,在硝烟弥漫的Java IDE大战中,以其快速的版本更新击败IBM的Visual Age for Java等而成就一番伟业。IBM在Visual Age for Java上已经无利可图之下,干脆将之贡献给开源社区,成为Eclipse的前身,真所谓"柳暗花明又一村"。浴火重生的Eclipse以其开放式的插件扩展机制、免费开源获得广大程序员(包括几乎所有的骨灰级程序员)的青睐,极具发展潜力。 3.1.6 学习软件工程 对小型项目而言,你可能认为软件工程没太大的必要。随着项目的复杂性越来越高,软件工程的必要性才会体现出来。参见"软件开发学习路线"小节。 3.2学习要点 确立的学习路线之后,我们还需要总结一下Java的学习要点,这些要点在前文多多少少提到过,只是笔者觉得这些地方特别要注意才对它们进行汇总,不要嫌我婆婆妈妈啊。 3.2.1勤查API文档 当程序员编写好某些类,觉得很有成就感,想把它贡献给各位苦难的同行。这时候你要使用"Javadoc"工具(包含在JDK中)生成标准的Java DOC文档,供同行使用。J2SE/J2EE/J2ME的DOC文档是程序员与程序员交流的工具,几乎人手一份,除了菜鸟之外。当需要某项功能的时候,你应该先查相应的DOC文档看看有没有现成的实现,有的话就不必劳神费心了直接用就可以了,找不到的时候才考虑自己实现。使用步骤一般如下: ●找特定的包,包一般根据功能组织。 ●找需要使用类,类命名规范的话我们由类的名字可猜出一二。 ●选择构造器,大多数使用类的方式是创建对象。 ●选择你需要的方法。 3.2.2 查书/google->写代码测试->查看源代码->请教别人 当我们遇到问题的时候该如何解决? 这时候不要急着问别人,太简单的问题,没经过思考的问题,别人会因此而瞧不起你。可以先找找书,到google中搜一下看看,绝大部分问题基本就解决了。而像"某些类/方法如何使用的问题",DOC文档就是答案。对某些知识点有疑惑是,写代码测试一下,会给你留下深刻的印象。而有的问题,你可能需要直接看API的源代码验证你的想法。万不得已才去请教别人。 3.2.3学习开源软件的设计思想 Java领域有许多源代码开放的工具、组件、框架,JUnit、ANT、Tomcat、Struts、Spring、Jive论坛、PetStore宠物店等等多如牛毛。这些可是前辈给我们留下的瑰宝呀。入宝山而空手归,你心甘吗?对这些工具、框架进行分析,领会其中的设计思想,有朝一日说不定你也能写一个XXX框架什么的,风光一把。分析开源软件其实是你提高技术、提高实战能力的便捷方法。 3.2.4 规范的重要性 没有规矩,不成方圆。这里的规范有两层含义。第一层含义是技术规范,多到http://www.jcp.org下载JSRXXX规范,多读规范,这是最权威准确最新的教材。第二层含义是编程规范,如果你使用了大量的独特算法,富有个性的变量及方法的命名方式;同时,没给程序作注释,以显示你的编程功底是多么的深厚。这样的代码别人看起来像天书,要理解谈何容易,更不用说维护了,必然会被无情地扫入垃圾堆。 3.2.5 不局限于Java 很不幸,很幸运,要学习的东西还有很多。不幸的是因为要学的东西太多且多变,没时间陪老婆家人或女朋友,导致身心疲惫,严重者甚至导致抑郁症。幸运的是别人要抢你饭碗绝非易事,他们或她们需要付出很多才能达成心愿。 Java不要孤立地去学习,需要综合学习数据结构、OOP、软件工程、UML、网络编程、数据库技术等知识,用横向纵向的比较联想的方式去学习会更有效。如学习Java集合的时候找数据结构的书看看;学JDBC的时候复习数据库技术;采取的依然是"需要的时候再学"的原则。 4.结束语 需要强调的是,学习软件开发确实有一定的难度,也很辛苦,需要付出很多努力,但千万不要半途而废。本文如果能对一直徘徊在Java神殿之外的朋友有所帮助的话,笔者也欣慰了。哈哈,怎么听起来老气横秋呀?没办法,在电脑的长期辐射之下,都快变成小老头了。最后奉劝各位程序员尤其是MM程序员,完成工作后赶快远离电脑,据《胡播乱报》报道,电脑辐射会在白皙的皮肤上面点缀一些小黑点,看起来鲜艳无比…… (文章提到的大连大工IT培训。本人没有任何攻击的意思)

    时间:2018-11-22 关键词: 软件开发

  • Atitit attilax提出的软件开发发展趋势与概念

    Atitit attilax提出的软件开发发展趋势与概念1. 长期化 复用化 跨平台 可移植性 12. 通用化 通用 化的渠道至少有3种 12.1. 模块化 12.2. 标准化接口 12.3. 改造将一种 经 过改造满足另一种 任务要求 加装部分模块 重构部分模块 12.4. 功能 经改进后 可由不同平台搭载,但仍完成同一种任务 13. 多功能化多任务 24. Dsl化可读性化 25. 小型化 26. 平台化 27. 系列化 梯队化 高中低档 2 1. 长期化 复用化 跨平台 可移植性不管是不是跨平台 可移植性,必须要复用性。。 2. 通用化 通用 化的渠道至少有3种2.1. 模块化2.2. 标准化接口2.3. 改造将一种 经 过改造满足另一种 任务要求 加装部分模块 重构部分模块2.4. 功能 经改进后 可由不同平台搭载,但仍完成同一种任务 经改进后,战斗力水平均产生了新的飞跃。 3. 组件化 模块化 快速组装化4.  多功能化多任务比如多个doa接口改为一个sql dsl接口。。实现多功能化。5. Dsl化可读性化6. 小型化7. 平台化8. 系列化 梯队化 高中低档 导弹发展需求与发展趋势分析_搜狐军事_搜狐网.mhtml

    时间:2018-10-11 关键词: 软件开发 atitit attilax

  • 软件开发中的资源管理

    软件开发中的资源管理

            前言:这是我在公司内部的一个培训,培训完之后特地整理成一篇文章。         应该说这是一个很大的题目,在这里我只是简单谈谈我的一些心得体会,不当之处,还请大家赐教。         要论述软件开发中资源处理,首先要明确软件开发中涉及到哪些资源。软件开发中涉及三方面的资源:人力资源、代码资源和文档资源。本文重点谈论如何管理代码资源和文档资源。          代码资源一般需要通过版本管理工具进行管理。为什么需要版本管理工具?一方面是因为现代软件开发是一个团队活动,是需要进行协作开发的;另一方面版本管理具有回溯历史版本的功能,在排错中具有重要意义。 那么一般常用的版本管理工具有哪些呢?在我刚参加工作时,使用的是微软出品的VSS 6.0。VSS 6.0的优点是简单,上手快,缺点是不适合复杂的协作开发环境,比如它不支持多人同时迁出同一个文件。当然后来微软对VSS 6.0做了升级,不过我没使用过比VSS6.0更高的版本。现在使用的是SVN。SVN是一个开源的集中式的源码版本管理工具,在IT界中广泛使用。现在广泛使用的还有Git。Git是一个开源的分布式的源码管理工具,在开源社区广泛使用。现在它在IT企业中也慢慢流行。 我最经常使用的SVN有四个操作:迁出(check out):将服务器的版本下载到本地作为一个副本。提交(commit):将本地修改的代码上传到服务器更新(update):下载服务器上最新代码到本地恢复(revert):将本地修改的代码还原到上一个版本          使用SVN常见的目录结构是怎样的?具体如下图:        从上图可以看到一个svn版本库下一般有三个目录:trunk、branches和tags。trunk很好理解,就是存放最新版本代码的目录。为什么会有branches和tags?就是说它们的作用是什么?branches作为存放分支版本的目录,主要起到一个试验的作用。比如当你试验一个新的绘图引擎,你在主干版本试验就不太合适。因为主干版本的代码是经常处在剧烈变动的状态,很可能导致试验无法进行,同时你编写试验代码也会影响其它人的代码。因此稳妥的办法是你复制一份主干版本到branches目录下作为一个分支来试验,待试验通过后再和主干版本进行代码合并。tags主要作用在于存放不作改动的比较稳定的历史版本。比如你要对外发布版本,你不可能编译最新代码来获取一个版本来对外发布,因为这个版本虽然是最新的,但肯定不是最稳定的,因为没有经过严格测试。因此你需要从tags目录下找一个稳定的历史版本来发布。 说完了自主代码的管理,我们再谈谈第三方库的管理。首先第一个问题是:为什么需要第三方库?第三方库的作用在于资源重用,减少开发时间。很多时候如果没有第三方库,要按时完成一个软件项目的开发是一件很困难的事情! 其次谈一下第三方库的种类。第三方库大致分为两种:商业第三方库和非商业的开源第三方库。其中商业第三方库又可以分为提供源码的商业第三方库和仅提供接口文件和库文件的商业第三方库。 如何选择第三方库?我的建议有以下几条:1.       优先选择开源第三方库。理由是:可以降低开发成本,同时利于定制。2.       在没有好的开源第三方库的情况下优先选择提供源码的第三方库。理由是方便定制。3.       优先选择成熟度高的第三方库。那么如何判断一个第三方库的成熟度?可以从以下方面考察:考察第三方库的更新频率,毫无疑问更新频率越高表示越活跃,也有利于其成熟;是否有活跃的交流社区,有表示成熟度更高;考察其在搜索引擎的搜索结果条数,条数越多表示越成熟。 如何利用第三方库?最基础是直接使用其提供的接口,高级一点是根据需要添加接口,同时修改它的bug。比较高级的是在剖析它的源码之后进行定制。比如淘宝对MySQL和hadoop的定制。 谈完了软件开发中代码管理,再谈谈软件开发中的文档管理。我们谈谈在软件开发中文档可以分为一下几类:1.       设计文档。如概要设计、详细设计2.       交流文档。如内部会议记录、和甲方的交流邮件3.       经验总结。如技术总结、开发中用到的电子书         文档在软件开发的作用其实是不亚于代码的,但是现实中开发人员往往对文档不够重视。其中一个重要原因是不少开发人员体会不到文档的作用。那么文档到底有什么用?在我看来至少有两方面作用:首先设计方面的文档本身就是甲方要求的,你不想写都不行;二是文档可以作用过程资产来共享。比如项目经理不可能每来一个新同事都通过口头来介绍项目情况(因为项目经理没有这个精力和时间),肯定是需要发一些文档来给他看,让他自己来学习。又比如开发人员离职,不通过文档又如何把工作顺利交接到同事手中呢? 文档也是经常变动的,因此它也是需要版本管理工具进行管理的。 最后我们看到一个版本数据库的目录可以是这样的:在trunk目录是这样的:在doc目录是这样的:

    时间:2018-10-11 关键词: 软件开发 资源管理

  • LabVIEW软件开发

    时间:2018-07-31 关键词: LabVIEW 软件开发

  • 在Linux上如何得到一个段错误的核心转储

    本周工作中,我花了整整一周的时间来尝试调试一个段错误。我以前从来没有这样做过,我花了很长时间才弄清楚其中涉及的一些基本事情(获得核心转储、找到导致段错误的行号)。于是便有了这篇博客来解释如何做那些事情! 在看完这篇博客后,你应该知道如何从“哦,我的程序出现段错误,但我不知道正在发生什么”到“我知道它出现段错误时的堆栈、行号了! ”。 什么是段错误? “段错误segmentation fault”是指你的程序尝试访问不允许访问的内存地址的情况。这可能是由于: 试图解引用空指针(你不被允许访问内存地址 0); 试图解引用其他一些不在你内存(LCTT 译注:指不在合法的内存地址区间内)中的指针; 一个已被破坏并且指向错误的地方的 C++ 虚表指针C++ vtable pointer,这导致程序尝试执行没有执行权限的内存中的指令; 其他一些我不明白的事情,比如我认为访问未对齐的内存地址也可能会导致段错误(LCTT 译注:在要求自然边界对齐的体系结构,如 MIPS、ARM 中更容易因非对齐访问产生段错误)。 这个“C++ 虚表指针”是我的程序发生段错误的情况。我可能会在未来的博客中解释这个,因为我最初并不知道任何关于 C++ 的知识,并且这种虚表查找导致程序段错误的情况也是我所不了解的。 但是!这篇博客后不是关于 C++ 问题的。让我们谈论的基本的东西,比如,我们如何得到一个核心转储? 步骤1:运行 valgrind 我发现找出为什么我的程序出现段错误的最简单的方式是使用 valgrind:我运行 valgrind -v your-program 这给了我一个故障时的堆栈调用序列。 简洁! 但我想也希望做一个更深入调查,并找出些 valgrind 没告诉我的信息! 所以我想获得一个核心转储并探索它。 如何获得一个核心转储 核心转储core dump是您的程序内存的一个副本,并且当您试图调试您的有问题的程序哪里出错的时候它非常有用。 当您的程序出现段错误,Linux 的内核有时会把一个核心转储写到磁盘。 当我最初试图获得一个核心转储时,我很长一段时间非常沮丧,因为 - Linux 没有生成核心转储!我的核心转储在哪里? 这就是我最终做的事情: 在启动我的程序之前运行 ulimit -c unlimited 运行 sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t ulimit:设置核心转储的最大尺寸 ulimit -c 设置核心转储的最大尺寸。 它往往设置为 0,这意味着内核根本不会写核心转储。 它以千字节为单位。 ulimit 是按每个进程分别设置的 —— 你可以通过运行 cat /proc/PID/limit 看到一个进程的各种资源限制。 例如这些是我的系统上一个随便一个 Firefox 进程的资源限制: $ cat /proc/6309/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 30571 30571 processes Max open files 1024 1048576 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 30571 30571 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us 内核在决定写入多大的核心转储文件时使用软限制soft limit(在这种情况下,max core file size = 0)。 您可以使用 shell 内置命令 ulimit(ulimit -c unlimited) 将软限制增加到硬限制hard limit。 kernel.core_pattern:核心转储保存在哪里 kernel.core_pattern 是一个内核参数,或者叫 “sysctl 设置”,它控制 Linux 内核将核心转储文件写到磁盘的哪里。 内核参数是一种设定您的系统全局设置的方法。您可以通过运行 sysctl -a 得到一个包含每个内核参数的列表,或使用 sysctl kernel.core_pattern 来专门查看 kernel.core_pattern设置。 所以 sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t 将核心转储保存到目录 /tmp下,并以 core 加上一系列能够标识(出故障的)进程的参数构成的后缀为文件名。 如果你想知道这些形如 %e、%p 的参数都表示什么,请参考 man core。 有一点很重要,kernel.core_pattern 是一个全局设置 —— 修改它的时候最好小心一点,因为有可能其它系统功能依赖于把它被设置为一个特定的方式(才能正常工作)。 kernel.core_pattern 和 Ubuntu 默认情况下在 ubuntu 系统中,kernel.core_pattern 被设置为下面的值: $ sysctl kernel.core_pattern kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P 这引起了我的迷惑(这 apport 是干什么的,它对我的核心转储做了什么?)。以下关于这个我了解到的: Ubuntu 使用一种叫做 apport 的系统来报告 apt 包有关的崩溃信息。 设定 kernel.core_pattern=|/usr/share/apport/apport %p %s %c %d %P 意味着核心转储将被通过管道送给 apport 程序。 apport 的日志保存在文件 /var/log/apport.log 中。 apport 默认会忽略来自不属于 Ubuntu 软件包一部分的二进制文件的崩溃信息 我最终只是跳过了 apport,并把 kernel.core_pattern 重新设置为 sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t,因为我在一台开发机上,我不在乎 apport 是否工作,我也不想尝试让 apport 把我的核心转储留在磁盘上。 现在你有了核心转储,接下来干什么? 好的,现在我们了解了 ulimit 和 kernel.core_pattern ,并且实际上在磁盘的 /tmp 目录中有了一个核心转储文件。太好了!接下来干什么?我们仍然不知道该程序为什么会出现段错误! 下一步将使用 gdb 打开核心转储文件并获取堆栈调用序列。 从 gdb 中得到堆栈调用序列 你可以像这样用 gdb 打开一个核心转储文件: $ gdb -c my_core_file 接下来,我们想知道程序崩溃时的堆栈是什么样的。在 gdb 提示符下运行 bt 会给你一个调用序列backtrace。在我的例子里,gdb 没有为二进制文件加载符号信息,所以这些函数名就像 “??????”。幸运的是,(我们通过)加载符号修复了它。 下面是如何加载调试符号。 symbol-file /path/to/my/binary sharedlibrary 这从二进制文件及其引用的任何共享库中加载符号。一旦我这样做了,当我执行 bt 时,gdb 给了我一个带有行号的漂亮的堆栈跟踪! 如果你想它能工作,二进制文件应该以带有调试符号信息的方式被编译。在试图找出程序崩溃的原因时,堆栈跟踪中的行号非常有帮助。:) 查看每个线程的堆栈 通过以下方式在 gdb 中获取每个线程的调用栈! thread apply all bt full gdb + 核心转储 = 惊喜 如果你有一个带调试符号的核心转储以及 gdb,那太棒了!您可以上下查看调用堆栈(LCTT 译注:指跳进调用序列不同的函数中以便于查看局部变量),打印变量,并查看内存来得知发生了什么。这是最好的。 如果您仍然正在基于 gdb 向导来工作上,只打印出栈跟踪与bt也可以。 :) ASAN 另一种搞清楚您的段错误的方法是使用 AddressSanitizer 选项编译程序(“ASAN”,即 $CC -fsanitize=address)然后运行它。 本文中我不准备讨论那个,因为本文已经相当长了,并且在我的例子中打开 ASAN 后段错误消失了,可能是因为 ASAN 使用了一个不同的内存分配器(系统内存分配器,而不是 tcmalloc)。 在未来如果我能让 ASAN 工作,我可能会多写点有关它的东西。(LCTT 译注:这里指使用 ASAN 也能复现段错误) 从一个核心转储得到一个堆栈跟踪真的很亲切! 这个博客听起来很多,当我做这些的时候很困惑,但说真的,从一个段错误的程序中获得一个堆栈调用序列不需要那么多步骤: 试试用 valgrind 如果那没用,或者你想要拿到一个核心转储来调查: 确保二进制文件编译时带有调试符号信息; 正确的设置 ulimit 和 kernel.core_pattern; 运行程序; 一旦你用 gdb 调试核心转储了,加载符号并运行 bt; 尝试找出发生了什么! 我可以使用 gdb 弄清楚有个 C++ 的虚表条目指向一些被破坏的内存,这有点帮助,并且使我感觉好像更懂了 C++ 一点。也许有一天我们会更多地讨论如何使用 gdb 来查找问题!

    时间:2018-07-23 关键词: Linux 软件开发 代码

  • 4种用于构建嵌入式Linux系统的工具

    Linux 被部署到比 Linus Torvalds 在他的宿舍里开发时所预期的更广泛的设备。令人震惊的支持了各种芯片,使得Linux 可以应用于大大小小的设备上:从 IBM 的巨型机到不如其连接的端口大的微型设备,以及各种大小的设备。它被用于大型企业数据中心、互联网基础设施设备和个人的开发系统。它还为消费类电子产品、移动电话和许多物联网设备提供了动力。 在为桌面和企业级设备构建 Linux 软件时,开发者通常在他们的构建机器上使用桌面发行版,如 Ubuntu 以便尽可能与被部署的机器相似。如 VirtualBox 和 Docker 这样的工具使得开发、测试和生产环境更好的保持了一致。 什么是嵌入式系统? 维基百科将嵌入式系统定义为:“在更大的机械或电气系统中具有专用功能的计算机系统,往往伴随着实时计算限制。” 我觉得可以很简单地说,嵌入式系统是大多数人不认为是计算机的计算机。它的主要作用是作为某种设备,而不被视为通用计算平台。 嵌入式系统编程的开发环境通常与测试和生产环境大不相同。它们可能会使用不同的芯片架构、软件堆栈甚至操作系统。开发工作流程对于嵌入式开发人员与桌面和 Web 开发人员来说是非常不同的。通常,其构建后的输出将包含目标设备的整个软件映像,包括内核、设备驱动程序、库和应用程序软件(有时也包括引导加载程序)。 在本文中,我将对构建嵌入式 Linux 系统的四种常用方式进行纵览。我将介绍一下每种产品的工作原理,并提供足够的信息来帮助读者确定使用哪种工具进行设计。我不会教你如何使用它们中的任何一个;一旦缩小了选择范围,就有大量深入的在线学习资源。没有任何选择适用于所有情况,我希望提供足够的细节来指导您的决定。 Yocto Yocto 项目 定义为“一个开源协作项目,提供模板、工具和方法,帮助您为嵌入式产品创建定制的基于 Linux 的系统,而不管硬件架构如何。”它是用于创建定制的 Linux 运行时映像的配方、配置值和依赖关系的集合,可根据您的特定需求进行定制。 完全公开:我在嵌入式 Linux 中的大部分工作都集中在 Yocto 项目上,而且我对这个系统的认识和偏见可能很明显。 Yocto 使用 Openembedded 作为其构建系统。从技术上讲,这两个是独立的项目;然而,在实践中,用户不需要了解区别,项目名称经常可以互换使用。 Yocto 项目的输出大致由三部分组成: 目标运行时二进制文件:这些包括引导加载程序、内核、内核模块、根文件系统映像。以及将 Linux 部署到目标平台所需的任何其他辅助文件。 包流:这是可以安装在目标上的软件包集合。您可以根据需要选择软件包格式(例如,deb、rpm、ipk)。其中一些可能预先安装在目标运行时二进制文件中,但可以构建用于安装到已部署系统的软件包。 目标 SDK:这些是安装在目标平台上的软件的库和头文件的集合。应用程序开发人员在构建代码时使用它们,以确保它们与适当的库链接 优点 Yocto 项目在行业中得到广泛应用,并得到许多有影响力的公司的支持。此外,它还拥有一个庞大且充满活力的开发人员社区和生态系统。开源爱好者和企业赞助商的结合的方式有助于推动 Yocto 项目。 获得 Yocto 的支持有很多选择。如果您想自己动手,有书籍和其他培训材料。如果您想获得专业知识,有许多有 Yocto 经验的工程师。而且许多商业组织可以为您的设计提供基于 Yocto 的 Turnkey 产品或基于服务的实施和定制。 Yocto 项目很容易通过 层 进行扩展,层可以独立发布以添加额外的功能,或针对项目发布时尚不可用的平台,或用于保存系统特有定制功能。层可以添加到你的配置中,以添加未特别包含在市面上版本中的独特功能;例如,“meta-browser” 层包含 Web 浏览器的清单,可以轻松为您的系统进行构建。因为它们是独立维护的,所以层可以按不同的时间发布(根据层的开发速度),而不是跟着标准的 Yocto 版本发布。 Yocto 可以说是本文讨论的任何方式中最广泛的设备支持。由于许多半导体和电路板制造商的支持,Yocto 很可能能够支持您选择的任何目标平台。主版本 Yocto 分支仅支持少数几块主板(以便达成合理的测试和发布周期),但是,标准工作模式是使用外部主板支持层。 最后,Yocto 非常灵活和可定制。您的特定应用程序的自定义可以存储在一个层进行封装和隔离,通常将要素层特有的自定义项存储为层本身的一部分,这可以将相同的设置同时应用于多个系统配置。Yocto 还提供了一个定义良好的层优先和覆盖功能。这使您可以定义层应用和搜索元数据的顺序。它还使您可以覆盖具有更高优先级的层的设置;例如,现有清单的许多自定义功能都将保留。 缺点 Yocto 项目最大的缺点是学习曲线陡峭。学习该系统并真正理解系统需要花费大量的时间和精力。 根据您的需求,这可能对您的应用程序不重要的技术和能力投入太大。 在这种情况下,与一家商业供应商合作可能是一个不错的选择。 Yocto 项目的开发时间和资源相当高。 需要构建的包(包括工具链,内核和所有目标运行时组件)的数量相当不少。 Yocto 开发人员的开发工作站往往是大型系统。 不建议使用小型笔记本电脑。 这可以通过使用许多提供商提供的基于云的构建服务器来缓解。 另外,Yocto 有一个内置的缓存机制,当它确定用于构建特定包的参数没有改变时,它允许它重新使用先前构建的组件。 建议 为您的下一个嵌入式 Linux 设计使用 Yocto 项目是一个强有力的选择。 在这里介绍的选项中,无论您的目标用例如何,它都是最广泛适用的。 广泛的行业支持,积极的社区和广泛的平台支持使其成为必须设计师的不错选择。 Buildroot Buildroot 项目定义为“通过交叉编译生成嵌入式 Linux 系统的简单、高效且易于使用的工具。”它与 Yocto 项目具有许多相同的目标,但它注重简单性和简约性。一般来说,Buildroot 会禁用所有软件包的所有可选编译时设置(有一些值得注意的例外),从而生成尽可能小的系统。系统设计人员需要启用适用于给定设备的设置。 Buildroot 从源代码构建所有组件,但不支持按目标包管理。因此,它有时称为固件生成器,因为镜像在构建时大部分是固定的。应用程序可以更新目标文件系统,但是没有机制将新软件包安装到正在运行的系统中。 Buildroot 输出主要由三部分组成: 将 Linux 部署到目标平台所需的根文件系统映像和任何其他辅助文件 适用于目标硬件的内核,引导加载程序和内核模块 用于构建所有目标二进制文件的工具链。 优点 Buildroot 对简单性的关注意味着,一般来说,它比 Yocto 更容易学习。核心构建系统用 Make 编写,并且足够短以便开发人员了解整个系统,同时可扩展到足以满足嵌入式 Linux 开发人员的需求。 Buildroot 核心通常只处理常见用例,但它可以通过脚本进行扩展。 Buildroot 系统使用普通的 Makefile 和 Kconfig 语言来进行配置。 Kconfig 由 Linux 内核社区开发,广泛用于开源项目,使得许多开发人员都熟悉它。 由于禁用所有可选的构建时设置的设计目标,Buildroot 通常会使用开箱即用的配置生成尽可能最小的镜像。一般来说,构建时间和构建主机资源的规模将比 Yocto 项目的规模更小。 缺点 关注简单性和最小化启用的构建方式意味着您可能需要执行大量的自定义来为应用程序配置 Buildroot 构建。此外,所有配置选项都存储在单个文件中,这意味着如果您有多个硬件平台,则需要为每个平台进行每个定制更改。 对系统配置文件的任何更改都需要全部重新构建所有软件包。与 Yocto 相比,这个问题通过最小的镜像大小和构建时间得到了一定的解决,但在你调整配置时可能会导致构建时间过长。 中间软件包状态缓存默认情况下未启用,并且不像 Yocto 实施那么彻底。这意味着,虽然第一次构建可能比等效的 Yocto 构建短,但后续构建可能需要重建许多组件。 建议 对于大多数应用程序,使用 Buildroot 进行下一个嵌入式 Linux 设计是一个不错的选择。如果您的设计需要多种硬件类型或其他差异,但由于同步多个配置的复杂性,您可能需要重新考虑,但对于由单一设置组成的系统,Buildroot 可能适合您。 OpenWRT/LEDE OpenWRT 项目开始为消费类路由器开发定制固件。您当地零售商提供的许多低成本路由器都可以运行 Linux 系统,但可能无法开箱即用。这些路由器的制造商可能无法提供频繁的更新来解决新的威胁,即使他们这样做,安装更新镜像的机制也很困难且容易出错。 OpenWRT 项目为许多已被其制造商放弃的设备生成更新的固件镜像,让这些设备焕发新生。 OpenWRT 项目的主要交付物是可用于大量商业设备的二进制镜像。它有网络可访问的软件包存储库,允许设备最终用户将新软件添加到他们的系统中。 OpenWRT 构建系统是一个通用构建系统,它允许开发人员创建自定义版本以满足他们自己的需求并添加新软件包,但其主要重点是目标二进制文件。 优点 如果您正在为商业设备寻找替代固件,则 OpenWRT 应位于您的选项列表中。它的维护良好,可以保护您免受制造商固件无法解决的问题。您也可以添加额外的功能,使您的设备更有用。 如果您的嵌入式设计专注于网络,则 OpenWRT 是一个不错的选择。网络应用程序是 OpenWRT 的主要用例,您可能会发现许多可用的软件包。 缺点 OpenWRT 对您的设计限制很多(与 Yocto 和 Buildroot 相比)。如果这些决定不符合您的设计目标,则可能需要进行大量的修改。 在部署的设备中允许基于软件包的更新是很难管理的。按照其定义,这会导致与您的 QA 团队测试的软件负载不同。此外,很难保证大多数软件包管理器的原子安装,以及错误的电源循环可能会使您的设备处于不可预知的状态。 建议 OpenWRT 是爱好者项目或商用硬件再利用的不错选择。它也是网络应用程序的不错选择。如果您需要从默认设置进行大量定制,您可能更喜欢 Buildroot 或 Yocto。 桌面发行版 设计嵌入式 Linux 系统的一种常见方法是从桌面发行版开始,例如 Debian 或 Red Hat,并删除不需要的组件,直到安装的镜像符合目标设备的占用空间。这是 Raspberry Pi 平台流行的 Raspbian发行版的方法。 优点 这种方法的主要优点是熟悉。通常,嵌入式 Linux 开发人员也是桌面 Linux 用户,并且精通他们的选择发行版。在目标上使用类似的环境可能会让开发人员更快地入门。根据所选的分布,可以使用 apt 和 yum 等标准封装工具安装许多其他工具。 可以将显示器和键盘连接到目标设备,并直接在那里进行所有的开发。对于不熟悉嵌入式空间的开发人员来说,这可能是一个更为熟悉的环境,无需配置和使用棘手的跨开发平台设置。 大多数桌面发行版可用的软件包数量通常大于前面讨论的嵌入式特定的构建器可用软件包数量。由于较大的用户群和更广泛的用例,您可能能够找到您的应用程序所需的所有运行时包,这些包已经构建并可供使用。 缺点 将目标平台作为您的主要开发环境可能会很慢。运行编译器工具是一项资源密集型操作,根据您构建的代码的多少,这可能会严重妨碍您的性能。 除了一些例外情况,桌面发行版的设计并不适合低资源系统,并且可能难以充分裁剪目标映像。同样,桌面环境中的预设工作流程对于大多数嵌入式设计来说都不理想。以这种方式获得可再现的环境很困难。手动添加和删除软件包很容易出错。这可以使用特定于发行版的工具进行脚本化,例如基于 Debian 系统的 debootstrap。为了进一步提高可再现性,您可以使用配置管理工具,如 CFEngine(我的雇主 Mender.io 完整披露了 这一工具)。但是,您仍然受发行版提供商的支配,他们将更新软件包以满足他们的需求,而不是您的需求。 建议 对于您打算推向市场的产品,请谨慎使用此方法。这对于爱好者应用程序来说是一个很好的模型;但是,对于需要支持的产品,这种方法很可能会遇到麻烦。虽然您可能能够获得更快的起步,但从长远来看,您可能会花费您的时间和精力。 其他考虑 这个讨论集中在构建系统的功能上,但通常有非功能性需求可能会影响您的决定。如果您已经选择了片上系统(SoC)或电路板,则您的选择很可能由供应商决定。如果您的供应商为特定系统提供板级支持包(BSP),使用它通常会节省相当多的时间,但请研究 BSP 的质量以避免在开发周期后期发生问题。 如果您的预算允许,您可能需要考虑为目标操作系统使用商业供应商。有些公司会为这里讨论的许多选项提供经过验证和支持的配置,除非您拥有嵌入式 Linux 构建系统方面的专业知识,否则这是一个不错的选择,可以让您专注于核心能力。 作为替代,您可以考虑为您的开发人员进行商业培训。这可能比商业操作系统供应商便宜,并且可以让你更加自给自足。这是快速找到您选择的构建系统基础知识的学习曲线。 最后,您可能已经有一些开发人员拥有一个或多个系统的经验。如果你的工程师有倾向性,当你做出决定时,肯定值得考虑。 总结 构建嵌入式 Linux 系统有多种选择,每种都有优点和缺点。将这部分设计放在优先位置至关重要,因为在以后的过程中切换系统的成本非常高。除了这些选择之外,还有新的系统在开发中。希望这次讨论能够为评估新的系统(以及这里提到的系统)提供一些背景,并帮助您为下一个项目做出坚实的决定。

    时间:2018-07-10 关键词: Linux 软件开发 代码

  • Linux 应用程序入住Fuchsia 操作系统

    近日,谷歌已经为其新兴开源的 Fuchsia OS 添加了一个 Guest App,以使 Linux 应用程序能够在 Fuchsia 中作为虚拟机(VM)运行。这个 Guest App 使用了一个叫作 Machina 的库,相比传统的模拟器,Guest App 与宿主操作系统的集成更加紧密。 上个月,谷歌推出了 Crostini ,该项目技术让 Chromebook 用户可以更容易的在 Chrome OS 虚拟机中运行主流的 Linux 应用程序。本周,宏碁宣布 Chromebook Flip C101 今年晚些时候也将提供 Linux 支持,是少数支持 Linux 应用程序的 Chromebook 之一。 虽然 Chrome OS 除了支持 Android 外,还将支持 Linux 应用程序,但这并算不上什么大惊喜,因为 Android 和 Chrome OS 本来都基于 Linux。 然而,Google 在 2016 年推出 Fuchsia 时首先强调的一件事是,它不是基于 Linux 内核。 Fuchsia 将包含独立的 UI:用于手机的 Armadillo 用户界面和用于桌面的 Capybara 用户界面,以及 Android Things 和其他新的 Android 变体,将紧密集成 Google 智能助理语音技术。从本质上讲,这与微软未能为手机和笔记本电脑提供通用 Windows 或 Canonical 已停用的“融合”版本的 Ubuntu 的计划相同。 无论 Fuchsia 的命运如何,Google 需要吸引成熟的应用程序以及开发人员,而实现这一目标的最佳方式是添加 Linux 应用程序兼容性。9to5Google 建议,新的 Guest 应用最初应该支持包括 Debian 在内的基于 Linux 的平台,通过与 Machina 库一起工作实现比 QEMU 更好的集成。

    时间:2018-07-10 关键词: Linux 软件开发 代码

  • Linux各文件夹的结构说明及用途介绍

    Linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令。 /dev:设备特殊文件。 /etc:系统管理和配置文件。 /etc/rc.d:启动的配 置文件和脚本。 /home:用户主目录的基点,比如用户user的主目录就是/home/user,可以用~user表示。 /lib:标准程序设计库,又 叫动态链接共享库,作用类似windows里的.dll文件。 /sbin:系统管理命令,这 里存放的是系统管理员使用的管理程序。 /tmp:公用的临时文件存储 点。 /root:系统管理员的主目 录。 /mnt:系统提供这个目录是 让用户临时挂载其他的文件系统。 /lost+found:这个 目录平时是空的,系统非正常关机而留下“无家可归”的文件就在这里。 /proc:虚拟的目录,是系 统内存的映射。可直接访问这个目录来获取系统信息。 /var:某些大文件的溢出 区,比方说各种服务的日志文件。 /usr:最庞大的目录,要用 到的应用程序和文件几乎都在这个目录。其中包含: /usr/x11r6:存放x window的目录。 /usr/bin:众多的应用程序。 /usr/sbin:超级用户的一些管理程序。 /usr/doc:linux文档。 /usr/include:linux下开发和编译应用程序所需要的头文件。 /usr/lib:常用的动态链接库和软件包的配置文件。 /usr/man:帮助文档。 /usr/src:源代码,linux内核的源代码就放在/usr/src/linux 里。 /usr/local/bin:本地增加的命令。 /usr/local/lib:本地增加的库根文件系统。 通常情况下,根文件系统所占空间一般应该比较小,因为其中的绝大部分文件都不需要经常改动,而且包括严格的文件和一个小的 不经常改变的文件系统不容易损坏。除了可能的一个叫/vmlinuz标准的系统引导映像之外,根目录一般不含任何文 件。所有其他文件在根文件系统的子目录中。 1. /bin目录 /bin目录包含了引导启动所需的命令或普通用户可能用的命令(可能在引导启动后)。这些命 令都是二进制文件的可执行程序(bin是binary的简称),多是系统中重要的系统文件。 2. /sbin目录 /sbin目录类似/bin ,也用于存储二进制文件。因为其中的大部分文件多是系统管理员使用的基本的系统程序,所以虽然普通用户必要且允许时可以使用,但一般不给普通用户使 用。 3. /etc目录 /etc目录存放着各种系统配置文件,其中包括了用户信息文件/etc/passwd, 系统初始化文件/etc/rc等。linux正是靠这些文件才得以正常地运行。 4. /root目录 /root目录是超级用户的目录。 5. /lib目录 /lib目录是根文件系统上的程序所需的共享库,存放了根文件系统程序运行所需的共享文件。 这些文件包含了可被许多程序共享的代码,以避免每个程序都包含有相同的子程序的副本,故可以使得可执行文件变得更小,节省空间。 6. /lib/modules目录 /lib/modules目录包含系统核心可加载各种模块,尤其是那些在恢复损坏的系统时重 新引导系统所需的模块(例如网络和文件系统驱动)。 7. /dev目录 /dev目录存放了设备文件,即设备驱动程序,用户通过这些文件访问外部设备。比如,用户可 以通过访问/dev/mouse来访问鼠标的输入,就像访问其他文件一样。 8. /tmp目录 /tmp目录存放程序在运行时产生的信息和数据。但在引导启动后,运行的程序最好使用/var/tmp来 代替/tmp,因为前者可能拥有一个更大的磁盘空间。 9. /boot目录 /boot目录存放引导加载器(bootstrap loader)使用的文件,如lilo,核心映像也经常放在这里,而不是放在根目录中。但是如果有许多核心映像,这个目录就可能变得很大,这时使用单独的 文件系统会更好一些。还有一点要注意的是,要确保核心映像必须在ide硬盘的前1024柱面内。 10. /mnt目录 /mnt目录是系统管理员临时安装(mount)文件系统的安装点。程序并不自动支持安装到/mnt 。/mnt下面可以分为许多子目录,例如/mnt/dosa可能是使用 msdos文件系统的软驱,而/mnt/exta可能是使用ext2文件系统的软驱,/mnt/cdrom光 驱等等。 11. /proc, /usr, /var, /home目录 其他文件系统的安装点。 目录树可以分为小的部分,每个部分可以在自己的磁盘或分区上。主要部分是根、/usr 、/var 和 /home 文件系统。每个部分有不同的目的。 每台机器都有根文件系统,它包含系统引导和使其他文件系统得以mount所必要的文件,根文件系统应该有单用户状态所必须的足够的内容。还应该包括修复损坏 系统、恢复备份等的工具。 /usr 文件系统包含所有命令、库、man页和其他一般操作中所需的不改变的文件。 /usr 不应该有 一般使用中要修改的文件。这样允许此文件系统中的文件通过网络共享,这样可以更有效,因为这样节省了磁盘空间(/usr 很容易是数百兆),且易于管理 (当升级应用时,只有主/usr 需要改变,而无须改变每台机器) 即使此文件系统在本地盘上,也可以只读mount,以减少系统崩溃时文件系统的损 坏。 /var 文件系统包含会改变的文件,比如spool目录(mail、news、打印机等用的), log文件、 formatted manual pages和暂存文件。传统上/var 的所有东西曾在 /usr 下的某个地方,但这样/usr 就不可能只读安装 了。 /home 文件系统包含用户家目录,即系统上的所有实际数据。一个大的/home 可能要分为若干文件系统,需要在 /home 下加一级名字,如/home/students 、/home/staff 等。 下面详细介绍: /etc文件系统 /etc目录包含各种系统配置文件,下面说明其中的一些。其他的你应该知道它们属于哪个程序, 并阅读该程序的man页。许多网络配置文件也在/etc中。 1. /etc/rc或/etc/rc.d或/etc/rc?.d:启动、或改变运行级时运 行的脚本或脚本的目录。 2. /etc/passwd:用户数据库,其中的域给出了用户名、真实姓名、用户起始目 录、加密口令和用户的其他信息。 3. /etc/fdprm:软盘参数表,用以说明不同的软盘格式。可用setfdprm进 行设置。更多的信息见setfdprm的帮助页。 4. /etc/fstab:指定启动时需要自动安装的文件系统列表。也包括用swapon -a启用的swap区的信息。 5. /etc/group:类似/etc/passwd ,但说明的不是用户信息而是组的信息。包括组的各种数据。 6. /etc/inittab:init 的配置文件。 7. /etc/issue:包括用户在登录提示符前的输出信息。通常包括系统的一段短说明 或欢迎信息。具体内容由系统管理员确定。 8. /etc/magic:“file”的配置文件。包含不同文件格式的说 明,“file”基于它猜测文件类型。 9. /etc/motd:motd是message of the day的缩写,用户成功登录后自动输出。内容由系统管理员确定。 常用于通告信息,如计划关机时间的警告等。 10. /etc/mtab:当前安装的文件系统列表。由脚本(scritp)初始化,并由 mount命令自动更新。当需要一个当前安装的文件系统的列表时使用(例如df命令)。 11. /etc/shadow:在安装了影子(shadow)口令软件的系统上的影子口令 文件。影子口令文件将/etc/passwd文件中的加密口令移动到/etc/shadow中,而后者只对超级用户(root)可读。这使破译口令更困 难,以此增加系统的安全性。 12. /etc/login.defs:login命令的配置文件。 13. /etc/printcap:类似/etc/termcap ,但针对打印机。语法不同。 14. /etc/profile 、/etc/csh.login、/etc/csh.cshrc:登 录或启动时bourne或cshells执行的文件。这允许系统管理员为所有用户建立全局缺省环境。 15. /etc/securetty:确认安全终端,即哪个终端允许超级用户(root) 登录。一般只列出虚拟控制台,这样就不可能(至少很困难)通过调制解调器(modem)或网络闯入系统并得到超级用户特权。 16. /etc/shells:列出可以使用的shell。chsh命令允许用户在本文件 指定范围内改变登录的shell。提供一台机器ftp服务的服务进程ftpd检查用户shell是否列在/etc/shells文件 中,如果不是,将不允许该用户登录。 17. /etc/termcap:终端性能数据库。说明不同的终端用什么“转义序列”控 制。写程序时不直接输出转义序列(这样只能工作于特定品牌的终端),而是从/etc/termcap中查找要做的工作的 正确序列。这样,多数的程序可以在多数终端上运行。 /dev文件系统 /dev目录包括所有设备的设备文件。设备文件用特定的约定命名,这在设备列表中说明。设备文件在安装时由系 统产生,以后可以用/dev/makedev描述。/dev/makedev.local 是系统管理员为本地设备文件(或连接)写的描述文稿(即如一些非标准设备驱动不是标准makedev 的一部分)。下面简要介绍/dev下 一些常用文件。 1. /dev/console:系统控制台,也就是直接和系统连接的监视器。 2. /dev/hd:ide硬盘驱动程序接口。如:/dev/hda指的是第一个硬 盘,had1则是指/dev/hda的第一个分区。如系统中有其他的硬盘,则依次为/dev /hdb、/dev/hdc、. . . . . .;如有多个分区则依次为hda1、hda2 . . . . . . 3. /dev/sd:scsi磁盘驱动程序接口。如系统有scsi硬盘,就不会访问/dev/had, 而会访问/dev/sda。 4. /dev/fd:软驱设备驱动程序。如:/dev/fd0指 系统的第一个软盘,也就是通常所说的a盘,/dev/fd1指第二个软盘,. . . . . .而/dev/fd1 h1440则表示访问驱动器1中的4.5高密盘。 5. /dev/st:scsi磁带驱动器驱动程序。 6. /dev/tty:提供虚拟控制台支持。如:/dev/tty1指 的是系统的第一个虚拟控制台,/dev/tty2则是系统的第二个虚拟控制台。 7. /dev/pty:提供远程登陆伪终端支持。在进行telnet登录时就要用到/dev/pty设 备。 8. /dev/ttys:计算机串行接口,对于dos来说就是“com1”口。 9. /dev/cua:计算机串行接口,与调制解调器一起使用的设备。 10. /dev/null:“黑洞”,所有写入该设备的信息都将消失。例如:当想要将屏幕 上的输出信息隐藏起来时,只要将输出信息输入到/dev/null中即可。 /usr文件系统 /usr是个很重要的目录,通常这一文件系统很大,因为所有程序安装在这里。/usr里 的所有文件一般来自linux发行版;本地安装的程序和其他东西在/usr/local下,因为这样可以在升级新版系 统或新发行版时无须重新安装全部程序。/usr目录下的许多内容是可选的,但这些功能会使用户使用系统更加有效。/usr可容纳许多大型的软件包和它们的 配置文件。下面列出一些重要的目录(一些不太重要的目录被省略了)。 1. /usr/x11r6:包含x window系统的所有可执行程序、配置文件和支持文件。为简化x的开发和安装,x的文件没有集成到系统中。x window系统是一个功能强大的图形环境,提供了大量的图形工具程序。用户如果对microsoft windows比较熟悉的话,就不会对x window系统感到束手无策了。 2. /usr/x386:类似/usr/x11r6 ,但是是专门给x 11 release 5的。 3. /usr/bin:集中了几乎所有用户命令,是系统的软件库。另有些命令在/bin或/usr/local/bin中。 4. /usr/sbin:包括了根文件系统不必要的系统管理命令,例如多数服务程序。 5. /usr/man、/usr/info、/usr/doc:这些目录包含所有手册页、 gnu信息文档和各种其他文档文件。每个联机手册的“节”都有两个子目录。例如:/usr/man/man1中包含联机手册第一节的源码(没有格式化的原 始文件),/usr/man/cat1包含第一节已格式化的内容。联机手册分为以下九节:内部命令、系统调用、库函数、设备、文件格式、游戏、宏软件包、 系统管理和核心程序。 6. /usr/include:包含了c语言的头文件,这些文件多以.h结尾,用来描述c 语言程序中用到的数据结构、子过程和常量。为了保持一致性,这实际上应该放在/usr/lib下,但习惯上一直沿用了这 个名字。 7. /usr/lib:包含了程序或子系统的不变的数据文件,包括一些site – wide配置文件。名字lib来源于库(library); 编程的原始库也存在/usr/lib 里。当编译程序时,程序便会和其中的库进行连接。也有许多程序把配置文件存入其中。 8. /usr/local:本地安装的软件和其他文件放在这里。这与/usr很相似。用户 可能会在这发现一些比较大的软件包,如tex、emacs等。 /var文件系统 /var包含系统一般运行时要改变的数据。通常这些数据所在的目录的大小是要经常变化或扩充 的。原来/var目录中有些内容是在/usr中的,但为了保持/usr目录的相对稳定,就把那些需要经常改变的目录放到/var中了。每个系统是特定的, 即不通过网络与其他计算机共享。下面列出一些重要的目录(一些不太重要的目录省略了)。 1. /var/catman:包括了格式化过的帮助(man)页。帮助页的源文件一般存在 /usr/man/catman中;有些man页可能有预格式化的版本,存在/usr/man/cat中。而其他的man页在第一次看时都需要格式化,格 式化完的版本存在/var/man中,这样其他人再看相同的页时就无须等待格式化了。(/var/catman经常被 清除,就像清除临时目录一样。) 2. /var/lib:存放系统正常运行时要改变的文件。 3. /var/local:存放/usr/local中 安装的程序的可变数据(即系统管理员安装的程序)。注意,如果必要,即使本地安装的程序也会使用其他/var目录,例如/var/lock 。 4. /var/lock:锁定文件。许多程序遵循在/var/lock中 产生一个锁定文件的约定,以用来支持他们正在使用某个特定的设备或文件。其他程序注意到这个锁定文件时,就不会再使用这个设备或文件。 5. /var/log:各种程序的日志(log)文件,尤其是login (/var/log/wtmplog纪 录所有到系统的登录和注销) 和syslog (/var/log/messages 纪录存储所有核心和系统程序信息)。/var/log 里的文件经常不确定地增长,应该定期清除。 6. /var/run:保存在下一次系统引导前有效的关于系统的信息文件。例如,/var/run/utmp包 含当前登录的用户的信息。 7. /var/spool:放置“假脱机(spool)”程序的目录,如mail、 news、打印队列和其他队列工作的目录。每个不同的spool在/var/spool下有自己的子目录,例如,用户的邮箱就存放在/var/spool/mail 中。 8. /var/tmp:比/tmp允许更大的或需要存在较长时间的临时文件。注意系统管理 员可能不允许/var/tmp有很旧的文件。 /proc文件系统 /proc文件系统是一个伪的文件系统,就是说它是一个实际上不存在的目录,因而这是一个非 常特殊的目录。它并不存在于某个磁盘上,而是由核心在内存中产生。这个目录用于提供关于系统的信息。下面说明一些最重要的文件和目录(/proc文件系统 在proc man页中有更详细的说明)。 1. /proc/x:关于进程x的信息目录,这x是这一进程的标识号。每个进程在 /proc下有一个名为自己进程号的目录。 2. /proc/cpuinfo:存放处理器(cpu)的信息,如cpu的类型、制造商、 型号和性能等。 3. /proc/devices:当前运行的核心配置的设备驱动的列表。 4. /proc/dma:显示当前使用的dma通道。 5. /proc/filesystems:核心配置的文件系统信息。 6. /proc/interrupts:显示被占用的中断信息和占用者的信息,以及被占用 的数量。 7. /proc/ioports:当前使用的i/o端口。 8. /proc/kcore:系统物理内存映像。与物理内存大小完全一样,然而实际上没有 占用这么多内存;它仅仅是在程序访问它时才被创建。(注意:除非你把它拷贝到什么地方,否则/proc下没有任何东西占用任何磁盘空间。) 9. /proc/kmsg:核心输出的消息。也会被送到syslog。 10. /proc/ksyms:核心符号表。 11. /proc/loadavg:系统“平均负载”;3个没有意义的指示器指出系统当前 的工作量。 12. /proc/meminfo:各种存储器使用信息,包括物理内存和交换分区 (swap)。 13. /proc/modules:存放当前加载了哪些核心模块信息。 14. /proc/net:网络协议状态信息。 15. /proc/self:存放到查看/proc的 程序的进程目录的符号连接。当2个进程查看/proc时,这将会是不同的连接。这主要便于程序得到它自己的进程目录。 16. /proc/stat:系统的不同状态,例如,系统启动后页面发生错误的次数。 17. /proc/uptime:系统启动的时间长度。 18. /proc/version:核心版本。 /usr/local下一般是你安装软件的目录,这个目录就相当于在windows下的programefiles这个目录 /opt这个目录是一些大型软件的安装目录,或者是一些服务程序的安装目录 举个例子:刚才装的测试版firefox,就可以装到/opt/firefox_beta目录下,/opt/firefox_beta目录下面就包含了运 行firefox所需要的所有文件、库、数据等等。要删除firefox的时候,你只需删除/opt/firefox_beta目录即可,非常简单。 /usr/local 这里主要存放那些手动安装的软件,即 不是通过“新立得”或apt-get安装的软件 。 它和/usr目录具有相类似的目录结构 。让软件包管理器来管理/usr目录,而把自定义的脚本(scripts)放到/usr/local目录下面,我想这应该是个不错的主意。

    时间:2018-07-10 关键词: Linux 软件开发 代码

  • Linux基本命令总结

    一、Linux权限 Linux下有两种用户: 普通用户:在linux下做有限的事情; 超级用户:可以在linux系统下做任何事情,不受限制。 普通用户的提示符是“$”,超级用户的命令提示符是“#”。 命令: su [用户名] 功能:切换用户 Linux权限管理 1.文件访问者的分类 文件和文件目录的所有者:u—User 文件和文件目录的所有者所在的组的用户:g—Group 其他用户:o—Others 2.文件访问权限的种类 基本权限: read 对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录信息的权限。 write 对文件而言,具有修改文件内容的权限;对目录来说,具有删除移动目录内文件的权限。 execute 对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限。 - 表示不具有该权限。 二、Linux下基本命令 1.ls命令: 格式::ls [选项] [目录或文件] 功能:对于目录,列出该目录下的所有子目录与文件;对于文件,列出文件名以及其他信息。 常用选项: -l :列出文件的详细信息。 -a :列出目录下的所有文件,包括以 . 开头的隐含文件。 -d :将目录像文件一样显示,而不是显示其他文件。 -i :输出文件的i节点的索引信息。 -k :以k字节的形式表示文件的大小。 -n :用数字的UID,GID代替名称。 -F : 在每个文件名后面附上一个字符以说明该文件的类型,“*”表示可执行的普通文 件;“/”表示目录;“@”表示符号链接;“l”表示FIFOS;“=”表示套接字。 2.cd命令 格式:cd [目录名称] 功能:回到个人目录 常用选项: cd .. 返回上一级目录。 cd ../.. 将当前目录向上移动两级。 cd - 返回最近访问目录。 3.pwd命令 格式: pwd 功能:显示出当前工作目录的绝对路径。 4.touch命令 格式:touch[选项] 文件名… 功能:touch命令参数可以更改文档或目录的日期时间,包括存取时间和更改时间,或者新建一个不存在的文件。 常用选项: -a 仅改变指定文件的存取时间。 -c 不创建任何文件。 -m 仅改变指定文件的修改时间。 -d 使用指定的日期时间,而非现在的时间。 5.mkdir命令 格式:mkdir [选项] dir… 功能:mkdir命令用来创建目录。 常用选项: -p 建立一个目标树。 -m –mode=MODE 将新建目录的存取权限设置为MODE,存取权限用给定的八进制数字表示。 6.rm命令 格式:rm [选项] 文件列表 功能:rm命令删除文件或目录。 常用选项: -f –force 忽略不存在的文件,并且不给出提示信息。 -r -R,–recursive 递归地删除指定目录及其下属的各级子目录和相应的文件。 -i 交互式删除文件。 说明:rm命令删除指定的文件,默认情况下,它不能删除目录。如果文件不可写,则标准输入是tty(终端设备)。如果没有给出选项-f或者–force,rm命令删除之前会提示用户是否删除该文件;如果用户没有回答y或者Y,则不删除该文件。 7.rmdir命令 格式:rmdir [选项] dirname 功能:删除目录。 常用选项: -p –parents 递归删除目录 dirname,当子目录删除后其父目录为空时,也一同被删除。如果有非空的目录,则该目录保留下来。 8.man 命令 格式:man [选项] 命令 功能:man命令格式化并显示某一命令的联机帮助手册页。 常用选项: -k 根据关键字搜索联机帮助。 num 只在第num章节找。 -a 将所有章节的都显示出来。 说明:面手册分为8章: 1. 一般用户的命令; 2. 系统调用; 3. C语言函数库; 4. 有关驱动程序和系统设备的解释; 5. 配置文件的解释; 6. 游戏程序的命令; 7. 有用的杂类命令,如宏命令包等; 8. 有关系统维护和管理的命令。 9.cp命令 格式:cp [选项] 源文件或目录 目标文件或目录 功能:复制文件或目录。 常用选项: -f –force 强行复制文件或目录,不论文件或目录是否已经存在。 -d 复制时保留文件链接。 -i –interactive覆盖文件之前先询问用户。 -r 递归处理,将指定目录下的文件与子目录一并处理。若源文件或目录的形态,不属于目录或符号链接,则一律视为普通文件处理。 -R 或–recursive递归处理,将指定目录下的文件及子目录一并处理。 10.mv命令 格式:mv [选项] 源文件或目录 目标文件或目录 功能:mv命令对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。 常用选项: -f force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖。 -i 若目标文件(destination)已经存在时,就会询问是否覆盖。 11.cat/tac命令 格式:cat [选项] [文件] 功能:查看目标文件的内容。 (一般文档内容较短) 常用选项: -b 对非空输出行编号。 -n 对输出的所有行编号。 -s 不输出多行空行。 12.more命令 格式:more [选项] [文件] 功能:查看目标文件内容。(一般文档内容较长) 常用选项: -n 对输出的所有行编号。 -s 将文件中连续的空白行压缩成一个空白行显示。 -num 这个选项制定一个整数,表示一屏显示多少行。 q 退出more。 13.tree命令 格式:tree 路径 功能:显示文件和目录由根目录开始的树形结构。 常用选项: -p 只显示目录。 14.head命令 格式:head [选项] [文件] 功能:head命令在屏幕上显示指定文件的开头若干行。 常用选项: -c –bytes=[-]N 显示每个文件前面N字节。 -n –lines=[-]N 显示指定文件的前面N行。 15.tail命令 格式:tail [选项] [文件] 功能:用于显示指定文件的末尾,不指定文件时,作为输入信息进行处理。常用查看日志文件。 说明:tail命令从指定点开始将文件写到标注输出。使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不断刷新,使你看到最新的文件内容。 常用选项: -f 循环读取。 -n <行数> 显示行数。 16.时间相关的命令 date显示 date 指定格式显示时间:date+%Y:%m:%d date用法:date:date[OPTION]… [+FORMAT] %H 小时 %M 分钟 %S 秒 %X 相当于%H:%M:%S %d 日 %m 月份 %Y 完整年份 %F 相当于%Y-%m-%d 时间戳 时间->时间戳:date+%s 时间戳->时间:Unix时间戳是从1970年1月1日开始所经过的秒数,不考虑闰秒。 17.cal命令 格式:cal [参数] [月份] [年份] 功能:用于查询日历等时间信息,如果只有一个参数,则表示年份(1-9999),如果有两个参数,则表示月份和年份。 常用选项: -3 显示系统前一个月,当前月,下一个月的月历。 -j 显示在当年中的第几天(一年日期按天算,从1月1日算起,默认显示当前月在一年中的天数)。 -y 显示当前年份的日历。 18.find命令 格式:find pathname -options 功能:用于在文件树种查找文件,并作出相应的处理(可能访问磁盘)。 常用选项: -name 按照文件名查找文件。 19.grep命令 格式:grep [选项] 搜寻字符串文件 功能:在文件中搜索字符串,将找到的行打印出来。 常用选项: -i 忽略大小写的不同,所以大小写视为相同。 -n 顺便输出行号。 -v 反向选择,亦即显出没有‘搜寻字符串’内容的那一行。 20.zip/unzip命令 格式:zip 压缩文件.zip 目录或文件 功能:将目录或文件压缩成zip格式。 常用选项: -r 递归处理,将指定目录下的所有文件和子目录一并处理。 21.tar命令 格式:tar [-cxtzjvf] 文件与目录… 参数 功能:打包/解包,不打开它,直接看内容。 -c 建立一个压缩文件的参数指令(create的意思)。 -x 解开一个压缩文件的参数指令。 -t 查看tarfile里面的文件。 -z 是否同时具有gzip的属性?亦即是否需要用gzip压缩? -j 是否同时具有bzip2的属性?亦即是否需要用bzip2压缩? -v 压缩的过程中显示文件。这个常用,不建议用在背景执行过程。 -f 使用档名,请留意,在f之后要立即接档名,不要再加参数。 -C 解压到指定目录。 22.bc命令 bc命令可以很方便的进行浮点运算。 23.uname -r命令 格式:uname [选项] 功能:uname用来获取电脑和操作系统的相关信息。 常用选项: -a 或-all 详细输出所有信息,依次为内核名称,主机名,内核版本号,内核版本,硬件名,处理器类型,硬件平台类型,操作系统名称。 三、Linux系统根目录下各个目录的作用 /bin 二进制可执行命令。该目录下存放着普通用户的命令 /dev 系统的设备文件,即设备的驱动程序 /home 存放用户文件的主目录,用户数据 /lib 存放着和系统运行相关的库文件 /mnt 存放临时的映射文件,通常是一些用来安装其他设备的子目录 /boot 存放启动linux的核心文件 /media 存放着可移除的设备,比如软盘,光盘 /misc 储存着一些特殊的字符的定义 /net 存放着和网络相关的一些文件 /proc 存放着用户与内核的交互信息 /sbin 系统的管理命令,这里存放的是系统管理员使用的程序 /srv 系统启动服务时可以访问的数据库目录 /tmp 临时文件,重启后自动清空 /var 存放系统产生的经常变化的文件 /etc 系统所有的配置文件都在这个目录中 /opt (option : 自由选择)主要给源码安装软件时选择的安装目录位置 /root 超级用户的目录 /selinux 主要用来加固操作系统,提高系统的安全性 /sys 管理设备文件 /usr 最大的目录,存放着应用程序和文件 /lost-found 这个目录平时是空的,当系统非正常关机而留下的“无家可归”的文件便会储存在这里

    时间:2018-07-06 关键词: Linux 软件开发 代码

  • 4 种用于构建嵌入式 Linux 系统的工具

    Linux 被部署到比 Linus Torvalds 在他的宿舍里开发时所预期的更广泛的设备。令人震惊的支持了各种芯片,使得Linux 可以应用于大大小小的设备上:从 IBM 的巨型机到不如其连接的端口大的微型设备,以及各种大小的设备。它被用于大型企业数据中心、互联网基础设施设备和个人的开发系统。它还为消费类电子产品、移动电话和许多物联网设备提供了动力。 在为桌面和企业级设备构建 Linux 软件时,开发者通常在他们的构建机器上使用桌面发行版,如 Ubuntu 以便尽可能与被部署的机器相似。如 VirtualBox 和 Docker 这样的工具使得开发、测试和生产环境更好的保持了一致。 什么是嵌入式系统? 维基百科将嵌入式系统定义为:“在更大的机械或电气系统中具有专用功能的计算机系统,往往伴随着实时计算限制。” 我觉得可以很简单地说,嵌入式系统是大多数人不认为是计算机的计算机。它的主要作用是作为某种设备,而不被视为通用计算平台。 嵌入式系统编程的开发环境通常与测试和生产环境大不相同。它们可能会使用不同的芯片架构、软件堆栈甚至操作系统。开发工作流程对于嵌入式开发人员与桌面和 Web 开发人员来说是非常不同的。通常,其构建后的输出将包含目标设备的整个软件映像,包括内核、设备驱动程序、库和应用程序软件(有时也包括引导加载程序)。 在本文中,我将对构建嵌入式 Linux 系统的四种常用方式进行纵览。我将介绍一下每种产品的工作原理,并提供足够的信息来帮助读者确定使用哪种工具进行设计。我不会教你如何使用它们中的任何一个;一旦缩小了选择范围,就有大量深入的在线学习资源。没有任何选择适用于所有情况,我希望提供足够的细节来指导您的决定。 Yocto Yocto 项目 定义为“一个开源协作项目,提供模板、工具和方法,帮助您为嵌入式产品创建定制的基于 Linux 的系统,而不管硬件架构如何。”它是用于创建定制的 Linux 运行时映像的配方、配置值和依赖关系的集合,可根据您的特定需求进行定制。 完全公开:我在嵌入式 Linux 中的大部分工作都集中在 Yocto 项目上,而且我对这个系统的认识和偏见可能很明显。 Yocto 使用 Openembedded 作为其构建系统。从技术上讲,这两个是独立的项目;然而,在实践中,用户不需要了解区别,项目名称经常可以互换使用。 Yocto 项目的输出大致由三部分组成: 目标运行时二进制文件:这些包括引导加载程序、内核、内核模块、根文件系统映像。以及将 Linux 部署到目标平台所需的任何其他辅助文件。 包流:这是可以安装在目标上的软件包集合。您可以根据需要选择软件包格式(例如,deb、rpm、ipk)。其中一些可能预先安装在目标运行时二进制文件中,但可以构建用于安装到已部署系统的软件包。 目标 SDK:这些是安装在目标平台上的软件的库和头文件的集合。应用程序开发人员在构建代码时使用它们,以确保它们与适当的库链接 优点 Yocto 项目在行业中得到广泛应用,并得到许多有影响力的公司的支持。此外,它还拥有一个庞大且充满活力的开发人员社区和生态系统。开源爱好者和企业赞助商的结合的方式有助于推动 Yocto 项目。 获得 Yocto 的支持有很多选择。如果您想自己动手,有书籍和其他培训材料。如果您想获得专业知识,有许多有 Yocto 经验的工程师。而且许多商业组织可以为您的设计提供基于 Yocto 的 Turnkey 产品或基于服务的实施和定制。 Yocto 项目很容易通过 层 进行扩展,层可以独立发布以添加额外的功能,或针对项目发布时尚不可用的平台,或用于保存系统特有定制功能。层可以添加到你的配置中,以添加未特别包含在市面上版本中的独特功能;例如,“meta-browser” 层包含 Web 浏览器的清单,可以轻松为您的系统进行构建。因为它们是独立维护的,所以层可以按不同的时间发布(根据层的开发速度),而不是跟着标准的 Yocto 版本发布。 Yocto 可以说是本文讨论的任何方式中最广泛的设备支持。由于许多半导体和电路板制造商的支持,Yocto 很可能能够支持您选择的任何目标平台。主版本 Yocto 分支仅支持少数几块主板(以便达成合理的测试和发布周期),但是,标准工作模式是使用外部主板支持层。 最后,Yocto 非常灵活和可定制。您的特定应用程序的自定义可以存储在一个层进行封装和隔离,通常将要素层特有的自定义项存储为层本身的一部分,这可以将相同的设置同时应用于多个系统配置。Yocto 还提供了一个定义良好的层优先和覆盖功能。这使您可以定义层应用和搜索元数据的顺序。它还使您可以覆盖具有更高优先级的层的设置;例如,现有清单的许多自定义功能都将保留。 缺点 Yocto 项目最大的缺点是学习曲线陡峭。学习该系统并真正理解系统需要花费大量的时间和精力。 根据您的需求,这可能对您的应用程序不重要的技术和能力投入太大。 在这种情况下,与一家商业供应商合作可能是一个不错的选择。 Yocto 项目的开发时间和资源相当高。 需要构建的包(包括工具链,内核和所有目标运行时组件)的数量相当不少。 Yocto 开发人员的开发工作站往往是大型系统。 不建议使用小型笔记本电脑。 这可以通过使用许多提供商提供的基于云的构建服务器来缓解。 另外,Yocto 有一个内置的缓存机制,当它确定用于构建特定包的参数没有改变时,它允许它重新使用先前构建的组件。 建议 为您的下一个嵌入式 Linux 设计使用 Yocto 项目是一个强有力的选择。 在这里介绍的选项中,无论您的目标用例如何,它都是最广泛适用的。 广泛的行业支持,积极的社区和广泛的平台支持使其成为必须设计师的不错选择。 Buildroot Buildroot 项目定义为“通过交叉编译生成嵌入式 Linux 系统的简单、高效且易于使用的工具。”它与 Yocto 项目具有许多相同的目标,但它注重简单性和简约性。一般来说,Buildroot 会禁用所有软件包的所有可选编译时设置(有一些值得注意的例外),从而生成尽可能小的系统。系统设计人员需要启用适用于给定设备的设置。 Buildroot 从源代码构建所有组件,但不支持按目标包管理。因此,它有时称为固件生成器,因为镜像在构建时大部分是固定的。应用程序可以更新目标文件系统,但是没有机制将新软件包安装到正在运行的系统中。 Buildroot 输出主要由三部分组成: 将 Linux 部署到目标平台所需的根文件系统映像和任何其他辅助文件 适用于目标硬件的内核,引导加载程序和内核模块 用于构建所有目标二进制文件的工具链。 优点 Buildroot 对简单性的关注意味着,一般来说,它比 Yocto 更容易学习。核心构建系统用 Make 编写,并且足够短以便开发人员了解整个系统,同时可扩展到足以满足嵌入式 Linux 开发人员的需求。 Buildroot 核心通常只处理常见用例,但它可以通过脚本进行扩展。 Buildroot 系统使用普通的 Makefile 和 Kconfig 语言来进行配置。 Kconfig 由 Linux 内核社区开发,广泛用于开源项目,使得许多开发人员都熟悉它。 由于禁用所有可选的构建时设置的设计目标,Buildroot 通常会使用开箱即用的配置生成尽可能最小的镜像。一般来说,构建时间和构建主机资源的规模将比 Yocto 项目的规模更小。 缺点 关注简单性和最小化启用的构建方式意味着您可能需要执行大量的自定义来为应用程序配置 Buildroot 构建。此外,所有配置选项都存储在单个文件中,这意味着如果您有多个硬件平台,则需要为每个平台进行每个定制更改。 对系统配置文件的任何更改都需要全部重新构建所有软件包。与 Yocto 相比,这个问题通过最小的镜像大小和构建时间得到了一定的解决,但在你调整配置时可能会导致构建时间过长。 中间软件包状态缓存默认情况下未启用,并且不像 Yocto 实施那么彻底。这意味着,虽然第一次构建可能比等效的 Yocto 构建短,但后续构建可能需要重建许多组件。 建议 对于大多数应用程序,使用 Buildroot 进行下一个嵌入式 Linux 设计是一个不错的选择。如果您的设计需要多种硬件类型或其他差异,但由于同步多个配置的复杂性,您可能需要重新考虑,但对于由单一设置组成的系统,Buildroot 可能适合您。 OpenWRT/LEDE OpenWRT 项目开始为消费类路由器开发定制固件。您当地零售商提供的许多低成本路由器都可以运行 Linux 系统,但可能无法开箱即用。这些路由器的制造商可能无法提供频繁的更新来解决新的威胁,即使他们这样做,安装更新镜像的机制也很困难且容易出错。 OpenWRT 项目为许多已被其制造商放弃的设备生成更新的固件镜像,让这些设备焕发新生。 OpenWRT 项目的主要交付物是可用于大量商业设备的二进制镜像。它有网络可访问的软件包存储库,允许设备最终用户将新软件添加到他们的系统中。 OpenWRT 构建系统是一个通用构建系统,它允许开发人员创建自定义版本以满足他们自己的需求并添加新软件包,但其主要重点是目标二进制文件。 优点 如果您正在为商业设备寻找替代固件,则 OpenWRT 应位于您的选项列表中。它的维护良好,可以保护您免受制造商固件无法解决的问题。您也可以添加额外的功能,使您的设备更有用。 如果您的嵌入式设计专注于网络,则 OpenWRT 是一个不错的选择。网络应用程序是 OpenWRT 的主要用例,您可能会发现许多可用的软件包。 缺点 OpenWRT 对您的设计限制很多(与 Yocto 和 Buildroot 相比)。如果这些决定不符合您的设计目标,则可能需要进行大量的修改。 在部署的设备中允许基于软件包的更新是很难管理的。按照其定义,这会导致与您的 QA 团队测试的软件负载不同。此外,很难保证大多数软件包管理器的原子安装,以及错误的电源循环可能会使您的设备处于不可预知的状态。 建议 OpenWRT 是爱好者项目或商用硬件再利用的不错选择。它也是网络应用程序的不错选择。如果您需要从默认设置进行大量定制,您可能更喜欢 Buildroot 或 Yocto。 桌面发行版 设计嵌入式 Linux 系统的一种常见方法是从桌面发行版开始,例如 Debian 或 Red Hat,并删除不需要的组件,直到安装的镜像符合目标设备的占用空间。这是 Raspberry Pi 平台流行的 Raspbian发行版的方法。 优点 这种方法的主要优点是熟悉。通常,嵌入式 Linux 开发人员也是桌面 Linux 用户,并且精通他们的选择发行版。在目标上使用类似的环境可能会让开发人员更快地入门。根据所选的分布,可以使用 apt 和 yum 等标准封装工具安装许多其他工具。 可以将显示器和键盘连接到目标设备,并直接在那里进行所有的开发。对于不熟悉嵌入式空间的开发人员来说,这可能是一个更为熟悉的环境,无需配置和使用棘手的跨开发平台设置。 大多数桌面发行版可用的软件包数量通常大于前面讨论的嵌入式特定的构建器可用软件包数量。由于较大的用户群和更广泛的用例,您可能能够找到您的应用程序所需的所有运行时包,这些包已经构建并可供使用。 缺点 将目标平台作为您的主要开发环境可能会很慢。运行编译器工具是一项资源密集型操作,根据您构建的代码的多少,这可能会严重妨碍您的性能。 除了一些例外情况,桌面发行版的设计并不适合低资源系统,并且可能难以充分裁剪目标映像。同样,桌面环境中的预设工作流程对于大多数嵌入式设计来说都不理想。以这种方式获得可再现的环境很困难。手动添加和删除软件包很容易出错。这可以使用特定于发行版的工具进行脚本化,例如基于 Debian 系统的 debootstrap。为了进一步提高可再现性,您可以使用配置管理工具,如 CFEngine(我的雇主 Mender.io 完整披露了 这一工具)。但是,您仍然受发行版提供商的支配,他们将更新软件包以满足他们的需求,而不是您的需求。 建议 对于您打算推向市场的产品,请谨慎使用此方法。这对于爱好者应用程序来说是一个很好的模型;但是,对于需要支持的产品,这种方法很可能会遇到麻烦。虽然您可能能够获得更快的起步,但从长远来看,您可能会花费您的时间和精力。 其他考虑 这个讨论集中在构建系统的功能上,但通常有非功能性需求可能会影响您的决定。如果您已经选择了片上系统(SoC)或电路板,则您的选择很可能由供应商决定。如果您的供应商为特定系统提供板级支持包(BSP),使用它通常会节省相当多的时间,但请研究 BSP 的质量以避免在开发周期后期发生问题。 如果您的预算允许,您可能需要考虑为目标操作系统使用商业供应商。有些公司会为这里讨论的许多选项提供经过验证和支持的配置,除非您拥有嵌入式 Linux 构建系统方面的专业知识,否则这是一个不错的选择,可以让您专注于核心能力。 作为替代,您可以考虑为您的开发人员进行商业培训。这可能比商业操作系统供应商便宜,并且可以让你更加自给自足。这是快速找到您选择的构建系统基础知识的学习曲线。 最后,您可能已经有一些开发人员拥有一个或多个系统的经验。如果你的工程师有倾向性,当你做出决定时,肯定值得考虑。 总结 构建嵌入式 Linux 系统有多种选择,每种都有优点和缺点。将这部分设计放在优先位置至关重要,因为在以后的过程中切换系统的成本非常高。除了这些选择之外,还有新的系统在开发中。希望这次讨论能够为评估新的系统(以及这里提到的系统)提供一些背景,并帮助您为下一个项目做出坚实的决定。

    时间:2018-07-06 关键词: Linux 软件开发 代码

  • Linux下可执行文件格式详解

    Linux下面,目标文件、共享对象文件、可执行文件都是使用ELF文件格式来存储的。程序经过编译之后会输出目标文件,然后经过链接可以产生可执行文件或者共享对象文件。linux下面使用的ELF文件和Windows操作系统使用的PE文件都是从Unix系统的COFF文件格式演化来的。 我们先来了解一些基本的想法。 首先,最重要的思路是一个程序从人能读懂的格式转换为供操作系统执行的二进制格式之后,代码和数据是分开存放的,之所以这样设计有这么几个原因: 1、程序执行之后,代码和数据可以被映射到不同属性的虚拟内存中。因为代码一般是只读的,而数据是可读可写的; 2、现代CPU有强大的缓存体系。程序和代码分离可以提高程序的局部性,增加缓存命中的概率; 3、还有最重要的一个原因是当有多个程序副本在运行的时候,只读部分可以只在内存中保留一份,这样大大节省了内存。 在ELF的定义中,把他们分开存放的地方称为一个 Section ,就是一个段。 一个ELF文件中重要的段包括: .text 段:存储 只读程序 .data 段:存储 已经初始化的全局变量和静态变量 .bss 段:存储 未初始化的全局变量和静态变量,因为这些变量的值为0,所以这个段在文件当中不占据空间 .rodata 段:存储 只读数据,比如字符串常量 我们用一个例子来看一下ELF文件的格式到底是什么。首先,在Linux下编写一个C程序:SimpleSection.c [cpp] view plain copy int printf(const char *format, ... ); int global_init_var = 16; int global_unint_var; void func1 (int ); int main() { static int static_var = -32; static int static_var_uninit; int a = 1; int b; func1(static_var + global_init_var + a + b); return a; } void func1 (int i) { printf("%d\n", i); } 然后,产生目标文件: [cpp] view plain copy [root@xuxingwang-centos Program]# gcc -c SimpleSection.c [root@xuxingwang-centos Program]# file SimpleSection.o SimpleSection.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped file命令的结果也告诉我们,这是一个32位ELF的文件,类型是 relocatable ,就是可重定位。所以目标文件又叫做可重定位文件。 elf文件的最开始是elf文件头信息,32位有52个字节组成。我们可以使用 readelf 工具来查看一下: [cpp] view plain copy [root@xuxingwang-centos Program]# readelf -h SimpleSection.o ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 224 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 40 (bytes) Number of section headers: 11 Section header string table index: 8 Entry point address 指的是程序入口地址,如果是可执行文件,这个字段会有值; 他之前的字段是一些说明字段; Start of program headers 指的是 程序头表 的起始位置。程序头表 是从装载视图的角度对elf的各个段进行的分类信息;结构和段表相似; Start of section headers 指出了elf除文件头以外的最重要的信息:段表 的起始位置。段表包含了各个段的名称、属性、大小、位置等重要信息。操作系统首先找到段表,然后根据段表的信息去找到各个段。段表是一个类似数组的结构,一个段的信息是这个数组的一个元素。 Size of this header 指的是头文件大小,32位都是 52 个字节,0x34个字节。 Size of program headers 指的是每个 程序头表 的大小。 Number of program headers 指的是 程序头表 的数目。 Size of sections headers 指的是每个 段表 的大小; Number of section headers 指的是 段表的数量; Section header string table index 指出了段表当中用到的字符串表在段表中的下标。 文件头之后,紧跟着的是 程序头,因为目标文件没有链接,所以没有装载信息。我们这里可以先不理会这个东西,以后专门再说他。 程序头之后就是各个段的数据,我们用工具查看一下: [cpp] view plain copy [root@xuxingwang-centos Program]# readelf -S SimpleSection.o There are 11 section headers, starting at offset 0xe0: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00000000 000034 000020 00 AX 0 0 4 [ 2] .rel.text REL 00000000 0003f4 000010 08 9 1 4 [ 3] .data PROGBITS 00000000 000054 000008 00 WA 0 0 4 [ 4] .bss NOBITS 00000000 00005c 000004 00 WA 0 0 4 [ 5] .rodata PROGBITS 00000000 00005c 000004 00 A 0 0 1 [ 6] .comment PROGBITS 00000000 000060 00002d 01 MS 0 0 1 [ 7] .note.GNU-stack PROGBITS 00000000 00008d 000000 00 0 0 1 [ 8] .shstrtab STRTAB 00000000 00008d 000051 00 0 0 1 [ 9] .symtab SYMTAB 00000000 000298 0000f0 10 10 10 4 [10] .strtab STRTAB 00000000 000388 00006b 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) 各个字段意思依次是:段序号、段名称、段类型、段虚拟地址、偏移量、大小、ES、标志、Lk、Inf、对齐。 没有解释的列可以先不考虑,我们先关注其他几个列。 第0个段是为了读取的时候下标不用减1。 紧跟着的就是代码段,偏移量为0x34,就是说在文件头结尾之后马上就是代码段; 代码段之后,偏移量 0x54 的地方就是 数据段,占8个字节,就是程序中已经被赋值的一个全局变量和一个静态变量; 紧接着是.bss段,这里只存储了一个static变量,因为 未初始化的那个全局变量被一种优化机制存储到了 .common 段,这里可以不做理会; 然后是只读数据段.rodata,这里存储的是 printf 里面的 %d\n 这三个字符,外加结束符\0,总共4个字节的空间 我们根据Size这一列来算一下这些段总共占据的空间,(.bss由于不占空间,不用算进来): .text 0x20 .data 0x8 .rodata 0x4 .comment 0x2d .shstrtab 0x51 .rel.text 0x10 .symtab 0xf0 .strtab 0x6b 这里的每一个段都有一个段表元素来描述,总共11个。从头文件得知,每个元素的大小为40字节。也就是说段表总共占了 0x1b8 个字节的空间。而且段表的开始地址由于内存对齐需要,中间空了2个字节。因为段表的开始地址是第224个字节; .rel.text 的开始地址也由于内存对齐的要求,补了一个空字节。

    时间:2018-07-04 关键词: Linux 软件开发 代码

  • Linux添加自定义系统调用

    一、源码修改 1下载一个与所用系统内核版本接近的内核,放在/usr/src下,解压,作个链接ln -s linux-2.6.18.1 linux 2修改:修改三个地方 1)/usr/src/linux/kerner/sys.c中添加, asmlinkage int sys_mysyscall(int a) { return a; } 2)定义系统调用号,/usr/src/linux/include/asm-i386/unistd.h #define _NR_sysmycall 318 //不能与前面已有的重复 #define _NR_syscalls 319//修改系统中所用系统调用数目 3)在系统调用向量表里添加自定义的系统调用函数入口位置, /usr/src/linux/arch/i386/kernel/syscall_table.S,以前老版本是entry.s .long sys_mysyscall 二、内核编译 1.在/boot下复制配置文件,到/usr/src/linux下,改名位config,make menuconfig,可以不用修改,直接退出 2.make clean 清空以前的编译痕迹 3.make,编译出来的是bzImage 4.make modules,make modules-install//编译、安装config里配置的模块 如不执行次步骤,对于有的系统,制作不了initrd文件。系统就启动不了 5.如果直接make install,系统会自动制作initrd文件,并复制initrd和bzimage文件到/boot下,修改grub.conf文件,重启系统,选择进入新内核 6.不使用make install命令。复制bzImage到/boot下,改名位vmlinuz-2.6.18.1,手工制作initrd文件,/mkinitrd initrd-2.6.18.1.img 2.6.18.1,initrd文件名位initrd-2.6.18.1 7.修改grub.conf文件,复制原来已有的启动设置,把title和kernel和initrd改名为新制作的即可 三、编写代码测试 int main(void) { int a=syscall(318,100);//318是系统调用号,100是参数 printf("%d\n",a); return 0; } syscall是内核提供为用户程序的一个函数, 如果不使用syscall函数,也可以使用宏定义,但是在2.6.20以后的版本里,没有宏定义,需要自己从其他版本里复制过来添加。

    时间:2018-07-04 关键词: Linux 软件开发 代码

  • linux drivers中的mmap实现

    drivers中file_operations的mmap操作的作用是: 将设备驱动内核空间的内存映射到用户空间里,可以通过用户空间中的mmap系统调用代替系统调用write和read。目的是提高读写效率。 系统调用mmap: void* mmap (caddr_t addr, size_t len, int prot, int flags, off_t offset) 其中addr一般为NULL,目的是使内核自动分配可用的虚拟空间地址,并通过返回值返回,并与MAP_FAILED比较; prot一般为PROT_WRITE | PROT_READ; flags为MAP_SHARED或MAP_PRIVATE之一;offset表示从设备文件都开始多大偏移处映射,一般为0。 文件操作mmap : int (*mmap) (struct file* filp, struct vm_area_struct* vma) 定义struct vm_operations_struct xxx_vm_ops = { .open = xxx_vm_open, .close = xxx_vm_close, .nopage = xxx_vm_nopage, }; 编写mmap文件操作函数的方式有两种: 一.使用remap_pfn_range一次性申请,不需要定义nopage函数 1.在mmap中调用remap_pfn_range; 2.在mmap中对vma->vm_ops进行附值; 3.在mmap结尾处主动调用vm_ops中的open; 二.定义nopage函数,在发生缺页时由内核申请内存中的物理页,由driver在nopage中将page与vma挂钩 1.mmap中除了对vma->vm_ops进行附值和主动调用vm_ops中的open外; 2.将设备内存首先按PAGE_SIZE对齐,最终只将页对齐的设备内存映射到用户空间中。然后将对齐操作处理后的虚拟地址逐页进行SetPageReserved(virt_to_page(virt_addr))保留(可选) 3.在nopage函数中,首先计算缺页的虚拟内存地址实际的内存页物理地址与设备文件开始处的偏移量offset;然后比较该偏移量是否超过映射的设备文件大小;最后将该缺页地址的虚拟地址变换成页帧号并申请该页。

    时间:2018-07-04 关键词: Linux 软件开发 代码

首页  上一页  1 2 3 4 5 下一页 尾页
发布文章

技术子站

更多

项目外包