Graphics framework for GR-PEACH. When you use this program, we judge you have agreed to the following contents. https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE

Dependents:   ImageZoomInout_Sample ImageRotaion_Sample ImageScroll_Sample GR-PEACH_LCD_4_3inch_Save_to_USB ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers r_ospl.c Source File

r_ospl.c

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * DISCLAIMER
00003 * This software is supplied by Renesas Electronics Corporation and is only
00004 * intended for use with Renesas products. No other uses are authorized. This
00005 * software is owned by Renesas Electronics Corporation and is protected under
00006 * all applicable laws, including copyright laws.
00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
00016 * Renesas reserves the right, without notice, to make changes to this software
00017 * and to discontinue the availability of this software. By using this software,
00018 * you agree to the additional terms and conditions found by accessing the
00019 * following link:
00020 * http://www.renesas.com/disclaimer
00021 * Copyright (C) 2012 - 2015 Renesas Electronics Corporation. All rights reserved.
00022 *******************************************************************************/
00023 /**
00024 * @file  r_ospl.c
00025 * @brief   OS Porting Layer. Functions not depended on any environment.
00026 *
00027 * $Module: OSPL $ $PublicVersion: 0.90 $ (=R_OSPL_VERSION)
00028 * $Rev: 35 $
00029 * $Date:: 2014-04-15 21:38:18 +0900#$
00030 */
00031 
00032 
00033 /******************************************************************************
00034 Includes   <System Includes> , "Project Includes"
00035 ******************************************************************************/
00036 #include  "r_ospl.h"
00037 #include  "iodefine.h"
00038 #include  "iobitmasks/cpg_iobitmask.h"
00039 #include  "r_ospl_private.h"
00040 #include  "r_ospl_os_less_private.h"
00041 #if R_OSPL_IS_PREEMPTION
00042 #include  "r_ospl_RTX_private.h"
00043 #endif
00044 #include  "locking.h"
00045 #ifdef __ICCARM__
00046 #include <intrinsics.h>
00047 #endif
00048 #ifdef  __GNUC__
00049 #if ! IS_MBED_USED
00050 #include  "irq.h"
00051 #endif
00052 #endif
00053 #if R_OSPL_DEBUG_TOOL
00054 #include  <stdio.h>
00055 #endif
00056 #ifndef R_OSPL_NDEBUG
00057 #include  <string.h>
00058 #endif
00059 
00060 
00061 /******************************************************************************
00062 Typedef definitions
00063 ******************************************************************************/
00064 
00065 /******************************************************************************
00066 Macro definitions
00067 ******************************************************************************/
00068 
00069 /******************************************************************************
00070 Imported global variables and functions (from other files)
00071 ******************************************************************************/
00072 
00073 /******************************************************************************
00074 Exported global variables and functions (to be accessed by other files)
00075 ******************************************************************************/
00076 
00077 /******************************************************************************
00078 Private global variables and functions
00079 ******************************************************************************/
00080 
00081 static void  R_OSPL_TABLE_Search_Sub( const r_ospl_table_t *self,
00082                                       const void *Key, r_ospl_table_searched_t *out_Searched );
00083 
00084 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
00085 static r_ospl_error_t  *R_OSPL_GetCurrentThreadError_Sub( r_ospl_if_not_t TypeOfIfNot );
00086 #endif
00087 
00088 
00089 /**
00090 * @def  R_OSPL_DEFAULT_DEBUG_THREAD_COUNT
00091 * @brief  For until calling "R_OSPL_SET_DEBUG_WORK"
00092 * @par Parameters
00093 *    None
00094 * @return  None.
00095 */
00096 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
00097 #define  R_OSPL_DEFAULT_DEBUG_THREAD_COUNT  2
00098 #endif
00099 
00100 
00101 /** For until calling "R_OSPL_SET_DEBUG_WORK" */
00102 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
00103 static r_ospl_table_block_t  gs_thread_index_table_body[ R_OSPL_DEFAULT_DEBUG_THREAD_COUNT ];
00104 #endif
00105 
00106 
00107 /** For until calling "R_OSPL_SET_DEBUG_WORK" */
00108 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
00109 static r_ospl_error_t  gs_error;
00110 #endif
00111 
00112 
00113 /** as <r_ospl_global_error_t> */
00114 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
00115 
00116 /* ->MISRA 8.7 : If not defined R_OSPL_ERROR_BREAK, this is referenced by only 1 function. */ /* ->SEC M2.2.1 */
00117 static r_ospl_global_error_t  gs_global_error =
00118     /* <-MISRA 8.7 */ /* <-SEC M2.2.1 */
00119 {
00120     {                                     /* .ThreadIndexTable */
00121         gs_thread_index_table_body,          /* .Area */
00122         0,                                   /* .Count */
00123         R_OSPL_DEFAULT_DEBUG_THREAD_COUNT,   /* .MaxCount */
00124         NULL,                                /* .KeyCache */
00125         0,                                   /* .IndexCache */
00126         0,                                   /* .FirstFreeIndex */
00127 #if R_OSPL_IS_PREEMPTION
00128         true                                 /* .Is_T_Lock */
00129 #endif
00130     },
00131     &gs_error,  /* .ErrorArray */
00132 
00133 #if R_OSPL_ERROR_BREAK
00134     0,          /* .RaisedGlobalErrorID */  /* Necessary T-Lock */
00135     0           /* .BreakGlobalErrorID */
00136 #endif
00137 };
00138 #endif
00139 
00140 
00141 /***********************************************************************
00142 * Implement: R_OSPL_GetVersion
00143 ************************************************************************/
00144 int32_t  R_OSPL_GetVersion(void)
00145 {
00146     return  R_OSPL_VERSION;
00147 }
00148 
00149 
00150 /***********************************************************************
00151 * Implement: R_OSPL_IsPreemption
00152 ************************************************************************/
00153 bool_t  R_OSPL_IsPreemption(void)
00154 {
00155     return  R_OSPL_IS_PREEMPTION;
00156 }
00157 
00158 
00159 /***********************************************************************
00160 * Implement: R_OSPL_FLAG32_InitConst
00161 ************************************************************************/
00162 void  R_OSPL_FLAG32_InitConst( volatile r_ospl_flag32_t *const  self )
00163 {
00164     IF_DQ( self == NULL ) {
00165         goto fin;
00166     }
00167 
00168     self->Flags = 0;
00169 
00170 fin:
00171     return;
00172 }
00173 
00174 
00175 /***********************************************************************
00176 * Implement: R_OSPL_FLAG32_Set
00177 ************************************************************************/
00178 void  R_OSPL_FLAG32_Set( volatile r_ospl_flag32_t *const  self, bit_flags32_t const  SetFlags )
00179 {
00180     IF_DQ( self == NULL ) {
00181         goto fin;
00182     }
00183 
00184     self->Flags |= SetFlags;
00185 
00186 fin:
00187     return;
00188 }
00189 
00190 
00191 /***********************************************************************
00192 * Implement: R_OSPL_FLAG32_Clear
00193 ************************************************************************/
00194 void  R_OSPL_FLAG32_Clear( volatile r_ospl_flag32_t *const  self, bit_flags32_t const  ClearFlags1 )
00195 {
00196     IF_DQ( self == NULL ) {
00197         goto fin;
00198     }
00199 
00200     self->Flags &= ~ClearFlags1;
00201 
00202 fin:
00203     return;
00204 }
00205 
00206 
00207 /***********************************************************************
00208 * Implement: R_OSPL_FLAG32_Get
00209 ************************************************************************/
00210 bit_flags32_t  R_OSPL_FLAG32_Get( volatile const r_ospl_flag32_t *const  self )
00211 {
00212     bit_flags32_t  return_value;
00213 
00214     IF_DQ( self == NULL ) {
00215         return_value = 0;
00216         goto fin;
00217     }
00218 
00219     return_value = self->Flags;
00220 
00221 fin:
00222     return  return_value;
00223 }
00224 
00225 
00226 /***********************************************************************
00227 * Implement: R_OSPL_FLAG32_GetAndClear
00228 ************************************************************************/
00229 bit_flags32_t  R_OSPL_FLAG32_GetAndClear( volatile r_ospl_flag32_t *const  self )
00230 {
00231     bit_flags32_t  return_value;
00232 
00233     IF_DQ( self == NULL ) {
00234         return_value = 0;
00235         goto fin;
00236     }
00237 
00238     return_value = self->Flags;
00239     self->Flags = 0;
00240 
00241 fin:
00242     return  return_value;
00243 }
00244 
00245 
00246 /***********************************************************************
00247 * Implement: R_OSPL_ASYNC_CopyExceptAThread
00248 ************************************************************************/
00249 void  R_OSPL_ASYNC_CopyExceptAThread( const r_ospl_async_t *const  Source,
00250                                       r_ospl_async_t *const  Destination )
00251 {
00252     IF_DQ( Destination == NULL ) {
00253         goto fin;
00254     }
00255     IF_DQ( Source == NULL ) {
00256         goto fin;
00257     }
00258 
00259     *Destination = *Source;
00260     Destination->A_Thread = NULL;
00261 
00262 fin:
00263     return;
00264 }
00265 
00266 
00267 /***********************************************************************
00268 * Implement: R_OSPL_EnableAllInterrupt
00269 ************************************************************************/
00270 void  R_OSPL_EnableAllInterrupt(void)
00271 {
00272     __enable_irq();
00273 }
00274 
00275 
00276 /***********************************************************************
00277 * Implement: R_OSPL_DisableAllInterrupt
00278 ************************************************************************/
00279 bool_t  R_OSPL_DisableAllInterrupt(void)
00280 {
00281 #ifdef __ICCARM__
00282     bool_t  was_enabled = ( ( __get_interrupt_state() & 0x80 ) == 0 );
00283     __disable_irq();
00284     return  was_enabled;
00285 #else
00286     return  (bool_t)( __disable_irq() == 0 );
00287 #endif
00288 }
00289 
00290 
00291 /***********************************************************************
00292 * Implement: R_BSP_InterruptsEnable
00293 ************************************************************************/
00294 void  R_BSP_InterruptsEnable(void)
00295 {
00296     __enable_irq();
00297 }
00298 
00299 
00300 /***********************************************************************
00301 * Implement: R_BSP_InterruptsDisable
00302 ************************************************************************/
00303 void  R_BSP_InterruptsDisable(void)
00304 {
00305 #ifdef __ICCARM__
00306     __disable_irq();
00307 #else
00308     int_fast32_t  ret;
00309 
00310     ret = __disable_irq();
00311     R_UNREFERENCED_VARIABLE( ret );  /* QAC 3200 : This is not error information */
00312 #endif
00313 }
00314 
00315 
00316 /***********************************************************************
00317 * Implement: R_OSPL_LockChannel
00318 ************************************************************************/
00319 errnum_t  R_OSPL_LockChannel( int_fast32_t ChannelNum, int_fast32_t *out_ChannelNum,
00320                               mcu_lock_t  HardwareIndexMin,  mcu_lock_t  HardwareIndexMax )
00321 {
00322     errnum_t    e;
00323     bool_t      is_success;
00324     mcu_lock_t  hardware_index;
00325 
00326     ASSERT_D( HardwareIndexMin <= HardwareIndexMax,  e=E_OTHERS; goto fin );
00327 
00328     if ( ChannelNum == R_OSPL_UNLOCKED_CHANNEL ) {
00329         ASSERT_D( out_ChannelNum != NULL,  e=E_OTHERS; goto fin );
00330 
00331 #if BSP_CFG_USER_LOCKING_ENABLED
00332         for ( hardware_index = HardwareIndexMin;  hardware_index <= HardwareIndexMax;
00333                 hardware_index += 1 ) {
00334             is_success = R_BSP_HardwareLock( hardware_index );
00335             if ( is_success ) {
00336                 break;
00337             }
00338         }
00339         IF ( hardware_index > HardwareIndexMax ) {
00340             e=E_FEW_ARRAY;
00341             goto fin;
00342         }
00343 #else
00344         e= R_OSPL_LockUnlockedChannel( out_ChannelNum,
00345                                        HardwareIndexMin, HardwareIndexMax );
00346         IF(e) {
00347             goto fin;
00348         }
00349         out_ChannelNum = NULL;
00350 #endif
00351     } else {
00352         hardware_index = (mcu_lock_t)( HardwareIndexMin + ChannelNum );
00353 
00354         IF_D ( hardware_index < HardwareIndexMin  ||  hardware_index > HardwareIndexMax ) {
00355             e=E_FEW_ARRAY;
00356             goto fin;
00357         }
00358 
00359         is_success = R_BSP_HardwareLock( hardware_index );
00360         IF ( ! is_success ) {
00361             e=E_ACCESS_DENIED;
00362             goto fin;
00363         }
00364     }
00365 
00366     if ( out_ChannelNum != NULL ) {
00367         *out_ChannelNum = hardware_index - HardwareIndexMin;
00368     }
00369 
00370     e=0;
00371 fin:
00372     return  e;
00373 }
00374 
00375 
00376 /***********************************************************************
00377 * Implement: R_OSPL_UnlockChannel
00378 ************************************************************************/
00379 errnum_t  R_OSPL_UnlockChannel( int_fast32_t ChannelNum,  errnum_t  e,
00380                                 mcu_lock_t  HardwareIndexMin,  mcu_lock_t  HardwareIndexMax )
00381 {
00382     bool_t      is_success;
00383     mcu_lock_t  hardware_index;
00384 
00385     ASSERT_D( HardwareIndexMin <= HardwareIndexMax,  e= R_OSPL_MergeErrNum( e, E_OTHERS ) );
00386 
00387     hardware_index = (mcu_lock_t)( HardwareIndexMin + ChannelNum );
00388 
00389     if ( hardware_index >= HardwareIndexMin  &&  hardware_index <= HardwareIndexMax ) {
00390         is_success = R_BSP_HardwareUnlock( hardware_index );
00391         IF ( ! is_success ) {
00392             e= R_OSPL_MergeErrNum( e, E_ACCESS_DENIED );
00393         }
00394     }
00395 
00396     return  e;
00397 }
00398 
00399 
00400 /***********************************************************************
00401 * Implement: R_OSPL_C_LOCK_InitConst
00402 ************************************************************************/
00403 void  R_OSPL_C_LOCK_InitConst( r_ospl_c_lock_t *const  self )
00404 {
00405     IF_DQ( self == NULL ) {
00406         goto fin;
00407     }
00408 
00409     self->IsLocked = false;
00410 
00411 fin:
00412     return;
00413 }
00414 
00415 
00416 /***********************************************************************
00417 * Implement: R_OSPL_C_LOCK_Lock
00418 ************************************************************************/
00419 errnum_t  R_OSPL_C_LOCK_Lock( r_ospl_c_lock_t *const  self )
00420 {
00421     errnum_t  e;
00422 
00423     IF_DQ( self == NULL ) {
00424         e=E_OTHERS;
00425         goto fin;
00426     }
00427 
00428     IF ( R_OSPL_THREAD_GetCurrentId() == NULL ) {  /* Interrupt */
00429         e = E_NOT_THREAD;
00430         R_OSPL_RaiseUnrecoverable( e );
00431         goto fin;
00432     }
00433 
00434     IF ( IS( self->IsLocked ) ) {
00435         e=E_ACCESS_DENIED;
00436         goto fin;
00437     }
00438 
00439     self->IsLocked = true;
00440 
00441     e=0;
00442 fin:
00443     return  e;
00444 }
00445 
00446 
00447 /***********************************************************************
00448 * Implement: R_OSPL_C_LOCK_Unlock
00449 ************************************************************************/
00450 errnum_t  R_OSPL_C_LOCK_Unlock( r_ospl_c_lock_t *const  self )
00451 {
00452     errnum_t  e;
00453 
00454     if ( self != NULL ) {
00455 
00456         IF ( R_OSPL_THREAD_GetCurrentId() == NULL ) {  /* Interrupt */
00457             e = E_NOT_THREAD;
00458             R_OSPL_RaiseUnrecoverable( e );
00459             goto fin;
00460         }
00461 
00462         IF ( ! self->IsLocked ) {
00463             /* Check not unlock the object that was initialized by other thread */
00464             e = E_ACCESS_DENIED;
00465             goto fin;
00466         }
00467 
00468         self->IsLocked = false;
00469     }
00470 
00471     e=0;
00472 fin:
00473     return  e;
00474 }
00475 
00476 
00477 /***********************************************************************
00478 * Implement: R_OSPL_I_LOCK_LockStub
00479 ************************************************************************/
00480 bool_t  R_OSPL_I_LOCK_LockStub( void *const  self_ )
00481 {
00482     R_IT_WILL_BE_NOT_CONST( self_ );
00483     R_UNREFERENCED_VARIABLE( self_ );
00484     return  false;
00485 }
00486 
00487 
00488 /***********************************************************************
00489 * Implement: R_OSPL_I_LOCK_UnlockStub
00490 ************************************************************************/
00491 void  R_OSPL_I_LOCK_UnlockStub( void *const  self_ )
00492 {
00493     R_IT_WILL_BE_NOT_CONST( self_ );
00494     R_UNREFERENCED_VARIABLE( self_ );
00495 }
00496 
00497 
00498 /***********************************************************************
00499 * Implement: R_OSPL_I_LOCK_RequestFinalizeStub
00500 ************************************************************************/
00501 void  R_OSPL_I_LOCK_RequestFinalizeStub( void *const  self_ )
00502 {
00503     R_IT_WILL_BE_NOT_CONST( self_ );
00504     R_UNREFERENCED_VARIABLE( self_ );
00505 }
00506 
00507 
00508 /***********************************************************************
00509 * Implement: R_OSPL_MEMORY_Barrier
00510 ************************************************************************/
00511 void  R_OSPL_MEMORY_Barrier(void)
00512 {
00513     /* ->QAC 1006 : asm */
00514     __asm("DSB");
00515     /* <-QAC 1006 */
00516 }
00517 
00518 
00519 /***********************************************************************
00520 * Implement: R_OSPL_InstructionSyncBarrier
00521 ************************************************************************/
00522 void  R_OSPL_InstructionSyncBarrier(void)
00523 {
00524     /* ->QAC 1006 : asm */
00525     __asm("ISB");
00526     /* <-QAC 1006 */
00527 }
00528 
00529 
00530 /***********************************************************************
00531 * Implement: R_OSPL_CALLER_Initialize
00532 ************************************************************************/
00533 void  R_OSPL_CALLER_Initialize( r_ospl_caller_t *const  self,  r_ospl_async_t *const  Async,
00534                                 volatile void *const  PointerToState,  int_t const  StateValueOfOnInterrupting,
00535                                 void *const  I_Lock, const r_ospl_i_lock_vtable_t *const  I_LockVTable )
00536 {
00537     ASSERT_D( Async != NULL,  R_NOOP() );
00538     ASSERT_D( PointerToState != NULL,  R_NOOP() );
00539     IF_DQ( self == NULL ) {}
00540     else {
00541         self->Async = Async;
00542         self->PointerToState = (volatile int_fast32_t *) PointerToState;
00543         self->StateValueOfOnInterrupting = StateValueOfOnInterrupting;
00544         self->I_Lock = I_Lock;
00545         self->I_LockVTable = I_LockVTable;
00546     }
00547 
00548 #ifndef R_OSPL_NDEBUG
00549     /* Set sentinel */
00550     ASSERT_D( IS_ALL_BITS_NOT_SET( Async->Flags, R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ),
00551               R_NOOP() );
00552     ASSERT_D( IS_ALL_BITS_NOT_SET( R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE,
00553                                    ~R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ),  R_NOOP() );
00554 
00555     Async->Flags |= R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE;
00556 #endif
00557 }
00558 
00559 
00560 /***********************************************************************
00561 * Implement: R_OSPL_FTIMER_InitializeIfNot
00562 ************************************************************************/
00563 errnum_t  R_OSPL_FTIMER_InitializeIfNot( r_ospl_ftimer_spec_t *const  out_Specification )
00564 {
00565     /* ->SEC M1.11.1 : Can not const "is_initialized" because timing */
00566     bool_t  is_initialized;
00567     /* <-SEC M1.11.1 */
00568 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2
00569     enum { bits_CST1_CST2 = 0x06 };
00570 #endif
00571 
00572     /* ->QAC 0306 */
00573 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0
00574     struct st_ostm *const  reg_OSTM = &OSTM0;
00575 #elif  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1
00576     struct st_ostm *const  reg_OSTM = &OSTM1;
00577 #endif
00578     /* <-QAC 0306 */
00579 
00580     /* ->QAC 0306 */
00581 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0
00582     R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR5, CPG_STBCR5_MSTP51,
00583                                   CPG_STBCR5_MSTP51_SHIFT, 0 );
00584 
00585 #elif  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1
00586     R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR5, CPG_STBCR5_MSTP50,
00587                                   CPG_STBCR5_MSTP50_SHIFT, 0 );
00588 
00589 #elif  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2
00590     R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR3, CPG_STBCR3_MSTP33,
00591                                   CPG_STBCR3_MSTP33_SHIFT, 0 );
00592 #endif
00593 
00594 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2
00595     is_initialized = IS_ALL_BITS_NOT_SET( MTU2.TSTR, bits_CST1_CST2 );
00596 #else
00597     is_initialized = ( (int_fast32_t) reg_OSTM->OSTMnTE == 0 );
00598 #endif
00599     /* <-QAC 0306 */
00600 
00601     if ( IS( is_initialized ) ) {  /* Integer Promotions */
00602 #if  R_OSPL_FTIMER_IS != R_OSPL_FTIMER_IS_MTU2_1_2
00603         enum {  free_running_no_interrupt = 2 };
00604 #endif
00605         bool_t  was_all_enabled; /* = false; */ /* QAC 3197 */
00606 
00607         was_all_enabled = R_OSPL_DisableAllInterrupt();
00608 
00609 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2
00610         {
00611             enum { external_clock_TCLKD = 0x07u };
00612 
00613             /* ->QAC 0306 */
00614 
00615             /* Channel 1 */
00616             MTU2.TCR_1  = (uint8_t) external_clock_TCLKD;  /* overflow of the timer2 */
00617             MTU2.TMDR_1 = 0;
00618             MTU2.TIOR_1 = 0;
00619             MTU2.TIER_1 = 0;
00620             MTU2.TSR_1  = 0;
00621             MTU2.TCNT_1 = 0;
00622 
00623             /* Channel 2 */
00624             MTU2.TCR_2  = 0;  /* 33MHz */
00625             MTU2.TMDR_2 = 0;
00626             MTU2.TIOR_2 = 0;
00627             MTU2.TIER_2 = 0;
00628             MTU2.TSR_2  = 0;
00629             MTU2.TCNT_2 = 0;
00630 
00631             /* Timer start */
00632             /* MTU2.TSTR |= bits_CST1_CST2; */
00633             {
00634                 uint8_t const  value = MTU2.TSTR;
00635                 MTU2.TSTR = (uint8_t)( (uint_fast32_t) value | bits_CST1_CST2 );
00636             } /* QAC 2100 */
00637 
00638             /* <-QAC 0306 */
00639         }
00640 #else
00641         if ( (int_fast32_t) reg_OSTM->OSTMnTE == 0 ) {  /* Integer Promotions */
00642             reg_OSTM->OSTMnCTL = free_running_no_interrupt;
00643             reg_OSTM->OSTMnTS = 1;
00644         }
00645 #endif
00646 
00647         if ( IS( was_all_enabled ) ) {
00648             R_OSPL_EnableAllInterrupt();
00649         }
00650     }
00651 
00652     R_OSPL_FTIMER_GetSpecification( out_Specification );
00653 
00654     return  0;
00655 }
00656 
00657 
00658 /***********************************************************************
00659 * Implement: R_OSPL_FTIMER_GetSpecification
00660 ************************************************************************/
00661 void  R_OSPL_FTIMER_GetSpecification( r_ospl_ftimer_spec_t *const  out_Specification )
00662 {
00663     if ( out_Specification != NULL ) {
00664         enum { msec_numerator   = 1 };      /* SEC M1.10.1, QAC-3132 */
00665         enum { msec_denominator = 33333 };  /* SEC M1.10.1, QAC-3132 */
00666         static const uint32_t  max_count = 0xFFFFFFFFu;  /* SEC M1.10.1, QAC-3132 */
00667         static const uint32_t  extension_of_count = (1000 * msec_denominator) / msec_numerator;
00668         /* SEC M1.10.1, QAC-3132 */
00669 
00670         out_Specification->msec_Numerator   = msec_numerator;
00671         out_Specification->msec_Denominator = msec_denominator;
00672         out_Specification->MaxCount = max_count;
00673         out_Specification->ExtensionOfCount = extension_of_count;
00674     }
00675 }
00676 
00677 
00678 /***********************************************************************
00679 * Implement: R_OSPL_FTIMER_Get
00680 ************************************************************************/
00681 uint32_t  R_OSPL_FTIMER_Get(void)
00682 {
00683 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2
00684     enum { num_16bit = 16 }; /* SEC M1.10.1, QAC-3132 */
00685     /* ->QAC 0306 */
00686 
00687     uint32_t  now_high = (uint32_t)(MTU2.TCNT_1);
00688     uint32_t  not_low  = (uint32_t)(MTU2.TCNT_2);
00689 
00690     while( now_high != (uint32_t)(MTU2.TCNT_1) ) {
00691         /* If higher byte was changed while reading lower byte, re-read. */
00692         now_high = (uint32_t)(MTU2.TCNT_1);
00693         not_low  = (uint32_t)(MTU2.TCNT_2);
00694     }
00695 
00696     return  ( now_high << num_16bit ) | not_low;
00697 
00698     /* <-QAC 0306 */
00699 #else
00700 
00701     /* ->QAC 0306 */
00702 #if  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0
00703     struct st_ostm *const  reg_OSTM = &OSTM0;
00704 #elif  R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1
00705     struct st_ostm *const  reg_OSTM = &OSTM1;
00706 #endif
00707     /* <-QAC 0306 */
00708 
00709     ASSERT_R( reg_OSTM->OSTMnCMP == 0x0000000u,  R_NOOP() );
00710     /* If "OSTMnCMP != 0", OSTMnCNT is set from 0 to OSTMnCMP-1 */
00711 
00712     return  reg_OSTM->OSTMnCNT;
00713 
00714 #endif
00715 }
00716 
00717 
00718 /***********************************************************************
00719 * Implement: R_OSPL_FTIMER_IsPast
00720 ************************************************************************/
00721 errnum_t  R_OSPL_FTIMER_IsPast( const r_ospl_ftimer_spec_t *const  ts,
00722                                 uint32_t const  Now,  uint32_t const  TargetTime,  bool_t *const  out_IsPast )
00723 {
00724     uint32_t const         target_minus_now = TargetTime - Now;
00725     static const uint32_t  minus_flag = 0x80000000u;
00726     errnum_t       e;
00727     bool_t const   is_past = IS_BIT_SET( target_minus_now, minus_flag );
00728 
00729     IF_DQ( ts == NULL ) {
00730         e=E_OTHERS;
00731         goto fin;
00732     }
00733     IF_DQ( out_IsPast == NULL ) {
00734         e=E_OTHERS;
00735         goto fin;
00736     }
00737 
00738     if ( IS( is_past ) ) {
00739         uint32_t const  now_minus_target = Now - TargetTime;
00740 
00741         IF ( now_minus_target > ts->ExtensionOfCount ) {
00742             e=E_TIME_OUT;
00743             goto fin;
00744         }
00745     }
00746 
00747     *out_IsPast = is_past;
00748 
00749     e=0;
00750 fin:
00751     return  e;
00752 }
00753 
00754 
00755 /***********************************************************************
00756 * Implement: R_OSPL_TABLE_InitConst
00757 ************************************************************************/
00758 void  R_OSPL_TABLE_InitConst( r_ospl_table_t *const  self,
00759                               void *const  Area,  size_t const  AreaByteSize,  bool_t const  Is_T_Lock )
00760 {
00761 #if  ! defined( R_OSPL_NDEBUG ) ||  R_OSPL_IS_PREEMPTION
00762     errnum_t  e;
00763 #endif
00764 #if R_OSPL_IS_PREEMPTION
00765     bool_t    is_lock = false;
00766 #endif
00767 
00768     IF_DQ( self == NULL ) {
00769 #ifndef R_OSPL_NDEBUG
00770         e=E_OTHERS;
00771 #endif
00772         goto fin;
00773     }
00774 
00775 #if R_OSPL_IS_PREEMPTION
00776     if ( IS( Is_T_Lock ) ) {
00777         if ( R_OSPL_THREAD_GetCurrentId() != NULL ) {  /* If not interrrupt context */
00778             e= R_OSPL_Start_T_Lock();
00779             if(e!=0) {
00780                 goto fin;
00781             }
00782             is_lock = true;  /* T-Lock to "self" */
00783         }
00784     }
00785 #endif
00786 
00787     self->Area       = Area;
00788     self->Count      = 0;
00789     self->MaxCount   = (int_fast32_t)( AreaByteSize / sizeof( r_ospl_table_block_t ) );
00790     self->KeyCache   = NULL;
00791     self->FirstFreeIndex = 0;
00792 #if R_OSPL_IS_PREEMPTION
00793     self->Is_T_Lock  = Is_T_Lock;
00794 #else
00795     R_UNREFERENCED_VARIABLE( Is_T_Lock );
00796 #endif
00797 
00798     /* Set "self->Area[].NextFreeIndex" */
00799     {
00800         r_ospl_table_block_t *const  block_array = (r_ospl_table_block_t *) Area;
00801         int_fast32_t                 index;
00802         int_fast32_t const           max_index = self->MaxCount - 1;
00803 
00804         IF_DQ( block_array == NULL ) {
00805 #ifndef R_OSPL_NDEBUG
00806             e=E_OTHERS;
00807 #endif
00808             goto fin;
00809         }
00810 
00811         for ( index = 0;  index < max_index;  index += 1 ) {
00812             block_array[ index ].NextFreeIndex = (int16_t)( index + 1 );
00813         }
00814         block_array[ max_index ].NextFreeIndex = (int16_t) R_OSPL_TABLE_BLOCK_NO_NEXT;
00815     }
00816 
00817 #ifndef R_OSPL_NDEBUG
00818     e=0;
00819 #endif
00820 fin:
00821     R_NOOP();/* for following all #if is false */
00822 
00823 #if R_OSPL_IS_PREEMPTION
00824     if ( IS( is_lock ) ) {
00825         R_OSPL_End_T_Lock();
00826     }
00827 #endif
00828 #ifndef R_OSPL_NDEBUG
00829     if ( e != 0 ) {
00830         R_DebugBreak( NULL, e );
00831     }
00832 #endif
00833 }
00834 
00835 
00836 /***********************************************************************
00837 * Implement: R_OSPL_TABLE_GetIndex
00838 ************************************************************************/
00839 errnum_t  R_OSPL_TABLE_GetIndex( r_ospl_table_t *const  self,  const void *const  Key,
00840                                  int_fast32_t *const  out_Index,  r_ospl_if_not_t const  TypeOfIfNot )
00841 {
00842     errnum_t  e;
00843 #if R_OSPL_IS_PREEMPTION
00844     bool_t    is_lock = false;
00845 #endif
00846 
00847     IF_DQ( self == NULL ) {
00848         e=E_OTHERS;
00849         goto fin;
00850     }
00851     IF_DQ( out_Index == NULL ) {
00852         e=E_OTHERS;
00853         goto fin;
00854     }
00855 
00856 #if R_OSPL_IS_PREEMPTION
00857     if ( IS( self->Is_T_Lock ) ) {
00858         if ( R_OSPL_THREAD_GetCurrentId() != NULL ) {  /* If not interrrupt context */
00859             e= R_OSPL_Start_T_Lock();
00860             if(e!=0) {
00861                 goto fin;
00862             }
00863             is_lock = true;  /* T-Lock to "self" */
00864         }
00865     }
00866 #endif
00867 
00868 
00869     if ( (Key == self->KeyCache)  &&  (self->Count >= 1) ) {
00870         *out_Index = self->IndexCache;
00871     } else {
00872         r_ospl_table_searched_t      searched;
00873         r_ospl_table_block_t *const  block_array = self->Area;
00874         int_fast32_t                 found_index;
00875 
00876         R_OSPL_TABLE_Search_Sub( self, Key, &searched );
00877 
00878         if ( ! searched.IsFound ) {
00879             int_fast32_t  so_index;  /* sorted_key_index */
00880             int_fast32_t  first_index;  /* FirstFreeIndex */
00881 
00882             if ( TypeOfIfNot == R_OSPL_ALLOCATE_IF_NOT ) {
00883                 if ( self->Count == self->MaxCount ) {
00884                     e = E_FEW_ARRAY;
00885                     goto fin;
00886                 }
00887 
00888                 /* Insert and Set "block_array[ searched.SortedKeyIndex ].Key" */
00889                 for ( so_index = self->Count - 1;
00890                         so_index >= searched.SortedKeyIndex;
00891                         so_index -= 1 ) {
00892                     block_array[ so_index + 1 ].Key   = block_array[ so_index ].Key;
00893                     block_array[ so_index + 1 ].Index = block_array[ so_index ].Index;
00894                 }
00895                 block_array[ searched.SortedKeyIndex ].Key = Key;
00896                 self->Count += 1;
00897 
00898                 /* Set "block_array[ searched.SortedKeyIndex ].Index" */
00899                 first_index = self->FirstFreeIndex;
00900                 block_array[ searched.SortedKeyIndex ].Index = (int16_t) first_index;
00901                 self->FirstFreeIndex = block_array[ first_index ].NextFreeIndex;
00902                 block_array[ first_index ].NextFreeIndex = R_OSPL_TABLE_BLOCK_USED;
00903 
00904             } else if ( TypeOfIfNot == R_OSPL_ERROR_IF_NOT ) {
00905                 e = E_NOT_FOUND_SYMBOL;
00906                 goto fin;
00907             } else { /* TypeOfIfNot == R_OSPL_DO_NOTHING_IF_NOT */
00908                 e = 0;
00909                 goto fin;
00910             }
00911             /* Don't use "IF", Because this function called from "IF". */
00912         }
00913 
00914         self->KeyCache = Key;
00915         found_index = block_array[ searched.SortedKeyIndex ].Index;
00916         self->IndexCache = found_index;
00917         *out_Index = found_index;
00918     }
00919 
00920     e=0;
00921 fin:
00922 #if R_OSPL_IS_PREEMPTION
00923     if ( IS( is_lock ) ) {
00924         R_OSPL_End_T_Lock();
00925     }
00926 #endif
00927     return  e;
00928 }
00929 
00930 
00931 /***********************************************************************
00932 * Implement: R_OSPL_TABLE_Free
00933 ************************************************************************/
00934 void  R_OSPL_TABLE_Free( r_ospl_table_t *const  self,  const void *const  Key )
00935 {
00936 #if  ! defined( R_OSPL_NDEBUG ) ||  R_OSPL_IS_PREEMPTION
00937     errnum_t  e;
00938 #endif
00939 #if R_OSPL_IS_PREEMPTION
00940     bool_t    is_lock = false;
00941 #endif
00942     r_ospl_table_searched_t  searched;
00943 
00944     IF_DQ( self == NULL ) {
00945 #ifndef R_OSPL_NDEBUG
00946         e=0;
00947 #endif
00948         goto fin;
00949     }
00950 
00951 #if R_OSPL_IS_PREEMPTION
00952     if ( R_OSPL_THREAD_GetCurrentId() != NULL ) {  /* If not interrrupt context */
00953         e= R_OSPL_Start_T_Lock();
00954         if(e!=0) {
00955             goto fin;
00956         }
00957         is_lock = true;  /* T-Lock to "gs_global_error" */
00958     }
00959 #endif
00960 
00961     R_OSPL_TABLE_Search_Sub( self, Key, &searched );
00962 
00963     if ( IS( searched.IsFound ) ) {
00964         r_ospl_table_block_t *const  block_array = self->Area;
00965         int_fast32_t                 so_index;  /* sorted_key_index */
00966         int_fast32_t                 first_index;  /* FirstFreeIndex */
00967         int_fast32_t const           count_ = self->Count;  /* _ is for MISRA 5.6 */
00968 
00969         /* Set "FirstFreeIndex", ".NextFreeIndex" */
00970         first_index = self->FirstFreeIndex;
00971         self->FirstFreeIndex = block_array[ searched.SortedKeyIndex ].Index;
00972         block_array[ self->FirstFreeIndex ].NextFreeIndex = (int16_t) first_index;
00973 
00974         /* Remove one "r_ospl_table_block_t" */
00975         /* Set "self->KeyCache" */
00976         if ( searched.SortedKeyIndex < count_ ) {
00977             for ( so_index = searched.SortedKeyIndex;  so_index < count_ ;  so_index += 1 ) {
00978                 block_array[ so_index ].Key   = block_array[ so_index + 1 ].Key;
00979                 block_array[ so_index ].Index = block_array[ so_index + 1 ].Index;
00980             }
00981             self->KeyCache   = block_array[ searched.SortedKeyIndex ].Key;
00982             self->IndexCache = block_array[ searched.SortedKeyIndex ].Index;
00983         } else if ( searched.SortedKeyIndex > 0 ) { /* searched.SortedKeyIndex >= 1 */
00984             self->KeyCache   = block_array[ searched.SortedKeyIndex - 1 ].Key;
00985             self->IndexCache = block_array[ searched.SortedKeyIndex - 1 ].Index;
00986         } else {
00987             self->KeyCache = NULL;
00988         }
00989         self->Count -= 1;
00990     }
00991 
00992 #if  ! defined( R_OSPL_NDEBUG )
00993     e=0;
00994 #endif
00995 fin:
00996     R_NOOP();/* for following all #if is false */
00997 
00998 #if R_OSPL_IS_PREEMPTION
00999     if ( IS( is_lock ) ) {
01000         R_OSPL_End_T_Lock();
01001     }
01002 #endif
01003 #ifndef R_OSPL_NDEBUG
01004     if ( e != 0 ) {
01005         R_DebugBreak( NULL, e );
01006     }
01007 #endif
01008 }
01009 
01010 
01011 /***********************************************************************
01012 * Implement: R_OSPL_TABLE_Search_Sub
01013 ************************************************************************/
01014 static void  R_OSPL_TABLE_Search_Sub( const r_ospl_table_t *const  self,
01015                                       const void *const  Key,  r_ospl_table_searched_t *const  out_Searched )
01016 {
01017     int_fast32_t     left;
01018     int_fast32_t     right;
01019     int_fast32_t     middle;
01020     /* ->QAC 0306 : Sort by pointer value */
01021     uintptr_t const  target_key = (uintptr_t) Key;
01022     /* <-QAC 0306 */
01023     uintptr_t        middle_key;
01024     enum {           num_2 = 2 };  /* SEC M1.10.1, QAC-3132 */
01025     r_ospl_table_block_t  *array;
01026 
01027     IF_DQ( self == NULL ) {
01028         goto fin;
01029     }
01030     IF_DQ( out_Searched == NULL ) {
01031         goto fin;
01032     }
01033 
01034     array = self->Area;
01035 
01036 
01037     if ( self->Count == 0 ) {
01038         out_Searched->SortedKeyIndex = 0;
01039         out_Searched->IsFound = false;
01040     } else {
01041         left = 0;
01042         right = self->Count - 1;
01043 
01044         while ( (right - left) >= num_2 ) {
01045             middle = (int_fast32_t)( (uint_fast32_t)( right + left ) / num_2 );
01046             /* ->QAC 0306 : Sort by pointer value */
01047             middle_key = (uintptr_t) array[ middle ].Key;
01048             /* <-QAC 0306 */
01049 
01050             if ( target_key == middle_key ) {
01051                 out_Searched->SortedKeyIndex = middle;
01052                 out_Searched->IsFound = true;
01053                 goto fin;
01054             } else if ( target_key <  middle_key ) {
01055                 right = (int_fast32_t)( middle - 1 );
01056             } else {
01057                 left = (int_fast32_t)( middle + 1 );
01058             }
01059         }
01060 
01061         /* ->QAC 0306 : Sort by pointer value */
01062         if ( target_key == (uintptr_t) array[ left ].Key ) {
01063             out_Searched->SortedKeyIndex = left;
01064             out_Searched->IsFound = true;
01065         } else if ( target_key == (uintptr_t) array[ right ].Key ) {
01066             out_Searched->SortedKeyIndex = right;
01067             out_Searched->IsFound = true;
01068         } else if ( target_key < (uintptr_t) array[ left ].Key ) {
01069             out_Searched->SortedKeyIndex = left;
01070             out_Searched->IsFound = false;
01071         } else if ( target_key > (uintptr_t) array[ right ].Key ) {
01072             out_Searched->SortedKeyIndex = right + 1;
01073             out_Searched->IsFound = false;
01074         } else {
01075             out_Searched->SortedKeyIndex = right;
01076             out_Searched->IsFound = false;
01077         }
01078         /* <-QAC 0306 */
01079     }
01080 
01081 fin:
01082     return;
01083 }
01084 
01085 
01086 /***********************************************************************
01087 * Implement: R_OSPL_TABLE_Print
01088 ************************************************************************/
01089 #if R_OSPL_DEBUG_TOOL
01090 void  R_OSPL_TABLE_Print( r_ospl_table_t *const  self )
01091 {
01092     int_fast32_t  so_index;  /* sorted_key_index */
01093     int_fast32_t  index;
01094     r_ospl_table_block_t *const  array = self->Area;
01095 
01096     printf( "R_OSPL_TABLE_Print: r_ospl_table_t 0x%08X\n", (uintptr_t) self );
01097     printf( "    .Count = %d\n", self->Count );
01098     for ( so_index = 0;  so_index < self->Count;  so_index += 1 ) {
01099         printf( "    .Area[%d].Key, Index = 0x%08X, %d\n",
01100                 so_index,  (uintptr_t) array[ so_index ].Key,  array[ so_index ].Index );
01101     }
01102     printf( "    .FirstFreeIndex = %d\n", self->FirstFreeIndex );
01103     for ( index = 0;  index < self->MaxCount;  index += 1 ) {
01104         printf( "    .Area[%d].NextFreeIndex = %d\n", index,  array[ index ].NextFreeIndex );
01105     }
01106     printf( "        %d = R_OSPL_TABLE_BLOCK_NO_NEXT\n", R_OSPL_TABLE_BLOCK_NO_NEXT );
01107     printf( "        %d = R_OSPL_TABLE_BLOCK_USED\n", R_OSPL_TABLE_BLOCK_USED );
01108 }
01109 #endif
01110 
01111 
01112 /***********************************************************************
01113 * Implement: R_OSPL_CallInterruptCallback
01114 ************************************************************************/
01115 void  R_OSPL_CallInterruptCallback( const r_ospl_caller_t *const  self,
01116                                     const r_ospl_interrupt_t *const  InterruptSource )
01117 {
01118     errnum_t  e;
01119     r_ospl_async_t  *async;
01120 #if ! R_OSPL_IS_PREEMPTION
01121     r_ospl_master_t *const  gs_master = R_OSPL_GetPrivateContext();
01122     r_ospl_thread_def_t  *current_thread = NULL;  /* NULL is for avoid QAC 3353 */
01123 #endif
01124 #if R_OSPL_ERROR_BREAK
01125     static int_fast32_t  gs_nested_interrupt_level = 0;
01126 #endif
01127 
01128 #if R_OSPL_ERROR_BREAK
01129     gs_nested_interrupt_level += 1;
01130 #endif
01131 
01132 #if ! R_OSPL_IS_PREEMPTION
01133     IF_DQ( gs_master == NULL ) {
01134         e=E_OTHERS;
01135         goto fin;
01136     }
01137 
01138 #if R_OSPL_CPU_LOAD
01139     e= gs_master->IdleCallback( R_OSPL_INTERRUPT_START );
01140     IF(e) {
01141         goto fin;
01142     }
01143 #endif
01144 
01145     current_thread = gs_master->CurrentThread;
01146 #endif
01147 
01148     IF_DQ( self == NULL ) {
01149         e=E_OTHERS;
01150         goto fin;
01151     }
01152     IF_DQ( self->Async == NULL ) {
01153         e=E_OTHERS;
01154         goto fin;
01155     }
01156 
01157     async = self->Async;
01158 
01159     ASSERT_D( ( async->Flags & R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ) ==
01160               R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE,  e=E_OTHERS; goto fin );
01161     /* If failed, memory area of "Async" variable was overwritten by other variable. */
01162     /* Reason of failed may be not disabled interrupt */
01163     /* or not called "*_I_LOCK_Unlock()" disabling interrupt by "*_I_LOCK_Disable()". */
01164 
01165     IF_DQ( self->PointerToState == NULL ) {
01166         e=E_OTHERS;
01167         goto fin;
01168     }
01169     IF_DQ( async->InterruptCallback == NULL ) {
01170         e=E_OTHERS;
01171         goto fin;
01172     }
01173 
01174 #if ! R_OSPL_IS_PREEMPTION
01175     gs_master->CurrentThread = NULL;  /* Interrupt */
01176 #endif
01177 
01178     *self->PointerToState = self->StateValueOfOnInterrupting;
01179 
01180 
01181 
01182     e= async->InterruptCallback( InterruptSource, self );  /* Main of callback */
01183 
01184 
01185 
01186     if ( e != 0 ) {
01187         if ( async->ReturnValue == 0 ) {
01188             async->ReturnValue = e;
01189         }
01190         R_OSPL_CLEAR_ERROR();
01191     }
01192 
01193     e=0;
01194 fin:
01195 #if ! R_OSPL_IS_PREEMPTION
01196     IF_DQ ( gs_master == NULL ) {}
01197     else {
01198         gs_master->CurrentThread = current_thread;
01199 
01200 #if R_OSPL_CPU_LOAD
01201         {
01202             errnum_t  ee;
01203 
01204             ee= gs_master->IdleCallback( R_OSPL_INTERRUPT_END );
01205             e= R_OSPL_MergeErrNum( e, ee );
01206         }
01207 #endif
01208     }
01209 #endif
01210 
01211 
01212 #if R_OSPL_ERROR_BREAK
01213     gs_nested_interrupt_level -= 1;
01214 
01215     if ( gs_nested_interrupt_level == 0 ) {
01216         if ( gs_master != NULL ) {
01217             current_thread = gs_master->CurrentThread;
01218             gs_master->CurrentThread = NULL;
01219         }
01220 
01221 
01222         R_DEBUG_BREAK_IF_ERROR();
01223 
01224 
01225         if ( gs_master != NULL ) {
01226             gs_master->CurrentThread = current_thread;
01227         }
01228     }
01229 #endif
01230     R_UNREFERENCED_VARIABLE( e );
01231 }
01232 
01233 
01234 /***********************************************************************
01235 * Implement: R_OSPL_SetErrNum
01236 ************************************************************************/
01237 #if  R_OSPL_TLS_ERROR_CODE
01238 void  R_OSPL_SetErrNum( errnum_t const  e )
01239 {
01240     r_ospl_error_t  *err;
01241 
01242     if ( e != 0 ) {
01243 
01244         err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01245 
01246         if ( err != NULL ) {
01247             if ( err->ErrNum == 0 ) {
01248                 err->ErrNum = e;
01249             }
01250         }
01251     }
01252 }
01253 #endif
01254 
01255 
01256 /***********************************************************************
01257 * Implement: R_OSPL_GetErrNum
01258 ************************************************************************/
01259 #if  R_OSPL_TLS_ERROR_CODE
01260 errnum_t  R_OSPL_GetErrNum(void)
01261 {
01262     errnum_t         e;
01263     r_ospl_error_t  *err;
01264 
01265     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01266 
01267     if ( err != NULL ) {
01268         e = err->ErrNum;
01269     } else {
01270         e = E_NO_DEBUG_TLS;
01271     }
01272 
01273     return  e;
01274 }
01275 #endif
01276 
01277 
01278 /***********************************************************************
01279 * Implement: R_OSPL_CLEAR_ERROR
01280 ************************************************************************/
01281 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
01282 void  R_OSPL_CLEAR_ERROR(void)
01283 {
01284     r_ospl_error_t  *err;
01285 
01286     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_DO_NOTHING_IF_NOT );
01287 
01288     if ( err != NULL ) {
01289 #if R_OSPL_ERROR_BREAK
01290         err->IsError = false;
01291 #endif
01292 
01293 #if R_OSPL_TLS_ERROR_CODE
01294         err->ErrNum = 0;
01295 #endif
01296     }
01297 }
01298 #endif
01299 
01300 
01301 /**
01302 * @brief   Function part of error break
01303 *
01304 * @par Parameters
01305 *    None
01306 * @return  None.
01307 */
01308 #if R_OSPL_ERROR_BREAK
01309 static bool_t  R_OSPL_OnRaisingError_Sub( const char_t *const  FilePath,
01310         int_fast32_t const  LineNum );  /* QAC-3450 */
01311 static bool_t  R_OSPL_OnRaisingError_Sub( const char_t *const  FilePath,
01312         int_fast32_t const  LineNum )
01313 {
01314 #if  ! defined( R_OSPL_NDEBUG ) ||  R_OSPL_IS_PREEMPTION
01315     errnum_t         e;
01316 #endif
01317     bool_t           is_break = false;
01318 #if R_OSPL_IS_PREEMPTION
01319     bool_t           is_lock = false;
01320 #endif
01321     r_ospl_error_t  *err;
01322 
01323 
01324     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01325 
01326 
01327     if ( err != NULL ) {
01328         if ( IS( err->IsError ) ) {
01329             is_break = false;
01330         } else {
01331 #if R_OSPL_IS_PREEMPTION
01332             if ( R_OSPL_THREAD_GetCurrentId() != NULL ) {  /* If not interrrupt context */
01333                 e= R_OSPL_Start_T_Lock();
01334                 if(e!=0) {
01335                     goto fin;
01336                 }
01337                 is_lock = true;  /* T-Lock to "gs_global_error" */
01338             }
01339 #endif
01340 
01341             gs_global_error.RaisedGlobalErrorID ++;
01342             is_break = ( gs_global_error.RaisedGlobalErrorID ==
01343                          gs_global_error.BreakGlobalErrorID );
01344 
01345             err->IsError = true;
01346             err->ErrorID = gs_global_error.RaisedGlobalErrorID;
01347             err->FilePath = FilePath;
01348             err->LineNum = LineNum;
01349         }
01350     }
01351 
01352 #ifndef R_OSPL_NDEBUG
01353     e=0;
01354 #endif
01355 #if R_OSPL_IS_PREEMPTION
01356 fin:
01357     if ( IS( is_lock ) ) {
01358         R_OSPL_End_T_Lock();
01359     }
01360 #endif
01361 #ifndef R_OSPL_NDEBUG
01362     if ( e != 0 ) {
01363         R_DebugBreak( NULL, e );
01364     }
01365 #endif
01366     return  is_break;
01367 }
01368 #endif
01369 
01370 
01371 /***********************************************************************
01372 * Implement: R_OSPL_OnRaisingErrorForMISRA
01373 ************************************************************************/
01374 #if R_OSPL_ERROR_BREAK
01375 bool_t  R_OSPL_OnRaisingErrorForMISRA( bool_t const  Condition,  const char_t *const  File,
01376                                        int_t const  Line )
01377 {
01378     if ( IS( Condition ) ) {
01379         if ( R_OSPL_OnRaisingError_Sub( File, Line ) != 0 ) {
01380             R_DebugBreak( File, Line );
01381         }
01382     }
01383     return  Condition;
01384 }
01385 #endif
01386 
01387 
01388 /**
01389 * @brief   Function part of <R_DEBUG_BREAK_IF_ERROR>
01390 *
01391 * @par Parameters
01392 *    None
01393 * @return  None.
01394 */
01395 #if R_OSPL_ERROR_BREAK
01396 void  R_OSPL_DebugBreakIfError( const char_t *const  File,  int_t const  Line )
01397 {
01398     r_ospl_error_t  *err;
01399 
01400     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_DO_NOTHING_IF_NOT );
01401 
01402     if ( err != NULL  &&  err->IsError ) {
01403         /* See the value of "err->ErrorID" in watch window. */
01404         /* Call R_OSPL_SET_BREAK_ERROR_ID( N ); at main function. */
01405         printf( "<ERROR error_ID=\"0x%X\" file=\"%s(%d)\"/>\n",
01406                 err->ErrorID, err->FilePath, err->LineNum );
01407         R_DebugBreak( File, Line );
01408     }
01409 
01410     R_OSPL_CLEAR_ERROR();
01411 }
01412 #endif
01413 
01414 
01415 /***********************************************************************
01416 * Implement: R_OSPL_GET_ERROR_ID
01417 ************************************************************************/
01418 #if R_OSPL_ERROR_BREAK
01419 int_fast32_t  R_OSPL_GET_ERROR_ID(void)
01420 {
01421     return  gs_global_error.RaisedGlobalErrorID;
01422 }
01423 #endif
01424 
01425 
01426 /***********************************************************************
01427 * Implement: R_OSPL_SET_BREAK_ERROR_ID
01428 ************************************************************************/
01429 #if R_OSPL_ERROR_BREAK
01430 void  R_OSPL_SET_BREAK_ERROR_ID( int_fast32_t const  ErrorID )
01431 {
01432 #ifndef R_OSPL_NDEBUG
01433     if ( gs_global_error.BreakGlobalErrorID != ErrorID ) {
01434         printf( ">R_OSPL_SET_BREAK_ERROR_ID( %d );\n", ErrorID );
01435     }
01436 #endif
01437 
01438     gs_global_error.BreakGlobalErrorID = ErrorID;
01439 }
01440 #endif
01441 
01442 
01443 /***********************************************************************
01444 * Implement: R_OSPL_GetCurrentThreadError
01445 ************************************************************************/
01446 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
01447 r_ospl_error_t  *R_OSPL_GetCurrentThreadError(void)
01448 {
01449     return  R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01450 }
01451 #endif
01452 
01453 
01454 /**
01455 * @brief   GetCurrentThreadError
01456 *
01457 * @param   TypeOfIfNot <r_ospl_if_not_t>
01458 * @return  Error information of current thread
01459 */
01460 #if R_OSPL_ERROR_BREAK  ||  R_OSPL_TLS_ERROR_CODE
01461 static r_ospl_error_t  *R_OSPL_GetCurrentThreadError_Sub( r_ospl_if_not_t const  TypeOfIfNot )
01462 {
01463     errnum_t            e;
01464     int_fast32_t        index;
01465     r_ospl_error_t     *err = NULL;
01466     r_ospl_thread_id_t  th;  /* QAC 3441 */
01467 
01468     index = R_OSPL_NO_INDEX;
01469 
01470     th = R_OSPL_THREAD_GetCurrentId();
01471     e= R_OSPL_TABLE_GetIndex( &gs_global_error.ThreadIndexTable, th, &index, TypeOfIfNot );
01472     if ( e == E_FEW_ARRAY ) {
01473 #ifndef R_OSPL_NDEBUG
01474         if ( gs_global_error.ThreadIndexTable.Area == gs_thread_index_table_body ) {
01475             e = E_NO_DEBUG_TLS;
01476         }
01477 #endif
01478         goto fin;
01479     }
01480     if ( e != 0 ) {
01481         goto fin;
01482     }
01483 
01484     if ( index != R_OSPL_NO_INDEX ) {
01485         IF_DQ( gs_global_error.ErrorArray == NULL ) {
01486 #ifndef R_OSPL_NDEBUG
01487             e=E_OTHERS;
01488 #endif
01489             goto fin;
01490         }
01491         IF_DQ( index < -1 ) {
01492 #ifndef R_OSPL_NDEBUG
01493             e=E_OTHERS;
01494 #endif
01495             goto fin;
01496         }
01497 
01498         err = &gs_global_error.ErrorArray[ index ];
01499     }
01500 
01501 #ifndef R_OSPL_NDEBUG
01502     e=0;
01503 #endif
01504 fin:
01505 #ifndef R_OSPL_NDEBUG
01506     if ( e != 0 ) {
01507         R_DebugBreak( NULL, e );
01508         /* If e == 2 (E_FEW_ARRAY), Set big work area by "R_OSPL_SET_DEBUG_WORK". */
01509         /* If e == 29 (E_NO_DEBUG_TLS), Call "R_OSPL_SET_DEBUG_WORK". */
01510     }
01511 #endif
01512 
01513     return  err;
01514 }
01515 #endif
01516 
01517 
01518 /***********************************************************************
01519 * Implement: R_OSPL_SET_DEBUG_WORK
01520 ************************************************************************/
01521 #if R_OSPL_ERROR_BREAK
01522 void  R_OSPL_SET_DEBUG_WORK( void *const  WorkArea,  uint32_t const  WorkAreaSize )
01523 {
01524     errnum_t               e;
01525     int_fast32_t           count = WorkAreaSize / R_OSPL_DEBUG_WORK_1_SIZE;
01526     uint8_t               *work = WorkArea;
01527     r_ospl_table_block_t  *thread_index_array;
01528     r_ospl_error_t        *error_array;
01529     int_fast32_t           index;
01530 #if R_OSPL_IS_PREEMPTION
01531     bool_t                 is_lock = false;
01532 #endif
01533 
01534 #if R_OSPL_IS_PREEMPTION
01535     if ( R_OSPL_THREAD_GetCurrentId() != NULL ) {  /* If not interrrupt context */
01536         e= R_OSPL_Start_T_Lock();
01537         if(e!=0) {
01538             goto fin;
01539         }
01540         is_lock = true;  /* T-Lock to "gs_global_error" */
01541     }
01542 #endif
01543 
01544 
01545     if ( gs_global_error.ThreadIndexTable.Area != gs_thread_index_table_body ) {
01546         e = E_ACCESS_DENIED;
01547         goto fin;
01548     }
01549 
01550     thread_index_array = (r_ospl_table_block_t *) &work[0];
01551     error_array = (r_ospl_error_t *) &thread_index_array[ count ];
01552     ASSERT_D( (uint8_t *) &error_array[ count ] <= &work[ WorkAreaSize ],  e=E_FEW_ARRAY; goto fin );
01553 
01554     R_OSPL_TABLE_InitConst( &gs_global_error.ThreadIndexTable,
01555                             thread_index_array,  count * sizeof( thread_index_array[0] ), true );
01556 
01557     e= R_OSPL_TABLE_GetIndex( &gs_global_error.ThreadIndexTable,
01558                               gs_thread_index_table_body[0].Key, &index, R_OSPL_ALLOCATE_IF_NOT );
01559     if(e!=0) {
01560         goto fin;
01561     }
01562 
01563     gs_global_error.ErrorArray = error_array;
01564     gs_global_error.ErrorArray[ index ] = gs_error;
01565 
01566 #ifndef R_OSPL_NDEBUG
01567     memset( gs_thread_index_table_body, 0xFE, sizeof(gs_thread_index_table_body) );
01568     memset( &gs_error, 0xFE, sizeof(gs_error) );
01569 #endif
01570 
01571     e=0;
01572 fin:
01573 #if R_OSPL_IS_PREEMPTION
01574     if ( IS( is_lock ) ) {
01575         R_OSPL_End_T_Lock();
01576     }
01577 #endif
01578 #ifndef R_OSPL_NDEBUG
01579     if ( e != 0 ) {
01580         R_DebugBreak( NULL, e );
01581     }
01582 #endif
01583 }
01584 #endif
01585 
01586 
01587 /***********************************************************************
01588 * Implement: R_OSPL_MODIFY_THREAD_LOCKED_COUNT
01589 ************************************************************************/
01590 #if R_OSPL_ERROR_BREAK  &&  R_OSPL_IS_PREEMPTION
01591 void  R_OSPL_MODIFY_THREAD_LOCKED_COUNT( int_fast32_t Plus )
01592 {
01593     r_ospl_error_t  *err;
01594 
01595     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01596 
01597     if ( err != NULL ) {
01598         err->ThreadLockedCount += Plus;
01599     }
01600 }
01601 #endif
01602 
01603 
01604 /***********************************************************************
01605 * Implement: R_OSPL_GET_THREAD_LOCKED_COUNT
01606 ************************************************************************/
01607 #if R_OSPL_ERROR_BREAK  &&  R_OSPL_IS_PREEMPTION
01608 int_fast32_t  R_OSPL_GET_THREAD_LOCKED_COUNT(void)
01609 {
01610     int_fast32_t  count;
01611     r_ospl_error_t  *err;
01612 
01613     err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT );
01614 
01615     if ( err != NULL ) {
01616         count = err->ThreadLockedCount;
01617     } else {
01618         count = 0;
01619     }
01620 
01621     return  count;
01622 }
01623 #endif
01624 
01625