ISIX-RTOS - small operating system for ARM microcontrollers 1.2

irqtimers.c

Go to the documentation of this file.
00001 /*
00002  * irqtimers.c
00003  *
00004  *  Created on: 05-03-2011
00005  *      Author: lucck
00006  */
00007 /*-----------------------------------------------------------------------*/
00008 #include <prv/irqtimers.h>
00009 #include <isix/irqtimers.h>
00010 #include <isix/memory.h>
00011 #include <prv/list.h>
00012 #include <prv/scheduler.h>
00013 #include <string.h>
00014 
00015 /*-----------------------------------------------------------------------*/
00016 #ifdef ISIX_CONFIG_USE_TIMERS   //If timers are enabled
00017 /*-----------------------------------------------------------------------*/
00018 //List entry for the virtual timers
00019 static list_entry_t vtimer_list[2];
00020 //Overflowed and not overflowed list
00021 static list_entry_t *p_vtimer_list;
00022 static list_entry_t *pov_vtimer_list;
00023 /*-----------------------------------------------------------------------*/
00024 //Initialize vtimers infrastructure
00025 void isixp_vtimer_init(void)
00026 {
00027         list_init( &vtimer_list[0] );
00028         list_init( &vtimer_list[1] );
00029         //Initialize overflow waiting list
00030         p_vtimer_list = &vtimer_list[0];
00031         pov_vtimer_list = &vtimer_list[1];
00032 }
00033 
00034 /*-----------------------------------------------------------------------*/
00035 //Move selected task to waiting list
00036 static void add_vtimer_to_list(vtimer_t *timer)
00037 {
00038     //Scheduler lock
00039     isixp_enter_critical();
00040     timer->jiffies = isix_get_jiffies() + timer->timeout;
00041     if(timer->jiffies < isix_get_jiffies())
00042     {
00043         //Insert on overflow waiting list in time order
00044         vtimer_t *waitl;
00045         list_for_each_entry(pov_vtimer_list,waitl,inode)
00046         {
00047            if(timer->jiffies<waitl->jiffies) break;
00048         }
00049         list_insert_before(&waitl->inode,&timer->inode);
00050     }
00051     else
00052     {
00053         //Insert on waiting list in time order no overflow
00054         vtimer_t *waitl;
00055         list_for_each_entry(p_vtimer_list,waitl,inode)
00056         {
00057             if(timer->jiffies<waitl->jiffies) break;
00058         }
00059         list_insert_before(&waitl->inode,&timer->inode);
00060     }
00061     //Scheduler unlock
00062     isixp_exit_critical();
00063 }
00064 
00065 /*-----------------------------------------------------------------------*/
00066 //Call timer funcs in the interrupt context
00067 void isixp_vtimer_handle_time(tick_t jiffies)
00068 {
00069         if(jiffies == 0)
00070         {
00071            list_entry_t *tmp = p_vtimer_list;
00072            p_vtimer_list = pov_vtimer_list;
00073            pov_vtimer_list = tmp;
00074         }
00075         vtimer_t *vtimer;
00076         while( !list_isempty(p_vtimer_list) &&
00077                         jiffies>=(vtimer = list_get_first(p_vtimer_list,inode,vtimer_t))->jiffies
00078               )
00079         {
00080                 vtimer->timer_handler( vtimer->arg );
00081                 list_delete(&vtimer->inode);
00082                 add_vtimer_to_list(vtimer);
00083         }
00084 }
00085 
00086 /*-----------------------------------------------------------------------*/
00087 //Create the virtual timer
00088 vtimer_t* isix_vtimer_create(void (*func)(void*),void *arg )
00089 {
00090         vtimer_t * const timer = (vtimer_t*)isix_alloc(sizeof(vtimer_t));
00091         if( func == NULL )  return NULL;
00092     if( timer == NULL ) return NULL;
00093     memset( timer, 0, sizeof(*timer) );
00094     timer->arg = arg;
00095     timer->timer_handler = func;
00096     return timer;
00097 }
00098 
00099 /*-----------------------------------------------------------------------*/
00100 //Start the virtual timer
00101 int isix_vtimer_start(vtimer_t* timer, tick_t timeout)
00102 {
00103         if( timer == NULL ) return ISIX_EINVARG;
00104         isixp_enter_critical();
00105         //Search on ov list
00106         if( list_is_elem_assigned( &timer->inode ) )
00107         {
00108                 list_delete( &timer->inode );
00109         }
00110         //Add timer to waiting list
00111         if( timeout > 0 )
00112         {
00113                 timer->timeout = timeout;
00114                 add_vtimer_to_list( timer );
00115         }
00116         isixp_exit_critical();
00117         return ISIX_EOK;
00118 }
00119 
00120 /*-----------------------------------------------------------------------*/
00121 //Destroy the virtual timer
00122 int isix_vtimer_destroy(vtimer_t* timer)
00123 {
00124         if( timer == NULL ) return ISIX_EINVARG;
00125         isixp_enter_critical();
00126         if( list_is_elem_assigned( &timer->inode ) )
00127         {
00128                 isixp_exit_critical();
00129                 return ISIX_EBUSY;
00130         }
00131         isix_free( timer );
00132         isixp_exit_critical();
00133         return ISIX_EOK;
00134 }
00135 /*-----------------------------------------------------------------------*/
00136 
00137 
00138 #endif /* ISIX_CONFIG_USE_TIMERS */
00139 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines