altos: Declare task stack as union of uint8_t and uint32_t
authorKeith Packard <keithp@keithp.com>
Tue, 5 Feb 2019 06:38:23 +0000 (22:38 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 18 Feb 2019 21:08:23 +0000 (13:08 -0800)
Support -Wcast-align and -Wpointer-arith while still allowing
architectures to pick whether they want an 8-bit or 32-bit stack.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/avr/ao_arch.h
src/kernel/ao_task.h
src/lpc/ao_arch.h
src/lpc/ao_arch_funcs.h
src/stm/ao_arch.h
src/stm/ao_arch_funcs.h
src/stm32f4/ao_arch.h
src/stm32f4/ao_arch_funcs.h
src/stmf0/ao_arch.h
src/stmf0/ao_arch_funcs.h

index 6166c50..d3454f9 100644 (file)
@@ -78,27 +78,25 @@ extern uint8_t      ao_cpu_sleep_disable;
 
 #define ao_arch_task_globals   uint8_t ao_cpu_sleep_disable;
 
-#define ao_arch_task_members\
-       uint8_t *sp;                    /* saved stack pointer */
-
-#define ao_arch_init_stack(task, start) do {                   \
-       uint8_t         *sp = task->stack + AO_STACK_SIZE - 1;  \
-       uint16_t        a = (uint16_t) start;                   \
-       int             i;                                      \
-                                                               \
-       /* Return address */                                    \
-       AVR_PUSH8(sp, a);                                       \
-       AVR_PUSH8(sp, (a >> 8));                                \
-                                                               \
-       /* Clear register values */                             \
-       i = 32;                                                 \
-       while (i--)                                             \
-               AVR_PUSH8(sp, 0);                               \
-                                                               \
-       /* SREG with interrupts enabled */                      \
-       AVR_PUSH8(sp, 0x80);                                    \
-       task->sp = sp;                                          \
-} while (0);
+#define ao_arch_init_stack(task, start) \
+       do {                                                            \
+               uint8_t         *sp = task->stack8 + AO_STACK_SIZE - 1; \
+               uint16_t        a = (uint16_t) start;                   \
+               int             i;                                      \
+                                                                       \
+               /* Return address */                                    \
+               AVR_PUSH8(sp, a);                                       \
+               AVR_PUSH8(sp, (a >> 8));                                \
+                                                                       \
+               /* Clear register values */                             \
+               i = 32;                                                 \
+               while (i--)                                             \
+                       AVR_PUSH8(sp, 0);                               \
+                                                                       \
+               /* SREG with interrupts enabled */                      \
+               AVR_PUSH8(sp, 0x80);                                    \
+               task->sp8 = sp;                                         \
+       } while (0);
        
 #define ao_arch_save_regs() do {                                       \
                asm("push r31" "\n\t" "push r30");                      \
@@ -115,7 +113,7 @@ extern uint8_t      ao_cpu_sleep_disable;
                uint8_t sp_l, sp_h;                                     \
                asm("in %0,__SP_L__" : "=&r" (sp_l) );                  \
                asm("in %0,__SP_H__" : "=&r" (sp_h) );                  \
-               ao_cur_task->sp = (uint8_t *) ((uint16_t) sp_l | ((uint16_t) sp_h << 8)); \
+               ao_cur_task->sp8 = (uint8_t *) ((uint16_t) sp_l | ((uint16_t) sp_h << 8)); \
        } while (0)
 
 #define ao_arch_isr_stack()    /* nothing */
@@ -140,8 +138,8 @@ extern uint8_t      ao_cpu_sleep_disable;
 
 #define ao_arch_restore_stack() do { \
                uint8_t sp_l, sp_h;                                     \
-               sp_l = (uint16_t) ao_cur_task->sp                     \
-               sp_h = ((uint16_t) ao_cur_task->sp) >> 8;               \
+               sp_l = (uint16_t) ao_cur_task->sp8;                     \
+               sp_h = ((uint16_t) ao_cur_task->sp8) >> 8;              \
                asm("out __SP_H__,%0" : : "r" (sp_h) );                 \
                asm("out __SP_L__,%0" : : "r" (sp_l) );                 \
                asm("pop r0"    "\n\t"                                  \
index 709e10c..d27ef06 100644 (file)
 
 /* An AltOS task */
 struct ao_task {
-       void *wchan;            /* current wait channel (NULL if running) */
+       void *wchan;                    /* current wait channel (NULL if running) */
        uint16_t alarm;                 /* abort ao_sleep time */
-       ao_arch_task_members            /* any architecture-specific fields */
-       uint8_t task_id;                /* unique id */
+       uint16_t task_id;               /* unique id */
+       /* Saved stack pointer */
+       union {
+               uint32_t        *sp32;
+               uint8_t         *sp8;
+       };
        const char *name;               /* task name */
-#ifdef NEWLIB
-       int __errno;                    /* storage for errno in newlib libc */
-#endif
 #if HAS_TASK_QUEUE
        struct ao_list  queue;
        struct ao_list  alarm_queue;
 #endif
-       uint8_t stack[AO_STACK_SIZE] AO_STACK_ALIGNMENT;        /* saved stack */
+       /* Provide both 32-bit and 8-bit stacks, always 32-bit aligned */
+       union {
+               uint32_t stack32[AO_STACK_SIZE>>2];
+               uint8_t stack8[AO_STACK_SIZE];
+       };
 #if HAS_SAMPLE_PROFILE
        uint32_t ticks;
        uint32_t yields;
index 35dcc9d..7821839 100644 (file)
@@ -60,9 +60,6 @@
 
 #define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
 
-#define ao_arch_task_members\
-       uint32_t *sp;                   /* saved stack pointer */
-
 #define ao_arch_block_interrupts()     asm("cpsid i")
 #define ao_arch_release_interrupts()   asm("cpsie i")
 
index 345108a..1368f7e 100644 (file)
@@ -109,7 +109,7 @@ ao_arch_memory_barrier(void) {
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)
 {
-       uint32_t        *sp = (uint32_t *) (void *) (task->stack + AO_STACK_SIZE);
+       uint32_t        *sp = &task->stack32[AO_STACK_SIZE >> 2];
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -127,7 +127,7 @@ ao_arch_init_stack(struct ao_task *task, void *start)
        /* PRIMASK with interrupts enabled */
        ARM_PUSH32(sp, 0);
 
-       task->sp = sp;
+       task->sp32 = sp;
 }
 
 static inline void ao_arch_save_regs(void) {
@@ -146,17 +146,14 @@ static inline void ao_arch_save_regs(void) {
 static inline void ao_arch_save_stack(void) {
        uint32_t        *sp;
        asm("mov %0,sp" : "=&r" (sp) );
-       ao_cur_task->sp = (sp);
-       if ((uint8_t *) sp < &ao_cur_task->stack[0])
+       ao_cur_task->sp32 = (sp);
+       if (sp < &ao_cur_task->stack32[0])
                ao_panic (AO_PANIC_STACK);
 }
 
 static inline void ao_arch_restore_stack(void) {
-       uint32_t        sp;
-       sp = (uint32_t) ao_cur_task->sp;
-
        /* Switch stacks */
-       asm("mov sp, %0" : : "r" (sp) );
+       asm("mov sp, %0" : : "r" (ao_cur_task->sp32) );
 
        /* Restore PRIMASK */
        asm("pop {r0}");
index 52576b4..c95c7cd 100644 (file)
@@ -58,9 +58,6 @@
 
 #define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
 
-#define ao_arch_task_members\
-       uint32_t *sp;                   /* saved stack pointer */
-
 /*
  * For now, we're running at a weird frequency
  */
index e55ecb7..ad46ef3 100644 (file)
@@ -475,7 +475,7 @@ ao_arch_irq_check(void) {
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)
 {
-       uint32_t        *sp = (uint32_t *) ((void*) task->stack + AO_STACK_SIZE);
+       uint32_t        *sp = &task->stack32[AO_STACK_SIZE>>2];
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -493,7 +493,7 @@ ao_arch_init_stack(struct ao_task *task, void *start)
        /* BASEPRI with interrupts enabled */
        ARM_PUSH32(sp, 0);
 
-       task->sp = sp;
+       task->sp32 = sp;
 }
 
 static inline void ao_arch_save_regs(void) {
@@ -517,12 +517,12 @@ static inline void ao_arch_save_regs(void) {
 static inline void ao_arch_save_stack(void) {
        uint32_t        *sp;
        asm("mov %0,sp" : "=&r" (sp) );
-       ao_cur_task->sp = (sp);
+       ao_cur_task->sp32 = (sp);
 }
 
 static inline void ao_arch_restore_stack(void) {
        /* Switch stacks */
-       asm("mov sp, %0" : : "r" (ao_cur_task->sp) );
+       asm("mov sp, %0" : : "r" (ao_cur_task->sp32) );
 
 #ifdef AO_NONMASK_INTERRUPTS
        /* Restore BASEPRI */
index 73dc3e9..7dd4c80 100644 (file)
@@ -38,9 +38,6 @@
 
 #define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
 
-#define ao_arch_task_members\
-       uint32_t *sp;                   /* saved stack pointer */
-
 #define ao_arch_naked_declare  __attribute__((naked))
 #define ao_arch_naked_define
 
index b1ffb5b..8ff31b4 100644 (file)
@@ -84,7 +84,7 @@ ao_arch_irq_check(void) {
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)
 {
-       uint32_t        *sp = (uint32_t *) ((void*) task->stack + AO_STACK_SIZE);
+       uint32_t        *sp = &task->stack32[AO_STACK_SIZE>>2];
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -110,7 +110,7 @@ ao_arch_init_stack(struct ao_task *task, void *start)
        /* BASEPRI with interrupts enabled */
        ARM_PUSH32(sp, 0);
 
-       task->sp = sp;
+       task->sp32 = sp;
 }
 
 static inline void ao_arch_save_regs(void) {
@@ -142,12 +142,12 @@ static inline void ao_arch_save_regs(void) {
 static inline void ao_arch_save_stack(void) {
        uint32_t        *sp;
        asm("mov %0,sp" : "=&r" (sp) );
-       ao_cur_task->sp = (sp);
+       ao_cur_task->sp32 = (sp);
 }
 
 static inline void ao_arch_restore_stack(void) {
        /* Switch stacks */
-       asm("mov sp, %0" : : "r" (ao_cur_task->sp) );
+       asm("mov sp, %0" : : "r" (ao_cur_task->sp32) );
 
 #ifdef AO_NONMASK_INTERRUPTS
        /* Restore BASEPRI */
index 8256eba..e5f7e1f 100644 (file)
@@ -65,9 +65,6 @@ extern const uint16_t ao_romconfig_check;
 extern const uint16_t ao_serial_number;
 extern const uint32_t ao_radio_cal;
 
-#define ao_arch_task_members\
-       uint32_t *sp;                   /* saved stack pointer */
-
 #define ao_arch_block_interrupts()     asm("cpsid i")
 #define ao_arch_release_interrupts()   asm("cpsie i")
 
index b2ce77a..9233f04 100644 (file)
@@ -389,7 +389,7 @@ ao_arch_memory_barrier(void) {
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)
 {
-       uint32_t        *sp = (uint32_t *) ((void *) task->stack + AO_STACK_SIZE);
+       uint32_t        *sp = &task->stack32[AO_STACK_SIZE >> 2];
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -407,7 +407,7 @@ ao_arch_init_stack(struct ao_task *task, void *start)
        /* PRIMASK with interrupts enabled */
        ARM_PUSH32(sp, 0);
 
-       task->sp = sp;
+       task->sp32 = sp;
 }
 
 static inline void ao_arch_save_regs(void) {
@@ -426,17 +426,14 @@ static inline void ao_arch_save_regs(void) {
 static inline void ao_arch_save_stack(void) {
        uint32_t        *sp;
        asm("mov %0,sp" : "=&r" (sp) );
-       ao_cur_task->sp = (sp);
-       if ((uint8_t *) sp < &ao_cur_task->stack[0])
+       ao_cur_task->sp32 = (sp);
+       if (sp < &ao_cur_task->stack32[0])
                ao_panic (AO_PANIC_STACK);
 }
 
 static inline void ao_arch_restore_stack(void) {
-       uint32_t        sp;
-       sp = (uint32_t) ao_cur_task->sp;
-
        /* Switch stacks */
-       asm("mov sp, %0" : : "r" (sp) );
+       asm("mov sp, %0" : : "r" (ao_cur_task->sp32) );
 
        /* Restore PRIMASK */
        asm("pop {r0}");