论坛

低级编程

开始于 aniruddhpr4 2年前 25回复 最新回复2年前 970意见

在嵌入式编程方面,我是一个新手。如果给我头文件和ARM或AVR等的所有启动代码,我可以编写简单的东西。但是,我想更深入地研究,我的目标是为给定的硬件编写每段代码。

我进行了一些研究,并了解了如何从头开始执行程序。要编写低级代码,初始化代码等,许多人建议阅读数据表,但我无法掌握数据表中到底需要做什么。

例如,我为此选择了atmega328p,并尝试通读数据手册以了解如何编写复位矢量和所有低级编程的代码,但徒劳无功,我什至不知道从哪里开始。

从理论上讲,它是简化的(我提到了O'Reilly 用C和C ++编程嵌入式系统),似乎是可能的。但是,任何地方都没有适当的资源或理论可以指导实际应用。

有人能指出我正确的方向吗?我应该从数据表的哪儿开始?我应该找什么?如果您可以给我完整的路线图,那将非常有帮助。

[-]
回覆者 QL 十二月3,2018

您可能想尝试的一种资源是 YouTube上的“现代嵌入式系统编程”视频课程。本课程使用现代的ARM Cortex-M微控制器在前20课左右教授低级编程,包括您要求的一切(机器代码,寄存器访问,函数调用,启动代码,中断等)。后面的课程继续说明嵌入式系统的体系结构。

[-]
回覆者 Bob11十二月3,2018

很久以前,在高中时,我使用带有前面板拨动开关和几个7段显示器的6800来包装自己的计算机,并手动拨动汇编代码。我实际上让一切正常。这是真正非常低级的方法!

假设您现在正在采用理智的方法,并从所选微控制器的开发板开始,步骤大致如下:

1)首先学习如何读写内存。这些天通常意味着学习如何将代码加载到FLASH中。几十年前,这意味着EEPROM刻录机和UV擦除,而今天,则意味着您拥有合适的调试/编程探针。确认您可以在复位向量处写入/读取存储器。

2)仔细阅读复位向量。它必须是分支指令吗?您将代码放在哪里?除了在默认情况下可能启用的看门狗定时器,它可能会意外地咆哮着,现在不必担心中断或其他任何事情。通常,默认情况下未启用它们,这是可取的。参见数据表。

3)您的开发板应该有一个驱动LED的端口或类似于监视代码执行的端口。 (当您在此级别上探索微米时,还可以使用示波器来探测引脚。)

4)编写SIMPLE汇编代码以完成非常简单的操作,例如从复位向量跳转到一个简单的例程,该例程每秒切换LED的开/关。这将涉及学习如何使加载程序将代码和复位向量放置在内存中的正确位置,如何启用和设置LED点亮的端口为输出模式,以及如何关闭任何看门狗或启用任何内部处理器可能需要的时钟。在此阶段,请勿尝试使用堆栈或其他任何东西。只需设置LED端口位,加载寄存器,递减计数,清除LED端口位,加载寄存器,递减计数,然后跳回到起点。数据表是您的朋友,这里还有供应商提供的有关如何启动微处理器的所有应用笔记。我建议如果可能的话在此阶段使用命令行工具,因为当今大多数供应商都提供GUI工具,这些工具将“引导您”远远超出这些初始学习步骤,并隐藏您尝试学习的所有实现细节。

5)一旦您到达LED闪烁的位置,您就回家了。下一步是增加一些外围设备。这通常涉及编写一些简单的函数来访问所涉及的端口,这意味着添加一些代码以正确地将堆栈指针设置在内存中,以便您可以从子例程中跳转和返回。完成此操作后,您可以尝试启用一个或两个简单的中断处理程序,并检查它们是否按预期工作。

6)如果您准备好使用C,现在该学习一下crt0,它是在main()之前运行的C启动代码。没什么太多的了-复位向量将跳转到设置堆栈指针的代码,并使用内存中bss(数据)区域的地址加载一些寄存器,必须清除静态数据区域,可能必须将一些常量数据从FLASH复制到RAM,并进行其他设置,以便该处理器的C编译器需要ABI。供应商的GUI工具通常会隐藏这些内容,因此您可能需要花点时间才能找到您的电路板/编译器组合的要求。通常是在汇编中完成,最后是跳转到main()。您还必须编写一些代码来确定main()返回时该怎么办。

如果您已完成上述工作,则您基本上已经完成了目标。现在,您已经从复位向量获得了处理器,开始执行代码所需的最低处理器设置,以及设置中断处理程序正常工作和C正常运行所需的各种地址空间,堆栈等。现在,您已经在main()中。世界是你的!


[-]
回覆者 aniruddhpr4 十二月3,2018

非常感谢!这真的很有帮助!

[-]
回覆者 杰克·克伦斯 十二月5,2018

Bob11钉了它!!!

插口

[-]
回覆者 dnj 十二月3,2018

我几乎不会同意QL的准备工作。进入裸机编程需要一些婴儿步骤,以防止淹没在游泳池深处。

曾经有一段时间,即使是在商业机器上的处理器也很容易用汇编语言进行编程。我不停地编程(在1960年代),这需要某种形式的汇编程序。 FORTRAN只是没有为所有事情削减。这些机器已经绝迹了,因此您应该寻找一种半现代的替代品,以获得汇编器甚至嵌入式C的感觉。

我有一个使用8051内核的项目。由于我深深地沉迷于C和C ++,不得不重新整理过去几年来我忘记的所有事情。寄存器结构很简单;指示很简单;并且容量有限。但是,这些小型处理器是数百万个设备的核心。也许数十亿。

物有所值的钱将是找到一个使用8051的开发套件,看看是否可以启动,启动它,并按照其他答复的建议做一些简单的事情。一旦具备了这些基础知识,就可以将知识扩展到所有外设寄存器,寻址模式,中断向量等中,而这些将在更加复杂的ARM CORTEX处理器中找到。

该知识非常有用,因为您可以真正了解处理器在做什么,而不是调用某些高级API来为您做所有事情。您将开始像计算机一样思考并了解正在发生的事情。

祝好运。这是一个启发性的经历。

如果您可以找到Knuth博士的编程书籍的一些副本,则可以找到他发明的MIX汇编语言以在其书籍中说明算法。他们很老,但是很经典。

[-]
回覆者 aniruddhpr4 十二月3,2018

谢谢。我在较早的学期就曾就8051进行过一门课程,我尝试过该课程,但没有按照您要求我来这里的方式进行。因此,我一定会尝试一下。 


是的,一定会推荐Knuth博士。非常感谢你!

[-]
回覆者 托姆金斯 十二月3,2018
首先,我的预选赛。我爱自由狗屎!


STMicroelectronics制造许多名为发现板的低成本模块。我有一些使用基于STM32的发现板的经验。

STM建立并积极维护了一个软件开发基础结构,以支持STM32产品系列。这包括编程应用程序,跟踪应用程序以及它们所谓的STM32CubeMX。除了Cube之外,还有可下载的示例源代码库(初始化,驱动程序,示例外设代码等)以及RTOS的集成, FreeRTOS StemWin ,一个专业的图形堆栈库。此外,他们最近购买了Atollic来收购 TrueSTUDIO ,基于Eclipse的C / C ++集成开发工具.

除发现委员会以外,以上所有内容均为免费!

这个发现委员会 32F746G发现,可从DigiKey购买,价格为$ 57.00加元。

可通过STM32CubeMX获得的示例源代码非常广泛,对于研究基于ARM技术的32位MCU开发的任何人来说,这都是非常棒的。

STM32CubeMX源代码具有许多流行的开发工具(Keil,IAR等)的示例源,TrueSTUDIO和TrueSTUDIO将转换OpenSTM32格式的源代码示例。

我相信,自己编写所有代码都是一项令人称赞的工作,但是,鉴于通过所有免费工具都可获得的资源,如果您正在为市场开发产品,那么您可以获得更好的投资回报率(又称投资回报率)您的时间和精力))(如果您利用制造商提供的固定代码,并且在竞争对手之前将产品展示在消费者面前)。

最后,STMIcroelectronics基础结构包括各种库和MCU的大量文档和说明,使用它们的产品集不会出错。


[-]
回覆者 aniruddhpr4 十二月3,2018

哈哈,免费的狗屎让我想更深入。自从我开始使用Linux以来,我一直在寻找所有付费产品的替代方案。我可以使用STM32 Discovery开发板。我正在使用Eclipse CDT和GNU MCU工具链对其进行编程。但是我还没有尝试过cubeMX。因此,我一定会给出您建议的一切,请尝试。谢谢。

[-]
回覆者 拉力哥 十二月4,2018

Atmega328确实不需要任何初始化代码即可启动。您只需要了解跳转向量所在位置的一些基本知识即可。复位地址最简单的形式是地址0x0000,然后是中断跳转地址,您只需要确保将jmp START放在地址0x0000即可。无需进行其他任何初始化即可开始。这里有一个不错的小教程,展示了您需要多少汇编程序才能入门。它的扩展足以引起您的兴趣,并实际上创建了通用的嵌入式“ hello world”。

//medium.com/jungletronics/meeting-assembly-...


但是,正如其他张贴者所说的那样,不仅要有数据表,而且要有指令集文档,这总是一个好主意,并时刻注意勘误表...。

[-]
回覆者 mr_bandit 十二月5,2018

首先,该线程中有很多好东西!

其次-我的父亲,他曾经是60年代末70年代初的顶级操作系统设计师之一。他教我如何编程-当时是8080装配体。调试使用DBG来放置“补丁”:将JMP放置到未使用的内存区域,将助记符asm递进二进制文件放入该区域,然后再返回JMP。 (调用堆栈为 非常 小。) 显然,保持良好的记录至关重要。初始编程是在ASM上对编码纸进行的,编码纸由打孔卡服务放到打孔卡上。运行汇编程序并非易事且缓慢。

从那以后,他使用了我一直用于ASM编程的格式。 ASM是(通常)人类可以正常处理的底层代码,并且代码可能变得晦涩难懂。这种格式有助于理解发生了什么。

(他还向我提供了有关评论的建议:假设您的代码将由带有发夹的连环杀手进行更新/调试,并且您的姓名位于标题中。请记住,您将是另一个人,六个月或下个星期)

格式为:

注释块,其中包含所有已使用的寄存器及其包含的内容(例如“R5: 循环次数“),后跟一个评论 什么 您将要做的(例如“通过带有循环计数器和从设备baz读取的foo []数组调用bar()运行,将foo [loop_counter]设置为bar()结果“)。您还可以列出如何处理伪代码(谷歌“伪代码”)。一些示例: http://www.unf.edu/~broggio/cop2221/2221pseu.htm

用所有要使用的寄存器结束注释块。 (R5 =循环次数; R6 =循环计数器; R7 = bar()的参数,并从bar()返回值; R8 =来自设备baz的结果; R9 =刮擦)(每一个都应该单独一行,格式化干净以便于理解-该编辑器的格式化太简单了。)

然后-10..12行ASM代码。如果您不止这些,则您的代码太复杂-重构以简化。保持格式整齐,可读!一行上的任何注释都应解释模糊的内容(“这是一个易失性设备寄存器”,“读取U16的MS字节”,而不是“将1加到R5 ”)。

THEN-下一个注释块

一种类似的方法适用于高级语言-带有您将使用的变量,算法和结果的注释块。

记住吻:保持愚蠢”。 聪明之处在于算法,而不是代码。该代码应类似于“ run dick run”.

查看清单。查看如何将ASM助记符转换为机器代码。

[-]
回覆者 CustomSarge 十二月3,2018

从我的头顶上:

>尝试查找所选处理器的汇编手册/指南。

>熟悉该处理器附带的任何IDE(集成开发环境)。

>使用用于LED的栅极/晶体管驱动器构建uC电路,并编写代码使其闪烁。

>将构建更改为STP04CM05之类的LED驱动器,并使其代码闪烁,然后排序。

>继续逐步构建更复杂的内容并编写更多代码来完成。

>在基础知识不是坚实的基础的同时,也不要试图学习高级技术。了解I2C,LCD,键盘输入和其他必要的设备。您将以耐心和毅力到达那里。 

>当您进入具有多个并发功能的应用程序时,将发生编码中断(时间和原因)。

大致轮廓,仅此而已...良好的狩猎<<<)))


[-]
回覆者 吉姆_255 十二月3,2018

aniruddhpr4 ,

我的第一个问题是为什么?您选择的处理器是20 Mhz 8位设备,指令周期时间为50nS。坦白地说,该设备的C语言工具和库应该生成足够快的代码,即使是最严格的中断服务时序,也几乎可以用到该部分的任何内容。

我是一位经验丰富的嵌入式系统工程师,具有40多年的经验。自从使用C语言以来,我一直在开发各种嵌入式系统。在嵌入式环境中,我们唯一的编程语言是汇编器。实际上,在汇编器应用程序存在之前,我已经在MACHINE CODE中写了很多东西。我们从头开始了一切。如果这确实是您要去的地方,请扔掉C编译器并使用汇编器。每个处理器,AVR,ARM,PIC,Z-80、8086等都有自己的汇编语言,因此,您将必须为所使用的每个处理器学习一种新的语言。简而言之,没有“完整的路线图”,因为每个处理器都不相同。


-吉姆

[-]
回覆者 杰克·克伦斯 十二月3,2018

吉姆,像你一样,我是一个“经验丰富”的计算机专家。像您一样,我早在C可用之前就开始编写代码。但是我对您的评论感到困惑,因为没有汇编程序,您不得不编写MACHINE代码。 AFAIK,组装商的历史几乎与计算机一样长。除了EDSAC之类的异常值,甚至就此而言,Babbage引擎之外,第一个汇编器是为IBM 701(大约)编写的。 1951年。我本人正在编写IBM 650代码。 1956年。

因此,我确定您的意思不是“存在汇编程序之前”。我猜想您肯定是在为某个处理器编写汇编程序之前就为该处理器编写程序。也许是飞行计算机?

但是即使那样,_NOBODY_也必须用“机器代码”编写程序。 AFAIK,没有“现代化”的数字计算机(自1948年以来就没有)被制造出来,没有与指令集相关的助记符。  

我已经不记得所有的8080助记符了,但是我确实记得CALL的十六进制代码是十六进制CD,RET C9,JMP C3等。如果您确实没有汇编器,那么写下来就很容易了您的程序作为助记符,然后手工汇编为等效的十六进制代码。

顺便说一句,我遇到了一些以努力工作而自豪的人。 1961年,我实际上让一个坚定的系统程序员自豪地宣布(我的意思是),

“汇编语言是w夫!真正的程序员使用绝对二进制代码!”

当然,他是个白痴。我很确定你不是。

因此,再次让您感到困惑的是您从头开始编写MACHINE代码的断言。您愿意详细说明吗?






[-]
回覆者 吉姆_255 十二月3,2018

好吧,我很乐于阐述。

早在1977年,我当时就在用8080/8088 Z-80、6502和其他几种处理器设计嵌入式系统。 Z-80和8080/8088组装机都没有在市场上销售,直到1980年初。我们在大学里有一个叫做Bi-Tran Six的教练机。我们将其编程为八进制,这是我在电子工程专业学习时的切入点。  //imgur.com/gallery/INabLxA


[-]
回覆者 杰克·克伦斯 十二月5,2018

吉姆,非常感谢您提供的其他详细信息。我看到你&我走过许多相同的道路。

不过,我对日期还是有些困惑。您是否确定其中的某些日期是100%?

1974年,我担任阿拉巴马州亨茨维尔市一家名为Comp-Sultants的公司的经理。我们当时正在围绕Intel 4004,然后是4040构建嵌入式系统。我们甚至出售了一套计算机套件: http://www.oldcomputermuseum.com/micro-440.html

现在,英特尔自1971年以来一直在销售4004,您只需要知道英特尔就不会在没有开发系统的情况下出售芯片,因此我们可以实际使用它。我们有一台单板计算机,其中包含4004芯片和一些RAM,以及ROM中的汇编器和调试器。也是EPROM读取器/刻录机。 I / O是通过Teletype ASR-33进行的。后来,我们升级了ROM,以便组装到4040。我本人在那块板上写了很多程序-都是在1976年之前。

1975年,我们获得了为Scientific Atlanta开发8080软件的合同。到那时,英特尔公司拥有一台非常不错的计算机Intellec 8,它具有64K RAM和ROM中的汇编器/调试器。我为该项目编写了所有软件。

一句话:我们似乎在8090 Z-80上做了很多相同的事情,但我仍然无法理解您的评论,即直到1980年才有商业装配商可用。

插口

.

[-]
回覆者 aniruddhpr4 十二月3,2018

为什么的答案是,我只想了解幕后发生的事情。

我也在学习汇编代码,但即使是汇编代码,例如,Keil汇编器也需要启动。因此,提出了很多我不喜欢的抽象。我想尽可能靠近设备。无论如何,谢谢您的答复。

[-]
回覆者 dbrion06 十二月5,2018

好吧,我同意吉姆的话:

40年前,在使用asm进行编码之前,我写了(用铅笔,纸和橡皮擦(用于打字错误和错误))应该做什么(使用algol / pascal:虽然没有编译器,但两种语言都存在,众所周知) 。

现在,有优化的交叉编译器(和代码检查器:检测到未初始化的变量:它们与CPU无关...)和优化器:gcc(对于avr-s,arm-s和esp-s)和sdcc(对于Z80)和衍生自8051的广告)有一定程度的优化。

您应该问自己一个问题:我能用ASM编码比优化的c(++)更好吗? sdcc(平凡的)和gcc都生成汇编-因此,该问题可以获得每个问题的答案...-为了理解(优化的)生成的代码,google搜索可以带回(询问google“ avr汇编说明”,如果您国家有一个舒适的网络)文档,很难找到一千年前的文档,例如 //www.microchip.com/webdoc/avrassembler/avra...


自学汇编时还有另一个问题:除非一个人找到书和时间来阅读它们(一个人应该),否则人会读一个人自己的错误并复制它们……(生成的程序集会减少恐怖)。论坛试图纠正主要问题,但不能纠正不良习惯。

您应该对C ++有所了解,并了解生成的程序集。模拟器(从未使用过)可能会很有帮助。


我同意在极少数情况下,内联汇编(每个C编译器都可以处理内联汇编,AFAIK)很有用:我知道最近的neopixel库(需要周期精确计时的地方) //github.com/adafruit/Adafruit_NeoPixel/blob... (用于许多ASM-s)和avr-libc(由arduino使用,但已隐藏....)。但是绝大多数人几乎不使用汇编程序。


在初始化之前就已经存在下载程序的方式(“ bootloaders”)(否则,如何放置复位向量?中断处理程序?)

[-]
回覆者 jms_nh 十二月3,2018

对于PIC单片机,请尝试使用 我的客户中心  -它为不同的外设设置寄存器,并为您提供了一个很好的起点,因此您知道何时需要微调数据表中的内容。 (尽管从理论上讲,MCC应该能够支持大约90-99%的用例,具体取决于外围设备。)

同样,通过处理器寄存器进行“低级编程”的想法完全独立于汇编与C / C ++的选择。这里有一些答案提到了汇编,但这不是您要的。您可以很好地使用C或C ++访问CPU寄存器,只需要正确的#include文件和链接描述文件,以便编译器和链接程序生成适当的代码。 (打印精美:编译器拥有您不应该在C中接触的某些主寄存器,例如程序计数器,堆栈指针和任何ALU寄存器。)

[-]
回覆者 杰克·克伦斯 十二月3,2018

嗨,阿妮!我们已经阅读了您的询问和答复,并提供了一些建议。其中一些做法会以错误的方式擦伤其他人,对于任何冒犯,我事先表示歉意。

首先,不要关注所有告诉您不要做自己想做的人。确实,构建基于AVR的系统的最简单方法是购买Arduino并在IDE中编写C ++代码,从而大量使用了许多可用的库。 


但是您已经明确表示,您希望对CPU内核有更深入的了解。恕我直言,没有人有权告诉您您想学习它是愚蠢的。

其次,不要注意那些提到8051的人的建议,也不要在汇编程序存在之前就编写代码(必须在1954年之前,也许是更早)。

事实是,早期的微处理器(例如8080,Z80、8051等)来自不同的时代,当时CPU是主板上的一个芯片。 RAM,ROM,I / O设备等都是硬连线的,并由分立的片选逻辑提供支持。


现代微控制器完全是不同的野兽。它们是片上系统(SoC)设备,所有逻辑都是可编程的。


早在1994年,我就与摩托罗拉68332签订了一份构建系统的合同。它并非完全是SoC,RAM和ROM仍然是分开的,而是计数器,计时器,I / O设备,甚至片选逻辑。都在芯片上。因此,您要做的第一件事就是编写初始化代码。

好消息是,摩托罗拉拥有庞大的用户手册,其中描述了初始化芯片所需的一切。


坏消息是,手册难以理解。它倾向于说“您可以执行此操作,或者您可以再次执行该操作”,但从未说明替代方法的优缺点。


幸运的是,Moto还拥有一位专家-阅读一(1)位专家-我只将其称为Charlie。我猜想查理传播得很薄,但是他总是可以在24小时内访问到,并且总是会花时间来解释不同方法的优缺点。


非常感谢Charlie,我能够创建可靠的启动代码,从而正确初始化内存空间,计数器,看门狗定时器,UART等,以及中断向量。该项目取得了成功,产品按时按预算交付。

当其他人说您不必再做这些事情时,其他人说的很对,因为存在图书馆。

即便如此,我还是非常满意地知道_EXACTLY_的,启动代码在做什么,以及如果需要的话,如何自己更改它。


我敢打赌,你也愿意。





[-]
回覆者 aniruddhpr4 十二月3,2018

是!您可以按自己的意愿去做。我猜我们越努力,满意度就越高。无论如何,谢谢您的答复。

[-]
回覆者 mr_bandit 十二月3,2018

阅读数据表是一门艺术和科学。有时他们说谎。请注意勘误表-它们出了问题,可以为您节省很多时间。

您可以为arduinos编写“ raw” C。有关详细信息,请访问atmel(现在为微芯片)。免费的C IDE是 //www.microchip.com/design-centers/8-bit/avr...

为了使事情变得简单一些,请使用十几岁的2.0或2.0 ++版本,因为引导加载程序真的很简单。特定位置。 teensybootloader设置在同一位置。要加载新代码,请按十几岁按钮。 (所有这些都在pjrc.com上进行了解释。)请注意,teensy 3.x主板使用ARM,因此工具链有所不同。)

要做的第一件事是使LED闪烁。查看Arduino示例的代码(如果我记得的话,“ blinky”)。查看#include文件,然后查看代码。然后查找328 mpu数据表中使用的寄存器。您需要对任何IO寄存器做一些事情:设置方向(输入/输出),是否输出,每个输出引脚的初始值等等。

确实有助于理解布尔运算(AND和OR-在C语言中&和|)和(反演)“〜”和(非)“!”)。通常,尤其是在寄存器中,这是如何操作位的。

QL 为您提供了一个很好的链接。如果使用Arduino,则需要比较/对比Atmel和ARM。

但是-如果您使用QL的课程链接,请使用teensy 3.0-引导程序的顺序应大致相同。

当您进入外围设备时,请从SPI开始,并从Adafruit或Sparkfun获得SPI芯片突破。 (您也可以使用I2C,但是更难点位)

还有-拿来一个黑格尔镜 http://www.saelig.com/product/ds1054z.htm 不到$ 400美元-到目前为止,我只想提到一个在互联网上发现的简单黑客程序,它将通过更改EEPROM中的一个字节将该范围从50 MHz转换为100 MHz。您将首先认为4个频道太多了,然后您会为4个频道感到高兴...

祝你好运,成功!

[-]
回覆者 焊点 十二月4,2018

您想为给定的硬件编写每段代码。我认为,大多数代码将是C和C ++,用汇编语言进行的所有工作都是……可能,但为什么要放弃所有使事情变得容易一些的事情呢?

如果我做对了,您的麻烦就从重置开始,然后再执行代码,直到您的程序建立了一个能够处理编译器创建的二进制代码的环境为止。

这部分的内容确实不是一件容易的事,因为您不仅需要涵盖处理器所需的内容,而且还需要编译器希望完成的内容。

例子:

-一些处理器在引导地址上有一个ROM覆盖层,用于执行引导加载程序。需要关闭该覆盖,这是通过对一些寄存器进行编程来完成的。

-有些处理器具有内置存储器,必须在访问之前启用这些存储器,同样,您很可能需要为此正确写入一些寄存器。

-必须设置堆栈存储器,以便在调用子例程时可以将返回地址压入有意义的地址,并在返回时弹出。

-不错的C编译器将在启动期间将所有gobal变量初始化为零。必须有一些执行此操作的代码,因为通常不指定存储器的复位值,并且肯定不能为零。其他存储区域需要初始化为其他值,例如全局变量的初始化值不等于零。

您只会在数据表中找到其中的一些东西。您可能在其中找到了复位向量的位置和结构,但其余的是...用C语言建立C环境和互通汇编语言。

我的建议:用C语言编写一个小应用程序,这是一个简单的应用程序,它使用开发环境附带的所有内容,除了增加计数器外没有任何其他用途。将可执行文件下载到处理器中,并使用调试器从复位向量开始一步一步地完成反汇编代码,直到到达main()为止。您会发现在那里执行着很多令人惊讶的事情,其中​​许多来自编译器的运行时库。

并行了解ASM-C互通标准(在ARM世界中称为“过程调用标准”),因此您了解如何调用函数以及如何传递参数和返回值。

问题是:这些事情因处理器系列而异。即使在ARM世界中,复位向量在所有设备上看起来也不相同,并且在Intel计算机上的子例程调用与您在ARM世界中看到的完全不同。因此,首先要决定要在哪个HW平台上进行自我教育,然后再进行深入研究。我已经完成了您在ARM世界中打算做的所有事情,即使对于我来说,将我的知识映射到其他处理器体系结构(例如ARC或Tensilica)也不是一件容易的事。

祝好运并玩得开心点!

[-]
回覆者 aniruddhpr4 十二月4,2018

非常感谢!那是很多有价值的信息。我浏览了一些文章和博客,其中许多链接器调整已完成。所以我猜想我也必须做一点编译器环境设置。无论如何,我愿意在任何程度上去了解这一切。至少对于单个设备。

[-]
回覆者 Atomq 十二月4,2018

大约20年前,我处于同一状态。.我的MSC论文是基于8052的,幸运的是-由于不同的原因-我被迫使用汇编器。我认为这是一个很好的起点。它的好处是可以按照我需要的方式控制所有硬件,再加上经验,其好处是花了一些时间来掌握所有系统。我的下一步是转移到AVR系列产品,并首先接触C编码。 8位AVR在其架构,相当直观的组织化SFR和内存映射的意义上并不太复杂。 Well C为您提供了构建“应用程序”所需的所有开销,您甚至可以编写自己的对象来模仿C ++对象编程,并完全控制硬件。

我想在这里指出,一旦您知道如何调用函数以及如何将参数传递给C,就可以在使用C进行编程时随时随地使用汇编代码。

了解设备是必须的。这就是为什么您需要手动获取所用微控制器的数据表的原因。首先是要了解特定硬件的工作原理(接口,ADC,看门狗等),然后如何利用SFR位控制或配置它。您可以在数据表中找到所有必需的信息。

我会说很多努力,但是收获是按照您想要的方式控制所有引擎的乐趣。我建议的下一步是进入一些更复杂的架构,例如STM32,并使用CUBE,在该架构中可以为您编写所有初始化代码,然后让预配置的引擎以您自己的代码驱动。

希望对您有所帮助。祝你好运。亚当。

[-]
回覆者 韦丹 2019年3月18日

这个线程有点旧,但是我想我和你在一个相似的地方。您已经从经验丰富的论坛成员那里获得了很多很好的建议;我之所以加上两分钱,恰恰是因为我不在那个小组中。去年,我得到了一个基于ARM的NXP开发板(FRDM-KV11Z),我希望我的一些天赋能为您提供帮助。

拿到开发板后,我下载了试用版IAR工具链,并编写了使某些LED闪烁的程序。 Miro Samek博士的YouTube视频为我提供了一个很好的帮助,我建议您观看前5到10个速成视频。

我决定下一步是使用供应商提供的API编写一些软件,但是在阅读了文档之后,我发现它们的结构令人困惑且混乱。我开始考虑编写自己的硬件抽象层(HAL),并阅读有关在C中实现这一层的知识。在我的实验过程中,通过使用 -S  在LLVM和GCC中标记以生成汇编代码。通过阅读此编译器生成的程序集,我开始了解该芯片在底层执行代码的工作。备有ARM用户指南以帮助阅读助记符非常有用。

在开始编写HAL之后不久,我就对C感到厌倦。当时我也在学习Python,并希望使用一种更加面向对象的语言。我尝试了一些用C ++进行的编程,这很有趣,但是最终我被Ada的错误所困扰。我真的很喜欢Ada,主要是因为Ada具有强大的类型系统,这使我更容易抽象出内存映射的硬件寄存器。在此网站上寻找Ada支持时,我发现了一个 很棒的教程 由Maciej Sobczak撰写。即使您不打算使用Ada,我也认为本教程的前四部分对理解如何编译,链接和生成二进制文件很有用。

现在,我已经全面讨论了,现在回到编写汇编代码的位置。这实际上只是为了我自己的利益。我想更好地了解处理器的启动和链接需求。我有一个 github仓库 我将自己的工作保持在MIT许可之下,以便任何人都可以使用我的代码来扩大学习范围。我还建议Miro Samek博士撰写的一系列文章 使用GNU构建裸机ARM系统.

以下是我的一些个人看法:

  • 我想用一个 自由  工具链(相对于试用版),这样我就可以在使用相同工具的同时扩大复杂性
  • 我想避免使用IDE,因为它在配置菜单后隐藏了很多实现细节
  • 但是我 必须 有办法连接探针,否则无法调试
  • 我也想知道如何阅读汇编,所以我从根本上了解处理器在做什么

祝您一切顺利。我发现学习嵌入式系统非常有趣,富有挑战性并且非常有意义。

干杯,

丹尼尔