test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aioif.c Source File

aioif.c

00001 /******************************************************************************
00002  *
00003  * $Rev: $
00004  * $Date::                           $
00005  *
00006  * Description : ITRON support functions for IOIF Asynchronous I/O header file
00007  *
00008  * (C) Copyright RENESAS ELECTRONICS EUROPE Ltd 2012 All Rights Reserved
00009  *****************************************************************************/
00010 
00011 /*************************************************************************
00012  System Includes
00013 *************************************************************************/
00014 
00015 #include <r_errno.h>
00016 #include <cmsis_os.h>
00017 #include <aioif.h>
00018 #if(1) /* mbed */
00019 #include "cmsis.h"
00020 #include "mbed_critical.h"
00021 #else  /* not mbed */
00022 #include <ipcb.h>
00023 #include <ioif_aio_helper.h>
00024 #endif /* end mbed */
00025 #include <misratypes.h>
00026 #include "bsp_drv_cmn.h"
00027 #if defined (__ICCARM__)
00028 #include <intrinsics.h>
00029 #endif
00030 
00031 /*************************************************************************
00032  OS Resources
00033 *************************************************************************/
00034 
00035 
00036 /*************************************************************************
00037  Functions
00038 *************************************************************************/
00039 static void ahf_lock(AHF_S * const ahf);
00040 static void ahf_unlock(AHF_S * const ahf);
00041 
00042 static void ahf_lock(AHF_S * const ahf)
00043 {
00044     if(ahf->flags & AHF_LOCKSEM)
00045     {
00046         osMutexAcquire(ahf->semid, 0);
00047     }
00048     else if (ahf->flags & AHF_LOCKINT)
00049     {
00050         core_util_critical_section_enter();
00051     }
00052     else
00053     {
00054         ;   /* MISRA compliance. */
00055     }
00056 }
00057 
00058 static void ahf_unlock(AHF_S * const ahf)
00059 {
00060     if(ahf->flags & AHF_LOCKSEM)
00061     {
00062         osMutexRelease(ahf->semid);
00063     }
00064     else if (ahf->flags & AHF_LOCKINT)
00065     {
00066         core_util_critical_section_exit();
00067     }
00068     else
00069     {
00070         ;   /* MISRA compliance. */
00071     }
00072 }
00073 
00074 /***********************************************************************************
00075 Function Name:         ahf_create
00076 
00077 Description:    Creates an empty aio control queue pointer.
00078                 Creates a mutex if AHF_CREATESEM bit flag is set.
00079 
00080 Parameters:     ahf  - aio queue structure pointer.
00081                 f    - flag indicating that at semaphore is to be created.
00082 
00083 Return value:   0 on success.   negative error code on error.
00084 ***********************************************************************************/
00085 int32_t ahf_create (AHF_S * const ahf, const uint32_t f)
00086 {
00087     osMutexAttr_t* p_mutex_def;
00088     uint32_t*     p_mutex_data;
00089 
00090     if (ahf == NULL)
00091     {
00092         return EFAULT_RBSP;
00093     }
00094 
00095     ahf->head = NULL;
00096     ahf->tail = NULL;
00097     ahf->flags = f;
00098 
00099     /* create the mutex if required */
00100     if (f & AHF_CREATESEM)
00101     {
00102 #if defined (__GNUC__)
00103         /* disable all irq */
00104         core_util_critical_section_enter();
00105 #endif/*__GNUC__*/
00106         p_mutex_def = calloc(1, sizeof(osMutexAttr_t));
00107 #if defined (__GNUC__)
00108         /* enable all irq */
00109         core_util_critical_section_exit();
00110 #endif/*__GNUC__*/
00111         if ( NULL == p_mutex_def )
00112         {
00113             return ENOMEM_RBSP;
00114         }
00115 #if defined (__GNUC__)
00116         /* disable all irq */
00117         core_util_critical_section_enter();
00118 #endif/*__GNUC__*/
00119         p_mutex_data = calloc(7, sizeof(uint32_t));
00120 #if defined (__GNUC__)
00121         /* enable all irq */
00122         core_util_critical_section_exit();
00123 #endif/*__GNUC__*/
00124         if ( NULL == p_mutex_data )
00125         {
00126 #if defined (__GNUC__)
00127             /* disable all irq */
00128             core_util_critical_section_enter();
00129 #endif/*__GNUC__*/
00130             free(p_mutex_def);
00131 #if defined (__GNUC__)
00132             /* enable all irq */
00133             core_util_critical_section_exit();
00134 #endif/*__GNUC__*/
00135             return ENOMEM_RBSP;
00136         }
00137         p_mutex_def->cb_mem = p_mutex_data;
00138         ahf->p_cmtx = p_mutex_def;
00139         ahf->semid = osMutexNew (p_mutex_def);
00140         if ( NULL == ahf->semid )
00141         {
00142 #if defined (__GNUC__)
00143             /* disable all irq */
00144             core_util_critical_section_enter();
00145 #endif/*__GNUC__*/
00146             free(p_mutex_data);
00147             free(p_mutex_def);
00148 #if defined (__GNUC__)
00149             /* enable all irq */
00150             core_util_critical_section_exit();
00151 #endif/*__GNUC__*/
00152             return ENOMEM_RBSP;
00153         }
00154     }
00155 
00156     return 0;
00157 }
00158 
00159 /***********************************************************************************
00160 Function Name:         ahf_destroy
00161 
00162 Description:    Delete aio control block mutex (if it exists).
00163                 Note: This function does not delete the aio control block queue.
00164 
00165 Parameters:     ahf  - aio queue structure pointer.
00166 
00167 Return value:   void
00168 
00169 ***********************************************************************************/
00170 void ahf_destroy (AHF_S const * const ahf)
00171 {
00172     if (ahf == NULL)
00173     {
00174         return;
00175     }
00176 
00177     if (ahf->flags & AHF_CREATESEM)
00178     {
00179         osMutexDelete (ahf->semid);
00180 #if defined (__GNUC__)
00181         /* disable all irq */
00182         core_util_critical_section_enter();
00183 #endif/*__GNUC__*/
00184         free(ahf->p_cmtx->cb_mem);
00185         free(ahf->p_cmtx);
00186 #if defined (__GNUC__)
00187         /* enable all irq */
00188         core_util_critical_section_exit();
00189 #endif/*__GNUC__*/
00190     }
00191 }
00192 
00193 /***********************************************************************************
00194 Function Name:         ahf_addtail
00195 
00196 Description:    Add an aio control block to the queue.
00197 
00198 Parameters:     ahf  - aio queue structure pointer.
00199                 aio  - pointer to queue structure.
00200 
00201 Return value:   void
00202 
00203 ***********************************************************************************/
00204 void ahf_addtail (AHF_S * const ahf, struct aiocb * const aio)
00205 {
00206     if (ahf == NULL)
00207     {
00208         return;
00209     }
00210 
00211     ahf_lock (ahf);
00212     if (ahf->tail != NULL)
00213     {
00214         ahf->tail->pNext = aio;
00215     }
00216     aio->pPrev = ahf->tail;
00217     aio->pNext = NULL;
00218     ahf->tail = aio;
00219     if (ahf->head == NULL)
00220     {
00221         /* list was empty */
00222         ahf->head = aio;
00223     }
00224 
00225     ahf_unlock (ahf);
00226 }
00227 
00228 /***********************************************************************************
00229 Function Name:         ahf_removehead
00230 
00231 Description:    Remove an aio control block from the queue.
00232 
00233 Parameters:     ahf  - aio queue structure pointer.
00234 
00235 Return value:   aio control block, or NULL if queue is empty.
00236 
00237 ***********************************************************************************/
00238 struct aiocb *ahf_removehead (AHF_S * const ahf)
00239 {
00240     struct aiocb *aio;
00241 
00242     if (ahf == NULL)
00243     {
00244         return(NULL);
00245     }
00246 
00247     ahf_lock (ahf);
00248 
00249     aio = ahf->head;
00250     if (aio != NULL)
00251     {
00252         ahf->head = aio->pNext;
00253         if (aio->pNext != NULL)
00254         {
00255             aio->pNext->pPrev = NULL;
00256         }
00257         if (ahf->tail == aio)
00258         {
00259             /* the list is now empty */
00260             ahf->tail = NULL;
00261         }
00262     }
00263 
00264     ahf_unlock (ahf);
00265     return aio;
00266 }
00267 
00268 /***********************************************************************************
00269 Function Name:         ahf_peekhead
00270 
00271 Description:    Get an aio control block from the queue, but do not remove from the queue.
00272 
00273 Parameters:     ahf  - aio queue structure pointer.
00274 
00275 Return value:   aio control block, or NULL if queue is empty.
00276 
00277 ***********************************************************************************/
00278 struct aiocb *ahf_peekhead (AHF_S * const ahf)
00279 {
00280     struct aiocb *aio;
00281 
00282     ahf_lock (ahf);
00283 
00284     aio = ahf->head;
00285 
00286     ahf_unlock (ahf);
00287     return aio;
00288 }
00289 
00290 /***********************************************************************************
00291 Function Name:         ahf_cancelall
00292 
00293 Description:    Empty an aio control block queue.
00294 
00295 Parameters:     ahf  - aio queue structure pointer.
00296 
00297 Return value:   void
00298 
00299 ***********************************************************************************/
00300 void ahf_cancelall (AHF_S * const ahf)
00301 {
00302     struct aiocb *cur, *next;
00303 
00304     ahf_lock (ahf);
00305 
00306     /* cancel all pending requests */
00307     cur = ahf->head;
00308     while (cur != NULL)
00309     {
00310         next = cur->pNext;
00311         cur->aio_return = ECANCELED_RBSP;
00312         ahf_complete (ahf, cur);
00313         cur = next;
00314     }
00315     /* mark the list as empty */
00316     ahf->head = NULL;
00317     ahf->tail = NULL;
00318 
00319     ahf_unlock (ahf);
00320 }
00321 
00322 /***********************************************************************************
00323 Function Name:         ahf_complete
00324 
00325 Description:    Flag that the operation is complete.
00326                 If required by the sigev_notify variable contents, the calling task is
00327                 notified.
00328                 If a notify was setup, it is signalled.
00329 
00330 Parameters:     ahf  - aio queue structure pointer.
00331                 aio  - pointer to queue structure.
00332 
00333 Return value:   0 on success.   negative error code on error.
00334 
00335 ***********************************************************************************/
00336 void ahf_complete (AHF_S *ahf, struct aiocb * const aio)
00337 {
00338 #if(1) /* mbed */
00339 #else  /* not mbed */
00340     int rv;
00341 #endif /* end mbed */
00342     UNUSED_ARG(ahf);
00343 
00344     if (NULL == aio)
00345     {
00346         return;
00347     }
00348 
00349     /* Flag that the operation is complete */
00350     /*  This function must be here
00351         because another task may release AIOCB block
00352         after the task changed by an iTRON function in the switch statement */
00353     aio->aio_complete = 1;
00354     switch (aio->aio_sigevent.sigev_notify)
00355     {
00356     case SIGEV_EVENT:
00357          osSignalSet ((osThreadId_t)aio->aio_sigevent.sigev_value.sival_int,
00358              (int32_t)aio->aio_sigevent.sigev_signo);
00359         break;
00360 
00361     case SIGEV_THREAD:
00362         if (aio->aio_sigevent.sigev_notify_function)
00363         {
00364             (aio->aio_sigevent.sigev_notify_function)
00365                 (aio->aio_sigevent.sigev_value);
00366         }
00367         break;
00368 
00369 #if(1) /* mbed */
00370 #else  /* not mbed */
00371     case SIGEV_CALLBACK:
00372         rv = ipcb_callback ((ipcb_id_t*)aio->aio_sigevent.sigev_signo, &aio->aio_sigevent);
00373         break;
00374 #endif /* end mbed */
00375 
00376     default:
00377         /* No notify function */
00378         break;
00379 
00380     }
00381 
00382     /* Wakeup any suspended tasks */
00383 #if(1) /* mbed */
00384 #else  /* not mbed */
00385     aio_complete_suspended(aio);
00386 #endif /* end mbed */
00387 }
00388 
00389 /***********************************************************************************
00390 Function Name:         ahf_cancel
00391 
00392 Description:    Remove an aio control block from the queue.
00393                 Signal completion to the calling task and wake it up.
00394                 If aio is NULL, cancel all.
00395 
00396 Parameters:     ahf  - aio queue structure pointer.
00397                 aio  - pointer to queue structure.
00398 
00399 Return value:   0 on success.   negative error code on error.
00400 
00401 ***********************************************************************************/
00402 int32_t ahf_cancel (AHF_S * const ahf, struct aiocb * const aio)
00403 {
00404     struct aiocb *cur;
00405     int32_t rv = EINVAL_RBSP;
00406 
00407     if (ahf == NULL)
00408     {
00409         return EFAULT_RBSP;
00410     }
00411 
00412     /* If aio is NULL, must cancel all. */
00413     if(NULL == aio)
00414     {
00415         ahf_cancelall(ahf);
00416         rv = 0;
00417     }
00418 
00419     else
00420     {
00421         ahf_lock (ahf);
00422 
00423         cur = ahf->head;
00424         while ((cur != NULL) && (cur != aio))
00425         {
00426             cur = cur->pNext;
00427         }
00428 
00429         if (cur == aio)
00430         {
00431             if (aio->pPrev != NULL)
00432             {
00433                 aio->pPrev->pNext = aio->pNext;
00434             }
00435 
00436             if (aio->pNext != NULL)
00437             {
00438                 aio->pNext->pPrev = aio->pPrev;
00439             }
00440 
00441             if (ahf->head == cur)
00442             {
00443                 ahf->head = cur->pNext;
00444             }
00445 
00446             if (ahf->tail == cur)
00447             {
00448                 ahf->tail = cur->pPrev;
00449             }
00450 
00451             cur->aio_return = ECANCELED_RBSP;
00452             ahf_complete (ahf, aio);
00453             rv = 0;
00454         }
00455 
00456         ahf_unlock (ahf);
00457     }
00458     return rv;
00459 }