summaryrefslogtreecommitdiffstats
path: root/mig_test/software/schedule.c
diff options
context:
space:
mode:
Diffstat (limited to 'mig_test/software/schedule.c')
-rw-r--r--mig_test/software/schedule.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/mig_test/software/schedule.c b/mig_test/software/schedule.c
new file mode 100644
index 0000000..41357eb
--- /dev/null
+++ b/mig_test/software/schedule.c
@@ -0,0 +1,144 @@
+/*
+ * $HeadURL: https://svn.fzd.de/repo/concast/FWF_Projects/FWKE/hw_sp605/bsp_zpuahb/software/schedule.c $
+ * $Date$
+ * $Author$
+ * $Revision$
+ */
+
+#include <types.h>
+#include "schedule.h"
+
+#define MAXTIMERS 10
+#define T_FREE 254 // > MAXTIMERS
+#define T_LAST 255
+
+typedef struct{
+ uint8_t next; // next in list or end mark
+ t_res delta; // delta to previous entry
+ funcp func;
+} t_ctrl_struct;
+
+
+t_ctrl_struct t_ctrl_lst[MAXTIMERS];
+t_res t_delay; // count down until next service
+uint8_t t_first; // point to first entry
+
+
+void scheduler_task_check(void)
+{
+ t_ctrl_struct *p; // for faster access
+
+ --t_delay;
+ while( t_delay == 0 ){ // serve if delay = 0
+ if( t_first == T_LAST ) // no function to serve
+ break;
+ p = &t_ctrl_lst[t_first];
+ t_first = p->next; // point to next
+ p->next = T_FREE; // mark free
+ t_delay = t_ctrl_lst[t_first].delta; // next delay delta
+ p->func(); // execute function
+ }
+}
+
+
+uint8_t scheduler_task_add( funcp func, t_res delay )
+{
+ uint8_t n;
+ uint8_t i; // index
+ uint8_t ipre; // previous index
+ t_res d1; // last delta delay
+ t_ctrl_struct *p; // for faster access
+
+ for( n = 0;; ){
+ p = &t_ctrl_lst[n];
+ if( p->next == T_FREE )
+ break;
+ n++;
+ if( n == MAXTIMERS )
+ return 1; // error, list full
+ }
+
+ i = t_first;
+ d1 = t_delay;
+ while( i != T_LAST ){ // check until end
+ if( d1 >= delay ){ // last >= new
+ t_ctrl_lst[i].delta = d1 - delay; // correct following entry
+ break;
+ }else{
+ delay -= d1; // remaining delay
+ ipre = i; // previous entry
+ i = t_ctrl_lst[i].next; // index of next entry
+ d1 = t_ctrl_lst[i].delta; // next delay delta
+ }
+ } // insert new entry
+
+ p->next = i; // following entry
+ p->delta = delay; // store remaining delay
+ p->func = func;
+
+ if( i == t_first ){ // insert at first
+ t_first = n;
+ t_delay = delay;
+ }else{
+ t_ctrl_lst[ipre].next = n; // previous entry
+ }
+ return 0; // successful
+}
+
+
+uint8_t scheduler_task_remove( funcp func )
+{
+ uint8_t ipre; // previous index
+ uint8_t irem; // index to be removed
+ uint8_t ifol = t_first; // following index
+ t_ctrl_struct *p; // for faster access
+
+ do{
+ if( ifol == T_LAST )
+ return 1; // not found
+ ipre = irem;
+ irem = ifol;
+ p = &t_ctrl_lst[irem];
+ ifol = p->next; // get next
+ }while( p->func != func ); // found it
+
+ p->next = T_FREE; // mark it as free
+ if( irem == t_first ){
+ t_first = ifol; // serve next entry
+ t_delay += t_ctrl_lst[ifol].delta; // correct current delta
+ }else{
+ t_ctrl_lst[ipre].next = ifol; // skip index
+ if( ifol != T_LAST ) // correct following delta
+ t_ctrl_lst[ifol].delta += p->delta;
+ }
+ return 0; // successful
+}
+
+
+void scheduler_init(void)
+{
+ uint8_t i;
+
+ for( i = MAXTIMERS; i; i-- )
+ t_ctrl_lst[i-1].next = T_FREE; // mark all free
+ t_first = T_LAST; // set no timer served
+}
+
+
+uint32_t scheduler_tasklist( void)
+{
+ uint8_t i;
+
+ for( i = MAXTIMERS; i; i-- )
+ {
+ if ( t_ctrl_lst[i-1].next != T_FREE)
+ {
+ putint( i);
+ putstr(": func: ");
+ puthex( 32, t_ctrl_lst[i-1].func);
+ putchar('\n');
+ }
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud