first test

Dependents:   LoRaWAN-lmic-app_tjm

Fork of LMiC by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers oslmic.cpp Source File

oslmic.cpp

00001 /*******************************************************************************
00002  * Copyright (c) 2014-2015 IBM Corporation.
00003  * All rights reserved. This program and the accompanying materials
00004  * are made available under the terms of the Eclipse Public License v1.0
00005  * which accompanies this distribution, and is available at
00006  * http://www.eclipse.org/legal/epl-v10.html
00007  *
00008  * Contributors:
00009  *    IBM Zurich Research Lab - initial API, implementation and documentation
00010  *******************************************************************************/
00011 
00012 #include "lmic.h"
00013 #include "debug.h"
00014 
00015 // RUNTIME STATE
00016 static struct 
00017 {
00018     osjob_t* scheduledjobs;
00019     osjob_t* runnablejobs;
00020 } OS;
00021 
00022 void os_init () 
00023 {
00024     debug("os_init enter\r\n");
00025     memset(&OS, 0x00, sizeof(OS));
00026     hal_init();
00027     radio_init();
00028     LMIC_init();
00029    debug("os_init exit\r\n");
00030 }
00031 
00032 ostime_t os_getTime () 
00033 {
00034     debug("os_getTime enter %d\r\n",hal_ticks());
00035     return hal_ticks();
00036 }
00037 
00038 static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) 
00039 {
00040    debug("unlinkjob enter\r\n");
00041     for( ; *pnext; pnext = &((*pnext)->next)) {
00042         if(*pnext == job) { // unlink
00043             *pnext = job->next;
00044             return 1;
00045         }
00046     }
00047     return 0;
00048 }
00049 
00050 // clear scheduled job
00051 void os_clearCallback (osjob_t* job) 
00052 {
00053    debug("os_clearCallback enter\r\n");
00054     hal_disableIRQs();
00055     unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
00056     hal_enableIRQs();
00057 }
00058 
00059 // schedule immediately runnable job
00060 void os_setCallback (osjob_t* job, osjobcb_t cb) 
00061 {
00062    debug("os_setCallback enter\r\n");
00063     osjob_t** pnext;
00064     hal_disableIRQs();
00065     // remove if job was already queued
00066     os_clearCallback(job);
00067     // fill-in job
00068     job->func = cb;
00069     job->next = NULL;
00070     // add to end of run queue
00071     for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
00072     *pnext = job;
00073     hal_enableIRQs();
00074 }
00075 
00076 // schedule timed job
00077 void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) 
00078 {
00079    debug("os_setTimedCallback enter %d\r\n",time);
00080     osjob_t** pnext;
00081     hal_disableIRQs();
00082     // remove if job was already queued
00083     os_clearCallback(job);
00084     // fill-in job
00085     job->deadline = time;
00086     job->func = cb;
00087     job->next = NULL;
00088     // insert into schedule
00089     for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) {
00090         if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!)
00091             // enqueue before next element and stop
00092             job->next = *pnext;
00093             break;
00094         }
00095     }
00096     *pnext = job;
00097     hal_enableIRQs();
00098 }
00099 
00100 // execute jobs from timer and from run queue
00101 void os_runloop () 
00102 {
00103    debug("os_runloop enter\r\n");
00104     while(1) {
00105         osjob_t* j = NULL;
00106         hal_disableIRQs();
00107         // check for runnable jobs
00108         if(OS.runnablejobs) {
00109             j = OS.runnablejobs;
00110             OS.runnablejobs = j->next;
00111         } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
00112             j = OS.scheduledjobs;
00113             OS.scheduledjobs = j->next;
00114         } else { // nothing pending
00115             hal_sleep(); // wake by irq (timer already restarted)
00116         }
00117         hal_enableIRQs();
00118         if(j) { // run job callback
00119             j->func(j);
00120         }
00121     }
00122 }