diff options
Diffstat (limited to 'FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib')
3 files changed, 172 insertions, 0 deletions
diff --git a/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.c b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.c new file mode 100644 index 000000000..fdff8f475 --- /dev/null +++ b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.c @@ -0,0 +1,46 @@ +#include "CException.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = {{ 0 }}; +#pragma GCC diagnostic pop + +//------------------------------------------------------------------------------------------ +// Throw +//------------------------------------------------------------------------------------------ +void Throw(CEXCEPTION_T ExceptionID) +{ + unsigned int MY_ID = CEXCEPTION_GET_ID; + CExceptionFrames[MY_ID].Exception = ExceptionID; + if (CExceptionFrames[MY_ID].pFrame) + { + longjmp(*CExceptionFrames[MY_ID].pFrame, 1); + } + CEXCEPTION_NO_CATCH_HANDLER(ExceptionID); +} + +//------------------------------------------------------------------------------------------ +// Explanation of what it's all for: +//------------------------------------------------------------------------------------------ +/* +#define Try + { <- give us some local scope. most compilers are happy with this + jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block + unsigned int MY_ID = CEXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking + PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at) + CExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- initialize my exception id to be NONE + if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0 + if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point. + +#define Catch(e) + else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted) + } + else <- an exception occurred + { e = CExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in. + CExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed. + } <- finish off that local scope we created to have our own variables + if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away + */ + diff --git a/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.h b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.h new file mode 100644 index 000000000..78f2f940c --- /dev/null +++ b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/CException.h @@ -0,0 +1,115 @@ +#ifndef _CEXCEPTION_H +#define _CEXCEPTION_H + +#include <setjmp.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#define CEXCEPTION_VERSION_MAJOR 1 +#define CEXCEPTION_VERSION_MINOR 3 +#define CEXCEPTION_VERSION_BUILD 2 +#define CEXCEPTION_VERSION ((CEXCEPTION_VERSION_MAJOR << 16) | (CEXCEPTION_VERSION_MINOR << 8) | CEXCEPTION_VERSION_BUILD) + +//To Use CException, you have a number of options: +//1. Just include it and run with the defaults +//2. Define any of the following symbols at the command line to override them +//3. Include a header file before CException.h everywhere which defines any of these +//4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first + +#ifdef CEXCEPTION_USE_CONFIG_FILE +#include "CExceptionConfig.h" +#endif + +//This is the value to assign when there isn't an exception +#ifndef CEXCEPTION_NONE +#define CEXCEPTION_NONE (0x5A5A5A5A) +#endif + +//This is number of exception stacks to keep track of (one per task) +#ifndef CEXCEPTION_NUM_ID +#define CEXCEPTION_NUM_ID (1) //there is only the one stack by default +#endif + +//This is the method of getting the current exception stack index (0 if only one stack) +#ifndef CEXCEPTION_GET_ID +#define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway +#endif + +//The type to use to store the exception values. +#ifndef CEXCEPTION_T +#define CEXCEPTION_T unsigned int +#endif + +//This is an optional special handler for when there is no global Catch +#ifndef CEXCEPTION_NO_CATCH_HANDLER +#define CEXCEPTION_NO_CATCH_HANDLER(id) +#endif + +//These hooks allow you to inject custom code into places, particularly useful for saving and restoring additional state +#ifndef CEXCEPTION_HOOK_START_TRY +#define CEXCEPTION_HOOK_START_TRY +#endif +#ifndef CEXCEPTION_HOOK_HAPPY_TRY +#define CEXCEPTION_HOOK_HAPPY_TRY +#endif +#ifndef CEXCEPTION_HOOK_AFTER_TRY +#define CEXCEPTION_HOOK_AFTER_TRY +#endif +#ifndef CEXCEPTION_HOOK_START_CATCH +#define CEXCEPTION_HOOK_START_CATCH +#endif + +//exception frame structures +typedef struct { + jmp_buf* pFrame; + CEXCEPTION_T volatile Exception; +} CEXCEPTION_FRAME_T; + +//actual root frame storage (only one if single-tasking) +extern volatile CEXCEPTION_FRAME_T CExceptionFrames[]; + +//Try (see C file for explanation) +#define Try \ + { \ + jmp_buf *PrevFrame, NewFrame; \ + unsigned int MY_ID = CEXCEPTION_GET_ID; \ + PrevFrame = CExceptionFrames[MY_ID].pFrame; \ + CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \ + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \ + CEXCEPTION_HOOK_START_TRY; \ + if (setjmp(NewFrame) == 0) { \ + if (1) + +//Catch (see C file for explanation) +#define Catch(e) \ + else { } \ + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \ + CEXCEPTION_HOOK_HAPPY_TRY; \ + } \ + else \ + { \ + e = CExceptionFrames[MY_ID].Exception; \ + (void)e; \ + CEXCEPTION_HOOK_START_CATCH; \ + } \ + CExceptionFrames[MY_ID].pFrame = PrevFrame; \ + CEXCEPTION_HOOK_AFTER_TRY; \ + } \ + if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) + +//Throw an Error +void Throw(CEXCEPTION_T ExceptionID); + +//Just exit the Try block and skip the Catch. +#define ExitTry() Throw(CEXCEPTION_NONE) + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // _CEXCEPTION_H diff --git a/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/meson.build b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/meson.build new file mode 100644 index 000000000..c9afe2048 --- /dev/null +++ b/FreeRTOS-Plus/Test/CMock/vendor/c_exception/lib/meson.build @@ -0,0 +1,11 @@ +# +# build script written by : Michael Brockus. +# github repo author: Mark VanderVoord. +# +# license: MIT +# +cexception_dir = include_directories('.') + +cexception_lib = static_library(meson.project_name(), + sources: ['CException.c'], + include_directories: cexception_dir) |