Arduino C Pointers

pointer

Below is an arduino program which demonstrates some basic principles about pointers.

Keep in mind, memory pointers (i.e. pointers to variables) are pointers to SRAM memory, while function pointers are pointers to flash memory. The AVR uses a modified Harvard Architecture, which allows the contents of the instruction memory to be accessed as if it were data. However, there are restrictions imposed upon access to flash memory. Most modern computers that are documented as Harvard Architecture (like the arduino) are, in fact, Modified Harvard Architecture.

memory map

So, considering the different types of memory in an 8-bit AVR µC, there are several overlapping addresses. For example, there is a 0x0000 address for each type, SRAM, flash and EEPROM. SRAM can be addressed via standard C pointers. Flash functions can be addresses per standard C pointers, however data placed in flash requires the use of the PROGMEM routines found in pgmspace.h. And finally EEPROM requires the use of the EEPROM routines found in eeprom.h.

Simple demonstration program:

//
//pointers by example
//

void setup() {
  char text[32];
  
  Serial.begin(9600);

  //
  //pointer basics
  //
  uint8_t n;  //declare a byte
  uint8_t *p; //declare a pointer to any uint8_t size variable
  n = 0x11;   //initialize n
  p = &n;     //initialize p to the address of n (p points to n)
  sprintf(text, " n = %x (n)\n", n); Serial.print(text);
  sprintf(text, "&n = %x (address of n)\n", &n); Serial.print(text);
  sprintf(text, " p = %x (address of n)\n", p); Serial.print(text);
  sprintf(text, "&p = %x (address of p)\n", &p); Serial.print(text);
  sprintf(text, "*p = %x (n)\n", *p); Serial.print(text);
  *p = 0x22;   //assign value to what p points at (n)
  sprintf(text, "After *p = 0x22, n = %x\n", n); Serial.print(text);
  Serial.println();

  //
  //pointer arithmetic
  //
  uint8_t a[] = { 1, 2, 3 }; //declare an array
  uint8_t *pa = a;           //declare pa and initailize to point to a
  pa = a;                    //does same as above
  sprintf(text, " a[0] = %x\n", a[0]); Serial.print(text);
  sprintf(text, "&a[0] = %04x (address of a)\n", &a[0]); Serial.print(text);
  sprintf(text, "   pa = %04x (address of a)\n", pa); Serial.print(text);
  sprintf(text, "  *pa = %x (a[0])\n", *pa); Serial.print(text);
  pa += 1;                   //increment pointer
  sprintf(text, "After increment, pa = %04x\n", pa); Serial.print(text);
  sprintf(text, "  *pa = %x (a[1])\n", *pa); Serial.print(text);
  Serial.println();
  
  //
  //machine endianness == little endian
  //
  uint32_t n32 = 0x12345678;     //declare and initialize 32-bit number (not order of digits)
  uint8_t* pn = (uint8_t *)&n32; //declare uint8_t pointer to 1st byte of 32-bit number
  for (uint8_t i=0; i<4; i++) {
    //iterate through all 4-bytes of n32, noting order of digits
    sprintf(text, "%p: %02x \n", pn, (uint8_t)*pn++); Serial.print(text);
  }
  Serial.println();
  
  //
  //function pointer
  //
  int16_t (*fptr)(int16_t); //declare a function pointer
  int16_t x = 5;            //initalze x for demonstration
  fptr = square;            //point fptr to square() function
  //call square using function pointer
  sprintf(text, "%d squared is %d\n", x, fptr(x)); Serial.print(text);
  //note: fptr is a word address 
  sprintf(text, " fptr = %04x (address of function square()\n", fptr); Serial.print(text);
  sprintf(text, "&fptr = %04x (address of fptr)\n", &fptr); Serial.print(text);
}

//example function
int16_t square(int16_t n) {
  return n*n;
}

void loop() { }

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

1 Response to Arduino C Pointers

  1. lu says:

    Clear explanation to help to understand addresses and pointers!!!!! Thank you!!!!!!!

Leave a comment