Senet-ized LMIC for MOTE_L152RC
Fork of lmic_MOTE_L152RC by
Diff: oslmic.cpp
- Revision:
- 0:f2716e543d97
- Child:
- 9:83ae7f34e88c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/oslmic.cpp Tue Jun 02 19:04:29 2015 +0000
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2015 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Zurich Research Lab - initial API, implementation and documentation
+ *******************************************************************************/
+
+#include "lmic.h"
+
+// RUNTIME STATE
+static struct {
+ osjob_t* scheduledjobs;
+ osjob_t* runnablejobs;
+} OS;
+
+void os_init () {
+ memset(&OS, 0x00, sizeof(OS));
+ hal_init();
+ radio_init();
+ LMIC_init();
+}
+
+ostime_t os_getTime () {
+ return hal_ticks();
+}
+
+static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
+ for( ; *pnext; pnext = &((*pnext)->next)) {
+ if(*pnext == job) { // unlink
+ *pnext = job->next;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// clear scheduled job
+void os_clearCallback (osjob_t* job) {
+ hal_disableIRQs();
+ unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
+ hal_enableIRQs();
+}
+
+// schedule immediately runnable job
+void os_setCallback (osjob_t* job, osjobcb_t cb) {
+ osjob_t** pnext;
+ hal_disableIRQs();
+ // remove if job was already queued
+ os_clearCallback(job);
+ // fill-in job
+ job->func = cb;
+ job->next = NULL;
+ // add to end of run queue
+ for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
+ *pnext = job;
+ hal_enableIRQs();
+}
+
+// schedule timed job
+void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
+ osjob_t** pnext;
+ hal_disableIRQs();
+ // remove if job was already queued
+ os_clearCallback(job);
+ // fill-in job
+ job->deadline = time;
+ job->func = cb;
+ job->next = NULL;
+ // insert into schedule
+ for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) {
+ if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!)
+ // enqueue before next element and stop
+ job->next = *pnext;
+ break;
+ }
+ }
+ *pnext = job;
+ hal_enableIRQs();
+}
+
+// execute jobs from timer and from run queue
+void os_runloop () {
+ while(1) {
+ osjob_t* j = NULL;
+ hal_disableIRQs();
+ // check for runnable jobs
+ if(OS.runnablejobs) {
+ j = OS.runnablejobs;
+ OS.runnablejobs = j->next;
+ } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
+ j = OS.scheduledjobs;
+ OS.scheduledjobs = j->next;
+ } else { // nothing pending
+ hal_sleep(); // wake by irq (timer already restarted)
+ }
+ hal_enableIRQs();
+ if(j) { // run job callback
+ j->func(j);
+ }
+ }
+}


