#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"); \
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 */
#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" \
/* 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;
#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")
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;
/* PRIMASK with interrupts enabled */
ARM_PUSH32(sp, 0);
- task->sp = sp;
+ task->sp32 = sp;
}
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}");
#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
*/
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;
/* BASEPRI with interrupts enabled */
ARM_PUSH32(sp, 0);
- task->sp = sp;
+ task->sp32 = sp;
}
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 */
#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
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;
/* BASEPRI with interrupts enabled */
ARM_PUSH32(sp, 0);
- task->sp = sp;
+ task->sp32 = sp;
}
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 */
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")
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;
/* PRIMASK with interrupts enabled */
ARM_PUSH32(sp, 0);
- task->sp = sp;
+ task->sp32 = sp;
}
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}");