Contiki-NG
platform.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, Swedish Institute of Computer Science.
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 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31/**
32 * \file
33 * COOJA Contiki mote main file.
34 * \author
35 * Fredrik Osterlind <fros@sics.se>
36 */
37
38#include <jni.h>
39#include <stdint.h>
40#include <stdio.h>
41#include <string.h>
42
43#include "contiki.h"
44#include "sys/cc.h"
45
46#include "sys/clock.h"
47#include "sys/etimer.h"
48#include "sys/cooja_mt.h"
49
50/*---------------------------------------------------------------------------*/
51/* Log configuration */
52#include "sys/log.h"
53#define LOG_MODULE "Cooja"
54#define LOG_LEVEL LOG_LEVEL_MAIN
55
56#include "lib/random.h"
57#include "lib/simEnvChange.h"
58
59#include "net/netstack.h"
60#include "net/queuebuf.h"
61
62#include "dev/eeprom.h"
63#include "dev/serial-line.h"
64#include "dev/cooja-radio.h"
65#include "dev/button-sensor.h"
66#include "dev/pir-sensor.h"
67#include "dev/vib-sensor.h"
68#include "dev/moteid.h"
69#include "dev/button-hal.h"
70#include "dev/gpio-hal.h"
71
72#include "sys/node-id.h"
73#include "services/rpl-border-router/rpl-border-router.h"
74#if BUILD_WITH_ORCHESTRA
75#include "orchestra.h"
76#endif /* BUILD_WITH_ORCHESTRA */
77#if BUILD_WITH_SHELL
78#include "serial-shell.h"
79#endif /* BUILD_WITH_SHELL */
80
81/* JNI-defined functions, depends on the environment variable CLASSNAME */
82#ifndef CLASSNAME
83#error CLASSNAME is undefined, required by platform.c
84#endif /* CLASSNAME */
85#define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c)
86#define COOJA_QUOTEME(a,b,c) a##b##c
87#define COOJA_JNI_PATH Java_org_contikios_cooja_corecomm_
88#define Java_org_contikios_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init)
89#define Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory)
90#define Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory)
91#define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
92#define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
93
94#if NETSTACK_CONF_WITH_IPV6
95#include "net/ipv6/uip.h"
96#include "net/ipv6/uip-ds6.h"
97#endif /* NETSTACK_CONF_WITH_IPV6 */
98
99/* The main function, implemented in contiki-main.c */
100int main(void);
101
102/* Simulation mote interfaces */
103SIM_INTERFACE_NAME(moteid_interface);
104SIM_INTERFACE_NAME(vib_interface);
105SIM_INTERFACE_NAME(rs232_interface);
106SIM_INTERFACE_NAME(simlog_interface);
107SIM_INTERFACE_NAME(beep_interface);
108SIM_INTERFACE_NAME(radio_interface);
109SIM_INTERFACE_NAME(button_interface);
110SIM_INTERFACE_NAME(pir_interface);
111SIM_INTERFACE_NAME(clock_interface);
112SIM_INTERFACE_NAME(leds_interface);
113SIM_INTERFACE_NAME(cfs_interface);
114SIM_INTERFACE_NAME(eeprom_interface);
115SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface, &eeprom_interface);
116/* Example: manually add mote interfaces */
117//SIM_INTERFACE_NAME(dummy_interface);
118//SIM_INTERFACES(..., &dummy_interface);
119
120/* Sensors */
121SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
122
123/*
124 * referenceVar is used for comparing absolute and process relative memory.
125 * (this must not be static due to memory locations)
126 */
127intptr_t referenceVar;
128
129/*
130 * Contiki and rtimer threads.
131 */
132static struct cooja_mt_thread rtimer_thread;
133static struct cooja_mt_thread process_run_thread;
134/*---------------------------------------------------------------------------*/
135/* Needed since the new LEDs API does not provide this prototype */
136void leds_arch_init(void);
137/*---------------------------------------------------------------------------*/
138static void
139rtimer_thread_loop(void *data)
140{
141 while(1)
142 {
143 rtimer_arch_check();
144
145 /* Return to COOJA */
146 cooja_mt_yield();
147 }
148}
149/*---------------------------------------------------------------------------*/
150static void
151set_lladdr(void)
152{
153 linkaddr_t addr;
154
155 memset(&addr, 0, sizeof(linkaddr_t));
156#if NETSTACK_CONF_WITH_IPV6
157 for(size_t i = 0; i < sizeof(uip_lladdr.addr); i += 2) {
158 addr.u8[i + 1] = simMoteID & 0xff;
159 addr.u8[i + 0] = simMoteID >> 8;
160 }
161#else /* NETSTACK_CONF_WITH_IPV6 */
162 addr.u8[0] = simMoteID & 0xff;
163 addr.u8[1] = simMoteID >> 8;
164#endif /* NETSTACK_CONF_WITH_IPV6 */
166}
167/*---------------------------------------------------------------------------*/
168void
170{
172 leds_arch_init();
173 return;
174}
175/*---------------------------------------------------------------------------*/
176void
178{
179 set_lladdr();
181}
182/*---------------------------------------------------------------------------*/
183void
185{
186 /* Initialize eeprom */
187 eeprom_init();
188 /* Start serial process */
189 serial_line_init();
190}
191/*---------------------------------------------------------------------------*/
192void
194{
195 while(1)
196 {
197 simProcessRunValue = process_run();
198 while(simProcessRunValue-- > 0) {
199 process_run();
200 }
201 simProcessRunValue = process_nevents();
202
203 /* Check if we must stay awake */
204 if(simDontFallAsleep) {
205 simDontFallAsleep = 0;
206 simProcessRunValue = 1;
207 }
208
209 /* Return to COOJA */
210 cooja_mt_yield();
211 }
212}
213/*---------------------------------------------------------------------------*/
214static void
215process_run_thread_loop(void *data)
216{
217 /* Yield once during bootup */
218 simProcessRunValue = 1;
219 cooja_mt_yield();
220
221 /* Then call common Contiki-NG main function */
222 main();
223}
224
225/**
226 * \brief Callback on load of library.
227 * \param vm unused
228 * \param reserved unused
229 *
230 * This function is required to return at least the JNI version for
231 * the functions we use.
232 *
233 * Java 11 is the oldest supported Java version so the function returns
234 * JNI_VERSION_10 for now.
235 */
236JNIEXPORT jint JNICALL
237JNI_OnLoad(JavaVM *vm, void *reserved)
238{
239 return JNI_VERSION_10;
240}
241
242/*---------------------------------------------------------------------------*/
243/**
244 * \brief Initialize a mote by starting processes etc.
245 * \param env JNI Environment interface pointer
246 * \param obj unused
247 *
248 * This function initializes a mote by starting certain
249 * processes and setting up the environment.
250 *
251 * This is a JNI function and should only be called via the
252 * responsible Java part (MoteType.java).
253 */
254JNIEXPORT void JNICALL
256{
257 /* Create rtimers and Contiki threads */
258 cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL);
259 cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL);
260 }
261/*---------------------------------------------------------------------------*/
262/**
263 * \brief Get a segment from the process memory.
264 * \param env JNI Environment interface pointer
265 * \param obj unused
266 * \param rel_addr Start address of segment
267 * \param length Size of memory segment
268 * \param mem_arr Byte array destination for the fetched memory segment
269 * \return Java byte array containing a copy of memory segment.
270 *
271 * Fetches a memory segment from the process memory starting at
272 * (rel_addr), with size (length). This function does not perform
273 * ANY error checking, and the process may crash if addresses are
274 * not available/readable.
275 *
276 * This is a JNI function and should only be called via the
277 * responsible Java part (MoteType.java).
278 */
279JNIEXPORT void JNICALL
280Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jlong rel_addr, jint length, jbyteArray mem_arr)
281{
282 (*env)->SetByteArrayRegion(
283 env,
284 mem_arr,
285 0,
286 (size_t) length,
287 (jbyte *) (((intptr_t)rel_addr) + referenceVar)
288 );
289}
290/*---------------------------------------------------------------------------*/
291/**
292 * \brief Replace a segment of the process memory with given byte array.
293 * \param env JNI Environment interface pointer
294 * \param obj unused
295 * \param rel_addr Start address of segment
296 * \param length Size of memory segment
297 * \param mem_arr Byte array contaning new memory
298 *
299 * Replaces a process memory segment with given byte array.
300 * This function does not perform ANY error checking, and the
301 * process may crash if addresses are not available/writable.
302 *
303 * This is a JNI function and should only be called via the
304 * responsible Java part (MoteType.java).
305 */
306JNIEXPORT void JNICALL
307Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jlong rel_addr, jint length, jbyteArray mem_arr)
308{
309 (*env)->GetByteArrayRegion(env, mem_arr, 0, length,
310 (jbyte *)((intptr_t)rel_addr + referenceVar));
311}
312/*---------------------------------------------------------------------------*/
313/**
314 * \brief Let mote execute one "block" of code (tick mote).
315 * \param env JNI Environment interface pointer
316 * \param obj unused
317 *
318 * Let mote defined by the active contiki processes and current
319 * process memory execute some program code. This code must not block
320 * or else this function will never return. A typical contiki
321 * process will return when it executes PROCESS_WAIT..() statements.
322 *
323 * Before the control is left to contiki processes, any messages
324 * from the Java part are handled. These may for example be
325 * incoming network data. After the contiki processes return control,
326 * messages to the Java part are also handled (those which may need
327 * special attention).
328 *
329 * This is a JNI function and should only be called via the
330 * responsible Java part (MoteType.java).
331 */
332JNIEXPORT void JNICALL
334{
335 simProcessRunValue = 0;
336
337 /* Let all simulation interfaces act first */
338 doActionsBeforeTick();
339
340 /* Poll etimer process */
341 if(etimer_pending()) {
343 }
344
345 /* Let rtimers run.
346 * Sets simProcessRunValue */
347 cooja_mt_exec(&rtimer_thread);
348
349 if(simProcessRunValue == 0) {
350 /* Rtimers done: Let Contiki handle a few events.
351 * Sets simProcessRunValue */
352 cooja_mt_exec(&process_run_thread);
353 }
354
355 /* Let all simulation interfaces act before returning to java */
356 doActionsAfterTick();
357
358 /* Do we have any pending timers */
359 simEtimerPending = etimer_pending();
360
361 /* Save nearest expiration time */
362 simEtimerNextExpirationTime = etimer_next_expiration_time();
363
364}
365/*---------------------------------------------------------------------------*/
366/**
367 * \brief Set the relative memory address of the reference variable.
368 * \param env JNI Environment interface pointer
369 * \param obj unused
370 * \param addr Relative memory address
371 *
372 * This is a JNI function and should only be called via the
373 * responsible Java part (MoteType.java).
374 */
375JNIEXPORT void JNICALL
377{
378 referenceVar = (((intptr_t)&referenceVar) - ((intptr_t)addr));
379}
Header file for the button HAL.
Default definitions of C compiler quirk work-arounds.
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jlong rel_addr, jint length, jbyteArray mem_arr)
Replace a segment of the process memory with given byte array.
Definition: platform.c:307
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj)
Initialize a mote by starting processes etc.
Definition: platform.c:255
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj)
Let mote execute one "block" of code (tick mote).
Definition: platform.c:333
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress(JNIEnv *env, jobject obj, jlong addr)
Set the relative memory address of the reference variable.
Definition: platform.c:376
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jlong rel_addr, jint length, jbyteArray mem_arr)
Get a segment from the process memory.
Definition: platform.c:280
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
Callback on load of library.
Definition: platform.c:237
EEPROM functions.
Event timer header file.
Header file for the GPIO HAL.
void button_hal_init()
Initialise the button HAL.
Definition: button-hal.c:213
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition: platform.c:169
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition: platform.c:114
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition: platform.c:123
bool eeprom_init(void)
Initialize the EEPROM module.
Definition: eeprom.c:79
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition: etimer.c:231
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition: etimer.c:145
clock_time_t etimer_next_expiration_time(void)
Get next event timer expiration time.
Definition: etimer.c:237
void gpio_hal_init()
Initialise the GPIO HAL.
Definition: gpio-hal.c:95
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:75
void platform_main_loop()
The platform's main loop, if provided.
Definition: platform.c:193
int process_run(void)
Run the system once - call poll handlers and process one event.
Definition: process.c:302
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
Header file for the logging system.
Include file for the Contiki low-layer network stack (NETSTACK)
Node-id (simple 16-bit identifiers) handling.
Orchestra header file.
Header file for the Packet queue buffer management.
Generic serial I/O process header filer.
A shell back-end for the serial port.
Header file for IPv6-related data structures.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
Header file for the uIP TCP/IP stack.
SENSORS & button_sensor
Exports global symbols for the sensor API.
Definition: z1-sensors.c:46