ISIX-RTOS - small operating system for ARM microcontrollers 1.2
|
00001 #include <isix/config.h> 00002 #include <isix/types.h> 00003 #include <isix/memory.h> 00004 #include <isix/semaphore.h> 00005 #include <isix/fifo.h> 00006 #include <prv/semaphore.h> 00007 #include <prv/scheduler.h> 00008 #include <string.h> 00009 #include <prv/fifo.h> 00010 00011 #ifndef ISIX_DEBUG_FIFO 00012 #define ISIX_DEBUG_FIFO ISIX_DBG_OFF 00013 #endif 00014 00015 00016 #if ISIX_DEBUG_FIFO == ISIX_DBG_ON 00017 #include <isix/printk.h> 00018 #else 00019 #define isix_printk(...) 00020 #endif 00021 00022 00023 /*-------------------------------------------------------*/ 00024 /* Create queue for n elements 00025 * if succes return queue pointer else return null 00026 */ 00027 00028 fifo_t* isix_fifo_create(int n_elem, int elem_size) 00029 { 00030 //Create fifo struct 00031 fifo_t *fifo = (fifo_t*)isix_alloc(sizeof(fifo_t)); 00032 if(!fifo) 00033 { 00034 isix_printk("FifoCreate: Error alloc fifo struct\n"); 00035 return NULL; 00036 } 00037 //Set fifo type 00038 fifo->type = IHANDLE_T_FIFO; 00039 //Calculate size 00040 fifo->size = n_elem * elem_size; 00041 //Create used memory struct 00042 fifo->mem_p = (char*)isix_alloc(fifo->size); 00043 if(!fifo->mem_p) 00044 { 00045 isix_printk("FifoCreate: Error alloc data\n"); 00046 isix_free(fifo); 00047 return NULL; 00048 } 00049 //Fill element of structure 00050 fifo->elem_size = elem_size; 00051 fifo->rx_p = fifo->tx_p = fifo->mem_p; 00052 //Create RX sem as 0 element in fifo (task sleep) 00053 isix_sem_create(&fifo->rx_sem,0); 00054 //Create tx sem as numer of element in fifo 00055 isix_sem_create(&fifo->tx_sem,n_elem); 00056 isix_printk("FifoCreate New fifo handler %08x\n",fifo); 00057 return fifo; 00058 } 00059 00060 /*----------------------------------------------------------------*/ 00061 //Fifo send to other task 00062 int isix_fifo_write(fifo_t *fifo,const void *item, tick_t timeout) 00063 { 00064 if(!fifo) return ISIX_EINVARG; 00065 //FIXME tu sie zesralo 00066 if(isix_sem_wait(&fifo->tx_sem,timeout)<0) 00067 { 00068 isix_printk("FifoWrite: Timeout on TX queue\n"); 00069 return ISIX_ETIMEOUT; 00070 } 00071 isixp_enter_critical(); 00072 memcpy(fifo->tx_p,item,fifo->elem_size); 00073 isix_printk("FifoWrite: Data write at TXp %08x\n",fifo->tx_p); 00074 fifo->tx_p+= fifo->elem_size; 00075 if(fifo->tx_p >= fifo->mem_p+fifo->size) fifo->tx_p = fifo->mem_p; 00076 isixp_exit_critical(); 00077 isix_printk("FifoWrite: New TXp %08x\n",fifo->tx_p); 00078 //Signaling RX thread with new data 00079 return isix_sem_signal(&fifo->rx_sem); 00080 } 00081 /*----------------------------------------------------------------*/ 00082 //Fifo send to other task 00083 int isix_fifo_write_isr(fifo_t *fifo,const void *item) 00084 { 00085 if(!fifo) return ISIX_EINVARG; 00086 if(isix_sem_get_isr(&fifo->tx_sem)<0) 00087 { 00088 isix_printk("FifoWriteISR: No space in TX queue\n"); 00089 return ISIX_EFIFOFULL; 00090 } 00091 isixp_enter_critical(); 00092 memcpy(fifo->tx_p,item,fifo->elem_size); 00093 isix_printk("FifoWriteISR: Data write at TXp %08x\n",fifo->tx_p); 00094 fifo->tx_p+= fifo->elem_size; 00095 if(fifo->tx_p >= fifo->mem_p+fifo->size) fifo->tx_p = fifo->mem_p; 00096 isixp_exit_critical(); 00097 isix_printk("FifoWriteISR: New TXp %08x\n",fifo->tx_p); 00098 //Signaling RX thread with new data 00099 return isix_sem_signal_isr(&fifo->rx_sem); 00100 } 00101 /*----------------------------------------------------------------*/ 00102 //Fifo receive from other task 00103 int isix_fifo_read(fifo_t *fifo,void *item, tick_t timeout) 00104 { 00105 if(!fifo) return ISIX_EINVARG; 00106 if(isix_sem_wait(&fifo->rx_sem,timeout)<0) 00107 { 00108 isix_printk("FifoRead: Timeout on RX queue\n"); 00109 return ISIX_ETIMEOUT; 00110 } 00111 isixp_enter_critical(); 00112 memcpy(item,fifo->rx_p,fifo->elem_size); 00113 isix_printk("FifoRead: Data write at RXp %08x\n",fifo->rx_p); 00114 fifo->rx_p+= fifo->elem_size; 00115 if(fifo->rx_p >= fifo->mem_p+fifo->size) fifo->rx_p = fifo->mem_p; 00116 isixp_exit_critical(); 00117 isix_printk("FifoRead: New Rxp %08x\n",fifo->rx_p); 00118 //Signaling TX for space avail 00119 return isix_sem_signal(&fifo->tx_sem); 00120 } 00121 00122 /*----------------------------------------------------------------*/ 00123 //Fifo receive from other task 00124 int isix_fifo_read_isr(fifo_t *fifo,void *item) 00125 { 00126 if(!fifo) return ISIX_EINVARG; 00127 if(isix_sem_get_isr(&fifo->rx_sem)<0) 00128 { 00129 isix_printk("FifoReadISR: No space in RX queue\n"); 00130 return ISIX_EFIFOFULL; 00131 } 00132 isixp_enter_critical(); 00133 memcpy(item,fifo->rx_p,fifo->elem_size); 00134 isix_printk("FifoReadISR: Data write at RXp %08x\n",fifo->rx_p); 00135 fifo->rx_p+= fifo->elem_size; 00136 if(fifo->rx_p >= fifo->mem_p+fifo->size) fifo->rx_p = fifo->mem_p; 00137 isixp_exit_critical(); 00138 isix_printk("FifoReadISR: New Rxp %08x\n",fifo->rx_p); 00139 //Signaling TX for space avail 00140 return isix_sem_signal_isr(&fifo->tx_sem); 00141 } 00142 00143 /*----------------------------------------------------------------*/ 00144 /* Delete created queue */ 00145 int isix_fifo_destroy(fifo_t *fifo) 00146 { 00147 isixp_enter_critical(); 00148 //Check for TXSEM ban be destroyed 00149 if(isixp_sem_can_destroy(&fifo->tx_sem)==false) 00150 { 00151 isix_printk("FifoDestroy: Error TXSem busy\n"); 00152 isixp_exit_critical(); 00153 return ISIX_EBUSY; 00154 } 00155 //Check for RXSEM can be destroyed 00156 if(isixp_sem_can_destroy(&fifo->rx_sem)==false) 00157 { 00158 isix_printk("FifoDestroy: Error RXSem busy\n"); 00159 isixp_exit_critical(); 00160 return ISIX_EBUSY; 00161 } 00162 //Destroy RXSEM and TXSEM 00163 isix_sem_destroy(&fifo->rx_sem); 00164 isix_sem_destroy(&fifo->tx_sem); 00165 //Free queue used memory 00166 isix_free(fifo->mem_p); 00167 isix_free(fifo); 00168 isixp_exit_critical(); 00169 return ISIX_EOK; 00170 } 00171 00172 /*----------------------------------------------------------------*/ 00173 //How many element is in fifo 00174 int isix_fifo_count(fifo_t *fifo) 00175 { 00176 if(!fifo) return ISIX_EINVARG; 00177 return isix_sem_getval(&fifo->rx_sem); 00178 } 00179 00180 /*----------------------------------------------------------------*/ 00181