“(unsigned int *) 0x400253FCU”是 TI Stellaris 微控制器头文件 <LM4F120H5QR.h> 中的指针吗?
Is "(unsigned int *) 0x400253FCU" a pointer in the TI Stellaris Microcontroller header file <LM4F120H5QR.h>?
背景:
我正在学习嵌入式系统编程。在这个过程中,我了解到“指针”是嵌入式系统中最重要的。一个指针是在C中声明的一个变量,它的值是另一个变量的地址。我可以通过 取消引用 指针来 manipulate/change 这个其他变量的值。
示例:
int *pt; // Integer pointer variable declaration.
float *pf; // Float pointer variable declaration.
int *pt
表示pt
是一个指针变量,可以指向int类型的变量。另一方面,指针变量fp
只能存储float类型变量的地址。
要将值(地址)分配给指针变量,必须使用地址运算符 (&
)。
int var = 20; //Actual variable declaration
int *pt; //Pointer Variable Declaration
pt = &var; //Here with the ampersand (&)operator we denotes an
//address in memory to the pt pointer.
/*Changing the variable value from 20 to 79*/
*pt = 79; //Dereference
printf (“Value of *pt variable: %d\n”, *pt); //Output:79
printf (“Value of var variable: %d\n”, var); //Output:79
这两个链接对我理解指针很有帮助:
Pointer (computer programming)
问题
当我看到 Stellaris LM4F120H5QR 微控制器的头文件时,我的问题就出现了。该头文件定义了具有内存地址的寄存器位置,如下所示:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
当我遇到这个语法时,我很困惑是否确实将“(volatile unsigned long *)0x400253FC)
”定义为指针并且整个句子可以解释为如下图所示?
Pointer Dereference Memory Location
如果不正确,有人可以解释解释嵌入式系统头文件的寄存器定义的正确方法吗?
Link 为头文件 --> Here
这是正确的反抗!!如果你尝试它,它会工作得很好....让我帮助你理解这个声明是如何工作的
访问特定内存地址的解释
如果你在内存中有一个特定的地址,例如(这个地址0x400253FC)并且你想写值(50 )到第一个字节下面的代码会出错
// the following code is wrong
0x400253FC = 50 ;
上面的代码会给出一个编译错误.. 那么如何告诉编译器将这个 (0x400253FC) 作为内存地址??,只需借助铸造
(unsinged char *)0x400253FC // cast this number 0x400253FC as char pointer
现在你有了一个指针,所以你可以取消引用它并将值写入内存(指针指向的地方),就像这样
*((unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
一些编译器在进行优化时会删除这行代码,以防止编译器这样做,我们添加了 volatile 说明符 ...所以表达式就像这个
*((volatile unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
这就是如何访问内存中的一个字节
如果你想访问内存中的4字节那么它会像这样
//assuming your compiler consider the long variable as 4 byte
*((volatile unsinged long*)0x400253FC) = 50; // write the value 50 in 4 byte in memory start with address 0x400253FC
(*((volatile unsigned long *)0x400253FC)) = 0x12345678
初等C,直接解析出来。我想你不知道混淆在哪里。
我想你了解类型转换
unsigned int x; //a variable
x = 0x400253FC; //assign the variable a value
(volatile unsigned long *)x //typecast x into a different type volatile unsigned long *
同样使用指针
volatile unsigned long *z;
(*z)=0x12345678; //at the address pointed to by z place the value 0x12345678;
把它分成几部分。
(
*
(
(volatile unsigned long *)0x400253FC
)
)
0x400253FC a value
(volatile unsigned long *)0x400253FC typecast that value into an unsigned long pointer
((volatile unsigned long *)0x400253FC) enclose that pointer as a whole at this point it is a pointer, like z from above.
*((volatile unsigned long *)0x400253FC) dereference it one level, like *z above you can now use this to manipulate the unsigned long address.
(*((volatile unsigned long *)0x400253FC)) good idea to wrap defines in parens to not confuse the compiler. doesn't hurt.
(*((volatile unsigned long *)0x400253FC)) = 0x12345678. Like *z = 0x12345678 above, write/store 0x12345678 to the address 0x400253FC
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
GPIO_PORTF_DATA_R = 0x12345678; store/write 0x12345678 to the address 0x400253FC
unsigned long k; k = GPIO_PORTF_DATA_R; load/read from address 0x400253FC and save it in k
如果你有一个 8 位宽的寄存器,那么调整类型转换。
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
SOME_8BIT_REG = 0x33;
你可以试试看
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
void fun ( void )
{
GPIO_PORTF_DATA_R = 0x12345678;
SOME_8BIT_REG = 0x33;
}
00000000 <fun>:
0: e3a02033 mov r2, #51 ; 0x33
4: e59f1010 ldr r1, [pc, #16] ; 1c <fun+0x1c>
8: e59f0010 ldr r0, [pc, #16] ; 20 <fun+0x20>
c: e59f3010 ldr r3, [pc, #16] ; 24 <fun+0x24>
10: e58103fc str r0, [r1, #1020] ; 0x3fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
18: e12fff1e bx lr
1c: 40025000
20: 12345678
24: 50067800
10: e58103fc str r0, [r1, #1020] ; 0x3fc
32 bit store (write) 0x12345678 to address 0x400253fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
8 bit store (write) 0x33 to address 0x5006789a
指令集无关紧要
0000000000000000 <fun>:
0: 48 c7 04 25 fc 53 02 movq [=16=]x12345678,0x400253fc
7: 40 78 56 34 12
c: c6 04 25 9a 78 06 50 movb [=16=]x33,0x5006789a
13: 33
14: c3 retq
Disassembly of section .text:
00000000 <fun>:
0: 123457b7 lui x15,0x12345
4: 40025737 lui x14,0x40025
8: 67878793 addi x15,x15,1656 # 12345678 <fun+0x12345678>
c: 3ef72e23 sw x15,1020(x14) # 400253fc <fun+0x400253fc>
10: 500687b7 lui x15,0x50068
14: 03300713 li x14,51
18: 88e78d23 sb x14,-1894(x15) # 5006789a <fun+0x5006789a>
1c: 8082 ret
背景:
我正在学习嵌入式系统编程。在这个过程中,我了解到“指针”是嵌入式系统中最重要的。一个指针是在C中声明的一个变量,它的值是另一个变量的地址。我可以通过 取消引用 指针来 manipulate/change 这个其他变量的值。
示例:
int *pt; // Integer pointer variable declaration.
float *pf; // Float pointer variable declaration.
int *pt
表示pt
是一个指针变量,可以指向int类型的变量。另一方面,指针变量fp
只能存储float类型变量的地址。
要将值(地址)分配给指针变量,必须使用地址运算符 (&
)。
int var = 20; //Actual variable declaration
int *pt; //Pointer Variable Declaration
pt = &var; //Here with the ampersand (&)operator we denotes an
//address in memory to the pt pointer.
/*Changing the variable value from 20 to 79*/
*pt = 79; //Dereference
printf (“Value of *pt variable: %d\n”, *pt); //Output:79
printf (“Value of var variable: %d\n”, var); //Output:79
这两个链接对我理解指针很有帮助:
Pointer (computer programming)
问题
当我看到 Stellaris LM4F120H5QR 微控制器的头文件时,我的问题就出现了。该头文件定义了具有内存地址的寄存器位置,如下所示:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
当我遇到这个语法时,我很困惑是否确实将“(volatile unsigned long *)0x400253FC)
”定义为指针并且整个句子可以解释为如下图所示?
Pointer Dereference Memory Location
如果不正确,有人可以解释解释嵌入式系统头文件的寄存器定义的正确方法吗?
Link 为头文件 --> Here
这是正确的反抗!!如果你尝试它,它会工作得很好....让我帮助你理解这个声明是如何工作的
访问特定内存地址的解释
如果你在内存中有一个特定的地址,例如(这个地址0x400253FC)并且你想写值(50 )到第一个字节下面的代码会出错
// the following code is wrong
0x400253FC = 50 ;
上面的代码会给出一个编译错误.. 那么如何告诉编译器将这个 (0x400253FC) 作为内存地址??,只需借助铸造
(unsinged char *)0x400253FC // cast this number 0x400253FC as char pointer
现在你有了一个指针,所以你可以取消引用它并将值写入内存(指针指向的地方),就像这样
*((unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
一些编译器在进行优化时会删除这行代码,以防止编译器这样做,我们添加了 volatile 说明符 ...所以表达式就像这个
*((volatile unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
这就是如何访问内存中的一个字节
如果你想访问内存中的4字节那么它会像这样
//assuming your compiler consider the long variable as 4 byte
*((volatile unsinged long*)0x400253FC) = 50; // write the value 50 in 4 byte in memory start with address 0x400253FC
(*((volatile unsigned long *)0x400253FC)) = 0x12345678
初等C,直接解析出来。我想你不知道混淆在哪里。
我想你了解类型转换
unsigned int x; //a variable
x = 0x400253FC; //assign the variable a value
(volatile unsigned long *)x //typecast x into a different type volatile unsigned long *
同样使用指针
volatile unsigned long *z;
(*z)=0x12345678; //at the address pointed to by z place the value 0x12345678;
把它分成几部分。
(
*
(
(volatile unsigned long *)0x400253FC
)
)
0x400253FC a value
(volatile unsigned long *)0x400253FC typecast that value into an unsigned long pointer
((volatile unsigned long *)0x400253FC) enclose that pointer as a whole at this point it is a pointer, like z from above.
*((volatile unsigned long *)0x400253FC) dereference it one level, like *z above you can now use this to manipulate the unsigned long address.
(*((volatile unsigned long *)0x400253FC)) good idea to wrap defines in parens to not confuse the compiler. doesn't hurt.
(*((volatile unsigned long *)0x400253FC)) = 0x12345678. Like *z = 0x12345678 above, write/store 0x12345678 to the address 0x400253FC
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
GPIO_PORTF_DATA_R = 0x12345678; store/write 0x12345678 to the address 0x400253FC
unsigned long k; k = GPIO_PORTF_DATA_R; load/read from address 0x400253FC and save it in k
如果你有一个 8 位宽的寄存器,那么调整类型转换。
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
SOME_8BIT_REG = 0x33;
你可以试试看
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
void fun ( void )
{
GPIO_PORTF_DATA_R = 0x12345678;
SOME_8BIT_REG = 0x33;
}
00000000 <fun>:
0: e3a02033 mov r2, #51 ; 0x33
4: e59f1010 ldr r1, [pc, #16] ; 1c <fun+0x1c>
8: e59f0010 ldr r0, [pc, #16] ; 20 <fun+0x20>
c: e59f3010 ldr r3, [pc, #16] ; 24 <fun+0x24>
10: e58103fc str r0, [r1, #1020] ; 0x3fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
18: e12fff1e bx lr
1c: 40025000
20: 12345678
24: 50067800
10: e58103fc str r0, [r1, #1020] ; 0x3fc
32 bit store (write) 0x12345678 to address 0x400253fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
8 bit store (write) 0x33 to address 0x5006789a
指令集无关紧要
0000000000000000 <fun>:
0: 48 c7 04 25 fc 53 02 movq [=16=]x12345678,0x400253fc
7: 40 78 56 34 12
c: c6 04 25 9a 78 06 50 movb [=16=]x33,0x5006789a
13: 33
14: c3 retq
Disassembly of section .text:
00000000 <fun>:
0: 123457b7 lui x15,0x12345
4: 40025737 lui x14,0x40025
8: 67878793 addi x15,x15,1656 # 12345678 <fun+0x12345678>
c: 3ef72e23 sw x15,1020(x14) # 400253fc <fun+0x400253fc>
10: 500687b7 lui x15,0x50068
14: 03300713 li x14,51
18: 88e78d23 sb x14,-1894(x15) # 5006789a <fun+0x5006789a>
1c: 8082 ret