LMiC LoRa Semtech + Nucleo
Fork of LMiC by
Embed:
(wiki syntax)
Show/hide line numbers
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 00014 // RUNTIME STATE 00015 static struct { 00016 osjob_t* scheduledjobs; 00017 osjob_t* runnablejobs; 00018 } OS; 00019 00020 void os_init () { 00021 memset(&OS, 0x00, sizeof(OS)); 00022 hal_init(); 00023 radio_init(); 00024 LMIC_init(); 00025 } 00026 00027 ostime_t os_getTime () { 00028 return hal_ticks(); 00029 } 00030 00031 static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) { 00032 for( ; *pnext; pnext = &((*pnext)->next)) { 00033 if(*pnext == job) { // unlink 00034 *pnext = job->next; 00035 return 1; 00036 } 00037 } 00038 return 0; 00039 } 00040 00041 // clear scheduled job 00042 void os_clearCallback (osjob_t* job) { 00043 hal_disableIRQs(); 00044 unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job); 00045 hal_enableIRQs(); 00046 } 00047 00048 // schedule immediately runnable job 00049 void os_setCallback (osjob_t* job, osjobcb_t cb) { 00050 osjob_t** pnext; 00051 hal_disableIRQs(); 00052 // remove if job was already queued 00053 os_clearCallback(job); 00054 // fill-in job 00055 job->func = cb; 00056 job->next = NULL; 00057 // add to end of run queue 00058 for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next)); 00059 *pnext = job; 00060 hal_enableIRQs(); 00061 } 00062 00063 // schedule timed job 00064 void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) { 00065 osjob_t** pnext; 00066 hal_disableIRQs(); 00067 // remove if job was already queued 00068 os_clearCallback(job); 00069 // fill-in job 00070 job->deadline = time; 00071 job->func = cb; 00072 job->next = NULL; 00073 // insert into schedule 00074 for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) { 00075 if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!) 00076 // enqueue before next element and stop 00077 job->next = *pnext; 00078 break; 00079 } 00080 } 00081 *pnext = job; 00082 hal_enableIRQs(); 00083 } 00084 00085 // execute jobs from timer and from run queue 00086 void os_runloop () { 00087 while(1) { 00088 osjob_t* j = NULL; 00089 hal_disableIRQs(); 00090 // check for runnable jobs 00091 if(OS.runnablejobs) { 00092 j = OS.runnablejobs; 00093 OS.runnablejobs = j->next; 00094 } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs 00095 j = OS.scheduledjobs; 00096 OS.scheduledjobs = j->next; 00097 } else { // nothing pending 00098 hal_sleep(); // wake by irq (timer already restarted) 00099 } 00100 hal_enableIRQs(); 00101 if(j) { // run job callback 00102 j->func(j); 00103 } 00104 } 00105 }
Generated on Tue Jul 12 2022 20:31:35 by 1.7.2