胡子了吗系统编程与嵌入式应用程序编程之间的区别!!

出品 | CSDN(ID:CSDNnews)

以下为译文:

登记!示波器!胡须!连载!C!循环剃须!胡须!休息!汇编!等等,我刚刚提到胡子了吗?

一提到“嵌入式程序员”这个词,我们这个行业的大多数人都会立刻想到一个英雄人物。

一位伟大的开发人员,拥有神秘的技能,对神秘的渊博知识,对个人卫生概念持怀疑态度,长着毛茸茸的脸和神一样的形象。

然而,在偷偷研究了这门学科几年之后,我在这里告诉你,你的想象都是错误的。

大多数嵌入式程序员没有胡子,你不必梦想使用汇编语言成为嵌入式程序员,嵌入式程序员洗个澡。

我还可以告诉你,嵌入式编程很有趣、很有回报,也很有挑战性。如果你对这篇文章感兴趣,那么未来你也有可能也在这一行。

请注意,以下内容可能有点雄心勃勃。我将描述嵌入式程序的外观,而不是大多数嵌入式程序的实际外观。

这可能是一个理想的情况。突然遇到嵌入式代码,你可能会觉得这是一个聪明人写的高端代码,这很吓人。

但我想告诉你,你会对 Spotify 的嵌入式编程感兴趣,而好的代码是我们努力的目标。

所以,如果你也是嵌入式程序员,可能这篇文章中呈现的代码和你日常使用的代码不一样,我理解你的感受,现实是真的,但生活可以更美好。

首先嵌入式网络那些事 代码,让我们谈谈嵌入式系统编程和嵌入式应用程序编程之间的区别。

嵌入式系统编程:可能就是你想象中的嵌入式编程。

它包括使嵌入式硬件平台正常运行所涉及的所有工作:编写设备驱动程序、引导加载程序、移植或编写操作系统、各种位操作以及考虑时钟周期问题。调试丢失的中断。

连续盯着示波器看了几个小时,抱怨编译器,讨厌中断控制器,就好像它是一个人一样。经常半夜惊醒,冷汗淋漓,试图说服自己猫偷了前面被中断的信号。对不起,我跑题了。嵌入式系统编程确实涉及非常低级的东西。

嵌入式应用程序编程:指为资源有限的系统编写应用程序的技术。这种开发比较容易,开发环境也不错。

您还可以在台式计算机上编写、测试和调试代码。尽管某些约束可能具有挑战性,但您无需考虑汇编、GPIO 引脚或 DMA 描述符。

但是,您必须考虑内存使用、运行时环境、代码大小和可移植性。但说真的,没有人喜欢这些工作吗?

本文讨论嵌入式应用程序编程,这是我们在 Spotify 花费的大部分时间的嵌入式编程类型。

简单之美

约束使我们的生活更有趣。

只用两列和一杯水录制的音乐专辑比用完整的管弦乐队录制的专辑需要更多的创造力。

虽然我对创造力或“音乐”这个词有非常规的理解。然而,我想说的是嵌入式编程很有趣嵌入式网络那些事 代码,但乐趣在哪里?

大多数嵌入式程序的第一个限制是大小,代码必须紧凑,常见的编程实践(代码需要模块化,易于维护和测试,经过测试)仍然适用于嵌入式程序,除了需要投入的数量代码量保持在最低限度,但也需要保证自给自足。

简而言之:优雅。好的嵌入式代码非常优雅。

那么什么是嵌入式编程呢?什么是嵌入式程序员?我们继续往下看……

内存使用 – 隐藏的杀手

嵌入式程序员需要避开现代内存管理概念。你几乎不可能实现垃圾回收。垃圾收集器可能会耗尽代码大小限制。

而且垃圾收集器还需要时不时的运行实际的垃圾收集,破坏了嵌入式程序的实时性。

您甚至需要避免使用常规 malloc,调用 malloc 可能会花费大量时间,因为分配器可能必须对分配的区域进行碎片整理以释放足够大的内存块以响应请求。

嵌入式程序员乐于直接管理内存、编写自定义分配器,甚至可以防止静态分配的内存块发生内存分配失败。

大多数嵌入式系统和普通计算机之间的主要区别在于内存的组织方式。

Intel x86) 等主流桌面和服务器处理器架构使用代码和数据存储在同一地址空间中的编程模型。

这意味着如果您的机器有 64MB 的 RAM(这太不可思议了!)而您的程序是 40MB(难以置信!),那么您只剩下 24MB 的数据(这么多,不,我用不完!)。

在家里,我们称之为冯诺依曼建筑,但在酒吧我们不敢说,因为它会导致争吵。

由于 RAM 是处理器中最耗电的部分,并且由于 RAM 占用了大量芯片面积,因此许多嵌入式系统使用代码和数据存储在单独存储器中的模型。

代码和静态数据存储在 ROM(通常是闪存或 EEPROM)中;动态数据存储在 RAM 中。ROM比RAM便宜很多,所以通常使用的次数更多(一般是5-10倍)。

RAM 和 ROM 可以有单独的地址空间(哈佛架构),也可以映射到统一的单一地址空间(修改后的哈佛架构,遗憾的是从未称为 Joker 架构)。

除非您需要编写引导加载程序或系统内升级功能(在这种情况下您需要写入代码的存储空间),否则您通常不会注意到两者之间的区别。

但这确实意味着代码的大小和RAM的使用需要分开计算。换句话说:在嵌入式系统中,代码大小限制与 RAM 使用限制不同。请记住,通常 RAM 使用率是最关键的参数。

你所看到的就是一切

嵌入式程序员确实是软件世界中最好的。他们喜欢手工编写程序、创建自己的代码库、使用 1960 年代的语言和使用机械键盘。

很少有现成的库可以满足嵌入式系统的特殊限制。虽然有很多 JSON 解析库,但很少有人能够支持解析大于 RAM 容量的文档。

嵌入式程序员总是乐于尝试现有的库,因为他们很懒惰。但是,如果没有合适的库,嵌入式程序员也乐于重新发明更小、更快的工具。

因为嵌入式程序员非常重视理解和控制代码的执行和资源的使用,所以几乎所有的代码都是用 C 编写的。

有时新的编程语言试图入侵嵌入式世界,却遭到嵌入式程序员的质疑。

这种语言有一些花哨的线程模型吗?请参阅下面的并发讨论。

这种语言有垃圾收集吗?请参阅下面的性能讨论。

图片[1]-胡子了吗系统编程与嵌入式应用程序编程之间的区别!!-老王博客

这种语言的编译器是否支持人类已知的所有计算机体系结构?

请参阅下面的可移植性讨论。简而言之,门槛很高,C 非常好。

嵌入式软件系统通常很好理解。缺乏第三方代码库和花哨的继承结构,以及严格的代码大小限制,都使代码保持小而易于理解。

在编写良好的嵌入式代码中,您在页面上看到的所有内容都是代码。嵌入式程序员不必剥离层来弄清楚代码实际上做了什么。

这并不是说实际嵌入式应用程序的逻辑不会非常复杂,但至少我们不需要通过抽象模式层来隐藏该逻辑。

并发

嵌入式开发人员不喜欢并发。对于查尔斯·巴贝奇(可编程计算机的发明者,计算机的先驱)来说,一次做一件事就足够了,你也一样。

大多数形式的并发支持需要不时保存状态并切换到新任务。

这需要多个堆栈,每个任务一个堆栈,以及大量 RAM,有时并不多。今天,堆栈可以轻松占用 1KB 或更多。

嵌入式程序员无法忍受这一点。他们宁愿手动处理协作任务切换、非阻塞 I/O、轮询、回调、手动任务调度、主循环。

这些是嵌入式程序员最常使用的东西。如果你不明白这些东西是什么意思也不要着急,你可以参考本文末尾的推荐书籍。

精明的读者可能会问:“不是所有类型的任务切换都需要保存任务的状态吗?难道你不把这项工作从操作系统交给程序员吗?”

嵌入式程序员会回答:“当然!”,或者:“把工作从操作系统转移给程序员,这就是嵌入式编程的工作!”

并发是个问题。然而,抛开先入为主的多线程概念,并发实际上要简单得多。您知道您的代码不会被中断,因此您可以轻松掌握执行顺序。

缺点是您需要为 I/O 等编写更多代码,因为您不能使用阻塞。

前面提到的可怜的嵌入式系统程序员运气不好,硬件中断会破坏一切。

可移植性

如果您的程序无法在所有已知的处理器架构上运行,那么您的程序就不是嵌入式程序。

大端、小端、基于堆栈的寻址、基于寄存器的寻址、RISC、CISC、标量、向量、DSP 或 PIC,没关系。

代码无论放在哪里都可以正常工作。一个字节包含8位?没那么快!嵌入式程序员不做任何假设,他们质疑一切。

如果有一天客户要求您的程序在带有分段只写内存和分支协处理器的 Chewbacca 5000 12.5 位基于堆栈的矢量 CPU 上运行,嵌入式程序员也可以自信地告诉他:没问题。

这对你意味着什么?对旧的 C 标准感到疯狂。

易于测试

由于嵌入式程序可以“脱机”执行多种类型的测试,因此嵌入式程序员可以在编写测试代码时尽可能多地尝试现代软件开发。

测试代码可以用 Node.JS、Python 或 C++ 编写。世界上没有比我们在测试代码中在堆栈上分配大对象更内疚的了。

在为硬件开发嵌入式程序时,测试是绝对关键的。您编写的代码最终会出现在永远不会更新的设备中。

有时您的代码会被烧录到 ROM 芯片中。如果在发布后发现错误,它们可能会非常昂贵。

因此,对现代测试原则的坚定承诺、对编写易于测试的代码的热情以及实现 100% 测试覆盖率的决心是嵌入式程序员的宝贵品质。

表现

对于大多数程序员来说,性能是一个简单的问题:“代码运行速度够快吗?”

如果代码运行得比要求的快,那么一切都很好。

对于嵌入式程序员来说,情况稍微复杂一些:“代码运行速度够快吗?实时性够吗?功耗有没有计划好?”

除了 RAM 和代码大小限制之外,代码还必须运行得足够快。

但不要太快。未使用的周期有助于降低功耗。更低的功耗意味着更长的电池寿命、更少的热量产生,以及在下一次硬件升级中使用更便宜、更慢的 CPU。

我们一直在与底层硬件人员一起玩游戏。良好的嵌入式代码设计可以将 CPU 推入睡眠模式,例如通过使用显式轮询,这允许系统在轮询之间进入睡眠状态。这也意味着代码不应因任何原因而阻塞。

一些嵌入式系统具有严格的实时要求,例如心脏起搏器。在这样的系统中运行的任何线程或任务必须保证在固定的时间内返回。

如果运行时间过长,系统可能会完全失败。例如,拿起起搏器将被归类为“有缺陷的”。不用说,为心脏起搏器编写代码并不适合胆小的人。

大多数嵌入式媒体应用程序都有软实时要求 – 如果线程或任务使用 CPU 的时间超过其应有的时间,系统性能将下降,但不会完全失败。

音频或视频可能会出现故障或冻结。用户界面可能会感觉延迟。这绝对不是一件好事,但也不是灾难性的。

编写具有良好实时特性的代码与编写有助于 CPU 休眠模式的代码非常相似,都利用了非常短的时间片,非常注意循环长度并且从不阻塞。了解您的代码路径。不惜一切代价避免递归。

我怎样才能成为一名嵌入式程序员?

一个理想的嵌入式程序员的重要特征是什么?

您需要对计算机体系结构的基础知识有深入的了解。了解内存层次结构、吞吐量瓶颈和硬件级并发问题。对寻址如何工作(指针)也有很强的心理把握。

此外,根据您需要使用的软件类型,您可能还需要掌握一些行业技能。例如,在 Spotify,您需要对网络有很好的了解。

如果您觉得您对计算机体系结构的基础知识没有扎实的了解?

那么请参考以下推荐书籍:

此外,好奇心也是嵌入式程序员最重要的品质,渴望了解事物运作的冲动和坚韧,愿意全身心投入工作并不断学习。

原文:.com/2019/04/09/an-opinionated-anthropology-of-the-embedded-programmer-its-habits-and-habitat/

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论