【问题标题】:Pointer to a register on a 16 bit controller指向 16 位控制器上的寄存器的指针
【发布时间】:2017-10-26 05:10:22
【问题描述】:

如何使用 IAR 的 EWB RL78 编译器在 16 位瑞萨 RL78 微控制器上声明指向具有 20 位地址的寄存器的指针?

例如:

static int *ptr = (int *)0xF1000;

上述方法不起作用,因为指针是 16 位地址。

【问题讨论】:

  • 您的编译器是否允许使用 32 位指针? sizeof(int*) 是什么?
  • IAR 为多个目标制作编译器,并不是所有的 16 位目标都是一样的;也许你可以更明确一点!
  • @EdKing : 只需要支持 20 位指针,sizeof(int*) 本身是不够的,还需要知道问题平台上CHAR_BIT 的值。
  • 有问题的微控制器是否使用分页? (或单独的外围地址空间?)
  • 16 位 MCU 将寄存器放在 20 位地址上?真的吗?这听起来很奇怪。它是哪个MCU?

标签: pointers embedded iar rl78


【解决方案1】:

如果有问题的寄存器是片上外围设备,那么您的工具链很可能已经包含一个处理器标头,其中声明了所有寄存器,在这种情况下您应该使用它。如果由于某种原因您不能或不想这样做,那么您至少可以看看它是如何声明此类寄存器的。

在任何情况下,您至少应该声明地址volatile,因为它不是常规的内存位置,并且作为正常外围行为的一部分,可能会超出您的代码的控制和知识范围。此外,您应该使用显式大小的数据类型,并且该寄存器不太可能被签名。

#include <stdint.h>

...

static volatile uint16_t* ptr = (uint16_t*)0xF1000u ;

添加了以下目标架构说明:

IAR RL78 编译器支持两种数据模型 - nearfar。来自 IAR 编译器手册:

● Near 数据模型可以访问最高 64 KB 的数据 记忆

● Far 数据模型可以寻址整个 1 MB 的数据 数据存储器。

near 模型是默认值。可以使用编译器选项设置远模型:--data_model=far;这将全局更改指针类型以允许 20 位寻址(在这种情况下,指针长度为 3 个字节)。

即使没有全局指定数据模型,也可以通过使用关键字__near__far 显式指定指针类型来覆盖默认指针类型。所以在问题的例子中,正确的声明应该是:

static volatile uint16_t __far* ptr = (uint16_t*)0xF1000u ;

注意__far 关键字的位置很关键。它的位置可以用来声明一个 to 远内存的指针,或一个 in 远内存的指针(或者您甚至可以同时声明到远内存和远内存)。

在 RL78 上,0xF1000 实际上是指数据闪存的开始,而不是问题中所述的 寄存器。通常,指向寄存器的指针不会被更改(这意味着它引用了不同的寄存器),因此可以合理地声明为 const:

static volatile uint16_t __far* const ptr = (uint16_t*)0xF1000u ;

__far 类似,const 的位置对语义至关重要。以上防止ptr被修改,但允许ptr所指的内容被修改。作为闪存,这可能并不总是可取或可能的,因此可以合理地将其声明为指向 const 值的 const 指针。

请注意,对于 RL78 特殊功能寄存器 (SFR),IAR 编译器有一个关键字 __sfr,专门用于寻址区域 0xFFF00-0xFFFFF 中的寄存器

例子:

#pragma location=0xFFF20
__no_init volatile uint8_t __sfr PORT1;  // PORT1 is located at address 0xFFF20

使用 IAR 特定编译器扩展的替代语法:

__no_init volatile uint8_t __sfr PORT1 @ 0xFFF20 ;

【讨论】:

  • 问题在于地址的大小(20 位长)。指针会将其转换为 16 位并将其弄乱。这里更多的是关于近/远指针。
  • 问题中没有任何内容表明该寄存器是 16 位宽。 uint16_t 必须对应于寄存器大小。根据我的经验,16 位 MCU 上的大多数寄存器只有 8 位宽。
  • @kamikazze: far & near 指针是对 C 的扩展,实现是编译器和处理器特定的。
  • @kamikazze :它会将值转换为目标上的指针大小,正如我已经评论过的那样,您没有泄露该信息。这并不意味着 16 位目标具有 16 位指针,事实上这不太可能。 near 和 far 指针是特定于体系结构的,例如用于 8086 分段寻址。编译器手册是查看的地方,但由于您没有指定体系结构,我们甚至不知道该查阅哪个手册。此外,您还没有评论我关于工具链或芯片供应商提供的标头的观点。答案就在你手中
  • @Clifford - 这是瑞萨电子 RL78。是的,“演员”并不是表达我想法的最佳方式。因此,所有指向 RAM 的指针都接近指针(16 位地址),并且寄存器具有 20 位地址。如果我将地址 0xF1000 设置为指针,它将指向 0x1000,因为它将适合 16 位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 2021-02-14
  • 1970-01-01
  • 2021-01-16
  • 2021-07-06
  • 1970-01-01
相关资源
最近更新 更多