Является ли "(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
Другие вопросы по тегам