Является ли "(unsigned int *) 0x400253FCU" указателем в файле заголовка микроконтроллера TI Stellaris <LM4F120H5QR.h>?
ИСТОРИЯ:
Я изучаю программирование встраиваемых систем. В процессе работы я узнал, что "Указатель" - это самая встраиваемая система. Указатель является переменной, объявленной в C, значение которого является адрес другой переменной. И я могу манипулировать / изменять значение этой другой переменной, разыменовывая указатель.
Пример:
int *pt; // Integer pointer variable declaration.
float *pf; // Float pointer variable declaration.
int *pt
Значит это pt
переменная-указатель, способная указывать на переменные типа int. С другой стороны, указатель переменнойfp
может хранить только адрес переменной типа с плавающей запятой.
Чтобы присвоить значение (адрес) переменной-указателю, оператор адреса (&
) необходимо использовать.
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
Эти две ссылки очень помогли мне понять указатели:
Основы работы с указателями в C
Указатель (компьютерное программирование)
ВОПРОС
Мой вопрос возникает, когда я сталкиваюсь с заголовочным файлом микроконтроллера Stellaris LM4F120H5QR. Этот заголовочный файл определяет ячейки регистров с адресами памяти следующим образом:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
Когда я наткнулся на этот синтаксис, я был сбит с толку, если действительно " (volatile unsigned long *)0x400253FC)
"был определен как указатель, и все предложение можно интерпретировать, как показано на рисунке ниже?
Место в памяти разыменования указателя
Если это неверно, может ли кто-нибудь объяснить, как правильно интерпретировать определение регистра для файла заголовка встроенной системы?
Ссылка на заголовочный файл -> Здесь
2 ответа
Это правильное определение!! и если вы попробуете, он будет работать нормально.... позвольте мне помочь вам понять этот статус, как это работает
Объяснение доступа к определенному адресу памяти
если у вас есть конкретный адрес в памяти, например, (этот адрес 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 $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