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