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 
69 #include "sys/node-id.h"
70 #include "services/rpl-border-router/rpl-border-router.h"
71 #if BUILD_WITH_ORCHESTRA
72 #include "orchestra.h"
73 #endif /* BUILD_WITH_ORCHESTRA */
74 #if BUILD_WITH_SHELL
75 #include "serial-shell.h"
76 #endif /* BUILD_WITH_SHELL */
77 
78 /* JNI-defined functions, depends on the environment variable CLASSNAME */
79 #ifndef CLASSNAME
80 #error CLASSNAME is undefined, required by platform.c
81 #endif /* CLASSNAME */
82 #define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c)
83 #define COOJA_QUOTEME(a,b,c) a##b##c
84 #define COOJA_JNI_PATH Java_org_contikios_cooja_corecomm_
85 #define Java_org_contikios_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init)
86 #define Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory)
87 #define Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory)
88 #define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
89 #define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
90 
91 #if NETSTACK_CONF_WITH_IPV6
92 #include "net/ipv6/uip.h"
93 #include "net/ipv6/uip-ds6.h"
94 #endif /* NETSTACK_CONF_WITH_IPV6 */
95 
96 /* The main function, implemented in contiki-main.c */
97 int main(void);
98 
99 /* Simulation mote interfaces */
100 SIM_INTERFACE_NAME(moteid_interface);
101 SIM_INTERFACE_NAME(vib_interface);
102 SIM_INTERFACE_NAME(rs232_interface);
103 SIM_INTERFACE_NAME(simlog_interface);
104 SIM_INTERFACE_NAME(beep_interface);
105 SIM_INTERFACE_NAME(radio_interface);
106 SIM_INTERFACE_NAME(button_interface);
107 SIM_INTERFACE_NAME(pir_interface);
108 SIM_INTERFACE_NAME(clock_interface);
109 SIM_INTERFACE_NAME(leds_interface);
110 SIM_INTERFACE_NAME(cfs_interface);
111 SIM_INTERFACE_NAME(eeprom_interface);
112 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);
113 /* Example: manually add mote interfaces */
114 //SIM_INTERFACE_NAME(dummy_interface);
115 //SIM_INTERFACES(..., &dummy_interface);
116 
117 /* Sensors */
118 SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
119 
120 /*
121  * referenceVar is used for comparing absolute and process relative memory.
122  * (this must not be static due to memory locations)
123  */
124 long referenceVar;
125 
126 /*
127  * Contiki and rtimer threads.
128  */
129 static struct cooja_mt_thread rtimer_thread;
130 static struct cooja_mt_thread process_run_thread;
131 
132 /*---------------------------------------------------------------------------*/
133 static void
134 rtimer_thread_loop(void *data)
135 {
136  while(1)
137  {
138  rtimer_arch_check();
139 
140  /* Return to COOJA */
141  cooja_mt_yield();
142  }
143 }
144 /*---------------------------------------------------------------------------*/
145 static void
146 set_lladdr(void)
147 {
148  linkaddr_t addr;
149 
150  memset(&addr, 0, sizeof(linkaddr_t));
151 #if NETSTACK_CONF_WITH_IPV6
152  {
153  int i;
154  for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) {
155  addr.u8[i + 1] = simMoteID & 0xff;
156  addr.u8[i + 0] = simMoteID >> 8;
157  }
158  }
159 #else /* NETSTACK_CONF_WITH_IPV6 */
160  addr.u8[0] = simMoteID & 0xff;
161  addr.u8[1] = simMoteID >> 8;
162 #endif /* NETSTACK_CONF_WITH_IPV6 */
163  linkaddr_set_node_addr(&addr);
164 }
165 /*---------------------------------------------------------------------------*/
166 void
168 {
169  return;
170 }
171 /*---------------------------------------------------------------------------*/
172 void
174 {
175  set_lladdr();
176 }
177 /*---------------------------------------------------------------------------*/
178 void
180 {
181  /* Initialize eeprom */
182  eeprom_init();
183  /* Start serial process */
184  serial_line_init();
185 }
186 /*---------------------------------------------------------------------------*/
187 void
189 {
190  while(1)
191  {
192  simProcessRunValue = process_run();
193  while(simProcessRunValue-- > 0) {
194  process_run();
195  }
196  simProcessRunValue = process_nevents();
197 
198  /* Check if we must stay awake */
199  if(simDontFallAsleep) {
200  simDontFallAsleep = 0;
201  simProcessRunValue = 1;
202  }
203 
204  /* Return to COOJA */
205  cooja_mt_yield();
206  }
207 }
208 /*---------------------------------------------------------------------------*/
209 static void
210 process_run_thread_loop(void *data)
211 {
212  /* Yield once during bootup */
213  simProcessRunValue = 1;
214  cooja_mt_yield();
215 
216  /* Then call common Contiki-NG main function */
217  main();
218 }
219 /*---------------------------------------------------------------------------*/
220 /**
221  * \brief Initialize a mote by starting processes etc.
222  * \param env JNI Environment interface pointer
223  * \param obj unused
224  *
225  * This function initializes a mote by starting certain
226  * processes and setting up the environment.
227  *
228  * This is a JNI function and should only be called via the
229  * responsible Java part (MoteType.java).
230  */
231 JNIEXPORT void JNICALL
233 {
234  /* Create rtimers and Contiki threads */
235  cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL);
236  cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL);
237  }
238 /*---------------------------------------------------------------------------*/
239 /**
240  * \brief Get a segment from the process memory.
241  * \param env JNI Environment interface pointer
242  * \param obj unused
243  * \param rel_addr Start address of segment
244  * \param length Size of memory segment
245  * \param mem_arr Byte array destination for the fetched memory segment
246  * \return Java byte array containing a copy of memory segment.
247  *
248  * Fetches a memory segment from the process memory starting at
249  * (rel_addr), with size (length). This function does not perform
250  * ANY error checking, and the process may crash if addresses are
251  * not available/readable.
252  *
253  * This is a JNI function and should only be called via the
254  * responsible Java part (MoteType.java).
255  */
256 JNIEXPORT void JNICALL
257 Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
258 {
259  (*env)->SetByteArrayRegion(
260  env,
261  mem_arr,
262  0,
263  (size_t) length,
264  (jbyte *) (((long)rel_addr) + referenceVar)
265  );
266 }
267 /*---------------------------------------------------------------------------*/
268 /**
269  * \brief Replace a segment of the process memory with given byte array.
270  * \param env JNI Environment interface pointer
271  * \param obj unused
272  * \param rel_addr Start address of segment
273  * \param length Size of memory segment
274  * \param mem_arr Byte array contaning new memory
275  *
276  * Replaces a process memory segment with given byte array.
277  * This function does not perform ANY error checking, and the
278  * process may crash if addresses are not available/writable.
279  *
280  * This is a JNI function and should only be called via the
281  * responsible Java part (MoteType.java).
282  */
283 JNIEXPORT void JNICALL
284 Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
285 {
286  jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0);
287  memcpy((char*) (((long)rel_addr) + referenceVar),
288  mem,
289  length);
290  (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0);
291 }
292 /*---------------------------------------------------------------------------*/
293 /**
294  * \brief Let mote execute one "block" of code (tick mote).
295  * \param env JNI Environment interface pointer
296  * \param obj unused
297  *
298  * Let mote defined by the active contiki processes and current
299  * process memory execute some program code. This code must not block
300  * or else this function will never return. A typical contiki
301  * process will return when it executes PROCESS_WAIT..() statements.
302  *
303  * Before the control is left to contiki processes, any messages
304  * from the Java part are handled. These may for example be
305  * incoming network data. After the contiki processes return control,
306  * messages to the Java part are also handled (those which may need
307  * special attention).
308  *
309  * This is a JNI function and should only be called via the
310  * responsible Java part (MoteType.java).
311  */
312 JNIEXPORT void JNICALL
314 {
315  simProcessRunValue = 0;
316 
317  /* Let all simulation interfaces act first */
318  doActionsBeforeTick();
319 
320  /* Poll etimer process */
321  if(etimer_pending()) {
323  }
324 
325  /* Let rtimers run.
326  * Sets simProcessRunValue */
327  cooja_mt_exec(&rtimer_thread);
328 
329  if(simProcessRunValue == 0) {
330  /* Rtimers done: Let Contiki handle a few events.
331  * Sets simProcessRunValue */
332  cooja_mt_exec(&process_run_thread);
333  }
334 
335  /* Let all simulation interfaces act before returning to java */
336  doActionsAfterTick();
337 
338  /* Do we have any pending timers */
339  simEtimerPending = etimer_pending();
340 
341  /* Save nearest expiration time */
342  simEtimerNextExpirationTime = etimer_next_expiration_time();
343 
344 }
345 /*---------------------------------------------------------------------------*/
346 /**
347  * \brief Set the relative memory address of the reference variable.
348  * \param env JNI Environment interface pointer
349  * \param obj unused
350  * \param addr Relative memory address
351  *
352  * This is a JNI function and should only be called via the
353  * responsible Java part (MoteType.java).
354  */
355 JNIEXPORT void JNICALL
357 {
358  referenceVar = (((long)&referenceVar) - ((long)addr));
359 }
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:116
void platform_main_loop()
The platform&#39;s main loop, if provided.
Definition: platform.c:188
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:284
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:257
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
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:313
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj)
Initialize a mote by starting processes etc.
Definition: platform.c:232
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:356
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 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
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:75