c-如何找到芯片上的官方信息保留地址和魔术位



如何从芯片制造商那里找到几个芯片的魔法地址列表?对它所支持的价值观做出恰当的解释?

我甚至想不出打电话/搜索它的术语。

刚刚开始嵌入式编程。我必须为各种各样的事情设置大量的魔法。

通常我会遇到一些东西:

MOV BLKMGC 0x01

REO034 = 0x80; // stops all onboard leds, boot freebsd, makes coffee, do laundy.
// use 0x81 if you have more white clothes than color ones.

有时会有评论解释他们在做什么。我主要是记下我在示例代码中找到的所有内容。msp430启动板的那些通常是由很好的、有很多评论的人写的,我甚至可以在芯片家族笔记上找到一些地址映射,但很难理解。在Arduinos上更常见的芯片在试图完全理解这一点时会让人更加期待。(当然,我仍然不确定如何搜索:)

到目前为止,我找到的最好的地方是我正在使用的芯片的头文件。。。但即便如此,举个例子:

void main(void) {
WDTCTL = WDTPW + WDTHOLD;                 // Stop Watch Dog Timer
// how 99% of msp430 programs start.

现在是头文件:

#define WDTCTL_               0x0120    /* Watchdog Timer Control */
sfrw(WDTCTL, WDTCTL_);
/* The bit names have been prefixed with "WDT" */
#define WDTIS0              (0x0001)
#define WDTIS1              (0x0002)
#define WDTSSEL             (0x0004)
#define WDTCNTCL            (0x0008)
#define WDTTMSEL            (0x0010)
#define WDTNMI              (0x0020)
#define WDTNMIES            (0x0040)
#define WDTHOLD             (0x0080)
#define WDTPW               (0x5A00)
/* WDT-interval times [1ms] coded with Bits 0-2 */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MDLY_32         (WDTPW+WDTTMSEL+WDTCNTCL)                         /* 32ms interval (default) */
#define WDT_MDLY_8          (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS0)                  /* 8ms     " */
#define WDT_MDLY_0_5        (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1)                  /* 0.5ms   " */
#define WDT_MDLY_0_064      (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1+WDTIS0)           /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ADLY_1000       (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL)                 /* 1000ms  " */
#define WDT_ADLY_250        (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0)          /* 250ms   " */
#define WDT_ADLY_16         (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1)          /* 16ms    " */
#define WDT_ADLY_1_9        (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0)   /* 1.9ms   " */
/* Watchdog mode -> reset after expired time */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MRST_32         (WDTPW+WDTCNTCL)                                  /* 32ms interval (default) */
#define WDT_MRST_8          (WDTPW+WDTCNTCL+WDTIS0)                           /* 8ms     " */
#define WDT_MRST_0_5        (WDTPW+WDTCNTCL+WDTIS1)                           /* 0.5ms   " */
#define WDT_MRST_0_064      (WDTPW+WDTCNTCL+WDTIS1+WDTIS0)                    /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ARST_1000       (WDTPW+WDTCNTCL+WDTSSEL)                          /* 1000ms  " */
#define WDT_ARST_250        (WDTPW+WDTCNTCL+WDTSSEL+WDTIS0)                   /* 250ms   " */
#define WDT_ARST_16         (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1)                   /* 16ms    " */
#define WDT_ARST_1_9        (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0)            /* 1.9ms   " */

没有对个别部分的解释,也没有现成的与最常见部分的组合。

奖金咆哮问题

既然它总是在功能强大、大多空闲的个人计算机上编译,为什么所有的编译器/IDE都选择模仿裸机的用户友好性?难道没有很多更好的格式可以做到这一点吗?如果我不想在性能上疯狂,那么对于普通的编码,我是否必须知道将地址0x0120设置为值0x5A80会停止看门狗计时器?头文件/IDE不能让它对我来说是watch_dog_timer( STOP );吗?

此信息可从制造商的数据表中获得。并非所有芯片都有可用的数据表1,所以在挑选芯片时请记住这一点。

举个例子,让我们看看ATmega48。这是一个简单的芯片,有一套不错的基本外围设备。

  1. 转到制造商的网站并找到产品页面。你可以在他们的网站上搜索,甚至可以使用谷歌,但我最成功的是点击制造商网页上的链接。转到页面的"文档"部分。

    ATmega48的文件可在http://www.atmel.com/devices/ATMEGA48.aspx?tab=documents

  2. 下载适当的PDF文件。这可能被称为"数据表"或"用户手册"。它绝对不是"应用说明"或"概述"。如果文件小于大约1 meg或小于100页长,则可能不是正确的文件。

    对于ATmega48,该文件被称为"ATmega48/88/168完整">

  3. "魔法地址"被称为寄存器这些是IO寄存器或外围寄存器,而不是您在编写用户空间程序时使用的那种寄存器。寄存器通常是唯一的,可以是只读的、只写的或读写的。

    对于ATmega48,您可以在第31节"寄存器摘要"中看到所有寄存器的列表。关于如何使用每个寄存器的说明,可以在描述相关外设的部分找到。例如,GPIO寄存器在第14节"I/O端口"中进行了描述,示例代码包括汇编和C.

额外的咆哮:如果你想在代码中编写watch_dog_timer( STOP );,你可以自己定义必要的宏和/或函数(最好是函数,除非你的编译器不好,嵌入式系统有时会出现这种情况2)。

我希望你说裸金属编程"用户友好"是在讽刺。

脚注:

1:例如,如果没有大订单和NDA,你就无法获得Raspberry Pi芯片的数据表。

2:根据我的经验,你经常想选择一个芯片,因为它有很好的编译器支持,而不是试图为你已经拥有的芯片找到一个好的编译器。至少,如果你是一个业余爱好者。GCC的目标是Atmel和ARM,与我使用过的一些垃圾IDE相比,这是非常奢侈的。

成为一名嵌入式程序员并不全是编程。其中很大一部分是阅读文档、示意图和黑客攻击(文档和示意图总是错误的或旧的或其他什么,永远不要100%相信它们)。

这是一个完全混合的袋子。有些供应商制作(相对)很棒的文档,有些则很糟糕,介于两者之间的一切,包括必须放弃你的第一个孩子才能访问文档(嗯,不完全是,但几乎是)。有些公司觉得有些东西是秘密的,你必须签署和保密协议,这并不意味着好的文件会来——这是一个混合的袋子,只是一旦你拿到了它,就更难得到,而且责任更大。有时你不得不把信息(姓名、电话号码等)交给销售人员,这是最糟糕的,因为你每周或每个月都会接到一个电话,直到你辞职或他们辞职,看看你是否准备好购买你询问的东西,或者你是否想了解这些令人兴奋的新产品。我倾向于将要求获得文档的公司(他们生产的每一种产品)列入黑名单,通常他们的产品不值得购买。

每家公司的文档解决方案都不同。你提到了msp430,你必须转到零件系列的一组文档,你得到的是寄存器的名称,而不是地址,然后你必须转到特定的零件数据表,以获得与名称相关的地址。我坚信,Atmel如此受欢迎的一个重要原因是,总的来说,他们的文档更好,他们的信息在那里,有时不是最好的文档,但大量的文档,大量的应用笔记,其他公司根本不会轻易发布的信息,等等,但随着时间的推移,你会觉得他们刚刚领先,与其他人相比,当你不得不深入研究atmel部分时,你不会那么担心。ARM,同样的答案,通常都是很好的文档(但核心不是芯片,所以你可能在一个糟糕的芯片供应商产品中有一个很好的ARM核心文档)。其他公司你必须挖掘示例程序才能找到东西,文档与示例软件不匹配,等等。

你基本上是在做我们其他人所做的事情。挖掘现有的编译器/汇编程序来源(实际上在汇编程序数据文件中找到了很难找到的关于atmel的信息,然后最后在atmel文档中找到)、原理图、示例程序、头文件。最终你会意识到,有些文档是由非技术类型的人编写的,他们有很好的写作技能,但不知道文档中的技术术语是什么。文件有时会落在图腾柱底部的人身上,新雇佣的人不具备任何生产技能,等等。并非总是如此,但有时也是如此。文档反映了这一点。有时,示例程序是一刀切的,可能是为许多芯片中的公共逻辑块设计的,这些逻辑块可能添加或删除了一些功能,你永远都在想为什么代码一直在篡改未记录或保留的位(这些比特可能在以前版本的逻辑或以后版本的逻辑中起作用,如果你仔细研究公司的所有产品,你可能会发现这些比特,而不是你使用的芯片)。我喜欢更改代码,而不是为了看看会发生什么而触摸那些未记录的部分。我真正喜欢(讨厌)的是一个启动卡的api调用,在那里你必须包含一个固件文件的路径。事实证明,如果你仔细研究驱动程序代码,固件文件是为一种风格的卡准备的,如果你没有那种风格的卡,你根本不需要这个文件,但api入口代码要求该文件是真实的,当我发现这一点时,这很烦人(重写了我的on驱动程序,更小、更快,更适合我正在做的事情)。

有些位和寄存器你永远不会发现。即使你在公司找到了一份工作,他们也可能不会给你机会,直到你在合适的部门呆了合适的时间。不要指望你想知道的一切都有。有些比特很神奇,有些比特模式或数据很神奇,有时你只需要随波逐流,按照他们告诉你的方式去做。。。看看visual6502项目,有些人一直在等待他们的整个职业生涯,直到退休,以了解处理器中一些奇怪的东西为什么以及如何工作。。。

最好的事情是你可能已经在做的事情。购买面向业余爱好者的主板,arduino、msp430启动板、stm32发现板、mbed、树莓pi等。获取原理图,或查看他们的网页和文档,找到设备的零件号,特别是处理器,然后转到他们的页面(通常这些都是兜售产品的芯片供应商,并不总是(arduino)。查找该部分,找到该部分的文档,有时是许多文档、家族和特定芯片等。在谷歌上搜索是否有开源项目,阅读这些源代码。如果你很幸运,并坚持下去,你可能会在你的carrer工作到一个可以影响或驱动设计、文档、样本等的地方。你猜怎么着,即使你在Atmel工作,是微控制器的嵌入式软件大师,你仍然必须阅读其他公司的文档,了解你需要构建的测试或销售芯片的电路板上的其他组件。它不会结束,它是工作的一部分。

许多示例程序使用定义和函数来隐藏原始地址和位,因为许多程序员希望看到的是单词,或者至少不是十六进制。就我个人而言,我更喜欢十六进制或位,因为我讨厌费力地浏览宏和头文件层来验证位是否正确。我在屏幕的一侧有数据表(十六进制数字、位数),在另一侧有文本编辑器编程,十六进制地址与文档匹配是一种非常温暖的模糊感觉。嵌入式是关于准确性和可靠性的。在某种程度上,你必须验证你的代码是坚如磐石的,如果你盲目地信任太多拥有太多宏/定义/函数层的人,而不以某种方式检查每一点,你就会失败,或者至少比部门中检查过但没有失败那么多的人更频繁地失败。当然,你不可能花很长时间来编写程序,所以你应该找到一种既能结合你对编码风格的偏好,又能提供可靠性的方法。让嵌入式变得有吸引力的一点是,你经常可以获得自由,你没有操作系统的规则或应用层访问事物的限制,等等。你可以随心所欲。。。

最新更新