[英]Is "(unsigned int *) 0x400253FCU" a pointer in the TI Stellaris Microcontroller header file <LM4F120H5QR.h>?
BACKGROUND :背景:
I'm learning embedded system programming.我正在学习嵌入式系统编程。 During the process I have learn that "Pointer" is a most for embedded system.在这个过程中,我了解到“指针”是嵌入式系统中最重要的。 A pointer is a variable declared in C whose value is the address of another variable.指针是在 C 中声明的变量,其值是另一个变量的地址。 And I can manipulate/change the value of this other variable by dereferencing a pointer.我可以通过取消引用指针来操纵/更改这个其他变量的值。
Example:例子:
int *pt; // Integer pointer variable declaration.
float *pf; // Float pointer variable declaration.
int *pt
means that pt
is a pointer variable capable of pointing to variables of type int. int *pt
表示pt
是一个指针变量,能够指向 int 类型的变量。 On the other hand, the pointer variable fp
can only store the address of a float type variable.另一方面,指针变量fp
只能存储float类型变量的地址。
To assign an value (address) to a pointer variable the address operator ( &
) must be used.要将值(地址)分配给指针变量,必须使用地址运算符 ( &
)。
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
These two links were very helpful for me to understand pointers:这两个链接对我理解指针很有帮助:
Pointer (computer programming)指针(计算机编程)
QUESTION题
My question arises when I come across the header file of the Stellaris LM4F120H5QR Microcontroller.当我遇到 Stellaris LM4F120H5QR 微控制器的 header 文件时,我的问题出现了。 This header file define the register locations with memory addresses as follows:这个 header 文件定义了具有 memory 地址的寄存器位置,如下所示:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
When I came across this syntax I was confused if indeed " (volatile unsigned long *)0x400253FC)
" has been define as a pointer and the whole sentence can be interpreted as shows in picture below?当我遇到这种语法时,我很困惑是否确实将“ (volatile unsigned long *)0x400253FC)
”定义为指针并且整个句子可以解释为如下图所示?
Pointer Dereference Memory Location指针取消引用 Memory 位置
If that is not correct, can someone explain the correct way to interpret the register definition for an embedded system header file?如果那不正确,有人可以解释解释嵌入式系统 header 文件的寄存器定义的正确方法吗?
this is a correct defiention.. and if you try it it will work just fine.... let me help you in understanding this statment how it work这是一个正确的反抗......如果你尝试它会工作得很好......让我帮助你理解这个声明它是如何工作的
if you have an a specific address in memory FOR example (this address 0x400253FC ) and you like to write value of ( 50 ) to the first byte the following code will be wrong例如,如果您在 memory 中有一个特定地址(此地址0x400253FC )并且您希望将 ( 50 ) 的值写入第一个字节,则以下代码将是错误的
// the following code is wrong
0x400253FC = 50 ;
the above code will give a compile error.. so how to tell compiler to make this ( 0x400253FC ) as a memory address??, simply will do that with help of casting上面的代码会给出一个编译错误.. 那么如何告诉编译器将这个 ( 0x400253FC ) 作为一个 memory 地址??,只需在转换的帮助下做到这一点
(unsinged char *)0x400253FC // cast this number 0x400253FC as char pointer
now you have a pointer so you could dereference it and write the value in memory ( where the pointer point to ) like this现在你有了一个指针,所以你可以取消引用它并将值写入 memory(指针指向的位置),如下所示
*((unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
some compilers when they make Optimization they will delete this line of code so to prevent the compiler from doing that we add the volatile specifier ... so the expression will be like this一些编译器在进行优化时会删除这行代码,以防止编译器这样做,我们添加了volatile 说明符...所以表达式将像这样
*((volatile unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
so this is how to accssess a byte in memory所以这就是如何访问 memory 中的一个字节
if you like to access 4 byte in memory so it will be like this如果你想访问 memory 中的 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
Elementary C, just parse it out.初等C,解析出来就好了。 I think you get it not sure where the confusion is.我认为您不确定混淆在哪里。
I think you understand typecasting我想你了解类型转换
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 *
Likewise using a pointer同样使用指针
volatile unsigned long *z;
(*z)=0x12345678; //at the address pointed to by z place the value 0x12345678;
break it into parts.把它分成几部分。
(
*
(
(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
If you have an 8 bit wide register then adjust the typecast as such.如果你有一个 8 位宽的寄存器,那么就这样调整类型转换。
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
SOME_8BIT_REG = 0x33;
you could just try it你可以试试
#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
Instruction set doesn't matter指令集无关紧要
0000000000000000 <fun>:
0: 48 c7 04 25 fc 53 02 movq $0x12345678,0x400253fc
7: 40 78 56 34 12
c: c6 04 25 9a 78 06 50 movb $0x33,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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.