Contiki-NG
Loading...
Searching...
No Matches
platform.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, George Oikonomou - http://www.spd.gr
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31/*---------------------------------------------------------------------------*/
32/**
33 * \addtogroup sys
34 * @{
35 */
36/*---------------------------------------------------------------------------*/
37/**
38 * \defgroup main The \os main function
39 *
40 * A platform-independent main function.
41 *
42 * \os provides a modular, platform-independent main function that aims to
43 * support all hardware ports.
44 *
45 * In a nutshell, the main routine has the following steps below:
46 *
47 * - Calls a platform-provided function to initialise basic hardware drivers
48 * - Initialises core \os modules, such as the process scheduler and timers
49 * - Calls a platform-provided function to initialise more hardware drivers
50 * - Initialises the network stack and TCP/IP
51 * - Calls a platform-provided function to initialise any remaining drivers
52 * - Enters the main loop
53 *
54 * The main loop will service all pending events and will then call a
55 * platform-dependent function to put the hardware in a low-power state.
56 *
57 * For more detail of which hardware driver should be implemented in which
58 * stage of the boot process, see the documentation of
59 * \e platform_init_stage_one(), \e platform_init_stage_two() and
60 * \e platform_init_stage_three()
61 *
62 * @{
63 */
64/*---------------------------------------------------------------------------*/
65/**
66 * \file
67 *
68 * Header file for the \os main routine
69 */
70/*---------------------------------------------------------------------------*/
71#ifndef PLATFORM_H_
72#define PLATFORM_H_
73/*---------------------------------------------------------------------------*/
74/**
75 * Controls whether the platform provides a custom main loop
76 *
77 * By default we will use the main loop provided here. This however does not
78 * work for some platforms, so we allow them to override it.
79 */
80#ifdef PLATFORM_CONF_PROVIDES_MAIN_LOOP
81#define PLATFORM_PROVIDES_MAIN_LOOP PLATFORM_CONF_PROVIDES_MAIN_LOOP
82#else
83#define PLATFORM_PROVIDES_MAIN_LOOP 0
84#endif
85/*---------------------------------------------------------------------------*/
86/**
87 * Controls whether the main function accepts arguments
88 *
89 * By default our main does not accept arguments. However, when running on
90 * native targets, command line arguments to main are required.
91 */
92#ifdef PLATFORM_CONF_MAIN_ACCEPTS_ARGS
93#define PLATFORM_MAIN_ACCEPTS_ARGS PLATFORM_CONF_MAIN_ACCEPTS_ARGS
94#else
95#define PLATFORM_MAIN_ACCEPTS_ARGS 0
96#endif
97/*---------------------------------------------------------------------------*/
98#if PLATFORM_MAIN_ACCEPTS_ARGS
99#include <getopt.h>
100
101#define CONTIKI_MIN_INIT_PRIO 110
102#define CONTIKI_VERBOSE_PRIO 120
103
104#define CONTIKI_MAX_INIT_PRIO 998
105
106struct contiki_callback_option {
107 struct contiki_callback_option *next;
108 struct option opt_struct;
109 int (*callback)(const char *);
110 const char *help;
111};
112
113/** A global argc, after parsing command line options. */
114extern int contiki_argc;
115/** A global argv, after parsing command line options. */
116extern char **contiki_argv;
117#endif /* PLATFORM_MAIN_ACCEPTS_ARGS */
118
119/**
120 * Add a command line option when the compilation unit is present.
121 *
122 * The second argument is the initialization of struct option
123 * for getopt_long.
124 *
125 * The third argument is a callback function of type int (*)(char *),
126 * or NULL. The callback will receieve optarg from getopt_long as
127 * parameter, and should return 0 on success. Any other
128 * return value will terminate main() with that exit code.
129 *
130 * The fourth argument is the string shown from --help. Pass NULL if
131 * the option should not be shown in the help.
132 *
133 * Example:
134 * @code
135 * CONTIKI_OPTION(CONTIKI_VERBOSE_PRIO,
136 * { "v", optional_argument, NULL, 0 }, verbose_callback,
137 * "verbosity level (0-5)\n");
138 * @endcode
139 *
140 * \param prio Priority. Higher priority will appear later in --help.
141 */
142#if PLATFORM_MAIN_ACCEPTS_ARGS
143#define CONTIKI_OPTION(prio, ...) \
144 static struct contiki_callback_option CC_CONCAT(callback_option, __LINE__) = \
145 { NULL, __VA_ARGS__ }; \
146 CC_CONSTRUCTOR((prio)) static void \
147 CC_CONCAT(add_option, __LINE__)(void) \
148 { \
149 void contiki_add_option(struct contiki_callback_option *); \
150 contiki_add_option(&CC_CONCAT(callback_option, __LINE__)); \
151 }
152#else
153#define CONTIKI_OPTION(prio, ...)
154#endif /* PLATFORM_MAIN_ACCEPTS_ARGS */
155
156/**
157 * Set the usage string shown for --help.
158 * \param prio Priority. If multiple compilation units set the usage
159 * string, the one with the highest priority takes effect.
160 * \param msg The usage message.
161 */
162#if PLATFORM_MAIN_ACCEPTS_ARGS
163#define CONTIKI_USAGE(prio, msg) \
164 CC_CONSTRUCTOR((prio)) static void \
165 CC_CONCAT(set_usage, __LINE__)(void) \
166 { \
167 void contiki_set_usage(const char *); \
168 contiki_set_usage((msg)); \
169 }
170#else
171#define CONTIKI_USAGE(prio, msg)
172#endif /* PLATFORM_MAIN_ACCEPTS_ARGS */
173
174/**
175 * Set extra usage help shown at the end of --help.
176 * \param prio Priority. If multiple compilation units set the extra
177 * usage help, the one with the highest priority takes effect.
178 * \param msg The usage message.
179 */
180#if PLATFORM_MAIN_ACCEPTS_ARGS
181#define CONTIKI_EXTRA_HELP(prio, msg) \
182 CC_CONSTRUCTOR((prio)) static void \
183 CC_CONCAT(set_extra_help, __LINE__)(void) \
184 { \
185 void contiki_set_extra_help(const char *); \
186 contiki_set_extra_help((msg)); \
187 }
188#else
189#define CONTIKI_EXTRA_HELP(prio, msg)
190#endif /* PLATFORM_MAIN_ACCEPTS_ARGS */
191/*---------------------------------------------------------------------------*/
192/**
193 * \brief Basic (Stage 1) platform driver initialisation.
194 *
195 * This function will get called early on in the \os boot sequence.
196 *
197 * In this function, the platform should initialise all core device drivers.
198 * For example, this is where you will normally want to initialise hardware
199 * timers/clocks, GPIO, LEDS. Normally this function will also enable the
200 * MCU's global interrupt.
201 *
202 * The \os process scheduler, software clocks and timers will not be
203 * running yet, so any platform drivers that rely on it should not be
204 * initialised here. Instead, they should be initialised in
205 * \e platform_init_stage_two() or in \e platform_init_stage_three()
206 *
207 * It is the port developer's responsibility to implement this function.
208 *
209 * \sa platform_init_stage_two()
210 * \sa platform_init_stage_three()
211 */
212void platform_init_stage_one(void);
213/*---------------------------------------------------------------------------*/
214/**
215 * \brief Stage 2 of platform driver initialisation.
216 *
217 * This function will be called by the \os boot sequence after parts of the
218 * core have been initialised. More specifically, when this function gets
219 * called, the following modules will be running:
220 *
221 * - Software clock
222 * - Process scheduler
223 * - Event timer (etimer)
224 * - Callback timer (ctimer)
225 * - rtimer
226 * - Energest (if enabled)
227 *
228 * Therefore, any platform driver that relies on any of the above modules
229 * should be initialised here or in \e platform_init_stage_three(),
230 * but not in \e platform_init_stage_one()
231 *
232 * The \os network stack will not be running yet, so any platform drivers
233 * that rely on networking should not be initialised here.
234 *
235 * When this function returns, the main routine will assume that the
236 * platform has enabled character I/O and can print to console. When
237 * this function returns, main() will attempt to initialise the network
238 * stack. For this to work properly, this function should also populate
239 * linkaddr_node_addr.
240 *
241 * It is the port developer's responsibility to implement this function.
242 *
243 * \sa platform_init_stage_one()
244 * \sa platform_init_stage_three()
245 */
246void platform_init_stage_two(void);
247/*---------------------------------------------------------------------------*/
248/**
249 * \brief Final stage of platform driver initialisation.
250 *
251 * Initialisation of platform-specific drivers that require networking to be
252 * running. This is also a good place to initialise sensor drivers.
253 *
254 * When this function returns, the main routine will assume that the
255 * hardware is fully initialised.
256 *
257 * It is the port developer's responsibility to implement this function.
258 *
259 * \sa platform_init_stage_one()
260 * \sa platform_init_stage_two()
261 */
263/*---------------------------------------------------------------------------*/
264/**
265 * \brief The platform's idle/sleep function
266 *
267 * This function will be called as part of the main loop after all events
268 * have been serviced. This is where you will normally put the device in a
269 * low-power state. Waking up from this state and tidying up the hardware
270 * is the port's responsibility.
271 *
272 * It is the port developer's responsibility to implement this function.
273 */
274void platform_idle(void);
275/*---------------------------------------------------------------------------*/
276/**
277 * \brief The platform's main loop, if provided
278 *
279 * If the platform developer wishes to do so, it is possible to override the
280 * main loop provided by \os's core. To do so, define
281 * PLATFORM_CONF_PROVIDES_MAIN_LOOP as 1.
282 *
283 * It is the port developer's responsibility to implement this function.
284 */
285void platform_main_loop(void);
286/*---------------------------------------------------------------------------*/
287#endif /* PLATFORM_H_ */
288/*---------------------------------------------------------------------------*/
289/**
290 * @}
291 * @}
292 */
void platform_init_stage_two(void)
Stage 2 of platform driver initialisation.
Definition platform.c:122
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition platform.c:113
void platform_main_loop(void)
The platform's main loop, if provided.
Definition tz-normal.c:103
void platform_idle(void)
The platform's idle/sleep function.
Definition platform.c:181
void platform_init_stage_three(void)
Final stage of platform driver initialisation.
Definition platform.c:165