title: Syntax using void pointers for functions and structs in simple kernel on an embedded system
body: <p>I'm writing an extremely simple kernel for an embedded systems class.  The board is the TI Stellaris EKI-LM3S8962.  It runs C and has an OLED display.  I am having issues with void pointers and de-referencing them.  Any help is much appreciated.</p>
  
  <p>My very small initial goal is to prove the concept of passing function pointers and struct pointers around.  Is this the way that I access the var batteryState pointed to by the pointer batteryStatePtr which is part of the data struct passed in?</p>
  
  <pre><code>void status (void* taskDataPtr) {
      // make a temporary pointer to a Status Data Struct type
      SDS* data;
      // set data equal to the void* taskDataPtr now cast as a SDS pointer
      data = (SDS*)(taskDataPtr);
      (*data-&gt;batteryStatePtr)--;
      ...
  </code></pre>
  
  <p>Here is a very stripped down version of my code, the important region can be located by ctrl-f "HERE IS"</p>
  
  <pre><code>struct MyStruct {
       void (*taskPtr)(void*);
       void* taskDataPtr;
  };
  typedef struct MyStruct TCB;
  </code></pre>
  
  <p>The taskPtr points to a function that takes a void* as an arg and has a void* to a data struct.  As a proof of concept I'm starting as small as possible.  There are two functions, status and display. </p>
  
  <pre><code>typedef struct DisplayDataStruct {
      uint*  batteryStatePtr;
  } DDS;
  DDS DisplayData;
  
  typedef struct StatusDataStruct {
      uint* batteryStatePtr;
  } SDS;
  SDS StatusData;
  </code></pre>
  
  <p>Status decrements the global variable batteryState through the taskDataPtr it is given.  Display concatenates it onto a string and shows it on the OLED.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  typedef unsigned int uint;
  typedef unsigned char uchar;
  typedef unsigned short ushort;
  
  void status (void* taskDataPtr);
  void display (void* taskDataPtr);
  
  void delay(uint msDelay);
  
  //  Declare a TCB structure
  struct MyStruct {
        void (*taskPtr)(void*);
        void* taskDataPtr;
  };
  typedef struct MyStruct TCB;
  
  // status var
  uint batteryState = 200;
  
  typedef struct DisplayDataStruct {
      uint*  batteryStatePtr;
  } DDS;
  DDS DisplayData;
  
  typedef struct StatusDataStruct {
      uint* batteryStatePtr;
  } SDS;
  SDS StatusData;
  
  void main(void)
  {
      DisplayData.batteryStatePtr = &amp;batteryState;
  
      StatusData.batteryStatePtr = &amp;batteryState;
  
        int i = 0;  //  queue index
        TCB* aTCBPtr;
  
        TCB* queue[2];
  
        TCB StatusTCB;
        TCB DisplayTCB;
  
        StatusTCB.taskPtr = status;
        StatusTCB.taskDataPtr = (void*)&amp;StatusData;
        DisplayTCB.taskPtr = display;
        DisplayTCB.taskDataPtr = (void*)&amp;DisplayData;
  
        // Initialize the task queue
        queue[0] = &amp;StatusTCB;
        queue[1] = &amp;DisplayTCB;
  
        // schedule and dispatch the tasks
        while(1)
        {
            for (i = 0; i &lt; 2; i++) {
               aTCBPtr = queue[i];
               aTCBPtr-&gt;taskPtr( (void*)(aTCBPtr-&gt;taskDataPtr) );
            }
            systemState = (systemState + 1) % 100;
            delay(50);
        }
  }
  
  void status (void* taskDataPtr) {
      // return if systemState != 0 aka run once every 5 sec
      if (systemState) {
        return;
      }
      // make a temporary pointer to a Status Data Struct type
      SDS* data;
      // set data equal to the void* taskDataPtr now cast as a SDS pointer
      data = (SDS*)(taskDataPtr);
  
  
      // HERE IS where I am stumped. Is (*data-&gt;batteryStatePtr)-- the way you do this????
      // access the batteryStatePtr through the struct data
      // then dereference the whole thing to get at batteryState
      if ((*(data-&gt;batteryStatePtr)) &gt; 0) {
        // decrement batteryState
        (*(data-&gt;batteryStatePtr))--;
      }
      return;
  }
  
  void display (void* taskDataPtr) {
      // run once every 5 sec
      if (systemState) {
        return;
      }
      DDS* data;
      data = (DDS*) taskDataPtr;
      char hold[12] = "Batt: ";
      char numHold[4];
      sprintf(numHold, "%u", (*(data-&gt;batteryStatePtr)));
      strcat(hold, numHold);
  
      // display the string hold
      RIT128x96x4StringDraw(hold, 15, 44, 15);
      return;
  }
  
  // use for loops to waste cycles, delay taken in ms
  void delay(uint msDelay)
  {
        // when i == 60000 and j == 100 function delays for ~ 7.6 sec
        msDelay = msDelay * 150 / 19;
        volatile unsigned long i = 0;
        volatile unsigned int j = 0;
  
        for (i = msDelay; i &gt; 0; i--) {
               for (j = 0; j &lt; 100; j++);
        }
        return;
  }
  </code></pre>