Contiki-NG
Loading...
Searching...
No Matches
contiki-main.c
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 main
34 * @{
35 */
36/*---------------------------------------------------------------------------*/
37/**
38 * \file
39 *
40 * Implementation of \os's main routine
41 */
42/*---------------------------------------------------------------------------*/
43#include "contiki.h"
44#include "contiki-net.h"
45#include "lib/ecc.h"
46#include "lib/random.h"
47#include "sys/node-id.h"
48#include "sys/platform.h"
49#include "sys/energest.h"
50#include "sys/stack-check.h"
51#include "dev/watchdog.h"
52
53#include "net/queuebuf.h"
57#include "services/rpl-border-router/rpl-border-router.h"
62
63#include <stdio.h>
64#include <stdint.h>
65/*---------------------------------------------------------------------------*/
66/* Log configuration */
67#include "sys/log.h"
68#define LOG_MODULE "Main"
69#define LOG_LEVEL LOG_LEVEL_MAIN
70
71#if PLATFORM_MAIN_ACCEPTS_ARGS
72/*---------------------------------------------------------------------------*/
73int contiki_argc;
74char **contiki_argv;
75/*---------------------------------------------------------------------------*/
76#include "lib/list.h"
77
78LIST(contiki_options);
79static const char *prog;
80static const char *help_usage;
81static const char *help_suffix;
82/*---------------------------------------------------------------------------*/
83void
84contiki_set_usage(const char *msg)
85{
86 help_usage = msg;
87}
88/*---------------------------------------------------------------------------*/
89void
90contiki_set_extra_help(const char *msg)
91{
92 help_suffix = msg;
93}
94/*---------------------------------------------------------------------------*/
95void
96contiki_add_option(struct contiki_callback_option *option)
97{
98 static bool initialized = false;
99 if(!initialized) {
100 list_init(contiki_options);
101 initialized = true;
102 }
103 list_add(contiki_options, option);
104}
105/*---------------------------------------------------------------------------*/
106static void
107print_help(void)
108{
109 printf("usage: %s [options]%s", prog, help_usage ? help_usage : "\n");
110 printf("Options are:\n");
111 for(struct contiki_callback_option *r = list_head(contiki_options);
112 r != NULL; r = r->next) {
113 if(!r->help) {
114 continue;
115 }
116 int short_len = r->opt_struct.flag == NULL && r->opt_struct.val ? 6 : 0;
117 if(short_len) {
118 printf(" -%c, ", (char)r->opt_struct.val);
119 }
120 int has_arg = r->opt_struct.has_arg;
121 const char *arg_desc = has_arg == no_argument ? "" :
122 has_arg == optional_argument ? " [value]" : " value ";
123 printf(" %c-%s%s%s\t%s", strlen(r->opt_struct.name) == 1 ? ' ' : '-',
124 r->opt_struct.name, arg_desc,
125 /* Insert extra tab for short option names. */
126 short_len + 3 + strlen(r->opt_struct.name) + strlen(arg_desc) < 8
127 ? "\t" : "",
128 r->help);
129 }
130 if(help_suffix) {
131 printf("%s", help_suffix);
132 }
133}
134/*---------------------------------------------------------------------------*/
135CC_NORETURN static int
136help_callback(const char *optarg)
137{
138 print_help();
139 exit(0);
140}
141CONTIKI_OPTION(CONTIKI_MAX_INIT_PRIO + 1, { "help", no_argument, NULL, 'h' },
142 help_callback, "display this help and exit\n");
143/*---------------------------------------------------------------------------*/
144static int
145parse_argv(int *argc, char ***argv)
146{
147 prog = *argv[0];
148 const int num_options = list_length(contiki_options);
149 struct contiki_callback_option options[num_options];
150 struct option long_options[num_options + 1];
151
152 int i = 0;
153 for(struct contiki_callback_option *r = list_head(contiki_options);
154 r != NULL; ++i, r = r->next) {
155 memcpy(&long_options[i], &r->opt_struct, sizeof(struct option));
156 memcpy(&options[i], r, sizeof(struct contiki_callback_option));
157 }
158 /* Null terminate options. */
159 memset(&long_options[i], 0, sizeof(struct option));
160
161 while(1) {
162 int ix = 0;
163 int c = getopt_long_only(*argc, *argv, "", long_options, &ix);
164 if(c == -1) { /* Processed all options. */
165 break;
166 }
167 if(c == '?') { /* Unknown option, print help and return error. */
168 print_help();
169 return 1;
170 }
171 if(options[ix].callback) { /* Option has a callback, call with optarg. */
172 int rv;
173 if((rv = options[ix].callback(optarg)) != 0) {
174 return rv;
175 }
176 }
177 }
178 *argc -= optind - 1;
179 *argv += optind - 1;
180 return 0;
181}
182/*---------------------------------------------------------------------------*/
183int
184main(int argc, char **argv)
185{
186 int rv;
187 if((rv = parse_argv(&argc, &argv)) != 0) {
188 return rv;
189 }
190 /* Remember argc/argv after command line options. */
191 contiki_argc = argc;
192 contiki_argv = argv;
193#else
194int
195main(void)
196{
197#endif /* PLATFORM_MAIN_ACCEPTS_ARGS */
199
200 clock_init();
201 rtimer_init();
202 process_init();
203 process_start(&etimer_process, NULL);
204 ctimer_init();
206
207 energest_init();
208
209#if STACK_CHECK_ENABLED
211#endif
212
214
215#if QUEUEBUF_ENABLED
216 queuebuf_init();
217#endif /* QUEUEBUF_ENABLED */
218
219 NETSTACK_RADIO.init();
220
221 /* at this point, the CSPRNG may have been fed with radio noise */
222 random_init();
223
224 NETSTACK_MAC.init();
225 NETSTACK_NETWORK.init();
226
227 node_id_init();
228#if ECC_ENABLED
229 ecc_init();
230#endif /* ECC_ENABLED */
231
232 LOG_INFO("Starting " CONTIKI_VERSION_STRING "\n");
233 LOG_DBG("TARGET=%s", CONTIKI_TARGET_STRING);
234#ifdef CONTIKI_BOARD_STRING
235 LOG_DBG_(", BOARD=%s", CONTIKI_BOARD_STRING);
236#endif
237 LOG_DBG_("\n");
238 LOG_INFO("- Routing: %s\n", NETSTACK_ROUTING.name);
239 LOG_INFO("- Net: %s\n", NETSTACK_NETWORK.name);
240 LOG_INFO("- MAC: %s\n", NETSTACK_MAC.name);
241 LOG_INFO("- 802.15.4 PANID: 0x%04x\n", IEEE802154_PANID);
242#if MAC_CONF_WITH_TSCH
243 LOG_INFO("- 802.15.4 TSCH default hopping sequence length: %u\n", (unsigned)sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE));
244#else /* MAC_CONF_WITH_TSCH */
245 LOG_INFO("- 802.15.4 Default channel: %u\n", IEEE802154_DEFAULT_CHANNEL);
246#endif /* MAC_CONF_WITH_TSCH */
247
248 LOG_INFO("Node ID: %u\n", node_id);
249 LOG_INFO("Link-layer address: ");
250 LOG_INFO_LLADDR(&linkaddr_node_addr);
251 LOG_INFO_("\n");
252
253#if NETSTACK_CONF_WITH_IPV6
254 {
255 uip_ds6_addr_t *lladdr;
256 memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr));
257 process_start(&tcpip_process, NULL);
258
259 lladdr = uip_ds6_get_link_local(-1);
260 LOG_INFO("Tentative link-local IPv6 address: ");
261 LOG_INFO_6ADDR(lladdr != NULL ? &lladdr->ipaddr : NULL);
262 LOG_INFO_("\n");
263 }
264#endif /* NETSTACK_CONF_WITH_IPV6 */
265
267
268#if BUILD_WITH_RPL_BORDER_ROUTER
269 rpl_border_router_init();
270 LOG_DBG("With RPL Border Router\n");
271#endif /* BUILD_WITH_RPL_BORDER_ROUTER */
272
273#if BUILD_WITH_ORCHESTRA
274 orchestra_init();
275 LOG_DBG("With Orchestra\n");
276#endif /* BUILD_WITH_ORCHESTRA */
277
278#if BUILD_WITH_SHELL
280 LOG_DBG("With Shell\n");
281#endif /* BUILD_WITH_SHELL */
282
283#if BUILD_WITH_COAP
284 coap_engine_init();
285 LOG_DBG("With CoAP\n");
286#endif /* BUILD_WITH_COAP */
287
288#if BUILD_WITH_SNMP
289 snmp_init();
290 LOG_DBG("With SNMP\n");
291#endif /* BUILD_WITH_SNMP */
292
293#if BUILD_WITH_SIMPLE_ENERGEST
295#endif /* BUILD_WITH_SIMPLE_ENERGEST */
296
297#if BUILD_WITH_TSCH_CS
298 /* Initialize the channel selection module */
300#endif /* BUILD_WITH_TSCH_CS */
301
302 autostart_start(autostart_processes);
303
305
306#if PLATFORM_PROVIDES_MAIN_LOOP
308#else
309 while(1) {
310 process_num_events_t r;
311 do {
312 r = process_run();
314 } while(r > 0);
315
317 }
318#endif
319
320 return 0;
321}
322/*---------------------------------------------------------------------------*/
323/**
324 * @}
325 */
void serial_shell_init(void)
Initializes Serial Shell module.
#define CC_NORETURN
Configure if the C compiler supports functions that are not meant to return e.g.
Definition cc.h:99
CoAP engine implementation.
Header file of ECC.
Header file for the energy estimation mechanism.
802.15.4 frame creation and parsing functions
void snmp_init()
Initializes the SNMP engine.
Definition snmp.c:57
void clock_init(void)
Arch-specific implementation of clock_init for the cc2538.
Definition clock.c:93
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Definition watchdog.c:72
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition watchdog.c:85
void watchdog_init(void)
Initialisation function for the WDT.
Definition watchdog.c:63
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition platform.c:165
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition platform.c:113
void platform_idle()
The platform's idle/sleep function.
Definition platform.c:181
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition platform.c:122
void ctimer_init(void)
Initialize the callback timer library.
Definition ctimer.c:86
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
static void list_init(list_t list)
Initialize a list.
Definition list.h:152
#define LIST(name)
Declare a linked list.
Definition list.h:90
int list_length(const_list_t list)
Get the length of a list.
Definition list.c:160
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition list.c:71
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition list.h:169
void platform_main_loop(void)
The platform's main loop, if provided.
Definition tz-normal.c:103
#define CONTIKI_OPTION(prio,...)
Add a command line option when the compilation unit is present.
Definition platform.h:153
static void node_id_init(void)
Initialize the node ID.
Definition node-id.h:61
process_num_events_t process_run(void)
Run the system once - call poll handlers and process one event.
Definition process.c:305
void process_start(struct process *p, process_data_t data)
Start a process.
Definition process.c:121
void process_init(void)
Initialize the process module.
Definition process.c:228
#define rtimer_init()
Initialize the real-time scheduler.
Definition rtimer.h:127
void simple_energest_init(void)
Initialize the deployment module.
void stack_check_init(void)
Initialize the stack area with a known pattern.
Definition stack-check.c:74
uip_lladdr_t uip_lladdr
Host L2 address.
Definition uip6.c:107
Linked list manipulation routines.
Header file for the logging system.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Definition mac.h:52
Node-id (simple 16-bit identifiers) handling.
Orchestra header file.
Header file for the Contiki-NG main routine.
Header file for the Packet queue buffer management.
Header file for generating non-cryptographic random numbers.
A shell back-end for the serial port.
A process that periodically prints out the time spent in radio tx, radio rx, total time and duty cycl...
SNMP Implementation of the process.
Stack checker library header file.
void(* init)(void)
Initialize the MAC driver.
Definition mac.h:72
Unicast address structure.
Definition uip-ds6.h:205
void tsch_cs_adaptations_init(void)
Initializes the TSCH hopping sequence selection module.
Definition tsch-cs.c:116
Header file for TSCH adaptive channel selection.