#pragma pack(1)
ensures that C struct
items are packed in order and on byte boundaries. It may save RAM - which is often precious in a microcontroller.
Packed structs also allow for casting directly over memory buffers for data interchange:
void f(void *buf)
{
struct ip_header *hdr = (struct ip_header *)buf;
hdr->dst = 0x8000001;
}
Be careful where you use #pragma pack
. It's globally scoped (as it's in the preprocessor), so forgetting to turn it off will affect any #include
files.
If you only mean to pack certain structs, consider using GCC's __attribute__ ((packed))
.
However, due to alignment issues, packed structs can impact performance.
For example:
When packed into bytes:
struct
{
uint8_t a;
uint32_t b;
uint8_t c;
uint8_t d:
};
Will be stored as (not accounting for endianness):
a, b0, b1, b2, b3, c, d
However, many architectures require 32bit accesses to be aligned to 32bit addresses. With the packed struct, the machine will have to make several byte accesses then stich them together again.
Faced with the above struct
without packing enabled, the compiler could reorganise it as:
b0, b1, b2, b3, a, c, d
So from the previously linked answer,
I think the most
interesting/beneficial things for me
would be the bullet about learning the
tools (compiler and linker), and
learning different styles of software
architecture (going from interrupt
based control loops to schedulers and
RTOSes)
Porting a small operating system to a new device could help you to understand schedulers and RTOSs. FreeRTOS is popular and well documented. eCos is another.
Writing a bootloader is a good way to get to grips with a linker as you'll want to divide up memory and flash into regions.
Another tip is to pick a completely new architecture or chip and build yourself a development board. Forcing yourself to start right from the beginning and look everything up in the datasheet is a good way to learn.
Explore Protothreads. Try writing the same programs in both a threaded and state machine style. Once you're done with Protothreads, write a real thread scheduler.
Best Answer
Show the workflow diagrams independently, one for the main loop, one for the DMA and the other for the interrupts.
As the interrups are triggered by external events (like ADC ready, timer, external interrupts) it cannot be in the main loop.
Just at the begining of the workflow, put the tittle in a circle, for example: "Main", "EXT_INT", "DMA", etc.
Good luck!