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
License
When you use this library, we judge you have agreed to the following contents.
https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE
Note
If you import the GraphicsFramework library, please import GR-PEACH_video library and R_BSP library together.
JPEG Converter
The JPEG Converter driver implements encode and decode functionality which uses the JCU of the RZ/A Series.
Hello World!
Import programJCU_HelloWorld
Hello World for JCU(JPEG Codec Unit). JCU is JPEG codec unit of RZ/A1. When you use this program, we judge you have agreed to the following contents. https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE
API
Import library
Data Structures |
|
struct | bitmap_buff_info_t |
Bitmap data setting struct.
More...
|
|
struct | encode_options_t |
Encode option setting.
More...
|
|
Public Types |
|
enum |
jpeg_conv_error_t
{
JPEG_CONV_OK = 0, JPEG_CONV_JCU_ERR = -1, JPEG_CONV_FORMA_ERR = -2, JPEG_CONV_PARAM_ERR = -3, JPEG_CONV_BUSY = -4, JPEG_CONV_PARAM_RANGE_ERR = -7 } |
Error codes. More... |
|
enum |
wr_rd_swa_t
{
WR_RD_WRSWA_NON = 0, WR_RD_WRSWA_8BIT = 1, WR_RD_WRSWA_16BIT = 2, WR_RD_WRSWA_16_8BIT = 3, WR_RD_WRSWA_32BIT = 4, WR_RD_WRSWA_32_8BIT = 5, WR_RD_WRSWA_32_16BIT = 6, WR_RD_WRSWA_32_16_8BIT = 7 } |
Write/Read image pixcel frame buffer swap setting. More... |
|
enum | wr_rd_format_t { WR_RD_YCbCr422 = 0x00, WR_RD_ARGB8888 = 0x01, WR_RD_RGB565 = 0x02 } |
Write/Read image pixcel format selects. More... |
|
enum | sub_sampling_t { SUB_SAMPLING_1_1 = 0x00, SUB_SAMPLING_1_2 = 0x01, SUB_SAMPLING_1_4 = 0x02, SUB_SAMPLING_1_8 = 0x03 } |
Thinning output image selects. More... |
|
enum | cbcr_offset_t { CBCR_OFFSET_0 = 0x00, CBCR_OFFSET_128 = 0x01 } |
Cb/Cr range selects for decode. More... |
|
Public Member Functions |
|
JPEG_Converter () | |
Constructor method of JPEG converter(encode/decode)
|
|
virtual | ~JPEG_Converter () |
Destructor method of JPEG converter(encode/decode)
|
|
JPEG_Converter::jpeg_conv_error_t | decode (void *pJpegBuff, bitmap_buff_info_t *psOutputBuff) |
Decode JPEG to rinear data.
|
|
JPEG_Converter::jpeg_conv_error_t | decode (void *pJpegBuff, bitmap_buff_info_t *psOutputBuff, decode_options_t *pOptions) |
JPEG data decode to bitmap.
|
|
JPEG_Converter::jpeg_conv_error_t | encode ( bitmap_buff_info_t *psInputBuff, void *pJpegBuff, size_t *pEncodeSize) |
Encode rinear data to JPEG.
|
|
JPEG_Converter::jpeg_conv_error_t | encode ( bitmap_buff_info_t *psInputBuff, void *pJpegBuff, size_t *pEncodeSize, encode_options_t *pOptions) |
Bitmap data encode to JPEG.
|
|
JPEG_Converter::jpeg_conv_error_t | SetQuality (const uint8_t qual) |
Set encode quality.
|
Correspondence file
A correspondence file of JPEG Converter is as the following table.
JPEG | Correspondence |
Width | >0(greater than 0) |
Height | >0(greater than 0) |
Color format | YCbCr444, YCbCr422, YCbCr420, YCbCr411 |
Bitmap | Correspondence |
Width | >0(greater than 0) |
Height | >0(greater than 0) |
Color format | YCbCr422 |
Notice
You run JPEG converter once destruction each time.
You set whether these JPEG files aren't input, or it check error setting decode(set in "flag" = true). The JPEG file which becomes correspondence outside will be the following condition.
- File besides the above-mentioned correspondence file.
- As information in the JPEG file, WIDTH or HEIGHT is larger than output buffer setting.
Buffer area is used encode/decode, set 8 bytes align and non-cash memory area. The output buffer when decoding, is made beyond the size decided in the size of the JPEG file, the format, setting of thinning out. You make output buffer for decode/encode to enough big size in order to stock this result. JPEG Converter, if you do not particularly perform specified, does not check size against the output data at the time of encoding and decoding. You set the output buffer so that there is no effect of corruption by the output data.
Color format
Color format in case to be converted from Bitmap to JPEG is either ARGB8888 or RGB555, YCbCr422.
Color format of the If you want to convert from JPEG file to Bitmap file is YCbCr422.
You correct "alpha(member of decode_options_t)" of setting and "output_cb_cr_offset(member of decode_options_t)" according to color format when decoding.
- example
decode to ARGB8888(WR_RD_ARGB8888 set in format member of bitmap_buff_info_t)
alpha = 0x01-0xFF
output_cb_cr_offset = CBCR_OFFSET_0
decode to YCbCr422(WR_RD_YCbCr422 set in format member of bitmap_buff_info_t)
alpha = 0
output_cb_cr_offset = CBCR_OFFSET_0 or CBCR_OFFSET_128
decode to RGB565(WR_RD_RGB565 set in format member of bitmap_buff_info_t)
alpha = 0
output_cb_cr_offset = CBCR_OFFSET_0
Decode/encode settings are optional
If omitted encode/decode settings, it will work with the following settings.
[Decode option setting (member of decode_options_t)]
- Vertical sub sampling is thinning output image to 1/1.
- Horizontal sub sampling is thinning output image to 1/1.
- Output data of Cb/Cr range is -128 to 127.
- Output data of swap in 8-bit units: 2-1-4-3-6-5-8-7.
- Alpha value of 0.
- JPEG format correspondence outside error check.
- It decode in a synchronous function.
[Encode option setting (member of encode_options_t)]
- DRI value is 0.
- Encoding JPEG file start width offset is 0.
- Encoding JPEG file start height offset is 0.
- Input data of Cb/Cr range of input data is -128 to 127.
- Input data swap in 8-bit units: 2-1-4-3-6-5-8-7.
- It don't check encode size.
- Quantization Y use default table(Quality75).
- Quantization C use default table(Quality75).
- Huffman Y DC use default table.
- Huffman C DC use default table.
- Huffman Y AC use default table.
- Huffman C AC use default table.
- It encode in a synchronous function.
Synchronous/asynchronous switching
Decoding and encoding setting to operate asynchronously by setting a callback function(decode_options_t and encode_options_t).
Quality
Quality changes are possible.
If you want to change the Quality, please specify the table made of Quality you want to change the address of the setting.
If you do not want to change the Quality, it will operate at Quality75.
RGA
The RGA library implements fast drawing functionality which uses the RGA of the RZ/A Series.
Supporting compiler is ARMCC, GCC ARM and IAR.
Hello World!
Import programRGA_HelloWorld
Hello World for RGA(Renesas Graphics Architecture). RGA is the Graphics Library of RZ/A1. When you use this program, we judge you have agreed to the following contents. https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE
ospl/src/r_ospl.c
- Committer:
- dkato
- Date:
- 2017-04-24
- Revision:
- 13:1ee2176ef13f
- Parent:
- 3:9f857750e4e9
File content as of revision 13:1ee2176ef13f:
/******************************************************************************* * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only * intended for use with Renesas products. No other uses are authorized. This * software is owned by Renesas Electronics Corporation and is protected under * all applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software * and to discontinue the availability of this software. By using this software, * you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * Copyright (C) 2012 - 2015 Renesas Electronics Corporation. All rights reserved. *******************************************************************************/ /** * @file r_ospl.c * @brief OS Porting Layer. Functions not depended on any environment. * * $Module: OSPL $ $PublicVersion: 0.90 $ (=R_OSPL_VERSION) * $Rev: 35 $ * $Date:: 2014-04-15 21:38:18 +0900#$ */ /****************************************************************************** Includes <System Includes> , "Project Includes" ******************************************************************************/ #include "r_ospl.h" #include "iodefine.h" #include "iobitmasks/cpg_iobitmask.h" #include "r_ospl_private.h" #include "r_ospl_os_less_private.h" #if R_OSPL_IS_PREEMPTION #include "r_ospl_RTX_private.h" #endif #include "locking.h" #ifdef __ICCARM__ #include <intrinsics.h> #endif #ifdef __GNUC__ #if ! IS_MBED_USED #include "irq.h" #endif #endif #if R_OSPL_DEBUG_TOOL #include <stdio.h> #endif #ifndef R_OSPL_NDEBUG #include <string.h> #endif /****************************************************************************** Typedef definitions ******************************************************************************/ /****************************************************************************** Macro definitions ******************************************************************************/ /****************************************************************************** Imported global variables and functions (from other files) ******************************************************************************/ /****************************************************************************** Exported global variables and functions (to be accessed by other files) ******************************************************************************/ /****************************************************************************** Private global variables and functions ******************************************************************************/ static void R_OSPL_TABLE_Search_Sub( const r_ospl_table_t *self, const void *Key, r_ospl_table_searched_t *out_Searched ); #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE static r_ospl_error_t *R_OSPL_GetCurrentThreadError_Sub( r_ospl_if_not_t TypeOfIfNot ); #endif /** * @def R_OSPL_DEFAULT_DEBUG_THREAD_COUNT * @brief For until calling "R_OSPL_SET_DEBUG_WORK" * @par Parameters * None * @return None. */ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE #define R_OSPL_DEFAULT_DEBUG_THREAD_COUNT 2 #endif /** For until calling "R_OSPL_SET_DEBUG_WORK" */ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE static r_ospl_table_block_t gs_thread_index_table_body[ R_OSPL_DEFAULT_DEBUG_THREAD_COUNT ]; #endif /** For until calling "R_OSPL_SET_DEBUG_WORK" */ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE static r_ospl_error_t gs_error; #endif /** as <r_ospl_global_error_t> */ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE /* ->MISRA 8.7 : If not defined R_OSPL_ERROR_BREAK, this is referenced by only 1 function. */ /* ->SEC M2.2.1 */ static r_ospl_global_error_t gs_global_error = /* <-MISRA 8.7 */ /* <-SEC M2.2.1 */ { { /* .ThreadIndexTable */ gs_thread_index_table_body, /* .Area */ 0, /* .Count */ R_OSPL_DEFAULT_DEBUG_THREAD_COUNT, /* .MaxCount */ NULL, /* .KeyCache */ 0, /* .IndexCache */ 0, /* .FirstFreeIndex */ #if R_OSPL_IS_PREEMPTION true /* .Is_T_Lock */ #endif }, &gs_error, /* .ErrorArray */ #if R_OSPL_ERROR_BREAK 0, /* .RaisedGlobalErrorID */ /* Necessary T-Lock */ 0 /* .BreakGlobalErrorID */ #endif }; #endif /*********************************************************************** * Implement: R_OSPL_GetVersion ************************************************************************/ int32_t R_OSPL_GetVersion(void) { return R_OSPL_VERSION; } /*********************************************************************** * Implement: R_OSPL_IsPreemption ************************************************************************/ bool_t R_OSPL_IsPreemption(void) { return R_OSPL_IS_PREEMPTION; } /*********************************************************************** * Implement: R_OSPL_FLAG32_InitConst ************************************************************************/ void R_OSPL_FLAG32_InitConst( volatile r_ospl_flag32_t *const self ) { IF_DQ( self == NULL ) { goto fin; } self->Flags = 0; fin: return; } /*********************************************************************** * Implement: R_OSPL_FLAG32_Set ************************************************************************/ void R_OSPL_FLAG32_Set( volatile r_ospl_flag32_t *const self, bit_flags32_t const SetFlags ) { IF_DQ( self == NULL ) { goto fin; } self->Flags |= SetFlags; fin: return; } /*********************************************************************** * Implement: R_OSPL_FLAG32_Clear ************************************************************************/ void R_OSPL_FLAG32_Clear( volatile r_ospl_flag32_t *const self, bit_flags32_t const ClearFlags1 ) { IF_DQ( self == NULL ) { goto fin; } self->Flags &= ~ClearFlags1; fin: return; } /*********************************************************************** * Implement: R_OSPL_FLAG32_Get ************************************************************************/ bit_flags32_t R_OSPL_FLAG32_Get( volatile const r_ospl_flag32_t *const self ) { bit_flags32_t return_value; IF_DQ( self == NULL ) { return_value = 0; goto fin; } return_value = self->Flags; fin: return return_value; } /*********************************************************************** * Implement: R_OSPL_FLAG32_GetAndClear ************************************************************************/ bit_flags32_t R_OSPL_FLAG32_GetAndClear( volatile r_ospl_flag32_t *const self ) { bit_flags32_t return_value; IF_DQ( self == NULL ) { return_value = 0; goto fin; } return_value = self->Flags; self->Flags = 0; fin: return return_value; } /*********************************************************************** * Implement: R_OSPL_ASYNC_CopyExceptAThread ************************************************************************/ void R_OSPL_ASYNC_CopyExceptAThread( const r_ospl_async_t *const Source, r_ospl_async_t *const Destination ) { IF_DQ( Destination == NULL ) { goto fin; } IF_DQ( Source == NULL ) { goto fin; } *Destination = *Source; Destination->A_Thread = NULL; fin: return; } /*********************************************************************** * Implement: R_OSPL_EnableAllInterrupt ************************************************************************/ void R_OSPL_EnableAllInterrupt(void) { __enable_irq(); } /*********************************************************************** * Implement: R_OSPL_DisableAllInterrupt ************************************************************************/ bool_t R_OSPL_DisableAllInterrupt(void) { #ifdef __ICCARM__ bool_t was_enabled = ( ( __get_interrupt_state() & 0x80 ) == 0 ); __disable_irq(); return was_enabled; #else return (bool_t)( __disable_irq() == 0 ); #endif } /*********************************************************************** * Implement: R_BSP_InterruptsEnable ************************************************************************/ void R_BSP_InterruptsEnable(void) { __enable_irq(); } /*********************************************************************** * Implement: R_BSP_InterruptsDisable ************************************************************************/ void R_BSP_InterruptsDisable(void) { #ifdef __ICCARM__ __disable_irq(); #else int_fast32_t ret; ret = __disable_irq(); R_UNREFERENCED_VARIABLE( ret ); /* QAC 3200 : This is not error information */ #endif } /*********************************************************************** * Implement: R_OSPL_LockChannel ************************************************************************/ errnum_t R_OSPL_LockChannel( int_fast32_t ChannelNum, int_fast32_t *out_ChannelNum, mcu_lock_t HardwareIndexMin, mcu_lock_t HardwareIndexMax ) { errnum_t e; bool_t is_success; mcu_lock_t hardware_index; ASSERT_D( HardwareIndexMin <= HardwareIndexMax, e=E_OTHERS; goto fin ); if ( ChannelNum == R_OSPL_UNLOCKED_CHANNEL ) { ASSERT_D( out_ChannelNum != NULL, e=E_OTHERS; goto fin ); #if BSP_CFG_USER_LOCKING_ENABLED for ( hardware_index = HardwareIndexMin; hardware_index <= HardwareIndexMax; hardware_index += 1 ) { is_success = R_BSP_HardwareLock( hardware_index ); if ( is_success ) { break; } } IF ( hardware_index > HardwareIndexMax ) { e=E_FEW_ARRAY; goto fin; } #else e= R_OSPL_LockUnlockedChannel( out_ChannelNum, HardwareIndexMin, HardwareIndexMax ); IF(e) { goto fin; } out_ChannelNum = NULL; #endif } else { hardware_index = (mcu_lock_t)( HardwareIndexMin + ChannelNum ); IF_D ( hardware_index < HardwareIndexMin || hardware_index > HardwareIndexMax ) { e=E_FEW_ARRAY; goto fin; } is_success = R_BSP_HardwareLock( hardware_index ); IF ( ! is_success ) { e=E_ACCESS_DENIED; goto fin; } } if ( out_ChannelNum != NULL ) { *out_ChannelNum = hardware_index - HardwareIndexMin; } e=0; fin: return e; } /*********************************************************************** * Implement: R_OSPL_UnlockChannel ************************************************************************/ errnum_t R_OSPL_UnlockChannel( int_fast32_t ChannelNum, errnum_t e, mcu_lock_t HardwareIndexMin, mcu_lock_t HardwareIndexMax ) { bool_t is_success; mcu_lock_t hardware_index; ASSERT_D( HardwareIndexMin <= HardwareIndexMax, e= R_OSPL_MergeErrNum( e, E_OTHERS ) ); hardware_index = (mcu_lock_t)( HardwareIndexMin + ChannelNum ); if ( hardware_index >= HardwareIndexMin && hardware_index <= HardwareIndexMax ) { is_success = R_BSP_HardwareUnlock( hardware_index ); IF ( ! is_success ) { e= R_OSPL_MergeErrNum( e, E_ACCESS_DENIED ); } } return e; } /*********************************************************************** * Implement: R_OSPL_C_LOCK_InitConst ************************************************************************/ void R_OSPL_C_LOCK_InitConst( r_ospl_c_lock_t *const self ) { IF_DQ( self == NULL ) { goto fin; } self->IsLocked = false; fin: return; } /*********************************************************************** * Implement: R_OSPL_C_LOCK_Lock ************************************************************************/ errnum_t R_OSPL_C_LOCK_Lock( r_ospl_c_lock_t *const self ) { errnum_t e; IF_DQ( self == NULL ) { e=E_OTHERS; goto fin; } IF ( R_OSPL_THREAD_GetCurrentId() == NULL ) { /* Interrupt */ e = E_NOT_THREAD; R_OSPL_RaiseUnrecoverable( e ); goto fin; } IF ( IS( self->IsLocked ) ) { e=E_ACCESS_DENIED; goto fin; } self->IsLocked = true; e=0; fin: return e; } /*********************************************************************** * Implement: R_OSPL_C_LOCK_Unlock ************************************************************************/ errnum_t R_OSPL_C_LOCK_Unlock( r_ospl_c_lock_t *const self ) { errnum_t e; if ( self != NULL ) { IF ( R_OSPL_THREAD_GetCurrentId() == NULL ) { /* Interrupt */ e = E_NOT_THREAD; R_OSPL_RaiseUnrecoverable( e ); goto fin; } IF ( ! self->IsLocked ) { /* Check not unlock the object that was initialized by other thread */ e = E_ACCESS_DENIED; goto fin; } self->IsLocked = false; } e=0; fin: return e; } /*********************************************************************** * Implement: R_OSPL_I_LOCK_LockStub ************************************************************************/ bool_t R_OSPL_I_LOCK_LockStub( void *const self_ ) { R_IT_WILL_BE_NOT_CONST( self_ ); R_UNREFERENCED_VARIABLE( self_ ); return false; } /*********************************************************************** * Implement: R_OSPL_I_LOCK_UnlockStub ************************************************************************/ void R_OSPL_I_LOCK_UnlockStub( void *const self_ ) { R_IT_WILL_BE_NOT_CONST( self_ ); R_UNREFERENCED_VARIABLE( self_ ); } /*********************************************************************** * Implement: R_OSPL_I_LOCK_RequestFinalizeStub ************************************************************************/ void R_OSPL_I_LOCK_RequestFinalizeStub( void *const self_ ) { R_IT_WILL_BE_NOT_CONST( self_ ); R_UNREFERENCED_VARIABLE( self_ ); } /*********************************************************************** * Implement: R_OSPL_MEMORY_Barrier ************************************************************************/ void R_OSPL_MEMORY_Barrier(void) { /* ->QAC 1006 : asm */ __asm("DSB"); /* <-QAC 1006 */ } /*********************************************************************** * Implement: R_OSPL_InstructionSyncBarrier ************************************************************************/ void R_OSPL_InstructionSyncBarrier(void) { /* ->QAC 1006 : asm */ __asm("ISB"); /* <-QAC 1006 */ } /*********************************************************************** * Implement: R_OSPL_CALLER_Initialize ************************************************************************/ void R_OSPL_CALLER_Initialize( r_ospl_caller_t *const self, r_ospl_async_t *const Async, volatile void *const PointerToState, int_t const StateValueOfOnInterrupting, void *const I_Lock, const r_ospl_i_lock_vtable_t *const I_LockVTable ) { ASSERT_D( Async != NULL, R_NOOP() ); ASSERT_D( PointerToState != NULL, R_NOOP() ); IF_DQ( self == NULL ) {} else { self->Async = Async; self->PointerToState = (volatile int_fast32_t *) PointerToState; self->StateValueOfOnInterrupting = StateValueOfOnInterrupting; self->I_Lock = I_Lock; self->I_LockVTable = I_LockVTable; } #ifndef R_OSPL_NDEBUG /* Set sentinel */ ASSERT_D( IS_ALL_BITS_NOT_SET( Async->Flags, R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ), R_NOOP() ); ASSERT_D( IS_ALL_BITS_NOT_SET( R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE, ~R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ), R_NOOP() ); Async->Flags |= R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE; #endif } /*********************************************************************** * Implement: R_OSPL_FTIMER_InitializeIfNot ************************************************************************/ errnum_t R_OSPL_FTIMER_InitializeIfNot( r_ospl_ftimer_spec_t *const out_Specification ) { /* ->SEC M1.11.1 : Can not const "is_initialized" because timing */ bool_t is_initialized; /* <-SEC M1.11.1 */ #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2 enum { bits_CST1_CST2 = 0x06 }; #endif /* ->QAC 0306 */ #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0 struct st_ostm *const reg_OSTM = &OSTM0; #elif R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1 struct st_ostm *const reg_OSTM = &OSTM1; #endif /* <-QAC 0306 */ /* ->QAC 0306 */ #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0 R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR5, CPG_STBCR5_MSTP51, CPG_STBCR5_MSTP51_SHIFT, 0 ); #elif R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1 R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR5, CPG_STBCR5_MSTP50, CPG_STBCR5_MSTP50_SHIFT, 0 ); #elif R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2 R_OSPL_SET_TO_8_BIT_REGISTER( &CPG.STBCR3, CPG_STBCR3_MSTP33, CPG_STBCR3_MSTP33_SHIFT, 0 ); #endif #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2 is_initialized = IS_ALL_BITS_NOT_SET( MTU2.TSTR, bits_CST1_CST2 ); #else is_initialized = ( (int_fast32_t) reg_OSTM->OSTMnTE == 0 ); #endif /* <-QAC 0306 */ if ( IS( is_initialized ) ) { /* Integer Promotions */ #if R_OSPL_FTIMER_IS != R_OSPL_FTIMER_IS_MTU2_1_2 enum { free_running_no_interrupt = 2 }; #endif bool_t was_all_enabled; /* = false; */ /* QAC 3197 */ was_all_enabled = R_OSPL_DisableAllInterrupt(); #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2 { enum { external_clock_TCLKD = 0x07u }; /* ->QAC 0306 */ /* Channel 1 */ MTU2.TCR_1 = (uint8_t) external_clock_TCLKD; /* overflow of the timer2 */ MTU2.TMDR_1 = 0; MTU2.TIOR_1 = 0; MTU2.TIER_1 = 0; MTU2.TSR_1 = 0; MTU2.TCNT_1 = 0; /* Channel 2 */ MTU2.TCR_2 = 0; /* 33MHz */ MTU2.TMDR_2 = 0; MTU2.TIOR_2 = 0; MTU2.TIER_2 = 0; MTU2.TSR_2 = 0; MTU2.TCNT_2 = 0; /* Timer start */ /* MTU2.TSTR |= bits_CST1_CST2; */ { uint8_t const value = MTU2.TSTR; MTU2.TSTR = (uint8_t)( (uint_fast32_t) value | bits_CST1_CST2 ); } /* QAC 2100 */ /* <-QAC 0306 */ } #else if ( (int_fast32_t) reg_OSTM->OSTMnTE == 0 ) { /* Integer Promotions */ reg_OSTM->OSTMnCTL = free_running_no_interrupt; reg_OSTM->OSTMnTS = 1; } #endif if ( IS( was_all_enabled ) ) { R_OSPL_EnableAllInterrupt(); } } R_OSPL_FTIMER_GetSpecification( out_Specification ); return 0; } /*********************************************************************** * Implement: R_OSPL_FTIMER_GetSpecification ************************************************************************/ void R_OSPL_FTIMER_GetSpecification( r_ospl_ftimer_spec_t *const out_Specification ) { if ( out_Specification != NULL ) { enum { msec_numerator = 1 }; /* SEC M1.10.1, QAC-3132 */ enum { msec_denominator = 33333 }; /* SEC M1.10.1, QAC-3132 */ static const uint32_t max_count = 0xFFFFFFFFu; /* SEC M1.10.1, QAC-3132 */ static const uint32_t extension_of_count = (1000 * msec_denominator) / msec_numerator; /* SEC M1.10.1, QAC-3132 */ out_Specification->msec_Numerator = msec_numerator; out_Specification->msec_Denominator = msec_denominator; out_Specification->MaxCount = max_count; out_Specification->ExtensionOfCount = extension_of_count; } } /*********************************************************************** * Implement: R_OSPL_FTIMER_Get ************************************************************************/ uint32_t R_OSPL_FTIMER_Get(void) { #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_MTU2_1_2 enum { num_16bit = 16 }; /* SEC M1.10.1, QAC-3132 */ /* ->QAC 0306 */ uint32_t now_high = (uint32_t)(MTU2.TCNT_1); uint32_t not_low = (uint32_t)(MTU2.TCNT_2); while( now_high != (uint32_t)(MTU2.TCNT_1) ) { /* If higher byte was changed while reading lower byte, re-read. */ now_high = (uint32_t)(MTU2.TCNT_1); not_low = (uint32_t)(MTU2.TCNT_2); } return ( now_high << num_16bit ) | not_low; /* <-QAC 0306 */ #else /* ->QAC 0306 */ #if R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM0 struct st_ostm *const reg_OSTM = &OSTM0; #elif R_OSPL_FTIMER_IS == R_OSPL_FTIMER_IS_OSTM1 struct st_ostm *const reg_OSTM = &OSTM1; #endif /* <-QAC 0306 */ ASSERT_R( reg_OSTM->OSTMnCMP == 0x0000000u, R_NOOP() ); /* If "OSTMnCMP != 0", OSTMnCNT is set from 0 to OSTMnCMP-1 */ return reg_OSTM->OSTMnCNT; #endif } /*********************************************************************** * Implement: R_OSPL_FTIMER_IsPast ************************************************************************/ errnum_t R_OSPL_FTIMER_IsPast( const r_ospl_ftimer_spec_t *const ts, uint32_t const Now, uint32_t const TargetTime, bool_t *const out_IsPast ) { uint32_t const target_minus_now = TargetTime - Now; static const uint32_t minus_flag = 0x80000000u; errnum_t e; bool_t const is_past = IS_BIT_SET( target_minus_now, minus_flag ); IF_DQ( ts == NULL ) { e=E_OTHERS; goto fin; } IF_DQ( out_IsPast == NULL ) { e=E_OTHERS; goto fin; } if ( IS( is_past ) ) { uint32_t const now_minus_target = Now - TargetTime; IF ( now_minus_target > ts->ExtensionOfCount ) { e=E_TIME_OUT; goto fin; } } *out_IsPast = is_past; e=0; fin: return e; } /*********************************************************************** * Implement: R_OSPL_TABLE_InitConst ************************************************************************/ void R_OSPL_TABLE_InitConst( r_ospl_table_t *const self, void *const Area, size_t const AreaByteSize, bool_t const Is_T_Lock ) { #if ! defined( R_OSPL_NDEBUG ) || R_OSPL_IS_PREEMPTION errnum_t e; #endif #if R_OSPL_IS_PREEMPTION bool_t is_lock = false; #endif IF_DQ( self == NULL ) { #ifndef R_OSPL_NDEBUG e=E_OTHERS; #endif goto fin; } #if R_OSPL_IS_PREEMPTION if ( IS( Is_T_Lock ) ) { if ( R_OSPL_THREAD_GetCurrentId() != NULL ) { /* If not interrrupt context */ e= R_OSPL_Start_T_Lock(); if(e!=0) { goto fin; } is_lock = true; /* T-Lock to "self" */ } } #endif self->Area = Area; self->Count = 0; self->MaxCount = (int_fast32_t)( AreaByteSize / sizeof( r_ospl_table_block_t ) ); self->KeyCache = NULL; self->FirstFreeIndex = 0; #if R_OSPL_IS_PREEMPTION self->Is_T_Lock = Is_T_Lock; #else R_UNREFERENCED_VARIABLE( Is_T_Lock ); #endif /* Set "self->Area[].NextFreeIndex" */ { r_ospl_table_block_t *const block_array = (r_ospl_table_block_t *) Area; int_fast32_t index; int_fast32_t const max_index = self->MaxCount - 1; IF_DQ( block_array == NULL ) { #ifndef R_OSPL_NDEBUG e=E_OTHERS; #endif goto fin; } for ( index = 0; index < max_index; index += 1 ) { block_array[ index ].NextFreeIndex = (int16_t)( index + 1 ); } block_array[ max_index ].NextFreeIndex = (int16_t) R_OSPL_TABLE_BLOCK_NO_NEXT; } #ifndef R_OSPL_NDEBUG e=0; #endif fin: R_NOOP();/* for following all #if is false */ #if R_OSPL_IS_PREEMPTION if ( IS( is_lock ) ) { R_OSPL_End_T_Lock(); } #endif #ifndef R_OSPL_NDEBUG if ( e != 0 ) { R_DebugBreak( NULL, e ); } #endif } /*********************************************************************** * Implement: R_OSPL_TABLE_GetIndex ************************************************************************/ errnum_t R_OSPL_TABLE_GetIndex( r_ospl_table_t *const self, const void *const Key, int_fast32_t *const out_Index, r_ospl_if_not_t const TypeOfIfNot ) { errnum_t e; #if R_OSPL_IS_PREEMPTION bool_t is_lock = false; #endif IF_DQ( self == NULL ) { e=E_OTHERS; goto fin; } IF_DQ( out_Index == NULL ) { e=E_OTHERS; goto fin; } #if R_OSPL_IS_PREEMPTION if ( IS( self->Is_T_Lock ) ) { if ( R_OSPL_THREAD_GetCurrentId() != NULL ) { /* If not interrrupt context */ e= R_OSPL_Start_T_Lock(); if(e!=0) { goto fin; } is_lock = true; /* T-Lock to "self" */ } } #endif if ( (Key == self->KeyCache) && (self->Count >= 1) ) { *out_Index = self->IndexCache; } else { r_ospl_table_searched_t searched; r_ospl_table_block_t *const block_array = self->Area; int_fast32_t found_index; R_OSPL_TABLE_Search_Sub( self, Key, &searched ); if ( ! searched.IsFound ) { int_fast32_t so_index; /* sorted_key_index */ int_fast32_t first_index; /* FirstFreeIndex */ if ( TypeOfIfNot == R_OSPL_ALLOCATE_IF_NOT ) { if ( self->Count == self->MaxCount ) { e = E_FEW_ARRAY; goto fin; } /* Insert and Set "block_array[ searched.SortedKeyIndex ].Key" */ for ( so_index = self->Count - 1; so_index >= searched.SortedKeyIndex; so_index -= 1 ) { block_array[ so_index + 1 ].Key = block_array[ so_index ].Key; block_array[ so_index + 1 ].Index = block_array[ so_index ].Index; } block_array[ searched.SortedKeyIndex ].Key = Key; self->Count += 1; /* Set "block_array[ searched.SortedKeyIndex ].Index" */ first_index = self->FirstFreeIndex; block_array[ searched.SortedKeyIndex ].Index = (int16_t) first_index; self->FirstFreeIndex = block_array[ first_index ].NextFreeIndex; block_array[ first_index ].NextFreeIndex = R_OSPL_TABLE_BLOCK_USED; } else if ( TypeOfIfNot == R_OSPL_ERROR_IF_NOT ) { e = E_NOT_FOUND_SYMBOL; goto fin; } else { /* TypeOfIfNot == R_OSPL_DO_NOTHING_IF_NOT */ e = 0; goto fin; } /* Don't use "IF", Because this function called from "IF". */ } self->KeyCache = Key; found_index = block_array[ searched.SortedKeyIndex ].Index; self->IndexCache = found_index; *out_Index = found_index; } e=0; fin: #if R_OSPL_IS_PREEMPTION if ( IS( is_lock ) ) { R_OSPL_End_T_Lock(); } #endif return e; } /*********************************************************************** * Implement: R_OSPL_TABLE_Free ************************************************************************/ void R_OSPL_TABLE_Free( r_ospl_table_t *const self, const void *const Key ) { #if ! defined( R_OSPL_NDEBUG ) || R_OSPL_IS_PREEMPTION errnum_t e; #endif #if R_OSPL_IS_PREEMPTION bool_t is_lock = false; #endif r_ospl_table_searched_t searched; IF_DQ( self == NULL ) { #ifndef R_OSPL_NDEBUG e=0; #endif goto fin; } #if R_OSPL_IS_PREEMPTION if ( R_OSPL_THREAD_GetCurrentId() != NULL ) { /* If not interrrupt context */ e= R_OSPL_Start_T_Lock(); if(e!=0) { goto fin; } is_lock = true; /* T-Lock to "gs_global_error" */ } #endif R_OSPL_TABLE_Search_Sub( self, Key, &searched ); if ( IS( searched.IsFound ) ) { r_ospl_table_block_t *const block_array = self->Area; int_fast32_t so_index; /* sorted_key_index */ int_fast32_t first_index; /* FirstFreeIndex */ int_fast32_t const count_ = self->Count; /* _ is for MISRA 5.6 */ /* Set "FirstFreeIndex", ".NextFreeIndex" */ first_index = self->FirstFreeIndex; self->FirstFreeIndex = block_array[ searched.SortedKeyIndex ].Index; block_array[ self->FirstFreeIndex ].NextFreeIndex = (int16_t) first_index; /* Remove one "r_ospl_table_block_t" */ /* Set "self->KeyCache" */ if ( searched.SortedKeyIndex < count_ ) { for ( so_index = searched.SortedKeyIndex; so_index < count_ ; so_index += 1 ) { block_array[ so_index ].Key = block_array[ so_index + 1 ].Key; block_array[ so_index ].Index = block_array[ so_index + 1 ].Index; } self->KeyCache = block_array[ searched.SortedKeyIndex ].Key; self->IndexCache = block_array[ searched.SortedKeyIndex ].Index; } else if ( searched.SortedKeyIndex > 0 ) { /* searched.SortedKeyIndex >= 1 */ self->KeyCache = block_array[ searched.SortedKeyIndex - 1 ].Key; self->IndexCache = block_array[ searched.SortedKeyIndex - 1 ].Index; } else { self->KeyCache = NULL; } self->Count -= 1; } #if ! defined( R_OSPL_NDEBUG ) e=0; #endif fin: R_NOOP();/* for following all #if is false */ #if R_OSPL_IS_PREEMPTION if ( IS( is_lock ) ) { R_OSPL_End_T_Lock(); } #endif #ifndef R_OSPL_NDEBUG if ( e != 0 ) { R_DebugBreak( NULL, e ); } #endif } /*********************************************************************** * Implement: R_OSPL_TABLE_Search_Sub ************************************************************************/ static void R_OSPL_TABLE_Search_Sub( const r_ospl_table_t *const self, const void *const Key, r_ospl_table_searched_t *const out_Searched ) { int_fast32_t left; int_fast32_t right; int_fast32_t middle; /* ->QAC 0306 : Sort by pointer value */ uintptr_t const target_key = (uintptr_t) Key; /* <-QAC 0306 */ uintptr_t middle_key; enum { num_2 = 2 }; /* SEC M1.10.1, QAC-3132 */ r_ospl_table_block_t *array; IF_DQ( self == NULL ) { goto fin; } IF_DQ( out_Searched == NULL ) { goto fin; } array = self->Area; if ( self->Count == 0 ) { out_Searched->SortedKeyIndex = 0; out_Searched->IsFound = false; } else { left = 0; right = self->Count - 1; while ( (right - left) >= num_2 ) { middle = (int_fast32_t)( (uint_fast32_t)( right + left ) / num_2 ); /* ->QAC 0306 : Sort by pointer value */ middle_key = (uintptr_t) array[ middle ].Key; /* <-QAC 0306 */ if ( target_key == middle_key ) { out_Searched->SortedKeyIndex = middle; out_Searched->IsFound = true; goto fin; } else if ( target_key < middle_key ) { right = (int_fast32_t)( middle - 1 ); } else { left = (int_fast32_t)( middle + 1 ); } } /* ->QAC 0306 : Sort by pointer value */ if ( target_key == (uintptr_t) array[ left ].Key ) { out_Searched->SortedKeyIndex = left; out_Searched->IsFound = true; } else if ( target_key == (uintptr_t) array[ right ].Key ) { out_Searched->SortedKeyIndex = right; out_Searched->IsFound = true; } else if ( target_key < (uintptr_t) array[ left ].Key ) { out_Searched->SortedKeyIndex = left; out_Searched->IsFound = false; } else if ( target_key > (uintptr_t) array[ right ].Key ) { out_Searched->SortedKeyIndex = right + 1; out_Searched->IsFound = false; } else { out_Searched->SortedKeyIndex = right; out_Searched->IsFound = false; } /* <-QAC 0306 */ } fin: return; } /*********************************************************************** * Implement: R_OSPL_TABLE_Print ************************************************************************/ #if R_OSPL_DEBUG_TOOL void R_OSPL_TABLE_Print( r_ospl_table_t *const self ) { int_fast32_t so_index; /* sorted_key_index */ int_fast32_t index; r_ospl_table_block_t *const array = self->Area; printf( "R_OSPL_TABLE_Print: r_ospl_table_t 0x%08X\n", (uintptr_t) self ); printf( " .Count = %d\n", self->Count ); for ( so_index = 0; so_index < self->Count; so_index += 1 ) { printf( " .Area[%d].Key, Index = 0x%08X, %d\n", so_index, (uintptr_t) array[ so_index ].Key, array[ so_index ].Index ); } printf( " .FirstFreeIndex = %d\n", self->FirstFreeIndex ); for ( index = 0; index < self->MaxCount; index += 1 ) { printf( " .Area[%d].NextFreeIndex = %d\n", index, array[ index ].NextFreeIndex ); } printf( " %d = R_OSPL_TABLE_BLOCK_NO_NEXT\n", R_OSPL_TABLE_BLOCK_NO_NEXT ); printf( " %d = R_OSPL_TABLE_BLOCK_USED\n", R_OSPL_TABLE_BLOCK_USED ); } #endif /*********************************************************************** * Implement: R_OSPL_CallInterruptCallback ************************************************************************/ void R_OSPL_CallInterruptCallback( const r_ospl_caller_t *const self, const r_ospl_interrupt_t *const InterruptSource ) { errnum_t e; r_ospl_async_t *async; #if ! R_OSPL_IS_PREEMPTION r_ospl_master_t *const gs_master = R_OSPL_GetPrivateContext(); r_ospl_thread_def_t *current_thread = NULL; /* NULL is for avoid QAC 3353 */ #endif #if R_OSPL_ERROR_BREAK static int_fast32_t gs_nested_interrupt_level = 0; #endif #if R_OSPL_ERROR_BREAK gs_nested_interrupt_level += 1; #endif #if ! R_OSPL_IS_PREEMPTION IF_DQ( gs_master == NULL ) { e=E_OTHERS; goto fin; } #if R_OSPL_CPU_LOAD e= gs_master->IdleCallback( R_OSPL_INTERRUPT_START ); IF(e) { goto fin; } #endif current_thread = gs_master->CurrentThread; #endif IF_DQ( self == NULL ) { e=E_OTHERS; goto fin; } IF_DQ( self->Async == NULL ) { e=E_OTHERS; goto fin; } async = self->Async; ASSERT_D( ( async->Flags & R_F_OSPL_ASYNC_FLAGS_SENTINEL_MASK ) == R_F_OSPL_ASYNC_FLAGS_SENTINEL_VALUE, e=E_OTHERS; goto fin ); /* If failed, memory area of "Async" variable was overwritten by other variable. */ /* Reason of failed may be not disabled interrupt */ /* or not called "*_I_LOCK_Unlock()" disabling interrupt by "*_I_LOCK_Disable()". */ IF_DQ( self->PointerToState == NULL ) { e=E_OTHERS; goto fin; } IF_DQ( async->InterruptCallback == NULL ) { e=E_OTHERS; goto fin; } #if ! R_OSPL_IS_PREEMPTION gs_master->CurrentThread = NULL; /* Interrupt */ #endif *self->PointerToState = self->StateValueOfOnInterrupting; e= async->InterruptCallback( InterruptSource, self ); /* Main of callback */ if ( e != 0 ) { if ( async->ReturnValue == 0 ) { async->ReturnValue = e; } R_OSPL_CLEAR_ERROR(); } e=0; fin: #if ! R_OSPL_IS_PREEMPTION IF_DQ ( gs_master == NULL ) {} else { gs_master->CurrentThread = current_thread; #if R_OSPL_CPU_LOAD { errnum_t ee; ee= gs_master->IdleCallback( R_OSPL_INTERRUPT_END ); e= R_OSPL_MergeErrNum( e, ee ); } #endif } #endif #if R_OSPL_ERROR_BREAK gs_nested_interrupt_level -= 1; if ( gs_nested_interrupt_level == 0 ) { if ( gs_master != NULL ) { current_thread = gs_master->CurrentThread; gs_master->CurrentThread = NULL; } R_DEBUG_BREAK_IF_ERROR(); if ( gs_master != NULL ) { gs_master->CurrentThread = current_thread; } } #endif R_UNREFERENCED_VARIABLE( e ); } /*********************************************************************** * Implement: R_OSPL_SetErrNum ************************************************************************/ #if R_OSPL_TLS_ERROR_CODE void R_OSPL_SetErrNum( errnum_t const e ) { r_ospl_error_t *err; if ( e != 0 ) { err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); if ( err != NULL ) { if ( err->ErrNum == 0 ) { err->ErrNum = e; } } } } #endif /*********************************************************************** * Implement: R_OSPL_GetErrNum ************************************************************************/ #if R_OSPL_TLS_ERROR_CODE errnum_t R_OSPL_GetErrNum(void) { errnum_t e; r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); if ( err != NULL ) { e = err->ErrNum; } else { e = E_NO_DEBUG_TLS; } return e; } #endif /*********************************************************************** * Implement: R_OSPL_CLEAR_ERROR ************************************************************************/ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE void R_OSPL_CLEAR_ERROR(void) { r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_DO_NOTHING_IF_NOT ); if ( err != NULL ) { #if R_OSPL_ERROR_BREAK err->IsError = false; #endif #if R_OSPL_TLS_ERROR_CODE err->ErrNum = 0; #endif } } #endif /** * @brief Function part of error break * * @par Parameters * None * @return None. */ #if R_OSPL_ERROR_BREAK static bool_t R_OSPL_OnRaisingError_Sub( const char_t *const FilePath, int_fast32_t const LineNum ); /* QAC-3450 */ static bool_t R_OSPL_OnRaisingError_Sub( const char_t *const FilePath, int_fast32_t const LineNum ) { #if ! defined( R_OSPL_NDEBUG ) || R_OSPL_IS_PREEMPTION errnum_t e; #endif bool_t is_break = false; #if R_OSPL_IS_PREEMPTION bool_t is_lock = false; #endif r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); if ( err != NULL ) { if ( IS( err->IsError ) ) { is_break = false; } else { #if R_OSPL_IS_PREEMPTION if ( R_OSPL_THREAD_GetCurrentId() != NULL ) { /* If not interrrupt context */ e= R_OSPL_Start_T_Lock(); if(e!=0) { goto fin; } is_lock = true; /* T-Lock to "gs_global_error" */ } #endif gs_global_error.RaisedGlobalErrorID ++; is_break = ( gs_global_error.RaisedGlobalErrorID == gs_global_error.BreakGlobalErrorID ); err->IsError = true; err->ErrorID = gs_global_error.RaisedGlobalErrorID; err->FilePath = FilePath; err->LineNum = LineNum; } } #ifndef R_OSPL_NDEBUG e=0; #endif #if R_OSPL_IS_PREEMPTION fin: if ( IS( is_lock ) ) { R_OSPL_End_T_Lock(); } #endif #ifndef R_OSPL_NDEBUG if ( e != 0 ) { R_DebugBreak( NULL, e ); } #endif return is_break; } #endif /*********************************************************************** * Implement: R_OSPL_OnRaisingErrorForMISRA ************************************************************************/ #if R_OSPL_ERROR_BREAK bool_t R_OSPL_OnRaisingErrorForMISRA( bool_t const Condition, const char_t *const File, int_t const Line ) { if ( IS( Condition ) ) { if ( R_OSPL_OnRaisingError_Sub( File, Line ) != 0 ) { R_DebugBreak( File, Line ); } } return Condition; } #endif /** * @brief Function part of <R_DEBUG_BREAK_IF_ERROR> * * @par Parameters * None * @return None. */ #if R_OSPL_ERROR_BREAK void R_OSPL_DebugBreakIfError( const char_t *const File, int_t const Line ) { r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_DO_NOTHING_IF_NOT ); if ( err != NULL && err->IsError ) { /* See the value of "err->ErrorID" in watch window. */ /* Call R_OSPL_SET_BREAK_ERROR_ID( N ); at main function. */ printf( "<ERROR error_ID=\"0x%X\" file=\"%s(%d)\"/>\n", err->ErrorID, err->FilePath, err->LineNum ); R_DebugBreak( File, Line ); } R_OSPL_CLEAR_ERROR(); } #endif /*********************************************************************** * Implement: R_OSPL_GET_ERROR_ID ************************************************************************/ #if R_OSPL_ERROR_BREAK int_fast32_t R_OSPL_GET_ERROR_ID(void) { return gs_global_error.RaisedGlobalErrorID; } #endif /*********************************************************************** * Implement: R_OSPL_SET_BREAK_ERROR_ID ************************************************************************/ #if R_OSPL_ERROR_BREAK void R_OSPL_SET_BREAK_ERROR_ID( int_fast32_t const ErrorID ) { #ifndef R_OSPL_NDEBUG if ( gs_global_error.BreakGlobalErrorID != ErrorID ) { printf( ">R_OSPL_SET_BREAK_ERROR_ID( %d );\n", ErrorID ); } #endif gs_global_error.BreakGlobalErrorID = ErrorID; } #endif /*********************************************************************** * Implement: R_OSPL_GetCurrentThreadError ************************************************************************/ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE r_ospl_error_t *R_OSPL_GetCurrentThreadError(void) { return R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); } #endif /** * @brief GetCurrentThreadError * * @param TypeOfIfNot <r_ospl_if_not_t> * @return Error information of current thread */ #if R_OSPL_ERROR_BREAK || R_OSPL_TLS_ERROR_CODE static r_ospl_error_t *R_OSPL_GetCurrentThreadError_Sub( r_ospl_if_not_t const TypeOfIfNot ) { errnum_t e; int_fast32_t index; r_ospl_error_t *err = NULL; r_ospl_thread_id_t th; /* QAC 3441 */ index = R_OSPL_NO_INDEX; th = R_OSPL_THREAD_GetCurrentId(); e= R_OSPL_TABLE_GetIndex( &gs_global_error.ThreadIndexTable, th, &index, TypeOfIfNot ); if ( e == E_FEW_ARRAY ) { #ifndef R_OSPL_NDEBUG if ( gs_global_error.ThreadIndexTable.Area == gs_thread_index_table_body ) { e = E_NO_DEBUG_TLS; } #endif goto fin; } if ( e != 0 ) { goto fin; } if ( index != R_OSPL_NO_INDEX ) { IF_DQ( gs_global_error.ErrorArray == NULL ) { #ifndef R_OSPL_NDEBUG e=E_OTHERS; #endif goto fin; } IF_DQ( index < -1 ) { #ifndef R_OSPL_NDEBUG e=E_OTHERS; #endif goto fin; } err = &gs_global_error.ErrorArray[ index ]; } #ifndef R_OSPL_NDEBUG e=0; #endif fin: #ifndef R_OSPL_NDEBUG if ( e != 0 ) { R_DebugBreak( NULL, e ); /* If e == 2 (E_FEW_ARRAY), Set big work area by "R_OSPL_SET_DEBUG_WORK". */ /* If e == 29 (E_NO_DEBUG_TLS), Call "R_OSPL_SET_DEBUG_WORK". */ } #endif return err; } #endif /*********************************************************************** * Implement: R_OSPL_SET_DEBUG_WORK ************************************************************************/ #if R_OSPL_ERROR_BREAK void R_OSPL_SET_DEBUG_WORK( void *const WorkArea, uint32_t const WorkAreaSize ) { errnum_t e; int_fast32_t count = WorkAreaSize / R_OSPL_DEBUG_WORK_1_SIZE; uint8_t *work = WorkArea; r_ospl_table_block_t *thread_index_array; r_ospl_error_t *error_array; int_fast32_t index; #if R_OSPL_IS_PREEMPTION bool_t is_lock = false; #endif #if R_OSPL_IS_PREEMPTION if ( R_OSPL_THREAD_GetCurrentId() != NULL ) { /* If not interrrupt context */ e= R_OSPL_Start_T_Lock(); if(e!=0) { goto fin; } is_lock = true; /* T-Lock to "gs_global_error" */ } #endif if ( gs_global_error.ThreadIndexTable.Area != gs_thread_index_table_body ) { e = E_ACCESS_DENIED; goto fin; } thread_index_array = (r_ospl_table_block_t *) &work[0]; error_array = (r_ospl_error_t *) &thread_index_array[ count ]; ASSERT_D( (uint8_t *) &error_array[ count ] <= &work[ WorkAreaSize ], e=E_FEW_ARRAY; goto fin ); R_OSPL_TABLE_InitConst( &gs_global_error.ThreadIndexTable, thread_index_array, count * sizeof( thread_index_array[0] ), true ); e= R_OSPL_TABLE_GetIndex( &gs_global_error.ThreadIndexTable, gs_thread_index_table_body[0].Key, &index, R_OSPL_ALLOCATE_IF_NOT ); if(e!=0) { goto fin; } gs_global_error.ErrorArray = error_array; gs_global_error.ErrorArray[ index ] = gs_error; #ifndef R_OSPL_NDEBUG memset( gs_thread_index_table_body, 0xFE, sizeof(gs_thread_index_table_body) ); memset( &gs_error, 0xFE, sizeof(gs_error) ); #endif e=0; fin: #if R_OSPL_IS_PREEMPTION if ( IS( is_lock ) ) { R_OSPL_End_T_Lock(); } #endif #ifndef R_OSPL_NDEBUG if ( e != 0 ) { R_DebugBreak( NULL, e ); } #endif } #endif /*********************************************************************** * Implement: R_OSPL_MODIFY_THREAD_LOCKED_COUNT ************************************************************************/ #if R_OSPL_ERROR_BREAK && R_OSPL_IS_PREEMPTION void R_OSPL_MODIFY_THREAD_LOCKED_COUNT( int_fast32_t Plus ) { r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); if ( err != NULL ) { err->ThreadLockedCount += Plus; } } #endif /*********************************************************************** * Implement: R_OSPL_GET_THREAD_LOCKED_COUNT ************************************************************************/ #if R_OSPL_ERROR_BREAK && R_OSPL_IS_PREEMPTION int_fast32_t R_OSPL_GET_THREAD_LOCKED_COUNT(void) { int_fast32_t count; r_ospl_error_t *err; err = R_OSPL_GetCurrentThreadError_Sub( R_OSPL_ALLOCATE_IF_NOT ); if ( err != NULL ) { count = err->ThreadLockedCount; } else { count = 0; } return count; } #endif