问题描述
我试图理解我的微控制器板提供的一些示例C代码。我真的很难理解整个指针内容。我在这个论坛上阅读了很多文章,还阅读了一些教程,然后慢慢地掌握了它的窍门:)但是... 在我的示例代码中,有以下代码行,无法使用我发现的任何信息解密。
#define SOMENAME ((uint32_t *)0x130010f0)
我了解到,#define
只是用相应的语句替换了已编译代码中所有出现的SOMENAME(不知道此解释是否正确,但我确实认为我正在这样做)。 / p>
现在,我能想象到的是,该语句的其余部分含义如下:
SOMENAME现在是指向地址0x130010f0的指针,但不是实际变量。
这是正确的吗?我可以将其例如用作:printf("value at address 0x130010f0: %p",SOMENAME)
,因为编译器将其替换为printf("value at address 0x130010f0: %p",((uint32_t *)0x130010f0))
,这给出了存储在该地址的值吗?如果我想要该指针的地址,打印语句将是什么?我不能吧因为指针没有地址,因为它不是变量?非常令人困惑...
该示例非常复杂,该定义也是其他定义的一部分,这些其他定义是指向struct的结构的指针,因此,此“简单”示例。在下面,您可以找到“整个”结构:
#define ROM_API_TREE ((uint32_t *)0x130010f0)
#define BOOTLOADER_POINTER ((bootloader_tree_t *)ROM_API_TREE)
flash_driver_interface_t *FLASH_API_TREE
#define FLASH_API_TREE BOOTLOADER_POINTER->flashDriver
typedef struct BootloaderTree{
...
const flash_driver_interface_t *flashDriver;
} bootloader_tree_t
typedef struct FlashDriverInterface{
...
status_t (*ffr_get_uuid)(flash_config_t *config,uint8_t *uuid);
} flash_driver_interface_t
/*
* I actually want to understand that statement,but as I fail
* already at the beginning,I posted this question
*/
status_t = FLASH_API_TREE->ffr_get_uuid(config,uuid);
解决方法
您正确地将SOMENAME
替换为((uint32_t *)0x130010f0)
的预处理器。这为您提供了一个指向uint32_t
的指针,该指针的值为0x130010f0
。
随后执行此操作:
printf("value at address 0x130010f0: %p",SOMENAME);
您实际上将打印指针的值,即0x130010f0,而不是指针所指向的。为此,您需要取消引用它,即:
printf("value at address 0x130010f0: %u",*SOMENAME);
但是,这假定0x130010f0是可以取消引用和读取的有效地址。通常只有在实现允许的某些特定嵌入式环境中才是这种情况。
,正如我所看到的,您基本上可以理解指针背后的许多内容。 SOMENAME是macro
而不是变量权限。在我接触代码之前,指针通常只是一个包含地址而不是值的变量。printf("value at address 0x130010f0: %p",SOMENAME);
是错误的,因为%p
期望值不是地址,并且您正在将地址传递给它,所以您要做的就是使用*
对其进行取消引用。
编写(uint32_t *)0x130010f0
时,会将地址转换为括号之间的writteb类型。
每当使用指针变得复杂时,请记住以下小例子:
int a = 10;
int *p = &a;// declare pointer of type integer. This is valid,adress of an integer variable contains adress of integer variable
int *j; //declare pointer of type integer
j = &a; //correct,because j expects an adress.
*j = &a; //wrong *j expects a value
printf("value of p: %p",*p);
printf("adress of p: %p",p); //or &p
,
这表明您的微控制器板具有程序可访问的32位设备。
我说“可访问”是因为该设备可以可读,可写或两者兼有。
我使用了一个通用术语“设备”,因为它可能是各种各样的东西。通常,这是一个只存储一个值的寄存器,但也可能是一个FIFO芯片,每次读取都会返回下一个存储的值。
假设它是一个寄存器:这些寄存器通常由单独的位或代表某些功能的小部分位组成。在这种情况下,您会看到如下所示的位域struct
声明(例如两个16位字段):
struct {
uint32_t someField : 16;
uint32_t otherField : 16;
} fields;