altos/arm: Align data so that gcc 5.4 doesn't do byte-accesses. Add -Wcast-align
[fw/altos] / src / kernel / ao_task.h
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #ifndef _AO_TASK_H_
20 #define _AO_TASK_H_
21 #if HAS_TASK_QUEUE
22 #include <ao_list.h>
23 #endif
24
25 #ifndef HAS_TASK_INFO
26 #define HAS_TASK_INFO 1
27 #endif
28
29 /* arm stacks must be 32-bit aligned */
30 #ifdef __arm__
31 #define AO_STACK_ALIGNMENT __attribute__ ((aligned(4)))
32 #endif
33 #ifdef SDCC
34 #define AO_STACK_ALIGNMENT
35 #endif
36 #ifdef __AVR__
37 #define AO_STACK_ALIGNMENT
38 #endif
39
40 /* An AltOS task */
41 struct ao_task {
42         __xdata void *wchan;            /* current wait channel (NULL if running) */
43         uint16_t alarm;                 /* abort ao_sleep time */
44         ao_arch_task_members            /* any architecture-specific fields */
45         uint8_t task_id;                /* unique id */
46         __code char *name;              /* task name */
47 #if HAS_TASK_QUEUE
48         struct ao_list  queue;
49         struct ao_list  alarm_queue;
50 #endif
51         uint8_t stack[AO_STACK_SIZE] AO_STACK_ALIGNMENT;        /* saved stack */
52 #if HAS_SAMPLE_PROFILE
53         uint32_t ticks;
54         uint32_t yields;
55         uint16_t start;
56         uint16_t max_run;
57 #endif
58 };
59
60 #ifndef AO_NUM_TASKS
61 #define AO_NUM_TASKS            16      /* maximum number of tasks */
62 #endif
63
64 #define AO_NO_TASK              0       /* no task id */
65
66 extern __xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS];
67 extern __data uint8_t ao_num_tasks;
68 extern __xdata struct ao_task *__data ao_cur_task;
69 extern __data uint8_t ao_task_minimize_latency; /* Reduce IRQ latency */
70
71 #ifndef HAS_ARCH_VALIDATE_CUR_STACK
72 #define ao_validate_cur_stack()
73 #endif
74
75 /*
76  ao_task.c
77  */
78
79 /* Suspend the current task until wchan is awoken.
80  * returns:
81  *  0 on normal wake
82  *  1 on alarm
83  */
84 uint8_t
85 ao_sleep(__xdata void *wchan);
86
87 /* Suspend the current task until wchan is awoken or the timeout
88  * expires. returns:
89  *  0 on normal wake
90  *  1 on alarm
91  */
92 uint8_t
93 ao_sleep_for(__xdata void *wchan, uint16_t timeout);
94
95 /* Wake all tasks sleeping on wchan */
96 void
97 ao_wakeup(__xdata void *wchan) __reentrant;
98
99 #if 0
100 /* set an alarm to go off in 'delay' ticks */
101 void
102 ao_alarm(uint16_t delay);
103
104 /* Clear any pending alarm */
105 void
106 ao_clear_alarm(void);
107 #endif
108
109 /* Yield the processor to another task */
110 void
111 ao_yield(void) ao_arch_naked_declare;
112
113 /* Add a task to the run queue */
114 void
115 ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant;
116
117 #if HAS_TASK_QUEUE
118 /* Called on timer interrupt to check alarms */
119 extern uint16_t ao_task_alarm_tick;
120 void
121 ao_task_check_alarm(uint16_t tick);
122 #endif
123
124 /* Terminate the current task */
125 void
126 ao_exit(void);
127
128 /* Dump task info to console */
129 void
130 ao_task_info(void);
131
132 /* Start the scheduler. This will not return */
133 void
134 ao_start_scheduler(void);
135
136 #if HAS_TASK_QUEUE
137 void
138 ao_task_init(void);
139 #else
140 #define ao_task_init()
141 #endif
142
143 #endif