RZ/A1H CMSIS-RTOS RTX BSP for GR-PEACH.

Dependents:   R_BSP_SSIF_HelloWorld GR-PEACH_Azure_Speech ImageZoomInout_Sample ImageRotaion_Sample ... more

Fork of R_BSP by Daiki Kato

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aioif.c Source File

aioif.c

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