5

I'm new to developing on embedded systems and am not used to having very little program memory (16kB in this case) to play with. I would like to be able to create global variables, arrays, and functions that I can access from anywhere in the program while only existing in one place in memory. My current approach is to use static class members and methods that I can use by simply including the header file (e.g. #include "spi.h").

What is the best approach for what I'm trying to do?

Here is an example class. From what I understand, variables such as _callback and function definitions like call() in the .cpp will only appear in spi.o so they will appear only once in memory, but I may be mixed up.

spi.h:

#ifndef SPI_H_
#define SPI_H_

#include "msp430g2553.h"

class SPI {
public:
    typedef void (*voidCallback)(void);

    static voidCallback _callback;
    static char largeArray[1000];
    static __interrupt void USCIA0TX_ISR();
    static void call();

    static void configure();
    static void transmitByte(unsigned char byte, voidCallback callback);
};

#endif /* SPI_H_ */

spi.cpp:

#include "spi.h"

SPI::voidCallback SPI::_callback = 0;
char SPI::largeArray[] = /* data */ ;

void SPI::configure() {
    UCA0MCTL = 0;
    UCA0CTL1 &= ~UCSWRST;                   
    IE2 |= UCA0TXIE;

}

void SPI::transmitByte(unsigned char byte, voidCallback callback) {
    _callback = callback;
    UCA0TXBUF = byte;
}

void SPI::call() {
    SPI::_callback();
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void SPI::USCIA0TX_ISR()
{
    volatile unsigned int i;
    while (UCA0STAT & UCBUSY);
    SPI::call();
}
JustcallmeDrago
  • 1,885
  • 1
  • 13
  • 23
  • to simply include the header and start using the "SPI" just use [Singleton pattern](http://stackoverflow.com/questions/1008019/c-singleton-design-pattern) , it is a common in embedded that you have one peripheral and only one object to deal with hardware no more objects allowed. , also you may use [factory pattern](http://stackoverflow.com/questions/5120768/how-to-implement-the-factory-pattern-in-c-correctly) to allow for example a certain number of objects (SPI channels) – Abdurahman Jun 19 '13 at 09:26

2 Answers2

10

The data members and the member functions of the class you wrote will only be defined once in memory. And if they're not marked static, the member functions will still only be defined once in memory. Non-static data members will be created in memory once for each object that you create, so if you only create one SPI object you only get one copy of its non-static data members. Short version: you're solving a non-problem.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
1

As per Pete, static won't affect code doubling up, only member vars. In your example, there is 0 difference between static non static memory usage except perhaps for the _callback var (which you call out as an error.) And that one variable would only double up if the class were created more than once.

If you want code to not exist in memory when not in use, look into overlays or some sort of dynamic linking process. DLL type code will probably be major overkill for 16K, but overlays with compressed code might help you out.

Also, beware of extra linked in code from libraries. Closely examine your .map files for code bloat from innocuous function calls. For instance, a single printf() call will link in all sorts of vargs stuff if it is the only thing using it. Same for software floating point (if you don't have a FP unit by default.)

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
  • Sorry, the "call out as an error" was a leftover from another question I asked. I updated the question with an example large array to illustrate what I'm talking about. – JustcallmeDrago Jun 17 '13 at 21:23
  • In your new case, there still is no reason to declare it static except to make it a singleton type object for (dubious) safety's sake. Again, you are better of studying your map file to see where you bloat is coming from and fighting things from there. – Michael Dorgan Jun 17 '13 at 21:27