diff options
author | Keith Packard <keithp@keithp.com> | 2016-12-17 20:58:36 -0800 |
---|---|---|
committer | Bdale Garbee <bdale@gag.com> | 2017-01-25 12:21:43 -0700 |
commit | fe25510fc23031f1a3c1b42edd37067d1989a9f6 (patch) | |
tree | 3cdc98d2c3d1c8d9bd95045771be7d15226d246b /src/kernel/ao_task.h | |
parent | 4163d88ed36ce8863218366f1fb504f7061a4ca5 (diff) |
altos/arm: Align data so that gcc 5.4 doesn't do byte-accesses. Add -Wcast-align
Gcc 5.4.1 tracks alignment of data through assignments, so that a
uint32_t pointer which comes from byte-aligned uint8_t data:
extern uint8_t foo[];
uint32_t *q = (void *) foo;
Fetches and stores through this pointer are done bytewise. This is
slow (meh), but if q references a device register, things to bad very
quickly.
This patch works around this bug in the compiler by adding
__attribute__((aligned(4))) tags to some variables, or changing them
from uint8_t to uint32_t. Places doing this will now be caught as I've
added -Wcast-align to the compiler flags. That required adding (void
*) casts, after the relevant code was checked to make sure the
compiler could tell that the addresses were aligned.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/kernel/ao_task.h')
-rw-r--r-- | src/kernel/ao_task.h | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h index f1dbd654..30b018ff 100644 --- a/src/kernel/ao_task.h +++ b/src/kernel/ao_task.h @@ -26,6 +26,17 @@ #define HAS_TASK_INFO 1 #endif +/* arm stacks must be 32-bit aligned */ +#ifdef __arm__ +#define AO_STACK_ALIGNMENT __attribute__ ((aligned(4))) +#endif +#ifdef SDCC +#define AO_STACK_ALIGNMENT +#endif +#ifdef __AVR__ +#define AO_STACK_ALIGNMENT +#endif + /* An AltOS task */ struct ao_task { __xdata void *wchan; /* current wait channel (NULL if running) */ @@ -37,7 +48,7 @@ struct ao_task { struct ao_list queue; struct ao_list alarm_queue; #endif - uint8_t stack[AO_STACK_SIZE]; /* saved stack */ + uint8_t stack[AO_STACK_SIZE] AO_STACK_ALIGNMENT; /* saved stack */ #if HAS_SAMPLE_PROFILE uint32_t ticks; uint32_t yields; |