datatypes bit depth

... the major advantage is on compiling. what about the run time?
...

based on p#18:
The compiler adds needed instructions to assure 32 bit registers properly handle 8 and 16 bit operations when requested.

This leads to perfectly safe and proper execution for the desired result.

However, at run time those added instructions will take extra time to load those instructions and execute them to get to that result.

That explains: "32 bit variables have optimal performance on 32 bit ARM."
 
Code:
#include <timelib.h>;

#pragma pack(push,1)

typedef struct MasterToSlaveCommandType {
    byte          command;
    unsigned long time;
    uint16_t      tempEtAl;  // can be maby things not just temperature temperature;
} MasterToSlaveCommandType;

MasterToSlaveCommandType data;

#pragma pack(pop)


void setup()
{
    Serial.begin(9600);
    Serial1.begin(9600);

    while (!Serial && millis() < 5000) {};
    Serial.print("Size of structure: ");
    Serial.println(sizeof(data));
    data.command = 1;
    data.time = now();
    data.tempEtAl = 12345;
    Serial.print("Size of command  : "); Serial.println(sizeof(data.command));
    Serial.print("Size of time     : "); Serial.println(sizeof(data.time));
    Serial.print("Size of tempEtAl : "); Serial.println(sizeof(data.tempEtAl));

    Serial1.write((uint8_t*)&data, sizeof(data));
}

void loop()
{
    delay(1);
}
On Teensy LC, all 16 and 32 bit variables must be aligned to 16 or 32 bit memory boundaries. By default the compiler always aligns them, so usually unaligned access only happens if you do something like typecasting arbitrary integers to pointers. You will get a fault on Teensy LC if unaligned memory access is attempted. Teensy 3 & 4 do allow unaligned memory access, at least to normal memory. Some peripherals support it, others don't. I believe there is also a config bit somewhere in the ARM processor which disables the ability to access unaligned memory, which would give the same behaviour as Teensy LC if you found and changed that setting.

But these cases are far outside the norm of regular programming.

Simply using 8 or 16 bit variables doesn't cause the CPU to fault or stop. ARM specifically designed it to be able to handle 8 and 16 bit variables.
Hi Paul,
In my code above, I see that when packed the structure only takes 7 bytes. How does that align with what you said in your quote above. Is it that the compiler transparently handles unpacking and re-packing the data when addressing the memory?
If so, would the line "Serial1.write((uint8_t*)&data, sizeof(data));" send the data correctly in the required format n(7 bytes of the correct data: byte/unsigned long/uint16_t )?
The data will be sent via a Lora transmitter and the receiving end will be a Lora receiver/T4.1.
The Lora transceivers send and receive bytes.
 
Using 'pack' overrides default behavior, without 'pack' does it take more bytes?

"C" is well designed to allow programmer to do anything ... good or bad.

As noted only T_LC would have a problem with access to that packed structure.

Code like this will show actual address of the element:
Serial.printf("data.command Addr:%p ", &data.command);
 
The LC operates just fine with the pack in, hence my question.
With the pack in total size is reported as 7 bytes, without 12 bytes.
It's no good sending an unknown length packet over the air if the sending and receiving devices are different.

So my question still stands will "Serial1.write((uint8_t*)&data, sizeof(data));" send the data ok to the other end?
 
Some links about structs:
* https://stackoverflow.com/questions/5397447/struct-padding-in-c
* http://www.catb.org/esr/structure-packing/

The internal structure of structs is not standardized and I wouldn’t rely on it. I’ve seen compilers do odd things. (Yes, there are certain “rules”, but I’ve still seen compilers sometimes do unexpected things.)

It’s been my strong preference to not use the internal binary structure of structs for protocols or data storage. If you use the same compiler and system at the other end then maybe, but it’s a can of worms.
 
The data will be sent via a Lora transmitter and the receiving end will be a Lora receiver/T4.1.
As you can see it's a Teensy both ends.

I was just concerned when Paul said that LC cannot have data/variables that are NOT 16 or 32 bit aligned on the LC.
As you can see in my demonstration code above I have data that is byte aligned without throwing a problem.

I was concerned that the code to send the data over the serial1/Lora port would not work ok.
The reason for using structs are a) to attempt to ensure that the data sent and received is consistent
and also to reduce the transmission time (7 bytes vs 12 bytes).

The latter is significant as other than sending data the LC will be essentially asleep, saving/extending battery life.

I would still like to know how the data alignment matches Paul's explanation of LC data alignment.
 
Back
Top