Writing a struct to flash memory - c++

I am having problems writing a struct to flash memory using a microcontroller (cortex-M0 inside nrf58122 SoC). I don't know enough c/c++ to determine if it's a memory management issue or a fundamental lack of understanding of programming.
I have a class with a struct member:
struct settings_t
{
uint16_t n;
uint8_t b;
bool e;
} settings;
In one of my class methods, I need to write the contents of this struct to flash memory in the microcontroller (no EEPROM available). There are pre-written functions that I call in order to do this---I understand I need to erase a page before writing to it. If I try the following:
settings = {
constants::n,
constants::b,
constants::e
};
Where the values n, b, e are of the correct type, and I follow this definition by:
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &settings, sizeof(settings));
I get a runtime error (program execution halts, don't have an error code for it) when the flashWriteBlock function executes. However, if I copy the struct first:
settings_t cpy = settings;
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &cpy, sizeof(settings));
Then it does work. Can anyone shed some insight into this? I can provide more detail as needed.

The documentation may not say it, but the implementation shows that both the source and destination must be 32-bit aligned:
int flashWriteBlock( void *dst, const void *src, int cb )
{
uint32_t *d = dst;
const uint32_t *s = src;
/* The rest of the function snipped*/
}
The failure is due to the settings variable being 16-bit aligned. It will have to be forced to 32-bit alignment. How this is done is compiler dependent. The following example works for gcc:
struct settings_t
{
uint16_t n;
uint8_t b;
bool e;
} __attribute__ ((aligned (4))) settings;

If you are talking about an Arduino Uno and related ATMega based controllers you might want to consult the official Arduino Website: Reading and Writing Data Structures to EEPROM. The page contains templates for EEPROM_readAnything and EEPROM_writeAnything.

Related

What's the modern C++ way to cast absolute addresses to pointer variables?

In the embedded world for ages people wrote hardware(-configuration)-register-mappings as structures, a really simple example for a 32-bit hardware:
#define hw_baseaddr ((uintptr_t) 0x10000000)
struct regs {
uint32_t reg1;
uint32_t reg2;
};
#define hw_reg ((volatile struct regs *) hw_baseaddr)
void f(void)
{
hw_reg->reg1 = 0xdeadcafe;
hw_reg->reg2 = 0xc0fefe;
}
This works very well, the compiler (gcc at least on our platform) recognizes that the hw_reg is referencing the same address (which is known and constant at compile-time) and is ld'ing it only once. The second st (store) is done with a 4-byte-offset with a single instruction - again on our platform.
How to reproduce this behavior with modern C++ (post C++11) without using #defines?
We tried a lot of things: static const inside and outside classes and constexpr. They both don't like (implicit) reinterprest_cast<>'s .
Responding to a comment as to why changing it: I'm afraid it's mostly fame and glory. But not only. With this C code debugging can be hard. Imagine you'd want to log all write-accesses, this approach would require you to rewrite everything everywhere. However, here I'm not looking for a solution which will simplify a specific situation, I'm looking for inspiration.
EDIT Just to clarify as per some comments: I'm asking this question not to change any code which is working (and was written in the 1990s). I'm looking for a solution for future projects, because I'm not totally happy with the define-implementation, and was asking myself whether modern C++ has a superior possibility.
I think variable templates make for an elegant solution here.
// Include this in some common header
template <class Impl>
volatile Impl& regs = *reinterpret_cast<volatile Impl*>(Impl::base_address);
template <std::uintptr_t BaseAddress>
struct HardwareAt {
static const std::uintptr_t base_address = BaseAddress;
// can't be instantiated
~HardwareAt() = delete;
};
// This goes in a certain HW module's header
struct MyHW : HardwareAt<0x10000000> {
std::uint32_t in;
std::uint32_t out;
};
// Example usage
int main()
{
std::printf("%p\n%p\n", &regs<MyHW>.in, &regs<MyHW>.out);
// or with alias for backward compatibility:
auto hw_reg = &regs<MyHW>;
std::printf("%p\n%p\n", &hw_reg->in, &hw_reg->out);
}
One benefit of using it like this instead of with macros, is that you're type safe, and you can actually refer to registers of different hardware modules from the same source file without mixing it all up.
Since the sole purpose of the #define is to give you access to struct members, you could use a template to do the equivalent. My compiler generates code for the template that is identical to the #define.
// #define hw_reg ((volatile struct regs *) hw_baseaddr)
template <class T, uintptr_t addr>
class RegsPtr
{
public:
RegsPtr() { ; }
volatile T* operator->() const { return reinterpret_cast<T*>(addr); }
volatile T& operator*() const { return *operator->(); }
};
const RegsPtr<struct regs, hw_baseaddr> hw_reg;

C++ Struct - Define Minimum Size

Is there a C++ (or MSVC) method of automatically padding a struct to a minimum size? For example, imagine the following pseudo-code:
#pragma pad(256) // bytes
struct SETUPDATA {
int var1;
double var2;
};
where sizeof(SETUPDATA) = 256 bytes
The goal here being, during development this struct's members can change without changing the footprint size at runtime.
You can use a union
struct SETUPDATA {
union { struct your_data; char [256]; }
}
or something like this. This ensures it's at least 256 but only as long as your_data is not larger.
You can also add a simple assert after that just does a compiler check assert(sizeof(struct SETUPDATA) == 256)
One way is to inherit from your "real" structure and use sizeof() to make up the padded structure, for example:
struct blah_real
{
int a;
};
struct blah : public blah_real
{
private:
char _pad[256 - sizeof(blah_real)];
};
You could use #ifdef DEBUG to only do this in the debug build and just use the real structure in release build.
The first thing you have ot ask yourself is why your application cares if the struct size changes. That indicate fragility to future changes and your design may be better served by instead allowing the application to seamlessly work in the face of struct size changes.
Perhaps you're trying to serialize the data directly and don't want to face changes in the format, but in that case you're already tying yourself to one specific representation of the structure in memory. For example support the size of one of the builtin-type members changes due to a compiler upgrade or options.
But let's say you really do want to do this.
Just wrap the data in an impl and pad the real struct:
struct SetupData
{
struct Impl
{
int var1;
double var2;
};
Impl impl_;
unsigned char pad_[256 - sizeof(Impl)];
};

Avoid creating multiple copies of code in memory

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();
}
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.
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.)

Struct offsets differ?

Normally I would have a good smile, but its so sneaky its not even funny.
How the hell can a struct differ from one file to another?
I had a struct like this:
typedef struct pp_sig_s
{
[...]
int flags;
size_t max;
bool is_reversed;
unsigned int sig[64];
size_t byref;
[...]
}
pp_sig_t;
It was defined in say "header01.h"
Some function I use is in "program01.cpp"
Declared this way
void PrintSig(pp_sig_t *s); // prints the content of sig[64] array in pp_sig_t for test purposes
Another object pp_sig_t called g_sig_1 was defined in "header02.cpp"...
This .cpp includes of course header01.h
I call the print routine this way inside it
PrintSig(&g_sig_1);
I notice the print result differs from the actual content.
Say sig contains 0xE8, then it printed 0xE800
Then, I thought, about 2 hours of investigation, it could be struct alignment.
I try it...
Declaring the struct this way in header01.h
#pragma push()
#pragma pack(4)
typedef struct pp_sig_s
{
[...]
int flags;
size_t max;
bool is_reversed;
unsigned int sig[64];
size_t byref;
[...]
}
pp_sig_t;
#pragma pop()
And suddenly everything works fine...
So basically its like if in program01.cpp the struct offsets were, i would guess, different than in program02.cpp...
How the hell can a struct differs from one file to another? How can we avoid this without using pragmas? Could it be called a compiler bug (i use Intel C++ XE Composer 2013 Update 2, on linux)?
It seems likely that this was caused by an alignment pragma that was in scope when one of the files included the header, but not when the other did.

How to read through types of a struct in C/C++

I am trying to find the "types" of any given variables in different structs and be able to read them. (keep in mind this is psuedo code)
For Example:
#include "stream.h" //a custom stream reader class I made
typedef unsigned char BYTE;
/***** SERIES OF DIFFERENT STRUCTS ******/
struct asset
{
char *name;
int size;
BYTE *data;
};
struct asset2
{
char *lang;
char *entry;
};
/*****************************************/
void readAsset( Enumerable<struct> &istruct)
{
foreach( object o in istruct )
{
switch( o )
{
case int:
&o = _stream->ReadInt32();
break;
case char:
&o = _stream->ReadChar();
break;
case *:
&o = _stream->ReadInt32();
break;
default: break;
}
}
}
I want it to be able to do the following:
asset a1;
asset2 a2;
readAsset( a1 );
readAsset( a2 );
and pass all the info from the file to a1 and a2.
I was wondering if there was a way in C/C++ to get the type of the data from any object in the struct then read based on that? is it possible with complex enums? Sorry for the bad code but I wanted it to be easier to understand what I'm trying to do.
Additional Info:
_stream is a pointer to a Stream class I made similar to Stream Reader in .Net It reads data from a file and advances it's position based on how big of data it was read.
I'll be happy to re-phrase if you don't understand what I'm asking.
There is no way to iterate through the members of a structure without listing them all out.
You can iterate through something like a structure at compile time using ::std::tuple in C++11.
You also can't really switch on type in that fashion. You can do it, but the way you do it is to have several functions with the same name that each take a different parameter type. Something like:
void doRead(StreamType &stream, int &data)
{
data = stream.readInt32();
}
void doRead(StreamType &stream, char &data)
{
data = stream.readChar();
}
// etc...
Then you just call doRead with your structure member and poof the compiler magically picks the right one based on the type.
In C++, the way to solve the problem you're solving here is a serialization library. If you have control of both the format written and the format read, you can use something like protobuf or boost::serialization to do this relatively easily without having to write a lot of your own code.
Additionally, a couple of issues with your code. Do not use a leading _ character in identifiers. Identifiers with a leading _ are reserved for use by the compiler or standard library implementation. Many compilers have special keywords that are compiler specific language extensions that start with an _ character. Using identifiers with a leading _ character may result in your code mysteriously failing to compile with all kinds of strange inscrutable errors in some environments.
You can get something like a struct that is enumerable at compile time. But it's ugly:
#include <tuple>
#include <string>
#include <vector>
#include <type_traits>
class asset : public ::std::tuple< ::std::string, ::std::vector<BYTE> >
{
public:
::std::string &name() { return ::std::get<0>(*this); }
const ::std::string &name() const { return ::std::get<0>(*this); }
::std::vector<BYTE> &data() { return ::std::get<1>(*this); }
const ::std::vector<BYTE> &data() const { return ::std::get<1>(*this); }
};
void writeToStream(Stream *out, const ::std::string &field)
{
out->writeString(field);
}
void writeToStream(Stream *out, const ::std::vector<BYTE> &field)
{
out->writeInt(field.size());
out->writeRaw(field.data(), field.size());
}
template <unsigned int fnum, typename... T>
typename ::std::enable_if< (fnum < sizeof...(T)), void >::type
writeToStream_n(Stream *out, const::std::tuple<T...> &field)
{
writeToStream(out, ::std::get<fnum>(field));
writeToStream_n<fnum+1, T...>(out, field);
}
template <unsigned int fnum, typename... T>
typename ::std::enable_if< (fnum >= sizeof...(T)) >::type
writeToStream_n(Stream *, const::std::tuple<T...> &)
{
}
template <typename... Tp>
void writeToStream(Stream *out, const ::std::tuple<Tp...> &composite)
{
writeToStream_n<0, Tp...>(out, composite);
}
void foo(Stream *out, const asset &a)
{
writeToStream(out, a);
}
Notice that there is no explicit writeToStream for the asset type. The compiler will write it at runtime by unpacking the ::std::tuple it's derived from and writing out each individual field.
Also, if you have bare pointers, you're writing poor C++. Please write idiomatic, good C++ if you're going to write C++. This whole thing you want to do with runtime reflection is just not the way to do things.
That's the reason I converted your char *name to a ::std::string and your size delimited BYTE array represented by your size and data fields into a ::std::vector. Using those types is the idiomatically correct way to write C++. Using bare pointers the way you were is not. Additionally, having two fields that have strongly related values (the data and size) fields that have no behavior or any other indication that they're associated would make it hard even for a compiler that does introspection at runtime to figure out the right thing to do. It can't know how big the BYTE array being pointed to by data is, and it can't know about your decision to encode this in size.
What you're asking for is something called Reflection - which is:
the ability of a computer program to examine
and modify the structure and behavior (specifically the values,
meta-data, properties and functions) of an object at runtime.
C++ doesn't have that "natively".
What I mean is - there have been some attempts at introducing some aspects of it - with varied degrees of success - which have produced some aspects of Reflection, but not "full" Reflection itself as you will get in a language like Ruby or so.
However, if you are feeling adventurous, you can try a Reflection library called Reflectabit:
To see if it might be worthwhile (which it might be considering your code), it is referenced here - which has quite a bit of examples on how to use the API:
http://www.altdevblogaday.com/2011/09/25/reflection-in-c-part-1-introduction/
Good luck!
The usual pattern in C++ is not to try and figure out what the members of the type are, but rather provide an operator, implemented by the implementor of the type, that is able to serialize/deserialize to disk.
You can take a look at, for example, the boost::serialize library. The usage is not too complex, you need to provide a function that lists your members in some order and then the library will take it from there and implement serialization to different formats.