2

我如何从芯片制造商那里找到几个芯片的幻地址列表?对它所支持的价值观进行了体面的解释?

我什至无法弄清楚调用/搜索它的术语。

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

通常我会遇到一些事情:

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 );让我使用吗?

4

2 回答 2

5

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

例如,让我们看一下 ATmega48。这是一个简单的芯片,带有一组不错的基本外围设备。

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

    对于 ATmega48,文档可在http://www.atmel.com/devices/ATMEGA48.aspx?tab=documents

  2. 下载相应的 PDF 文件。这可能被称为“数据表”或“用户手册”。它绝对不是“应用笔记”或“概述”。如果文件小于大约 1 兆或小于 100 页,则它可能不是正确的文件。

    对于ATmega48,文档名为“ATmega48/88/168 Complete”

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

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

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

当你说裸机编程是“用户友好的”时,我希望你是在讽刺。

脚注:

1:例如,没有大订单和保密协议,您无法获得树莓派上芯片的数据表。

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

于 2012-06-01T04:53:30.427 回答
4

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

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

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

你基本上在做我们其他人所做的事情。挖掘可用的东西,无论是编译器/汇编器源(实际上找到了在汇编器数据文件中很难找到的有关 atmel 的信息,然后最后在 atmel 文档中找到)、原理图、示例程序、头文件。最终您会意识到有些文档是由具有良好写作技巧的非技术人员编写的,但不知道文档中的技术术语是什么。文档有时会落到图腾柱底部的人身上,新员工会落到没有任何生产技能的人身上,等等。并非总是如此,但有时。文档反映了这一点。有时,示例程序是一刀切的,可能是为许多芯片中的公共逻辑块设计的,可能已经添加或删除了一些功能,而您永远摸不着头脑,为什么代码总是摆弄未记录或保留的位(那些bits 可能会在逻辑的早期版本或逻辑的更高版本中执行某些操作,如果您为公司挖掘所有产品,您可能会发现这些位,而不是它们对您使用的芯片很重要)。我喜欢更改代码,而不是为了看看会发生什么而触摸那些未记录的部分。我真正喜欢(讨厌)的一个是用于启动卡的 api 调用,您必须在其中包含固件文件的路径。事实证明,如果您深入研究驱动程序代码,固件文件是针对一种卡的,

一些位和一些寄存器你永远都不会知道。即使你在公司找到了一份工作,他们也可能不会让你进入,直到你在合适的部门工作了合适的时间。不要期望您想知道的一切都可用。有些位很神奇,有些位模式或数据很神奇,有时你只需要顺其自然,按照他们告诉你的方式去做......看看visual6502项目,有些人一直在等待他们的整个职业生涯并退休找出该处理器中一些奇怪的东西为什么以及如何工作......

最好的办法是你可能已经在做的事情。购买面向爱好者、arduino、msp430 启动板、stm32 发现板、mbed、树莓派等的板。获取原理图,或查看他们的网页和文档以查找设备的部件号,特别是处理器,然后转到他们的页面(通常这些是芯片供应商兜售他们的产品,并不总是(arduino)。查找那个部分,找到那个部分的文档,有时很多文档,家庭加上特定芯片等。做一些谷歌搜索看看如果有开源项目,请阅读这些资源。如果你很幸运并坚持下去,你可能会在你的职业生涯中达到某个阶段,你可以在某个地方工作,你可以影响或推动设计、文档、示例等。你猜怎么着, 即使您在 Atmel 工作并且是微控制器的嵌入式软件专家,您仍然需要阅读其他公司的文档,了解您需要构建的板上的其他组件以测试或销售您的芯片。它不会结束,它是工作的一部分。

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

于 2012-06-01T05:53:47.677 回答