Dependencies:   mbed C12832_lcd LCD_fonts TextLCD

Files at this revision

API Documentation at this revision

Comitter:
dan_cornhill
Date:
Thu Apr 14 20:21:15 2022 +0000
Commit message:
Reaction_2Player

Changed in this revision

C12832_lcd.lib Show annotated file Show diff for this revision Revisions of this file
LCD_fonts.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Mail.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/MemoryPool.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Mutex.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Mutex.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Queue.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/RtosTimer.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/RtosTimer.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Semaphore.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Semaphore.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Thread.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/Thread.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/rtos.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/rtos_idle.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtos/rtos_idle.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/HAL_CM.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Config.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/cmsis_os.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos/targets/TARGET_NXP/mbed_rtx4.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r fc74113aca28 C12832_lcd.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C12832_lcd.lib	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/dreschpe/code/C12832_lcd/#8f86576007d6
diff -r 000000000000 -r fc74113aca28 LCD_fonts.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD_fonts.lib	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/dreschpe/code/LCD_fonts/#d0b7d7bf1f56
diff -r 000000000000 -r fc74113aca28 TextLCD.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/simon/code/TextLCD/#308d188a2d3a
diff -r 000000000000 -r fc74113aca28 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,438 @@
+#include "mbed.h" //Including the libraries for the code
+#include "Small_7.h" //Including the libraries for the code
+#include "Arial_9.h" //Including the libraries for the code
+#include "C12832_lcd.h" //including the libraries for the code
+#include "stdio.h" //Including the libraries for the code
+#include "rtos.h" //Including the libraries for the code
+#include "TextLCD.h" // Including the libraries for the code
+
+DigitalOut LED_A(LED1); //Declaring I/O for the board
+DigitalOut LED_B(LED2); //Declaring I/O for the board
+DigitalOut LED_C(LED3); //Declaring I/O for the board
+DigitalOut LED_D(LED4); //Declaring I/O for the board
+DigitalIn Player1Input(p15); //Declaring I/O for the board
+DigitalIn Player2Input(p12); //Declaring I/O for the board
+DigitalIn PlayerCheck(p14); //Declaring I/O for the board
+C12832_LCD LCD; 
+Mutex LCD_Mutex;
+Timer T;
+PwmOut Speaker(p26); 
+int Player1Points; //Declaration of variables - Variable tracks points for Player1
+int Player2Points; //Declaration of variables - Variable tracks points for Player2
+float Time1; //Declaration of variables - Variable tracks time system for Player1
+float Time2; //Declaration of variables - Variable tracks time system for Player1
+float FastestTime; //Declaration of variables - Variable tracks time system for fastest reaction time through the rounds
+int Check=0; //Declaration of variables - Flags (Signals the function to run)
+int Ready=0; //Declaration of variables - Flags (Signals the function to run)
+int Player1Turn=0; //Declaration of variables - Flags (Signals the function to run)
+int Player1Begin=0; //Declaration of variables - Flags (Signals the function to run)
+int Player2Turn=0; //Declaration of variables - Flags (Signals the function to run)
+int Player2Begin=0; //Declaration of variables - Flags (Signals the function to run)
+int Scored=0; //Declaration of variables - scoring system for the rounds, allocation of points per round
+int i=0; //Declaration of variables 
+int Fast=0; //Declaration of variables - variable tracks which Player has fastest time 
+
+void GameStart(void const *args){ //Defining a function 
+    int i = 0; //Local variable
+    for (i=0; i<1; i++) { //For loop which runs the code only for a single cycle
+        LCD_Mutex.lock(); //Locks the LCD from other threads
+        LCD.locate(36,10); //Locates the start position for the print statement
+        LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+        LCD.printf("20001248"); //Prints text for student id number
+        LCD_Mutex.unlock(); //Unlocks LCD to other threads
+        wait(3); //Delay in seconds
+        LCD_Mutex.lock(); //Locks the LCD from other threads
+        LCD.locate(25,20); //Locates position for the print statement on the LCD
+        LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+        LCD.printf("Reaction_2Player"); //Prints name of featured program
+        LCD_Mutex.unlock(); //Unlocks the LCD to other threads
+        wait(1); //Delay in seconds
+        LED_A=1; //Turns LED 'ON' - (High = 1)
+        Speaker.period(1.0/800.0); //Speaker frequency set to 800Hz
+        Speaker = 0.05; //Duty cycle set to 5% - low range volume
+        wait(0.05); //Delay in seconds
+        Speaker = 0; //Turn 'OFF' speaker
+        wait(0.3); //Delay in seconds
+        LED_A=0; //Turns LED1 'OFF' - (Low = 0)
+        LED_B=1; //Turns LED2 'ON' - (High = 1)
+        Speaker.period(1.0/800.0); //Speaker frequency set to 800Hz
+        Speaker = 0.05; //Duty cycle set to 5% - low range volume
+        wait(0.05); //Delay in seconds
+        Speaker = 0; //Turn 'OFF' speaker
+        wait(0.3); //Delay in seconds
+        LED_B=0; //Turns LED2 'OFF' - (Low = 0)
+        LED_C=1; //Turns LED3 'ON' - (High = 1)
+        Speaker.period(1.0/800.0); //Speaker frequency set to 800Hz
+        Speaker = 0.05; //Duty cycle set to 5% - low range volume
+        wait(0.05); //Delay in seconds
+        Speaker = 0; //Turn 'OFF' speaker
+        wait(0.3); //Delay in seconds
+        LED_C=0; //Turns LED3 'OFF' - (Low = 0)
+        LED_D=1; //Turns LED4 'ON' - (High = 1)
+        Speaker.period(1.0/800.0); //Speaker frequency set to 800Hz
+        Speaker = 0.05; //Duty cycle set to 5% - low range volume
+        wait(0.05); //Delay in seconds
+        Speaker = 0; //Turn 'OFF' speaker
+        wait(0.3); //Delay in seconds
+        LED_D=0; //Turns LED4 'OFF' - (Low = 0)
+        wait(0.3); //Delay in seconds
+        LED_A=1; //Turns LED1 'ON' - (High = 1)
+        LED_B=1; //Turns LED2 'ON' - (High = 1)
+        LED_C=1; //Turns LED3 'ON' - (High = 1)
+        LED_D=1; //Turns LED4 'ON' - (High = 1)
+        Speaker.period(1.0/800.0); //Speaker frequency set to 800Hz
+        Speaker = 0.1f; //Duty cycle set to 1% - low range volume
+        wait(0.05); //Delay in seconds
+        Speaker = 0; //Turn 'OFF' speaker
+        wait(0.3); //Delay in seconds
+        LED_A=0; //Turns LED1 'OFF' - (Low = 0)
+        LED_B=0; //Turns LED2 'OFF' - (Low = 0)
+        LED_C=0; //Turns LED3 'OFF' - (Low = 0)
+        LED_D=0; //Turns LED4 'OFF' - (Low = 0)
+        LCD_Mutex.lock(); //Locks LCD from other threads
+        LCD.locate(0,0); 
+        LCD.cls(); //Clears LCD
+        LCD_Mutex.unlock(); //Unlocks LCD to other threads
+    }
+}
+void CheckThread(void const *args){ //Defining a function  
+    while(true){ //While loop which runs thread
+        if ((PlayerCheck) && (Check == 0)){ //Playercheck & check is the pressing of the joystick, if statement conditions are met it will run the code
+                Ready = 1;
+        }
+    }
+}
+void Player1Go(void const *args){ //Defining a function
+    while(true){ //While loop whichs runs thread
+        if (Player1Turn == 1){ //If statement conditions are met it will run the code for Player1
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 5
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("5"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 4
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("4"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 3
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("3"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 2
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("2"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 1
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("1"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(0,0); 
+            LCD.cls(); //Clears the LCD
+            LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            LED_A=1; //Turns LED1 'ON' - (High = 1)
+            T.start(); //Timer will start counting in seconds
+            Player1Begin=1; //Flag variable is used to signal condition is met, i.e. to initialise Player1 turn
+            Player1Turn=0; //Flag variable is used to signal condition is met, i.e. doesn't run IF statment if not required 
+        }
+    }
+}
+void Player1Action(void const *args){ //Defining a function
+    while(true){ //While loop whichs runs thread
+        if(Player1Input){ //Player1 presses joystick upward
+            if (Player1Begin == 1){ //If statement which will run when certain conditions are met
+                LED_A=0; //Turns LED4 'OFF' - (Low = 0)
+                T.stop(); //Timer stops
+                wait(0.01); //Delay in seconds
+                Time1 = T.read(); //Timer will be stopped, and read to signify time in seconds
+                if (Time1 < FastestTime);{ //Set new fastest time if condition is met
+                    FastestTime = Time1;
+                    Fast=1; //Player1 = Fastest Time
+                }
+                if (Time1 < 0.1){ //Scoring system for determing points for Player1 per round
+                    Player1Points += 30;
+                    Scored = 30;}
+                else if ((Time1 < 0.15) && (Time1 > 0.1)){
+                    Player1Points += 20;
+                    Scored = 20;}
+                else if ((Time1 < 0.25) && (Time1 > 0.15)){
+                    Player1Points += 10;
+                    Scored = 10;}
+                else if ((Time1 < 0.5) && (Time1 > 0.25)){
+                    Player1Points += 5;
+                    Scored = 5;}
+                else if ((Time1 < 1) && (Time1 > 0.5)){
+                    Player1Points += 3;
+                    Scored = 3;}
+                else if ((Time1 < 3) && (Time1 > 1)){
+                    Player1Points += 1;
+                    Scored = 1;}
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(30,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Scored: %d",Scored); //Print points for Player1 for that round
+                wait(2); //Delay in seconds
+                LCD.locate(0,0); 
+                LCD.cls(); //Clears LCD
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+                Player1Turn=0; //Ends Player1's turn
+                Player1Begin=0; 
+                T.reset();// Timer resets to zero
+            }
+        }
+    }
+}
+void Player2Go(void const *args){// Defining a function
+    while(true){ //While loop which runs thread
+        if (Player2Turn == 1){ //If statement conditions are met it will run the code for Player2
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 5
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("5"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 4
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("4"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 3
+            LCD.set_font((unsigned char*) Small_7); 
+            LCD.printf("3"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 2
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("2"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(55,10); //Locates start position for the print statement, i.e. number 1
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("1"); //Prints statement onto LCD. Countdown from 5 in descending order to 1
+            wait(1); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            LCD_Mutex.unlock(); //Unlocks LCD to other thread
+            LED_A=1; //Turns LED1 'ON' - (High = 1)
+            T.start(); //Timer will start counting in seconds
+            Player2Begin=1; //Flag variable is used to signal condition is met, i.e. to initialise Player1 turn
+            Player2Turn=0; //Flag variable is used to signal condition is met, i.e. doesn't run IF statment if not required 
+        }
+    }
+}
+
+void Player2Action(void const *args){
+    while(true){ //While loop which runs thread
+        if(Player2Input){ //Player1 presses joystick downward
+            if (Player2Begin == 1){ //If statement which will run when certain conditions are met
+                LED_A=0; //Turns LED1 'OFF' - (Low = 0)
+                T.stop(); //Timer stops
+                wait(0.01); //Delay in seconds
+                Time2 = T.read(); //Timer will be stopped, and read to signify time in seconds
+                if (Time2 < FastestTime);{ //Set new fastest time if condition is met
+                    FastestTime = Time2;
+                    Fast=2; //Player2 = Fastest Time
+                }
+                if (Time2 < 0.1){ //Scoring system for determing points for Player1 per round
+                    Player2Points += 30;
+                    Scored = 30;}
+                else if ((Time2 < 0.15) && (Time2 > 0.1)){
+                    Player2Points += 20;
+                    Scored = 20;}
+                else if ((Time2 < 0.25) && (Time2 > 0.15)){
+                    Player2Points += 10;
+                    Scored = 10;}
+                else if ((Time2 < 0.5) && (Time2 > 0.25)){
+                    Player2Points += 5;
+                    Scored = 5;}
+                else if ((Time2 < 1) && (Time2 > 0.5)){
+                    Player2Points += 3;
+                    Scored = 3;}
+                else if ((Time2 < 3) && (Time2 > 1)){
+                    Player2Points += 1;
+                    Scored = 1;}
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(30,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Scored: %d",Scored); //Print points for Player2 for that round
+                wait(2); //Delay in seconds
+                LCD.locate(0,0);
+                LCD.cls(); //Clears LCD
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+                Player2Turn=0; //Ends Player2's turn
+                Player2Begin=0;
+                T.reset(); //Timer resets to zero
+            }
+        }
+    }
+}
+void MainGame(void const *args){ //Defining a function
+    while(true){ //While loop which run thread
+        wait(6); //Delay in seconds
+        i = 0;
+        for (i=1;i<4;i++){ //For loop repeats three times to signify three rounds of reaction game
+            Check=1; //Flag variable is used to signal condition is met, i.e. sets checkthread conditions 
+            while(Ready == 0){ //While loop will continue until joystick is pressed
+                wait(0.5); //Delay in seconds
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(0,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Press Joystick In To Begin"); //Prints statement which is a command for the Player to begin the game
+                wait(0.5); //Dlay in seconds
+                LCD.locate(0,0);
+                LCD.cls(); //Clears LCD
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            Ready=0; //Resets flag variable
+            Check = 0; //Resets flag variable 
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            wait(0.1); //Delay in seconds
+            LCD.locate(30,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Get Set, Ready..."); //Prints statement which is a que to let Players know the game is beginning
+            wait(1); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clear LCD
+            LCD_Mutex.unlock(); //Unlock LCD to other threads
+            Player1Turn=1; //Flag variable for Player1
+            wait(9); //Delay in seconds
+            if ((Player1Begin == 1) && (T.read() > 3)){ //Reads timer constantly, and if timer reaches 3 seconds, the round will be forfeited as Player reaction is too slow
+                T.stop(); //Timer stops
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(30,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Too slow"); //Prints statement to let Players know of forfeit 
+                wait(1); //Delay in seconds
+                LCD.locate(15,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Player 1 Round Lost"); //Prints statement to let Player know they lost the round
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+                Player1Begin=0; 
+                Player1Turn=0;
+                LED_A=0; //Turns LED1 'OFF' - (Low = 0)
+                wait(1); //Delay in seconds
+                T.reset(); //Timer resets
+            }
+            wait(0.1); //Delay in seconds
+            Ready=0;
+            Check=1; //Checkthread conditions
+            while(Ready == 0){ //While loop whci runs thread. Will be infinite until joystick is pressed. Joysticks acts as an intterupt to this loop. 
+                wait(0.5); //Delay in seconds
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(0,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Press Joystick In To Begin"); //Prints statement which is a command for Player to begin the game
+                wait(0.5); //Delay in seconds
+                LCD.locate(0,0);
+                LCD.cls(); //Clears LCD
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            Ready=0; //Resets flag variable
+            Check = 0; //Resets flag variable
+            LCD_Mutex.lock(); //Locks LCD deom other threads
+            LCD.locate(0,0); 
+            LCD.cls(); //Clears LCD
+            wait(0.1); //Delay in seconds
+            LCD.locate(30,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Get Set, Ready..."); //Prints statement which is a que to let Players know the game is beginning
+            wait(1); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            Player2Turn=1; //Flag variable for Player2
+            wait(9); //Delay in seconds
+            if ((Player2Begin == 1) && (T.read() > 3)){ //Reads timer constantly, and if timer reaches 3 seconds, the round will be forfeited as Player reaction is too slow
+                T.stop(); //Timer stops
+                LCD_Mutex.lock(); //Locks LCD from other threads
+                LCD.locate(30,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Too Slow"); //Prints statement to let Players know of forfeit
+                wait(1); //Delay in seconds
+                LCD.locate(15,10); //Locates start position for the print statement
+                LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                LCD.printf("Player 2 Round Lost"); //Prints statement to let Player know they lost the round
+                LCD_Mutex.unlock(); //Unlocks LCD to other threads
+                Player2Begin=0; 
+                Player2Turn=0;
+                LED_A=0; //Turns LED1 'OFF' - (Low = 0)
+                wait(1); //Delay in seconds
+                T.reset(); //Timer resets
+            }
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(15,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("The Results Of Round %d",i); //Prints statement to show points accumulated in the round
+            wait(1); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD 
+            wait(0.1); //Delay in seconds
+            LCD.locate(30,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Player 1: %d",Player1Points); //Prints statement which shows Player1 points
+            LCD.locate(30,20); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Player 2: %d",Player2Points); //Prints statement which shows Player2 points
+            wait(2); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(30,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("After 3 rounds..."); //Prints statement of the total from the three rounds
+            wait(1); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            wait(0.01); //Delay in seconds
+            LCD.locate(10,0); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("The Fastest Reaction Time"); //Prints statement showing the fastest reaction time through the three rounds
+            LCD.locate(20,10); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Was By Player %d",Fast); //Prints statement showing which Player got the the fastest reaction time
+            LCD.locate(23,20); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("%f",FastestTime); //Prints statement - Fastest Time
+            wait(3); //Delay in seconds
+            LCD.locate(0,0);
+            LCD.cls(); //Clears LCD
+            LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            if (Player1Points > Player2Points){ //If Player1 has more points than Player2, the code will execute
+                    LCD_Mutex.lock(); //Locks LCD from other threads
+                    LCD.locate(20,10); //Locates start position for the print statement
+                    LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                    LCD.printf("Congrats, Player 1 Wins"); //Prints statement congratulating winner (Player1)
+                    LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            else if (Player2Points > Player1Points){ //If Player2 has more points than Player 1, the code will execute
+                    LCD_Mutex.lock(); //Locks LCD from other threads
+                    LCD.locate(20,10); //Locates start position for the print statement
+                    LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                    LCD.printf("Congrats, Player 2 Wins"); //Prints statement congratulating winner (Player2)
+                    LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            else if (Player1Points == Player2Points){ //If Player1 & Player2 have equal points, then the code will execute
+                    LCD_Mutex.lock(); //Locks LCD from other threads
+                    LCD.locate(30,10); //Locates start position for the print statement
+                    LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+                    LCD.printf("It's A Draw!!"); //Prints statement to acknowledge draw between Player1 & Player2
+                    LCD_Mutex.unlock(); //Unlocks LCD to other threads
+            }
+            LCD_Mutex.lock(); //Locks LCD from other threads
+            LCD.locate(30,20); //Locates start position for the print statement
+            LCD.set_font((unsigned char*) Small_7); //Setting of font size (small)
+            LCD.printf("Well Done!"); //Prints statement to recognise the end of the game
+            LCD_Mutex.unlock(); //Unlocks LCD to other threads
+    }
+
+}
+    int main(){ //Defining a function
+            Thread T1(GameStart); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T2(CheckThread); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T3(MainGame); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T4(Player1Go); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T5(Player1Action); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T6(Player2Go); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            Thread T7(Player2Action); //Threads runs constantly - (Threads are smalls sets of instructions which scedule and execute several functions at the same time.
+            wait(99999); //Delay in seconds
+            Thread::wait(1); 
+}
\ No newline at end of file
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Mail.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Mail.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,113 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef MAIL_H
+#define MAIL_H
+
+#include <stdint.h>
+#include <string.h>
+
+#include "cmsis_os.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The Mail class allow to control, send, receive, or wait for mail.
+ A mail is a memory block that is send to a thread or interrupt service routine.
+  @tparam  T         data type of a single message element.
+  @tparam  queue_sz  maximum number of messages in queue.
+*/
+template<typename T, uint32_t queue_sz>
+class Mail {
+public:
+    /** Create and Initialise Mail queue. */
+    Mail() {
+    #ifdef CMSIS_OS_RTX
+        memset(_mail_q, 0, sizeof(_mail_q));
+        _mail_p[0] = _mail_q;
+
+        memset(_mail_m, 0, sizeof(_mail_m));
+        _mail_p[1] = _mail_m;
+
+        _mail_def.pool = _mail_p;
+        _mail_def.queue_sz = queue_sz;
+        _mail_def.item_sz = sizeof(T);
+    #endif
+        _mail_id = osMailCreate(&_mail_def, NULL);
+    }
+
+    /** Allocate a memory block of type T
+      @param   millisec  timeout value or 0 in case of no time-out. (default: 0).
+      @return  pointer to memory block that can be filled with mail or NULL in case error.
+    */
+    T* alloc(uint32_t millisec=0) {
+        return (T*)osMailAlloc(_mail_id, millisec);
+    }
+
+    /** Allocate a memory block of type T and set memory block to zero.
+      @param   millisec  timeout value or 0 in case of no time-out.  (default: 0).
+      @return  pointer to memory block that can be filled with mail or NULL in case error.
+    */
+    T* calloc(uint32_t millisec=0) {
+        return (T*)osMailCAlloc(_mail_id, millisec);
+    }
+
+    /** Put a mail in the queue.
+      @param   mptr  memory block previously allocated with Mail::alloc or Mail::calloc.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus put(T *mptr) {
+        return osMailPut(_mail_id, (void*)mptr);
+    }
+
+    /** Get a mail from a queue.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  event that contains mail information or error code.
+    */
+    osEvent get(uint32_t millisec=osWaitForever) {
+        return osMailGet(_mail_id, millisec);
+    }
+
+    /** Free a memory block from a mail.
+      @param   mptr  pointer to the memory block that was obtained with Mail::get.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus free(T *mptr) {
+        return osMailFree(_mail_id, (void*)mptr);
+    }
+
+private:
+    osMailQId    _mail_id;
+    osMailQDef_t _mail_def;
+#ifdef CMSIS_OS_RTX
+    uint32_t     _mail_q[4+(queue_sz)];
+    uint32_t     _mail_m[3+((sizeof(T)+3)/4)*(queue_sz)];
+    void        *_mail_p[2];
+#endif
+};
+
+}
+
+#endif
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/MemoryPool.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/MemoryPool.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,86 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef MEMORYPOOL_H
+#define MEMORYPOOL_H
+
+#include <stdint.h>
+#include <string.h>
+
+#include "cmsis_os.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** Define and manage fixed-size memory pools of objects of a given type.
+  @tparam  T         data type of a single object (element).
+  @tparam  queue_sz  maximum number of objects (elements) in the memory pool.
+*/
+template<typename T, uint32_t pool_sz>
+class MemoryPool {
+public:
+    /** Create and Initialize a memory pool. */
+    MemoryPool() {
+    #ifdef CMSIS_OS_RTX
+        memset(_pool_m, 0, sizeof(_pool_m));
+        _pool_def.pool = _pool_m;
+
+        _pool_def.pool_sz = pool_sz;
+        _pool_def.item_sz =  sizeof(T);
+    #endif
+        _pool_id = osPoolCreate(&_pool_def);
+    }
+
+    /** Allocate a memory block of type T from a memory pool.
+      @return  address of the allocated memory block or NULL in case of no memory available.
+    */
+    T* alloc(void) {
+        return (T*)osPoolAlloc(_pool_id);
+    }
+
+    /** Allocate a memory block of type T from a memory pool and set memory block to zero.
+      @return  address of the allocated memory block or NULL in case of no memory available.
+    */
+    T* calloc(void) {
+        return (T*)osPoolCAlloc(_pool_id);
+    }
+
+    /** Return an allocated memory block back to a specific memory pool.
+      @param   address of the allocated memory block that is returned to the memory pool.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus free(T *block) {
+        return osPoolFree(_pool_id, (void*)block);
+    }
+
+private:
+    osPoolId    _pool_id;
+    osPoolDef_t _pool_def;
+#ifdef CMSIS_OS_RTX
+    uint32_t    _pool_m[3+((sizeof(T)+3)/4)*(pool_sz)];
+#endif
+};
+
+}
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Mutex.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Mutex.cpp	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,56 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "rtos/Mutex.h"
+
+#include <string.h>
+#include "platform/mbed_error.h"
+
+namespace rtos {
+
+Mutex::Mutex() {
+#ifdef CMSIS_OS_RTX
+    memset(_mutex_data, 0, sizeof(_mutex_data));
+    _osMutexDef.mutex = _mutex_data;
+#endif
+    _osMutexId = osMutexCreate(&_osMutexDef);
+    if (_osMutexId == NULL) {
+        error("Error initializing the mutex object\n");
+    }
+}
+
+osStatus Mutex::lock(uint32_t millisec) {
+    return osMutexWait(_osMutexId, millisec);
+}
+
+bool Mutex::trylock() {
+    return (osMutexWait(_osMutexId, 0) == osOK);
+}
+
+osStatus Mutex::unlock() {
+    return osMutexRelease(_osMutexId);
+}
+
+Mutex::~Mutex() {
+    osMutexDelete(_osMutexId);
+}
+
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Mutex.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Mutex.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,73 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#include <stdint.h>
+#include "cmsis_os.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The Mutex class is used to synchronise the execution of threads.
+ This is for example used to protect access to a shared resource.
+*/
+class Mutex {
+public:
+    /** Create and Initialize a Mutex object */
+    Mutex();
+
+    /** Wait until a Mutex becomes available.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever)
+      @return  status code that indicates the execution status of the function.
+     */
+    osStatus lock(uint32_t millisec=osWaitForever);
+
+    /** Try to lock the mutex, and return immediately
+      @return  true if the mutex was acquired, false otherwise.
+     */
+    bool trylock();
+
+    /** Unlock the mutex that has previously been locked by the same thread
+      @return  status code that indicates the execution status of the function.
+     */
+    osStatus unlock();
+
+    ~Mutex();
+
+private:
+    osMutexId _osMutexId;
+    osMutexDef_t _osMutexDef;
+#ifdef CMSIS_OS_RTX
+#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
+    int32_t _mutex_data[4];
+#else
+    int32_t _mutex_data[3];
+#endif
+#endif
+};
+
+}
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Queue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Queue.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,85 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include <stdint.h>
+#include <string.h>
+
+#include "cmsis_os.h"
+#include "platform/mbed_error.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The Queue class allow to control, send, receive, or wait for messages.
+ A message can be a integer or pointer value  to a certain type T that is send
+ to a thread or interrupt service routine.
+  @tparam  T         data type of a single message element.
+  @tparam  queue_sz  maximum number of messages in queue.
+*/
+template<typename T, uint32_t queue_sz>
+class Queue {
+public:
+    /** Create and initialise a message Queue. */
+    Queue() {
+    #ifdef CMSIS_OS_RTX
+        memset(_queue_q, 0, sizeof(_queue_q));
+        _queue_def.pool = _queue_q;
+        _queue_def.queue_sz = queue_sz;
+    #endif
+        _queue_id = osMessageCreate(&_queue_def, NULL);
+        if (_queue_id == NULL) {
+            error("Error initialising the queue object\n");
+        }
+    }
+
+    /** Put a message in a Queue.
+      @param   data      message pointer.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: 0)
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus put(T* data, uint32_t millisec=0) {
+        return osMessagePut(_queue_id, (uint32_t)data, millisec);
+    }
+
+    /** Get a message or Wait for a message from a Queue.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  event information that includes the message and the status code.
+    */
+    osEvent get(uint32_t millisec=osWaitForever) {
+        return osMessageGet(_queue_id, millisec);
+    }
+
+private:
+    osMessageQId    _queue_id;
+    osMessageQDef_t _queue_def;
+#ifdef CMSIS_OS_RTX
+    uint32_t        _queue_q[4+(queue_sz)];
+#endif
+};
+
+}
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/RtosTimer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/RtosTimer.cpp	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,55 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "rtos/RtosTimer.h"
+
+#include <string.h>
+
+#include "mbed.h"
+#include "cmsis_os.h"
+#include "platform/mbed_error.h"
+
+namespace rtos {
+
+void RtosTimer::constructor(mbed::Callback<void()> func, os_timer_type type) {
+#ifdef CMSIS_OS_RTX
+    _timer.ptimer = (void (*)(const void *))Callback<void()>::thunk;
+
+    memset(_timer_data, 0, sizeof(_timer_data));
+    _timer.timer = _timer_data;
+#endif
+    _function = func;
+    _timer_id = osTimerCreate(&_timer, type, &_function);
+}
+
+osStatus RtosTimer::start(uint32_t millisec) {
+    return osTimerStart(_timer_id, millisec);
+}
+
+osStatus RtosTimer::stop(void) {
+    return osTimerStop(_timer_id);
+}
+
+RtosTimer::~RtosTimer() {
+    osTimerDelete(_timer_id);
+}
+
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/RtosTimer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/RtosTimer.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,111 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef RTOS_TIMER_H
+#define RTOS_TIMER_H
+
+#include <stdint.h>
+#include "cmsis_os.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The RtosTimer class allow creating and and controlling of timer functions in the system.
+ A timer function is called when a time period expires whereby both on-shot and
+ periodic timers are possible. A timer can be started, restarted, or stopped.
+
+ Timers are handled in the thread osTimerThread.
+ Callback functions run under control of this thread and may use CMSIS-RTOS API calls.
+*/
+class RtosTimer {
+public:
+    /** Create timer.
+      @param   func      function to be executed by this timer.
+      @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
+      @param   argument  argument to the timer call back function. (default: NULL)
+      @deprecated Replaced with RtosTimer(Callback<void()>, os_timer_type)
+     */
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "Replaced with RtosTimer(Callback<void()>, os_timer_type)")
+    RtosTimer(void (*func)(void const *argument), os_timer_type type=osTimerPeriodic, void *argument=NULL) {
+        constructor(mbed::callback((void (*)(void *))func, argument), type);
+    }
+    
+    /** Create timer.
+      @param   func      function to be executed by this timer.
+      @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
+    */
+    RtosTimer(mbed::Callback<void()> func, os_timer_type type=osTimerPeriodic) {
+        constructor(func, type);
+    }
+    
+    /** Create timer.
+      @param   obj       pointer to the object to call the member function on.
+      @param   method    member function to be executed by this timer.
+      @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
+      @deprecated
+          The RtosTimer constructor does not support cv-qualifiers. Replaced by
+          RtosTimer(callback(obj, method), os_timer_type).
+    */
+    template <typename T, typename M>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "The RtosTimer constructor does not support cv-qualifiers. Replaced by "
+        "RtosTimer(callback(obj, method), os_timer_type).")
+    RtosTimer(T *obj, M method, os_timer_type type=osTimerPeriodic) {
+        constructor(mbed::callback(obj, method), type);
+    }
+
+    /** Stop the timer.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus stop(void);
+
+    /** Start the timer.
+      @param   millisec  time delay value of the timer.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus start(uint32_t millisec);
+
+    ~RtosTimer();
+
+private:
+    // Required to share definitions without
+    // delegated constructors
+    void constructor(mbed::Callback<void()> func, os_timer_type type);
+    
+    mbed::Callback<void()> _function;
+    osTimerId _timer_id;
+    osTimerDef_t _timer;
+#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
+    uint32_t _timer_data[5];
+#else
+    uint32_t _timer_data[6];
+#endif
+};
+
+}
+
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Semaphore.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Semaphore.cpp	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,48 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "rtos/Semaphore.h"
+
+#include <string.h>
+
+namespace rtos {
+
+Semaphore::Semaphore(int32_t count) {
+#ifdef CMSIS_OS_RTX
+    memset(_semaphore_data, 0, sizeof(_semaphore_data));
+    _osSemaphoreDef.semaphore = _semaphore_data;
+#endif
+    _osSemaphoreId = osSemaphoreCreate(&_osSemaphoreDef, count);
+}
+
+int32_t Semaphore::wait(uint32_t millisec) {
+    return osSemaphoreWait(_osSemaphoreId, millisec);
+}
+
+osStatus Semaphore::release(void) {
+    return osSemaphoreRelease(_osSemaphoreId);
+}
+
+Semaphore::~Semaphore() {
+    osSemaphoreDelete(_osSemaphoreId);
+}
+
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Semaphore.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Semaphore.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,64 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef SEMAPHORE_H
+#define SEMAPHORE_H
+
+#include <stdint.h>
+#include "cmsis_os.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The Semaphore class is used to manage and protect access to a set of shared resources. */
+class Semaphore {
+public:
+    /** Create and Initialize a Semaphore object used for managing resources.
+      @param number of available resources; maximum index value is (count-1). (default: 0).
+    */
+    Semaphore(int32_t count=0);
+
+    /** Wait until a Semaphore resource becomes available.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  number of available tokens, or -1 in case of incorrect parameters
+    */
+    int32_t wait(uint32_t millisec=osWaitForever);
+
+    /** Release a Semaphore resource that was obtain with Semaphore::wait.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus release(void);
+
+    ~Semaphore();
+
+private:
+    osSemaphoreId _osSemaphoreId;
+    osSemaphoreDef_t _osSemaphoreDef;
+#ifdef CMSIS_OS_RTX
+    uint32_t _semaphore_data[2];
+#endif
+};
+
+}
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Thread.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Thread.cpp	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,374 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "rtos/Thread.h"
+
+#include "mbed.h"
+#include "rtos/rtos_idle.h"
+
+// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
+#undef NULL  //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
+#include "rt_TypeDef.h"
+
+extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
+
+
+static void (*terminate_hook)(osThreadId id) = 0;
+extern "C" void thread_terminate_hook(osThreadId id)
+{
+    if (terminate_hook != (void (*)(osThreadId))NULL) {
+        terminate_hook(id);
+    }
+}
+
+namespace rtos {
+
+void Thread::constructor(osPriority priority,
+        uint32_t stack_size, unsigned char *stack_pointer) {
+    _tid = 0;
+    _dynamic_stack = (stack_pointer == NULL);
+
+#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
+    _thread_def.tpriority = priority;
+    _thread_def.stacksize = stack_size;
+    _thread_def.stack_pointer = (uint32_t*)stack_pointer;
+#endif
+}
+
+void Thread::constructor(Callback<void()> task,
+        osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
+    constructor(priority, stack_size, stack_pointer);
+
+    switch (start(task)) {
+        case osErrorResource:
+            error("OS ran out of threads!\n");
+            break;
+        case osErrorParameter:
+            error("Thread already running!\n");
+            break;
+        case osErrorNoMemory:
+            error("Error allocating the stack memory\n");
+        default:
+            break;
+    }
+}
+
+osStatus Thread::start(Callback<void()> task) {
+    _mutex.lock();
+
+    if (_tid != 0) {
+        _mutex.unlock();
+        return osErrorParameter;
+    }
+
+#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
+    _thread_def.pthread = Thread::_thunk;
+    if (_thread_def.stack_pointer == NULL) {
+        _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
+        MBED_ASSERT(_thread_def.stack_pointer != NULL);
+    }
+
+    //Fill the stack with a magic word for maximum usage checking
+    for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
+        _thread_def.stack_pointer[i] = 0xE25A2EA5;
+    }
+#endif
+    _task = task;
+    _tid = osThreadCreate(&_thread_def, this);
+    if (_tid == NULL) {
+        if (_dynamic_stack) {
+            delete[] (_thread_def.stack_pointer);
+            _thread_def.stack_pointer = (uint32_t*)NULL;
+        }
+        _mutex.unlock();
+        _join_sem.release();
+        return osErrorResource;
+    }
+
+    _mutex.unlock();
+    return osOK;
+}
+
+osStatus Thread::terminate() {
+    osStatus ret;
+    _mutex.lock();
+
+    // Set the Thread's tid to NULL and
+    // release the semaphore before terminating
+    // since this thread could be terminating itself
+    osThreadId local_id = _tid;
+    _join_sem.release();
+    _tid = (osThreadId)NULL;
+
+    ret = osThreadTerminate(local_id);
+
+    _mutex.unlock();
+    return ret;
+}
+
+osStatus Thread::join() {
+    int32_t ret = _join_sem.wait();
+    if (ret < 0) {
+        return osErrorOS;
+    }
+
+    // The semaphore has been released so this thread is being
+    // terminated or has been terminated. Once the mutex has
+    // been locked it is ensured that the thread is deleted.
+    _mutex.lock();
+    MBED_ASSERT(NULL == _tid);
+    _mutex.unlock();
+
+    // Release sem so any other threads joining this thread wake up
+    _join_sem.release();
+    return osOK;
+}
+
+osStatus Thread::set_priority(osPriority priority) {
+    osStatus ret;
+    _mutex.lock();
+
+    ret = osThreadSetPriority(_tid, priority);
+
+    _mutex.unlock();
+    return ret;
+}
+
+osPriority Thread::get_priority() {
+    osPriority ret;
+    _mutex.lock();
+
+    ret = osThreadGetPriority(_tid);
+
+    _mutex.unlock();
+    return ret;
+}
+
+int32_t Thread::signal_set(int32_t signals) {
+    // osSignalSet is thread safe as long as the underlying
+    // thread does not get terminated or return from main
+    return osSignalSet(_tid, signals);
+}
+
+int32_t Thread::signal_clr(int32_t signals) {
+    // osSignalClear is thread safe as long as the underlying
+    // thread does not get terminated or return from main
+    return osSignalClear(_tid, signals);
+}
+
+Thread::State Thread::get_state() {
+#if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM)
+#ifdef CMSIS_OS_RTX
+    State status = Deleted;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        status = (State)_thread_def.tcb.state;
+    }
+
+    _mutex.unlock();
+    return status;
+#endif
+#else
+    State status = Deleted;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        status = (State)osThreadGetState(_tid);
+    }
+
+    _mutex.unlock();
+    return status;
+#endif
+}
+
+uint32_t Thread::stack_size() {
+#ifndef __MBED_CMSIS_RTOS_CA9
+#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        size = _thread_def.tcb.priv_stack;
+    }
+
+    _mutex.unlock();
+    return size;
+#else
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        size = tcb->priv_stack;
+    }
+
+    _mutex.unlock();
+    return size;
+#endif
+#else
+    return 0;
+#endif
+}
+
+uint32_t Thread::free_stack() {
+#ifndef __MBED_CMSIS_RTOS_CA9
+#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
+        size = _thread_def.tcb.tsk_stack - bottom;
+    }
+
+    _mutex.unlock();
+    return size;
+#else
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t bottom = (uint32_t)tcb->stack;
+        size = tcb->tsk_stack - bottom;
+    }
+
+    _mutex.unlock();
+    return size;
+#endif
+#else
+    return 0;
+#endif
+}
+
+uint32_t Thread::used_stack() {
+#ifndef __MBED_CMSIS_RTOS_CA9
+#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
+        size = top - _thread_def.tcb.tsk_stack;
+    }
+
+    _mutex.unlock();
+    return size;
+#else
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
+        size =  top - tcb->tsk_stack;
+    }
+
+    _mutex.unlock();
+    return size;
+#endif
+#else
+    return 0;
+#endif
+}
+
+uint32_t Thread::max_stack() {
+#ifndef __MBED_CMSIS_RTOS_CA9
+#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t high_mark = 0;
+        while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
+            high_mark++;
+        size = _thread_def.tcb.priv_stack - (high_mark * 4);
+    }
+
+    _mutex.unlock();
+    return size;
+#else
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t high_mark = 0;
+        while (tcb->stack[high_mark] == 0xE25A2EA5)
+            high_mark++;
+        size = tcb->priv_stack - (high_mark * 4);
+    }
+
+    _mutex.unlock();
+    return size;
+#endif
+#else
+    return 0;
+#endif
+}
+
+osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) {
+    return osSignalWait(signals, millisec);
+}
+
+osStatus Thread::wait(uint32_t millisec) {
+    return osDelay(millisec);
+}
+
+osStatus Thread::yield() {
+    return osThreadYield();
+}
+
+osThreadId Thread::gettid() {
+    return osThreadGetId();
+}
+
+void Thread::attach_idle_hook(void (*fptr)(void)) {
+    rtos_attach_idle_hook(fptr);
+}
+
+void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
+    terminate_hook = fptr;
+}
+
+Thread::~Thread() {
+    // terminate is thread safe
+    terminate();
+#ifdef __MBED_CMSIS_RTOS_CM
+    if (_dynamic_stack) {
+        delete[] (_thread_def.stack_pointer);
+        _thread_def.stack_pointer = (uint32_t*)NULL;
+    }
+#endif
+}
+
+void Thread::_thunk(const void * thread_ptr)
+{
+    Thread *t = (Thread*)thread_ptr;
+    t->_task();
+    t->_mutex.lock();
+    t->_tid = (osThreadId)NULL;
+    t->_join_sem.release();
+    // rtos will release the mutex automatically
+}
+
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/Thread.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/Thread.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,355 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef THREAD_H
+#define THREAD_H
+
+#include <stdint.h>
+#include "cmsis_os.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mutex.h"
+
+namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
+
+/** The Thread class allow defining, creating, and controlling thread functions in the system.
+ *
+ *  Example:
+ *  @code
+ *  #include "mbed.h"
+ *  #include "rtos.h"
+ *
+ *  Thread thread;
+ *  DigitalOut led1(LED1);
+ *  volatile bool running = true;
+ *
+ *  // Blink function toggles the led in a long running loop
+ *  void blink(DigitalOut *led) {
+ *      while (running) {
+ *          *led = !*led;
+ *          Thread::wait(1000);
+ *      }
+ *  }
+ *
+ *  // Spawns a thread to run blink for 5 seconds
+ *  int main() {
+ *      thread.start(led1, blink);
+ *      Thread::wait(5000);
+ *      running = false;
+ *      thread.join();
+ *  }
+ *  @endcode
+ */
+class Thread {
+public:
+    /** Allocate a new thread without starting execution
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+    */
+    Thread(osPriority priority=osPriorityNormal,
+           uint32_t stack_size=DEFAULT_STACK_SIZE,
+           unsigned char *stack_pointer=NULL) {
+        constructor(priority, stack_size, stack_pointer);
+    }
+
+    /** Create a new thread, and start it executing the specified function.
+      @param   task           function to be executed by this thread.
+      @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+      @deprecated
+        Thread-spawning constructors hide errors. Replaced by thread.start(task).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
+
+        osStatus status = thread.start(task);
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
+    */
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(task).")
+    Thread(mbed::Callback<void()> task,
+           osPriority priority=osPriorityNormal,
+           uint32_t stack_size=DEFAULT_STACK_SIZE,
+           unsigned char *stack_pointer=NULL) {
+        constructor(task, priority, stack_size, stack_pointer);
+    }
+
+    /** Create a new thread, and start it executing the specified function.
+      @param   obj            argument to task.
+      @param   method         function to be executed by this thread.
+      @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+      @deprecated
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
+
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
+    */
+    template <typename T>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
+    Thread(T *argument, void (T::*task)(),
+           osPriority priority=osPriorityNormal,
+           uint32_t stack_size=DEFAULT_STACK_SIZE,
+           unsigned char *stack_pointer=NULL) {
+        constructor(mbed::callback(task, argument),
+                    priority, stack_size, stack_pointer);
+    }
+
+    /** Create a new thread, and start it executing the specified function.
+      @param   obj            argument to task.
+      @param   method         function to be executed by this thread.
+      @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+      @deprecated
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
+
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
+    */
+    template <typename T>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
+    Thread(T *argument, void (*task)(T *),
+           osPriority priority=osPriorityNormal,
+           uint32_t stack_size=DEFAULT_STACK_SIZE,
+           unsigned char *stack_pointer=NULL) {
+        constructor(mbed::callback(task, argument),
+                    priority, stack_size, stack_pointer);
+    }
+
+    /** Create a new thread, and start it executing the specified function.
+        Provided for backwards compatibility
+      @param   task           function to be executed by this thread.
+      @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+      @deprecated
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
+
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
+    */
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
+    Thread(void (*task)(void const *argument), void *argument=NULL,
+           osPriority priority=osPriorityNormal,
+           uint32_t stack_size=DEFAULT_STACK_SIZE,
+           unsigned char *stack_pointer=NULL) {
+        constructor(mbed::callback((void (*)(void *))task, argument),
+                    priority, stack_size, stack_pointer);
+    }
+
+    /** Starts a thread executing the specified function.
+      @param   task           function to be executed by this thread.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus start(mbed::Callback<void()> task);
+
+    /** Starts a thread executing the specified function.
+      @param   obj            argument to task
+      @param   method         function to be executed by this thread.
+      @return  status code that indicates the execution status of the function.
+      @deprecated
+          The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
+    */
+    template <typename T, typename M>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "The start function does not support cv-qualifiers. "
+        "Replaced by thread.start(callback(obj, method)).")
+    osStatus start(T *obj, M method) {
+        return start(mbed::callback(obj, method));
+    }
+
+    /** Wait for thread to terminate
+      @return  status code that indicates the execution status of the function.
+      @note not callable from interrupt
+    */
+    osStatus join();
+
+    /** Terminate execution of a thread and remove it from Active Threads
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus terminate();
+
+    /** Set priority of an active thread
+      @param   priority  new priority value for the thread function.
+      @return  status code that indicates the execution status of the function.
+    */
+    osStatus set_priority(osPriority priority);
+
+    /** Get priority of an active thread
+      @return  current priority value of the thread function.
+    */
+    osPriority get_priority();
+
+    /** Set the specified Signal Flags of an active thread.
+      @param   signals  specifies the signal flags of the thread that should be set.
+      @return  previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+    */
+    int32_t signal_set(int32_t signals);
+
+    /** Clears the specified Signal Flags of an active thread.
+      @param   signals  specifies the signal flags of the thread that should be cleared.
+      @return  resultant signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+    */
+    int32_t signal_clr(int32_t signals);
+
+    /** State of the Thread */
+    enum State {
+        Inactive,           /**< Not created or terminated */
+        Ready,              /**< Ready to run */
+        Running,            /**< Running */
+        WaitingDelay,       /**< Waiting for a delay to occur */
+        WaitingInterval,    /**< Waiting for an interval to occur */
+        WaitingOr,          /**< Waiting for one event in a set to occur */
+        WaitingAnd,         /**< Waiting for multiple events in a set to occur */
+        WaitingSemaphore,   /**< Waiting for a semaphore event to occur */
+        WaitingMailbox,     /**< Waiting for a mailbox event to occur */
+        WaitingMutex,       /**< Waiting for a mutex event to occur */
+
+        /* Not in sync with RTX below here */
+        Deleted,            /**< The task has been deleted */
+    };
+
+    /** State of this Thread
+      @return  the State of this Thread
+    */
+    State get_state();
+    
+    /** Get the total stack memory size for this Thread
+      @return  the total stack memory size in bytes
+    */
+    uint32_t stack_size();
+    
+    /** Get the currently unused stack memory for this Thread
+      @return  the currently unused stack memory in bytes
+    */
+    uint32_t free_stack();
+    
+    /** Get the currently used stack memory for this Thread
+      @return  the currently used stack memory in bytes
+    */
+    uint32_t used_stack();
+    
+    /** Get the maximum stack memory usage to date for this Thread
+      @return  the maximum stack memory usage to date in bytes
+    */
+    uint32_t max_stack();
+
+    /** Wait for one or more Signal Flags to become signaled for the current RUNNING thread.
+      @param   signals   wait until all specified signal flags set or 0 for any single signal flag.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  event flag information or error code.
+      @note not callable from interrupt
+    */
+    static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
+
+    /** Wait for a specified time period in millisec:
+      @param   millisec  time delay value
+      @return  status code that indicates the execution status of the function.
+      @note not callable from interrupt
+    */
+    static osStatus wait(uint32_t millisec);
+
+    /** Pass control to next thread that is in state READY.
+      @return  status code that indicates the execution status of the function.
+      @note not callable from interrupt
+    */
+    static osStatus yield();
+
+    /** Get the thread id of the current running thread.
+      @return  thread ID for reference by other functions or NULL in case of error.
+    */
+    static osThreadId gettid();
+    
+    /** Attach a function to be called by the RTOS idle task
+      @param   fptr  pointer to the function to be called
+    */
+    static void attach_idle_hook(void (*fptr)(void));
+
+    /** Attach a function to be called when a task is killed
+      @param   fptr  pointer to the function to be called
+    */
+    static void attach_terminate_hook(void (*fptr)(osThreadId id));
+
+    virtual ~Thread();
+
+private:
+    // Required to share definitions without
+    // delegated constructors
+    void constructor(osPriority priority=osPriorityNormal,
+                     uint32_t stack_size=DEFAULT_STACK_SIZE,
+                     unsigned char *stack_pointer=NULL);
+    void constructor(mbed::Callback<void()> task,
+                     osPriority priority=osPriorityNormal,
+                     uint32_t stack_size=DEFAULT_STACK_SIZE,
+                     unsigned char *stack_pointer=NULL);
+    static void _thunk(const void * thread_ptr);
+
+    mbed::Callback<void()> _task;
+    osThreadId _tid;
+    osThreadDef_t _thread_def;
+    bool _dynamic_stack;
+    Semaphore _join_sem;
+    Mutex _mutex;
+};
+
+}
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/rtos.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/rtos.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,49 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef RTOS_H
+#define RTOS_H
+
+#include "rtos/Thread.h"
+#include "rtos/Mutex.h"
+#include "rtos/RtosTimer.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mail.h"
+#include "rtos/MemoryPool.h"
+#include "rtos/Queue.h"
+
+using namespace rtos;
+
+/* Get mbed lib version number, as RTOS depends on mbed lib features
+   like mbed_error, Callback and others.
+*/
+#include "mbed.h"
+
+#if (MBED_LIBRARY_VERSION < 122)
+#error "This version of RTOS requires mbed library version > 121"
+#endif
+
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/rtos_idle.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/rtos_idle.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,51 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "rtos/rtos_idle.h"
+
+static void default_idle_hook(void)
+{
+    /* Sleep: ideally, we should put the chip to sleep.
+     Unfortunately, this usually requires disconnecting the interface chip (debugger).
+     This can be done, but it would break the local file system.
+    */
+    // sleep();
+}
+static void (*idle_hook_fptr)(void) = &default_idle_hook;
+
+void rtos_attach_idle_hook(void (*fptr)(void))
+{
+    //Attach the specified idle hook, or the default idle hook in case of a NULL pointer
+    if (fptr != NULL) {
+        idle_hook_fptr = fptr;
+    } else {
+        idle_hook_fptr = default_idle_hook;
+    }
+}
+
+void rtos_idle_loop(void)
+{
+    //Continuously call the idle hook function pointer
+    while (1) {
+        idle_hook_fptr();
+    }
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtos/rtos_idle.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtos/rtos_idle.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,42 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2012 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef RTOS_IDLE_H
+#define RTOS_IDLE_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rtos_attach_idle_hook(void (*fptr)(void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/HAL_CM.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/HAL_CM.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,207 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    HAL_CM.C
+ *      Purpose: Hardware Abstraction Layer for Cortex-M
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_HAL_CM.h"
+#include "cmsis_os.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+#ifdef DBG_MSG
+BIT dbg_msg;
+#endif
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_init_stack ---------------------------------*/
+
+void rt_init_stack (P_TCB p_TCB, FUNCP task_body) {
+  /* Prepare TCB and saved context for a first time start of a task. */
+  U32 *stk,i,size;
+
+  /* Prepare a complete interrupt frame for first task start */
+  size = p_TCB->priv_stack >> 2;
+  if (size == 0U) {
+    size = (U16)os_stackinfo >> 2;
+  }
+
+  /* Write to the top of stack. */
+  stk = &p_TCB->stack[size];
+
+  /* Auto correct to 8-byte ARM stack alignment. */
+  if ((U32)stk & 0x04U) {
+    stk--;
+  }
+
+  stk -= 16;
+
+  /* Default xPSR and initial PC */
+  stk[15] = INITIAL_xPSR;
+  stk[14] = (U32)task_body;
+
+  /* Clear R4-R11,R0-R3,R12,LR registers. */
+  for (i = 0U; i < 14U; i++) {
+    stk[i] = 0U;
+  }
+
+  /* Assign a void pointer to R0. */
+  stk[8] = (U32)p_TCB->msg;
+
+  /* Initial Task stack pointer. */
+  p_TCB->tsk_stack = (U32)stk;
+
+  /* Task entry point. */
+  p_TCB->ptask = task_body;
+
+
+#ifdef __MBED_CMSIS_RTOS_CM
+  /* Set a magic word for checking of stack overflow.
+   For the main thread (ID: MAIN_THREAD_ID) the stack is in a memory area shared with the
+   heap, therefore the last word of the stack is a moving target.
+   We want to do stack/heap collision detection instead.
+   Similar applies to stack filling for the magic pattern.
+  */
+  if (p_TCB->task_id != MAIN_THREAD_ID) {
+    p_TCB->stack[0] = MAGIC_WORD;
+
+    /* Initialize stack with magic pattern. */
+    if (os_stackinfo & 0x10000000U) {
+      if (size > (16U+1U)) {
+        for (i = ((size - 16U)/2U) - 1U; i; i--) {
+          stk -= 2U;
+          stk[1] = MAGIC_PATTERN;
+          stk[0] = MAGIC_PATTERN;
+        }
+        if (--stk > p_TCB->stack) {
+          *stk = MAGIC_PATTERN;
+        }
+      }
+    }
+  }
+#else
+  /* Initialize stack with magic pattern. */
+  if (os_stackinfo & 0x10000000U) {
+    if (size > (16U+1U)) {
+      for (i = ((size - 16U)/2U) - 1U; i; i--) {
+        stk -= 2U;
+        stk[1] = MAGIC_PATTERN;
+        stk[0] = MAGIC_PATTERN;
+      }
+      if (--stk > p_TCB->stack) {
+        *stk = MAGIC_PATTERN;
+      }
+    }
+  }
+
+  /* Set a magic word for checking of stack overflow. */
+  p_TCB->stack[0] = MAGIC_WORD;
+#endif
+}
+
+
+/*--------------------------- rt_ret_val ----------------------------------*/
+
+static __inline U32 *rt_ret_regs (P_TCB p_TCB) {
+  /* Get pointer to task return value registers (R0..R3) in Stack */
+#if defined(__TARGET_FPU_VFP)
+  if (p_TCB->stack_frame) {
+    /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */
+    return (U32 *)(p_TCB->tsk_stack + (8U*4U) + (16U*4U));
+  } else {
+    /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */
+    return (U32 *)(p_TCB->tsk_stack + (8U*4U));
+  }
+#else
+  /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */
+  return (U32 *)(p_TCB->tsk_stack + (8U*4U));
+#endif
+}
+
+void rt_ret_val (P_TCB p_TCB, U32 v0) {
+  U32 *ret;
+
+  ret = rt_ret_regs(p_TCB);
+  ret[0] = v0;
+}
+
+void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) {
+  U32 *ret;
+
+  ret = rt_ret_regs(p_TCB);
+  ret[0] = v0;
+  ret[1] = v1;
+}
+
+
+/*--------------------------- dbg_init --------------------------------------*/
+
+#ifdef DBG_MSG
+void dbg_init (void) {
+  if (((DEMCR & DEMCR_TRCENA) != 0U)     && 
+      ((ITM_CONTROL & ITM_ITMENA) != 0U) &&
+      ((ITM_ENABLE & (1UL << 31)) != 0U)) {
+    dbg_msg = __TRUE;
+  }
+}
+#endif
+
+/*--------------------------- dbg_task_notify -------------------------------*/
+
+#ifdef DBG_MSG
+void dbg_task_notify (P_TCB p_tcb, BOOL create) {
+  while (ITM_PORT31_U32 == 0U);
+  ITM_PORT31_U32 = (U32)p_tcb->ptask;
+  while (ITM_PORT31_U32 == 0U);
+  ITM_PORT31_U16 = (U16)((create << 8) | p_tcb->task_id);
+}
+#endif
+
+/*--------------------------- dbg_task_switch -------------------------------*/
+
+#ifdef DBG_MSG
+void dbg_task_switch (U32 task_id) {
+  while (ITM_PORT31_U32 == 0U);
+  ITM_PORT31_U8 = (U8)task_id;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,608 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RTX_CM_LIB.H
+ *      Purpose: RTX Kernel System Configuration
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+#include "mbed_error.h"
+
+#if   defined (__CC_ARM)
+#include <rt_misc.h>
+#pragma O3
+#define __USED __attribute__((used))
+#elif defined (__GNUC__)
+#pragma GCC optimize ("O3")
+#define __USED __attribute__((used))
+#elif defined (__ICCARM__)
+#define __USED __root
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Definitions
+ *---------------------------------------------------------------------------*/
+
+#define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
+#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
+
+#define OS_TCB_SIZE     64
+#define OS_TMR_SIZE     8
+
+typedef void    *OS_ID;
+typedef uint32_t OS_TID;
+typedef uint32_t OS_MUT[4];
+typedef uint32_t OS_RESULT;
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+
+#define runtask_id()    rt_tsk_self()
+#define mutex_init(m)   rt_mut_init(m)
+#define mutex_wait(m)   os_mut_wait(m,0xFFFFU)
+#define mutex_rel(m)    os_mut_release(m)
+
+extern uint8_t   os_running;
+extern OS_TID    rt_tsk_self    (void);
+extern void      rt_mut_init    (OS_ID mutex);
+extern OS_RESULT rt_mut_release (OS_ID mutex);
+extern OS_RESULT rt_mut_wait    (OS_ID mutex, uint16_t timeout);
+
+#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
+#define os_mut_release(mutex)      _os_mut_release((uint32_t)rt_mut_release,mutex)
+
+OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex)                   __svc_indirect(0);
+OS_RESULT _os_mut_wait    (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
+
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+#if (OS_TASKCNT == 0)
+#error "Invalid number of concurrent running threads!"
+#endif
+
+#if (OS_PRIVCNT >= OS_TASKCNT)
+#error "Too many threads with user-provided stack size!"
+#endif
+
+#if (OS_TIMERS != 0)
+#define OS_TASK_CNT (OS_TASKCNT + 1)
+#ifndef __MBED_CMSIS_RTOS_CM
+#define OS_PRIV_CNT (OS_PRIVCNT + 2)
+#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
+#endif
+#else
+#define OS_TASK_CNT  OS_TASKCNT
+#ifndef __MBED_CMSIS_RTOS_CM
+#define OS_PRIV_CNT (OS_PRIVCNT + 1)
+#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
+#endif
+#endif
+
+#ifndef OS_STKINIT
+#define OS_STKINIT  0
+#endif
+
+uint16_t const os_maxtaskrun = OS_TASK_CNT;
+#ifdef __MBED_CMSIS_RTOS_CM
+uint32_t const os_stackinfo  = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_IDLESTKSIZE*4);
+#else
+uint32_t const os_stackinfo  = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
+#endif
+uint32_t const os_rrobin     = (OS_ROBIN << 16) | OS_ROBINTOUT;
+uint32_t const os_tickfreq   = OS_CLOCK;
+uint16_t const os_tickus_i   = OS_CLOCK/1000000;
+uint16_t const os_tickus_f   = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000;
+uint32_t const os_trv        = OS_TRV;
+#if       defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)
+uint8_t  const os_flags      = 0;
+#else  /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
+uint8_t  const os_flags      = OS_RUNPRIV;
+#endif /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
+
+/* Export following defines to uVision debugger. */
+__USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS;
+__USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX;
+__USED uint32_t const os_clockrate = OS_TICK;
+__USED uint32_t const os_timernum  = 0U;
+
+/* Memory pool for TCB allocation    */
+_declare_box  (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
+uint16_t const mp_tcb_size = sizeof(mp_tcb);
+
+#ifdef __MBED_CMSIS_RTOS_CM
+/* Memory pool for os_idle_demon stack allocation. */
+_declare_box8 (mp_stk, OS_IDLESTKSIZE*4, 1);
+uint32_t const mp_stk_size = sizeof(mp_stk);
+#else
+/* Memory pool for System stack allocation (+os_idle_demon). */
+_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
+uint32_t const mp_stk_size = sizeof(mp_stk);
+
+/* Memory pool for user specified stack allocation (+main, +timer) */
+uint64_t       os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
+uint32_t const os_stack_sz = sizeof(os_stack_mem);
+#endif
+
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+/* Fifo Queue buffer for ISR requests.*/
+uint32_t       os_fifo[OS_FIFOSZ*2+1];
+uint8_t  const os_fifo_size = OS_FIFOSZ;
+
+/* An array of Active task pointers. */
+void *os_active_TCB[OS_TASK_CNT];
+
+/* User Timers Resources */
+#if (OS_TIMERS != 0)
+extern void osTimerThread (void const *argument);
+#ifdef __MBED_CMSIS_RTOS_CM
+osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ);
+#else
+osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
+#endif
+osThreadId osThreadId_osTimerThread;
+osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
+osMessageQId osMessageQId_osTimerMessageQ;
+#else
+osThreadDef_t os_thread_def_osTimerThread = { NULL };
+osThreadId osThreadId_osTimerThread;
+osMessageQDef(osTimerMessageQ, 0U, void *);
+osMessageQId osMessageQId_osTimerMessageQ;
+#endif
+
+/* Legacy RTX User Timers not used */
+uint32_t       os_tmr = 0U;
+uint32_t const *m_tmr = NULL;
+uint16_t const mp_tmr_size = 0U;
+
+/* singleton mutex */
+osMutexId singleton_mutex_id;
+osMutexDef(singleton_mutex);
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+ /* A memory space for arm standard library. */
+ static uint32_t std_libspace[OS_TASK_CNT][96/4];
+ static OS_MUT   std_libmutex[OS_MUTEXCNT];
+ static uint32_t nr_mutex;
+ extern void  *__libspace_start;
+#endif
+
+#if defined (__ICCARM__)
+static osMutexId  std_mutex_id_sys[_MAX_LOCK] = {0};
+static OS_MUT     std_mutex_sys[_MAX_LOCK] = {0};
+#define _FOPEN_MAX 10
+static osMutexId  std_mutex_id_file[_FOPEN_MAX] = {0};
+static OS_MUT     std_mutex_file[_FOPEN_MAX] = {0};
+void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
+{
+  osMutexDef_t def;
+  uint32_t index;
+  for (index = 0; index < _MAX_LOCK; index++) {
+    if (0 == std_mutex_id_sys[index]) {
+      def.mutex = &std_mutex_sys[index];
+      std_mutex_id_sys[index] = osMutexCreate(&def);
+      *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index];
+      return;
+    }
+  }
+  // This should never happen
+  error("Not enough mutexes\n");
+}
+
+void __iar_system_Mtxdst(__iar_Rmtx *mutex)/*Destroy a system lock */
+{
+  osMutexDelete(*(osMutexId*)*mutex);
+  *mutex = 0;
+}
+
+void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */
+{
+  osMutexWait(*(osMutexId*)*mutex, osWaitForever);
+}
+
+void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */
+{
+  osMutexRelease(*(osMutexId*)*mutex);
+}
+
+void __iar_file_Mtxinit(__iar_Rmtx *mutex)/*Initialize a file lock */
+{
+    osMutexDef_t def;
+    uint32_t index;
+    for (index = 0; index < _FOPEN_MAX; index++) {
+      if (0 == std_mutex_id_file[index]) {
+        def.mutex = &std_mutex_file[index];
+        std_mutex_id_file[index] = osMutexCreate(&def);
+        *mutex = (__iar_Rmtx*)&std_mutex_id_file[index];
+        return;
+      }
+    }
+    // The variable _FOPEN_MAX needs to be increased
+    error("Not enough mutexes\n");
+}
+
+void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */
+{
+  osMutexDelete(*(osMutexId*)*mutex);
+  *mutex = 0;
+}
+
+void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */
+{
+  osMutexWait(*(osMutexId*)*mutex, osWaitForever);
+}
+
+void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */
+{
+  osMutexRelease(*(osMutexId*)*mutex);
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX Optimizations (empty functions)
+ *---------------------------------------------------------------------------*/
+
+#if OS_ROBIN == 0
+ void rt_init_robin (void) {;}
+ void rt_chk_robin  (void) {;}
+#endif
+
+#if OS_STKCHECK == 0
+ void rt_stk_check  (void) {;}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Standard Library multithreading interface
+ *---------------------------------------------------------------------------*/
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+
+/*--------------------------- __user_perthread_libspace ---------------------*/
+
+void *__user_perthread_libspace (void) {
+  /* Provide a separate libspace for each task. */
+  uint32_t idx;
+
+  idx = (os_running != 0U) ? runtask_id () : 0U;
+  if (idx == 0U) {
+    /* RTX not running yet. */
+    return (&__libspace_start);
+  }
+  return ((void *)&std_libspace[idx-1]);
+}
+
+/*--------------------------- _mutex_initialize -----------------------------*/
+
+int _mutex_initialize (OS_ID *mutex) {
+  /* Allocate and initialize a system mutex. */
+
+  if (nr_mutex >= OS_MUTEXCNT) {
+    /* If you are here, you need to increase the number OS_MUTEXCNT. */
+    error("Not enough stdlib mutexes\n");
+  }
+  *mutex = &std_libmutex[nr_mutex++];
+  mutex_init (*mutex);
+  return (1);
+}
+
+
+/*--------------------------- _mutex_acquire --------------------------------*/
+
+__attribute__((used)) void _mutex_acquire (OS_ID *mutex) {
+  /* Acquire a system mutex, lock stdlib resources. */
+  if (os_running) {
+    /* RTX running, acquire a mutex. */
+    mutex_wait (*mutex);
+  }
+}
+
+
+/*--------------------------- _mutex_release --------------------------------*/
+
+__attribute__((used)) void _mutex_release (OS_ID *mutex) {
+  /* Release a system mutex, unlock stdlib resources. */
+  if (os_running) {
+    /* RTX running, release a mutex. */
+    mutex_rel (*mutex);
+  }
+}
+
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      RTX Startup
+ *---------------------------------------------------------------------------*/
+
+/* Main Thread definition */
+extern void pre_main (void);
+osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, 0U, NULL};
+
+#ifdef __CC_ARM
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+extern uint32_t          Image$$ARM_LIB_HEAP$$Base[];
+#define HEAP_START      ((uint32_t) Image$$ARM_LIB_HEAP$$Base)
+#else
+extern uint32_t          Image$$RW_IRAM1$$ZI$$Limit[];
+#define HEAP_START      (Image$$RW_IRAM1$$ZI$$Limit)
+#endif
+#elif defined(__GNUC__)
+extern uint32_t          __end__[];
+#define HEAP_START      (__end__)
+#elif defined(__ICCARM__)
+#pragma section="HEAP"
+#define HEAP_END  (void *)__section_end("HEAP")
+#endif
+
+void set_main_stack(void) {
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+    // Scheduler stack: OS_MAINSTKSIZE words
+    // Main thread stack: Reserved stack size - OS_MAINSTKSIZE words
+    os_thread_def_main.stack_pointer = (uint32_t *) FINAL_SP;
+    os_thread_def_main.stacksize = (uint32_t) INITIAL_SP - (uint32_t) FINAL_SP - OS_MAINSTKSIZE * 4;
+#else
+#if defined(__ICCARM__)
+    /* For IAR heap is defined  .icf file */
+    uint32_t main_stack_size = ((uint32_t)INITIAL_SP - (uint32_t)HEAP_END) - interrupt_stack_size;
+#else
+    /* For ARM , uARM, or GCC_ARM , heap can grow and reach main stack */
+#endif
+    // That is the bottom of the main stack block: no collision detection
+    os_thread_def_main.stack_pointer = HEAP_START;
+
+    // Leave OS_MAINSTKSIZE words for the scheduler and interrupts
+    os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_MAINSTKSIZE * 4);
+#endif
+}
+
+#if defined (__CC_ARM)
+
+#ifdef __MICROLIB
+
+int main(void);
+void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
+void $Super$$__cpp_initialize__aeabi_(void);
+
+void _main_init (void) {
+  osKernelInitialize();
+#ifdef __MBED_CMSIS_RTOS_CM
+  set_main_stack();
+#endif
+  osThreadCreate(&os_thread_def_main, NULL);
+  osKernelStart();
+  for (;;);
+}
+
+void $Sub$$__cpp_initialize__aeabi_(void)
+{
+  // this should invoke C++ initializers prior _main_init, we keep this empty and
+  // invoke them after _main_init (=starts RTX kernel)
+}
+
+void pre_main()
+{
+  singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+  $Super$$__cpp_initialize__aeabi_();
+  main();
+}
+
+#else
+
+void * armcc_heap_base;
+void * armcc_heap_top;
+
+int main(void);
+
+void pre_main (void)
+{
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+    __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
+    main();
+}
+
+/* The single memory model is checking for stack collision at run time, verifing
+   that the heap pointer is underneath the stack pointer.
+
+   With the RTOS there is not only one stack above the heap, there are multiple
+   stacks and some of them are underneath the heap pointer.
+*/
+#pragma import(__use_two_region_memory)
+
+__asm void __rt_entry (void) {
+
+  IMPORT  __user_setup_stackheap
+  IMPORT  armcc_heap_base
+  IMPORT  armcc_heap_top
+  IMPORT  _platform_post_stackheap_init
+  IMPORT  os_thread_def_main
+  IMPORT  osKernelInitialize
+#ifdef __MBED_CMSIS_RTOS_CM
+  IMPORT  set_main_stack
+#endif
+  IMPORT  osKernelStart
+  IMPORT  osThreadCreate
+
+  /* __user_setup_stackheap returns:
+   * - Heap base in r0 (if the program uses the heap).
+   * - Stack base in sp.
+   * - Heap limit in r2 (if the program uses the heap and uses two-region memory).
+   *
+   * More info can be found in:
+   * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide
+   */
+  BL      __user_setup_stackheap
+  LDR     R3,=armcc_heap_base
+  LDR     R4,=armcc_heap_top
+  STR     R0,[R3]
+  STR     R2,[R4]
+  BL      _platform_post_stackheap_init
+  BL      osKernelInitialize
+#ifdef __MBED_CMSIS_RTOS_CM
+  BL      set_main_stack
+#endif
+  LDR     R0,=os_thread_def_main
+  MOVS    R1,#0
+  BL      osThreadCreate
+  BL      osKernelStart
+  /* osKernelStart should not return */
+  B       .
+
+  ALIGN
+}
+
+#endif
+
+#elif defined (__GNUC__)
+
+osMutexDef(malloc_mutex);
+static osMutexId malloc_mutex_id;
+osMutexDef(env_mutex);
+static osMutexId env_mutex_id;
+
+extern int atexit(void (*func)(void));
+extern void __libc_fini_array(void);
+extern void __libc_init_array (void);
+extern int main(int argc, char **argv);
+
+void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+    malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex));
+    env_mutex_id = osMutexCreate(osMutex(env_mutex));
+    __libc_init_array();
+    main(0, NULL);
+}
+
+__attribute__((naked)) void software_init_hook_rtos (void) {
+  __asm (
+    "bl   osKernelInitialize\n"
+#ifdef __MBED_CMSIS_RTOS_CM
+    "bl   set_main_stack\n"
+#endif
+    "ldr  r0,=os_thread_def_main\n"
+    "movs r1,#0\n"
+    "bl   osThreadCreate\n"
+    "bl   osKernelStart\n"
+    /* osKernelStart should not return */
+    "B       .\n"
+  );
+}
+
+// Opaque declaration of _reent structure
+struct _reent;
+
+void __rtos_malloc_lock( struct _reent *_r )
+{
+    osMutexWait(malloc_mutex_id, osWaitForever);
+}
+
+void __rtos_malloc_unlock( struct _reent *_r )
+{
+    osMutexRelease(malloc_mutex_id);
+}
+
+void __rtos_env_lock( struct _reent *_r )
+{
+    osMutexWait(env_mutex_id, osWaitForever);
+}
+
+void __rtos_env_unlock( struct _reent *_r )
+{
+    osMutexRelease(env_mutex_id);
+}
+
+#elif defined (__ICCARM__)
+
+extern void* __vector_table;
+extern int  __low_level_init(void);
+extern void __iar_data_init3(void);
+extern __weak void __iar_init_core( void );
+extern __weak void __iar_init_vfp( void );
+extern void __iar_dynamic_initialization(void);
+extern void mbed_sdk_init(void);
+extern void mbed_main(void);
+extern int main(void);
+extern void exit(int arg);
+
+static uint8_t low_level_init_needed;
+
+void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+    if (low_level_init_needed) {
+        __iar_dynamic_initialization();
+    }
+    mbed_main();
+    main();
+}
+
+#pragma required=__vector_table
+void __iar_program_start( void )
+{
+#ifdef __MBED_CMSIS_RTOS_CM
+  __iar_init_core();
+  __iar_init_vfp();
+
+  uint8_t low_level_init_needed_local;
+
+  low_level_init_needed_local = __low_level_init();
+  if (low_level_init_needed_local) {
+    __iar_data_init3();
+    mbed_sdk_init();
+  }
+  /* Store in a global variable after RAM has been initialized */
+  low_level_init_needed = low_level_init_needed_local;
+#endif
+  osKernelInitialize();
+#ifdef __MBED_CMSIS_RTOS_CM
+  set_main_stack();
+#endif
+  osThreadCreate(&os_thread_def_main, NULL);
+  osKernelStart();
+  /* osKernelStart should not return */
+  while (1);
+}
+
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,281 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RTX_Conf_CM.C
+ *      Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
+ *      Rev.:    V4.70.1
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "cmsis_os.h"
+
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part BEGIN
+ *---------------------------------------------------------------------------*/
+
+// Include per-target RTX config file
+#include "mbed_rtx4.h"
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
+//
+// <h>Thread Configuration
+// =======================
+//
+//   <o>Number of concurrent running user threads <1-250>
+//   <i> Defines max. number of user threads that will run at the same time.
+//   <i> Default: 6
+#ifndef OS_TASKCNT
+ #error "no target defined"
+#endif
+
+#ifdef __MBED_CMSIS_RTOS_CM
+//   <o>Idle stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines default stack size for the Idle thread.
+#ifndef OS_IDLESTKSIZE
+ #define OS_IDLESTKSIZE 128
+#endif
+#else // __MBED_CMSIS_RTOS_CM
+//   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines default stack size for threads with osThreadDef stacksz = 0
+//   <i> Default: 200
+#ifndef OS_STKSIZE
+ #define OS_STKSIZE     200
+#endif
+#endif // __MBED_CMSIS_RTOS_CM
+
+//   <o>Main Thread stack size [bytes] <64-32768:8><#/4>
+#ifndef OS_MAINSTKSIZE
+ #error "no target defined"
+#endif
+
+#ifndef __MBED_CMSIS_RTOS_CM
+//   <o>Number of threads with user-provided stack size <0-250>
+//   <i> Defines the number of threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVCNT
+ #define OS_PRIVCNT     0
+#endif
+
+//   <o>Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4>
+//   <i> Defines the combined stack size for threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVSTKSIZE
+ #define OS_PRIVSTKSIZE 0       // this stack size value is in words
+#endif
+#endif // __MBED_CMSIS_RTOS_CM
+
+//   <q>Stack overflow checking
+//   <i> Enable stack overflow checks at thread switch.
+//   <i> Enabling this option increases slightly the execution time of a thread switch.
+#ifndef OS_STKCHECK
+ #define OS_STKCHECK    1
+#endif
+
+//   <q>Stack usage watermark
+//   <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
+//   <i> Enabling this option increases significantly the execution time of osThreadCreate.
+#ifndef OS_STKINIT
+  #if (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED)
+   #define OS_STKINIT   1
+  #else
+   #define OS_STKINIT   0
+  #endif
+#endif
+
+//   <o>Processor mode for thread execution
+//     <0=> Unprivileged mode
+//     <1=> Privileged mode
+//   <i> Default: Privileged mode
+#ifndef OS_RUNPRIV
+ #define OS_RUNPRIV     1
+#endif
+
+// </h>
+
+// <h>RTX Kernel Timer Tick Configuration
+// ======================================
+//   <q> Use Cortex-M SysTick timer as RTX Kernel Timer
+//   <i> Cortex-M processors provide in most cases a SysTick timer that can be used as
+//   <i> as time-base for RTX.
+#ifndef OS_SYSTICK
+ #define OS_SYSTICK                1
+#endif
+//
+//   <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
+//   <i> Defines the input frequency of the RTOS Kernel Timer.
+//   <i> When the Cortex-M SysTick timer is used, the input clock
+//   <i> is on most systems identical with the core clock.
+#ifndef OS_CLOCK
+ #error "no target defined"
+#endif
+
+//   <o>RTX Timer tick interval value [us] <1-1000000>
+//   <i> The RTX Timer tick interval value is used to calculate timeout values.
+//   <i> When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer.
+//   <i> Default: 1000  (1ms)
+#ifndef OS_TICK
+ #define OS_TICK        1000
+#endif
+
+// </h>
+
+// <h>System Configuration
+// =======================
+//
+// <e>Round-Robin Thread switching
+// ===============================
+//
+// <i> Enables Round-Robin Thread switching.
+#ifndef OS_ROBIN
+ #define OS_ROBIN       1
+#endif
+
+//   <o>Round-Robin Timeout [ticks] <1-1000>
+//   <i> Defines how long a thread will execute before a thread switch.
+//   <i> Default: 5
+#ifndef OS_ROBINTOUT
+ #define OS_ROBINTOUT   5
+#endif
+
+// </e>
+
+// <e>User Timers
+// ==============
+//   <i> Enables user Timers
+#ifndef OS_TIMERS
+ #define OS_TIMERS      1
+#endif
+
+//   <o>Timer Thread Priority
+//                        <1=> Low
+//     <2=> Below Normal  <3=> Normal  <4=> Above Normal
+//                        <5=> High
+//                        <6=> Realtime (highest)
+//   <i> Defines priority for Timer Thread
+//   <i> Default: High
+#ifndef OS_TIMERPRIO
+ #define OS_TIMERPRIO   5
+#endif
+
+//   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for Timer thread.
+//   <i> Default: 200
+#ifndef OS_TIMERSTKSZ
+ #define OS_TIMERSTKSZ  200
+#endif
+
+//   <o>Timer Callback Queue size <1-32>
+//   <i> Number of concurrent active timer callback functions.
+//   <i> Default: 4
+#ifndef OS_TIMERCBQS
+ #define OS_TIMERCBQS   4
+#endif
+
+// </e>
+
+//   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
+//                         <12=> 12 entries  <16=> 16 entries
+//                         <24=> 24 entries  <32=> 32 entries
+//                         <48=> 48 entries  <64=> 64 entries
+//                         <96=> 96 entries
+//   <i> ISR functions store requests to this buffer,
+//   <i> when they are called from the interrupt handler.
+//   <i> Default: 16 entries
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+// </h>
+
+//------------- <<< end of configuration section >>> -----------------------
+
+// Standard library system mutexes
+// ===============================
+//  Define max. number system mutexes that are used to protect
+//  the arm standard runtime library. For microlib they are not used.
+#ifndef OS_MUTEXCNT
+ #define OS_MUTEXCNT    12
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part END
+ *---------------------------------------------------------------------------*/
+
+#define OS_TRV          ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
+
+
+/*----------------------------------------------------------------------------
+ *      OS Idle daemon
+ *---------------------------------------------------------------------------*/
+extern void rtos_idle_loop(void);
+
+void os_idle_demon (void) {
+    /* The idle demon is a system thread, running when no other thread is      */
+    /* ready to run.                                                           */
+    rtos_idle_loop();
+}
+
+/*----------------------------------------------------------------------------
+ *      RTX Errors
+ *---------------------------------------------------------------------------*/
+extern void error(const char* format, ...);
+extern osThreadId svcThreadGetId (void);
+
+void os_error (uint32_t err_code) {
+    /* This function is called when a runtime error is detected. Parameter     */
+    /* 'err_code' holds the runtime error code (defined in RTX_Config.h).      */
+    osThreadId err_task = svcThreadGetId();
+    error("RTX error code: 0x%08X, task ID: 0x%08X\n", err_code, err_task);
+}
+
+void sysThreadError(osStatus status) {
+    if (status != osOK) {
+        osThreadId err_task = svcThreadGetId();
+        error("CMSIS-RTOS error status: 0x%08X, task ID: 0x%08X\n", status, err_task);
+    }
+}
+
+/*----------------------------------------------------------------------------
+ *      RTX Hooks
+ *---------------------------------------------------------------------------*/
+extern void thread_terminate_hook(osThreadId id);
+
+void sysThreadTerminate(osThreadId id) {
+    thread_terminate_hook(id);
+}
+
+/*----------------------------------------------------------------------------
+ *      RTX Configuration Functions
+ *---------------------------------------------------------------------------*/
+
+#include "RTX_CM_lib.h"
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Config.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,84 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RTX_CONFIG.H
+ *      Purpose: Exported functions of RTX_Config.c
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+
+/* Error Codes */
+#define OS_ERR_STK_OVF          1U
+#define OS_ERR_FIFO_OVF         2U
+#define OS_ERR_MBX_OVF          3U
+#define OS_ERR_TIMER_OVF        4U
+
+/* Definitions */
+#define BOX_ALIGN_8                   0x80000000U
+#define _declare_box(pool,size,cnt)   U32 pool[(((size)+3)/4)*(cnt) + 3]
+#define _declare_box8(pool,size,cnt)  U64 pool[(((size)+7)/8)*(cnt) + 2]
+#define _init_box8(pool,size,bsize)   _init_box (pool,size,(bsize) | BOX_ALIGN_8)
+
+/* Variables */
+extern U32 mp_tcb[];
+extern U64 mp_stk[];
+extern U32 os_fifo[];
+extern void *os_active_TCB[];
+
+/* Constants */
+extern U16 const os_maxtaskrun;
+extern U32 const os_trv;
+extern U8  const os_flags;
+extern U32 const os_stackinfo;
+extern U32 const os_rrobin;
+extern U32 const os_clockrate;
+extern U32 const os_timernum;
+extern U16 const mp_tcb_size;
+extern U32 const mp_stk_size;
+extern U32 const *m_tmr;
+extern U16 const mp_tmr_size;
+extern U8  const os_fifo_size;
+
+/* Functions */
+extern void os_idle_demon   (void);
+extern S32  os_tick_init    (void);
+extern U32  os_tick_val     (void);
+extern U32  os_tick_ovf     (void);
+extern void os_tick_irqack  (void);
+extern void os_tmr_call     (U16  info);
+extern void os_error        (U32 err_code);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,274 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    HAL_CM3.C
+ *      Purpose: Hardware Abstraction Layer for Cortex-M3
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_HAL_CM.h"
+#include "rt_Task.h"
+#include "rt_MemBox.h"
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_set_PSP ------------------------------------*/
+
+__asm void rt_set_PSP (U32 stack) {
+        MSR     PSP,R0
+        BX      LR
+}
+
+
+/*--------------------------- rt_get_PSP ------------------------------------*/
+
+__asm U32 rt_get_PSP (void) {
+        MRS     R0,PSP
+        BX      LR
+}
+
+
+/*--------------------------- os_set_env ------------------------------------*/
+
+__asm void os_set_env (void) {
+   /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
+        MOV     R0,SP                   ; PSP = MSP
+        MSR     PSP,R0
+        LDR     R0,=__cpp(&os_flags)
+        LDRB    R0,[R0]
+        LSLS    R0,#31
+        MOVNE   R0,#0x02                ; Privileged Thread mode, use PSP
+        MOVEQ   R0,#0x03                ; Unprivileged Thread mode, use PSP
+        MSR     CONTROL,R0
+        BX      LR
+
+        ALIGN
+}
+
+
+/*--------------------------- _alloc_box ------------------------------------*/
+
+__asm void *_alloc_box (void *box_mem) {
+   /* Function wrapper for Unprivileged/Privileged mode. */
+        LDR     R12,=__cpp(rt_alloc_box)
+        MRS     R3,IPSR
+        LSLS    R3,#24
+        BXNE    R12
+        MRS     R3,CONTROL
+        LSLS    R3,#31
+        BXEQ    R12
+        SVC     0
+        BX      LR
+
+        ALIGN
+}
+
+
+/*--------------------------- _free_box -------------------------------------*/
+
+__asm U32 _free_box (void *box_mem, void *box) {
+   /* Function wrapper for Unprivileged/Privileged mode. */
+        LDR     R12,=__cpp(rt_free_box)
+        MRS     R3,IPSR
+        LSLS    R3,#24
+        BXNE    R12
+        MRS     R3,CONTROL
+        LSLS    R3,#31
+        BXEQ    R12
+        SVC     0
+        BX      LR
+
+        ALIGN
+}
+
+
+/*-------------------------- SVC_Handler ------------------------------------*/
+
+__asm void SVC_Handler (void) {
+        PRESERVE8
+
+        IMPORT  SVC_Count
+        IMPORT  SVC_Table
+        IMPORT  rt_stk_check
+
+#ifdef  IFX_XMC4XXX
+        EXPORT  SVC_Handler_Veneer
+SVC_Handler_Veneer        
+#endif
+
+        MRS     R0,PSP                  ; Read PSP
+        LDR     R1,[R0,#24]             ; Read Saved PC from Stack
+        LDRB    R1,[R1,#-2]             ; Load SVC Number
+        CBNZ    R1,SVC_User
+
+        LDM     R0,{R0-R3,R12}          ; Read R0-R3,R12 from stack
+        BLX     R12                     ; Call SVC Function
+
+        MRS     R12,PSP                 ; Read PSP
+        STM     R12,{R0-R2}             ; Store return values
+
+        LDR     R3,=__cpp(&os_tsk)
+        LDM     R3,{R1,R2}              ; os_tsk.run, os_tsk.new
+        CMP     R1,R2
+        BEQ     SVC_Exit                ; no task switch
+
+        CBZ     R1,SVC_Next             ; Runtask deleted?
+        STMDB   R12!,{R4-R11}           ; Save Old context
+        STR     R12,[R1,#TCB_TSTACK]    ; Update os_tsk.run->tsk_stack
+
+        PUSH    {R2,R3}
+        BL      rt_stk_check            ; Check for Stack overflow
+        POP     {R2,R3}
+
+SVC_Next
+        STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
+
+        LDR     R12,[R2,#TCB_TSTACK]    ; os_tsk.new->tsk_stack
+        LDMIA   R12!,{R4-R11}           ; Restore New Context
+        MSR     PSP,R12                 ; Write PSP
+
+SVC_Exit
+        MVN     LR,#:NOT:0xFFFFFFFD     ; set EXC_RETURN value
+#ifdef  IFX_XMC4XXX
+        PUSH    {LR}
+        POP     {PC}
+#else
+        BX      LR
+#endif
+
+        /*------------------- User SVC ------------------------------*/
+
+SVC_User
+        PUSH    {R4,LR}                 ; Save Registers
+        LDR     R2,=SVC_Count
+        LDR     R2,[R2]
+        CMP     R1,R2
+        BHI     SVC_Done                ; Overflow
+
+        LDR     R4,=SVC_Table-4
+        LDR     R4,[R4,R1,LSL #2]       ; Load SVC Function Address
+
+        LDM     R0,{R0-R3,R12}          ; Read R0-R3,R12 from stack
+        BLX     R4                      ; Call SVC Function
+
+        MRS     R12,PSP
+        STM     R12,{R0-R3}             ; Function return values
+SVC_Done
+        POP     {R4,PC}                 ; RETI
+
+        ALIGN
+}
+
+
+/*-------------------------- PendSV_Handler ---------------------------------*/
+
+__asm void PendSV_Handler (void) {
+        PRESERVE8
+
+#ifdef  IFX_XMC4XXX
+        EXPORT  PendSV_Handler_Veneer
+PendSV_Handler_Veneer        
+#endif
+
+        BL      __cpp(rt_pop_req)
+
+Sys_Switch
+        LDR     R3,=__cpp(&os_tsk)
+        LDM     R3,{R1,R2}              ; os_tsk.run, os_tsk.new
+        CMP     R1,R2
+        BEQ     Sys_Exit
+
+        MRS     R12,PSP                 ; Read PSP
+        STMDB   R12!,{R4-R11}           ; Save Old context
+        STR     R12,[R1,#TCB_TSTACK]    ; Update os_tsk.run->tsk_stack
+
+        PUSH    {R2,R3}
+        BL      rt_stk_check            ; Check for Stack overflow
+        POP     {R2,R3}
+
+        STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
+
+        LDR     R12,[R2,#TCB_TSTACK]    ; os_tsk.new->tsk_stack
+        LDMIA   R12!,{R4-R11}           ; Restore New Context
+        MSR     PSP,R12                 ; Write PSP
+
+Sys_Exit
+        MVN     LR,#:NOT:0xFFFFFFFD     ; set EXC_RETURN value
+#ifdef  IFX_XMC4XXX
+        PUSH    {LR}
+        POP     {PC}
+#else
+        BX      LR                      ; Return to Thread Mode
+#endif
+
+        ALIGN
+}
+
+
+/*-------------------------- SysTick_Handler --------------------------------*/
+
+__asm void SysTick_Handler (void) {
+        PRESERVE8
+
+#ifdef  IFX_XMC4XXX
+        EXPORT  SysTick_Handler_Veneer
+SysTick_Handler_Veneer        
+#endif
+
+        BL      __cpp(rt_systick)
+        B       Sys_Switch
+
+        ALIGN
+}
+
+
+/*-------------------------- OS_Tick_Handler --------------------------------*/
+
+__asm void OS_Tick_Handler (void) {
+        PRESERVE8
+
+        BL      __cpp(os_tick_irqack)
+        BL      __cpp(rt_systick)
+        B       Sys_Switch
+
+        ALIGN
+}
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,57 @@
+;/*----------------------------------------------------------------------------
+; *      CMSIS-RTOS  -  RTX
+; *----------------------------------------------------------------------------
+; *      Name:    SVC_TABLE.S
+; *      Purpose: Pre-defined SVC Table for Cortex-M
+; *      Rev.:    V4.70
+; *----------------------------------------------------------------------------
+; *
+; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+; * All rights reserved.
+; * Redistribution and use in source and binary forms, with or without
+; * modification, are permitted provided that the following conditions are met:
+; *  - Redistributions of source code must retain the above copyright
+; *    notice, this list of conditions and the following disclaimer.
+; *  - Redistributions in binary form must reproduce the above copyright
+; *    notice, this list of conditions and the following disclaimer in the
+; *    documentation and/or other materials provided with the distribution.
+; *  - Neither the name of ARM  nor the names of its contributors may be used
+; *    to endorse or promote products derived from this software without
+; *    specific prior written permission.
+; *
+; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+; * POSSIBILITY OF SUCH DAMAGE.
+; *---------------------------------------------------------------------------*/
+
+
+                AREA    SVC_TABLE, CODE, READONLY
+
+                EXPORT  SVC_Count
+
+SVC_Cnt         EQU    (SVC_End-SVC_Table)/4
+SVC_Count       DCD     SVC_Cnt
+
+; Import user SVC functions here.
+;               IMPORT  __SVC_1
+
+                EXPORT  SVC_Table
+SVC_Table
+; Insert user SVC functions here. SVC 0 used by RTL Kernel.
+;               DCD     __SVC_1                 ; user SVC function
+
+SVC_End
+
+                END
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/cmsis_os.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/cmsis_os.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,749 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.h RTX header file
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+
+#ifndef _CMSIS_OS_H
+#define _CMSIS_OS_H
+
+#define CMSIS_OS_RTX
+
+// __MBED_CMSIS_RTOS_CM captures our changes to the RTX kernel
+#ifndef __MBED_CMSIS_RTOS_CM
+#define __MBED_CMSIS_RTOS_CM
+#endif
+// we use __CMSIS_RTOS version, which changes some API in the kernel
+#ifndef __CMSIS_RTOS
+#define __CMSIS_RTOS
+#endif
+
+// The stack space occupied is mainly dependent on the underling C standard library
+#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) || defined(TOOLCHAIN_IAR)
+#    define WORDS_STACK_SIZE   512
+#elif defined(TOOLCHAIN_ARM_MICRO)
+#    define WORDS_STACK_SIZE   128
+#endif
+
+#ifdef __MBED_CMSIS_RTOS_CM
+
+/* If os timers macro is set to 0, there's no timer thread created, therefore
+ * main thread has tid 0x01  
+ */
+#if defined(OS_TIMERS) && (OS_TIMERS == 0)
+#define MAIN_THREAD_ID 0x01
+#else
+#define MAIN_THREAD_ID 0x02
+#endif
+#endif
+
+#if defined(TARGET_XDOT_L151CC)
+#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE/2)
+#else
+#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE*4)
+#endif
+
+#define osCMSIS           0x10002U     ///< CMSIS-RTOS API version (main [31:16] .sub [15:0])
+
+#define osCMSIS_RTX     ((4<<16)|80)   ///< RTOS identification and version (main [31:16] .sub [15:0])
+
+#define osKernelSystemId "RTX V4.80"   ///< RTOS identification string
+
+
+#define osFeature_MainThread   1       ///< main can be thread
+#define osFeature_Pool         1       ///< Memory Pools available
+#define osFeature_MailQ        1       ///< Mail Queues available
+#define osFeature_MessageQ     1       ///< Message Queues available
+#define osFeature_Signals      16      ///< 16 Signal Flags available per thread
+#define osFeature_Semaphore    65535   ///< Maximum count for \ref osSemaphoreCreate function
+#define osFeature_Wait         0       ///< osWait not available
+#define osFeature_SysTick      1       ///< osKernelSysTick functions available
+#define osFeature_ThreadEnum   1       ///< Thread enumeration available
+
+#if defined (__CC_ARM)
+#define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
+#elif defined (__ICCARM__)
+#define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
+#else
+#define os_InRegs
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+// ==== Enumeration, structures, defines ====
+
+/// Priority used for thread control.
+typedef enum  {
+  osPriorityIdle          = -3,          ///< priority: idle (lowest)
+  osPriorityLow           = -2,          ///< priority: low
+  osPriorityBelowNormal   = -1,          ///< priority: below normal
+  osPriorityNormal        =  0,          ///< priority: normal (default)
+  osPriorityAboveNormal   = +1,          ///< priority: above normal
+  osPriorityHigh          = +2,          ///< priority: high
+  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
+  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
+} osPriority;
+
+/// Timeout value.
+#define osWaitForever     0xFFFFFFFFU    ///< wait forever timeout value
+
+/// Status code values returned by CMSIS-RTOS functions.
+typedef enum  {
+  osOK                    =     0,       ///< function completed; no error or event occurred.
+  osEventSignal           =  0x08,       ///< function completed; signal event occurred.
+  osEventMessage          =  0x10,       ///< function completed; message event occurred.
+  osEventMail             =  0x20,       ///< function completed; mail event occurred.
+  osEventTimeout          =  0x40,       ///< function completed; timeout occurred.
+  osErrorParameter        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
+  osErrorResource         =  0x81,       ///< resource not available: a specified resource was not available.
+  osErrorTimeoutResource  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.
+  osErrorISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osErrorISRRecursive     =  0x83,       ///< function called multiple times from ISR with same object.
+  osErrorPriority         =  0x84,       ///< system cannot determine priority or thread has illegal priority.
+  osErrorNoMemory         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorValue            =  0x86,       ///< value of a parameter is out of range.
+  osErrorOS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.
+  os_status_reserved      =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osStatus;
+
+
+/// Timer type value for the timer definition.
+typedef enum  {
+  osTimerOnce             =     0,       ///< one-shot timer
+  osTimerPeriodic         =     1        ///< repeating timer
+} os_timer_type;
+
+typedef enum {
+  osThreadInfoState,
+  osThreadInfoStackSize,
+  osThreadInfoStackMax,
+  osThreadInfoEntry,
+  osThreadInfoArg,
+
+  osThreadInfo_reserved   =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osThreadInfo;
+
+/// Entry point of a thread.
+typedef void (*os_pthread) (void const *argument);
+
+/// Entry point of a timer call back function.
+typedef void (*os_ptimer) (void const *argument);
+
+// >>> the following data type definitions may shall adapted towards a specific RTOS
+
+/// Thread ID identifies the thread (pointer to a thread control block).
+typedef struct os_thread_cb *osThreadId;
+
+/// Timer ID identifies the timer (pointer to a timer control block).
+typedef struct os_timer_cb *osTimerId;
+
+/// Mutex ID identifies the mutex (pointer to a mutex control block).
+typedef struct os_mutex_cb *osMutexId;
+
+/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
+typedef struct os_semaphore_cb *osSemaphoreId;
+
+/// Pool ID identifies the memory pool (pointer to a memory pool control block).
+typedef struct os_pool_cb *osPoolId;
+
+/// Message ID identifies the message queue (pointer to a message queue control block).
+typedef struct os_messageQ_cb *osMessageQId;
+
+/// Mail ID identifies the mail queue (pointer to a mail queue control block).
+typedef struct os_mailQ_cb *osMailQId;
+
+/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block).
+typedef uint32_t *osThreadEnumId;
+
+/// Thread Definition structure contains startup information of a thread.
+typedef struct os_thread_def  {
+  os_pthread               pthread;    ///< start address of thread function
+  osPriority             tpriority;    ///< initial thread priority
+  uint32_t               instances;    ///< maximum number of instances of that thread function
+  uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size
+#ifdef __MBED_CMSIS_RTOS_CM
+  uint32_t               *stack_pointer;  ///< pointer to the stack memory block
+#endif
+} osThreadDef_t;
+
+/// Timer Definition structure contains timer parameters.
+typedef struct os_timer_def  {
+  os_ptimer                 ptimer;    ///< start address of a timer function
+  void                      *timer;    ///< pointer to internal data
+} osTimerDef_t;
+
+/// Mutex Definition structure contains setup information for a mutex.
+typedef struct os_mutex_def  {
+  void                      *mutex;    ///< pointer to internal data
+} osMutexDef_t;
+
+/// Semaphore Definition structure contains setup information for a semaphore.
+typedef struct os_semaphore_def  {
+  void                  *semaphore;    ///< pointer to internal data
+} osSemaphoreDef_t;
+
+/// Definition structure for memory block allocation.
+typedef struct os_pool_def  {
+  uint32_t                 pool_sz;    ///< number of items (elements) in the pool
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< pointer to memory for pool
+} osPoolDef_t;
+
+/// Definition structure for message queue.
+typedef struct os_messageQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  void                       *pool;    ///< memory array for messages
+} osMessageQDef_t;
+
+/// Definition structure for mail queue.
+typedef struct os_mailQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< memory array for mail
+} osMailQDef_t;
+
+/// Event structure contains detailed information about an event.
+typedef struct  {
+  osStatus                 status;     ///< status code: event or error information
+  union  {
+    uint32_t                    v;     ///< message as 32-bit value
+    void                       *p;     ///< message or mail as void pointer
+    int32_t               signals;     ///< signal flags
+  } value;                             ///< event value
+  union  {
+    osMailQId             mail_id;     ///< mail id obtained by \ref osMailCreate
+    osMessageQId       message_id;     ///< message id obtained by \ref osMessageCreate
+  } def;                               ///< event definition
+} osEvent;
+
+
+//  ==== Kernel Control Functions ====
+
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+osStatus osKernelInitialize (void);
+
+/// Start the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+osStatus osKernelStart (void);
+
+/// Check if the RTOS kernel is already started.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+int32_t osKernelRunning(void);
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+
+/// \cond INTERNAL_VARIABLES
+extern uint32_t const os_tickfreq;
+extern uint16_t const os_tickus_i;
+extern uint16_t const os_tickus_f;
+/// \endcond
+
+/// Get the RTOS kernel system timer counter.
+/// \return RTOS kernel system timer as 32-bit value 
+uint32_t osKernelSysTick (void);
+
+/// The RTOS kernel system timer frequency in Hz.
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency os_tickfreq
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+/*
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+*/
+#define osKernelSysTickMicroSec(microsec) ((microsec * os_tickus_i) + ((microsec * os_tickus_f) >> 16))
+
+#endif    // System Timer available
+
+//  ==== Thread Management ====
+
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param         name         name of the thread function.
+/// \param         priority     initial priority of the thread function.
+/// \param         instances    number of possible thread instances.
+/// \param         stacksz      stack size (in bytes) requirements for the thread function.
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osThreadDef(name, priority, instances, stacksz)  \
+extern const osThreadDef_t os_thread_def_##name
+#else                            // define the object
+#ifdef __MBED_CMSIS_RTOS_CM
+#define osThreadDef(name, priority, stacksz)  \
+uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), (priority), 1, (stacksz), (os_thread_def_stack_##name) }
+#else
+#define osThreadDef(name, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), (priority), (instances), (stacksz)  }
+#endif
+#endif
+
+/// Access a Thread definition.
+/// \param         name          name of the thread definition object.
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osThread(name)  \
+&os_thread_def_##name
+
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in]     thread_def    thread definition referenced with \ref osThread.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+
+osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context);
+
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+osThreadId osThreadGetId (void);
+
+/// Terminate execution of a thread and remove it from Active Threads.
+/// \param[in]     thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus osThreadTerminate (osThreadId thread_id);
+
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+osStatus osThreadYield (void);
+
+/// Change priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+
+/// Get current priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the thread function.
+osPriority osThreadGetPriority (osThreadId thread_id);
+
+#ifdef __MBED_CMSIS_RTOS_CM
+/// Get current thread state.
+uint8_t osThreadGetState (osThreadId thread_id);
+#endif
+
+/// Get into from an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     info          information to read.
+/// \return current state of the thread function.
+/// \return requested info that includes the status code.
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info);
+
+//  ==== Generic Wait Functions ====
+
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "Time delay" value
+/// \return status code that indicates the execution status of the function.
+osStatus osDelay (uint32_t millisec);
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0))     // Generic Wait available
+
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec          \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+os_InRegs osEvent osWait (uint32_t millisec);
+
+#endif  // Generic Wait available
+
+
+//  ==== Timer Management Functions ====
+/// Define a Timer object.
+/// \param         name          name of the timer object.
+/// \param         function      name of the timer call back function.
+#if defined (osObjectsExternal)  // object is external
+#define osTimerDef(name, function)  \
+extern const osTimerDef_t os_timer_def_##name
+#else                            // define the object
+#define osTimerDef(name, function)  \
+uint32_t os_timer_cb_##name[6]; \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), (os_timer_cb_##name) }
+#endif
+
+/// Access a Timer definition.
+/// \param         name          name of the timer object.
+#define osTimer(name) \
+&os_timer_def_##name
+
+/// Create a timer.
+/// \param[in]     timer_def     timer object referenced with \ref osTimer.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "Time delay" value of the timer.
+/// \return status code that indicates the execution status of the function.
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+
+/// Stop the timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osTimerStop (osTimerId timer_id);
+
+/// Delete a timer that was created by \ref osTimerCreate.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osTimerDelete (osTimerId timer_id);
+
+
+//  ==== Signal Management ====
+
+/// Set the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that should be set.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event flag information or error code.
+os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec);
+
+
+//  ==== Mutex Management ====
+
+/// Define a Mutex.
+/// \param         name          name of the mutex object.
+#if defined (osObjectsExternal)  // object is external
+#define osMutexDef(name)  \
+extern const osMutexDef_t os_mutex_def_##name
+#else                            // define the object
+#define osMutexDef(name)  \
+uint32_t os_mutex_cb_##name[4] = { 0 }; \
+const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) }
+#endif
+
+/// Access a Mutex definition.
+/// \param         name          name of the mutex object.
+#define osMutex(name)  \
+&os_mutex_def_##name
+
+/// Create and Initialize a Mutex object.
+/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+
+/// Wait until a Mutex becomes available.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osMutexRelease (osMutexId mutex_id);
+
+/// Delete a Mutex that was created by \ref osMutexCreate.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osMutexDelete (osMutexId mutex_id);
+
+
+//  ==== Semaphore Management Functions ====
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))     // Semaphore available
+
+/// Define a Semaphore object.
+/// \param         name          name of the semaphore object.
+#if defined (osObjectsExternal)  // object is external
+#define osSemaphoreDef(name)  \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else                            // define the object
+#define osSemaphoreDef(name)  \
+uint32_t os_semaphore_cb_##name[2] = { 0 }; \
+const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) }
+#endif
+
+/// Access a Semaphore definition.
+/// \param         name          name of the semaphore object.
+#define osSemaphore(name)  \
+&os_semaphore_def_##name
+
+/// Create and Initialize a Semaphore object used for managing resources.
+/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in]     count         number of available resources.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+
+/// Wait until a Semaphore token becomes available.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+
+/// Release a Semaphore token.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+
+/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+
+#endif     // Semaphore available
+
+
+//  ==== Memory Pool Management Functions ====
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0))  // Memory Pool Management available
+
+/// \brief Define a Memory Pool.
+/// \param         name          name of the memory pool.
+/// \param         no            maximum number of blocks (objects) in the memory pool.
+/// \param         type          data type of a single block (object).
+#if defined (osObjectsExternal)  // object is external
+#define osPoolDef(name, no, type)   \
+extern const osPoolDef_t os_pool_def_##name
+#else                            // define the object
+#define osPoolDef(name, no, type)   \
+uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), (os_pool_m_##name) }
+#endif
+
+/// \brief Access a Memory Pool definition.
+/// \param         name          name of the memory pool
+#define osPool(name) \
+&os_pool_def_##name
+
+/// Create and Initialize a memory pool.
+/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+
+/// Allocate a memory block from a memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+void *osPoolAlloc (osPoolId pool_id);
+
+/// Allocate a memory block from a memory pool and set memory block to zero.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+void *osPoolCAlloc (osPoolId pool_id);
+
+/// Return an allocated memory block back to a specific memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in]     block         address of the allocated memory block that is returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+
+#endif   // Memory Pool Management available
+
+
+//  ==== Message Queue Management Functions ====
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0))     // Message Queues available
+
+/// \brief Create a Message Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of messages in the queue.
+/// \param         type          data type of a single message element (for debugger).
+#if defined (osObjectsExternal)  // object is external
+#define osMessageQDef(name, queue_sz, type)   \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else                            // define the object
+#define osMessageQDef(name, queue_sz, type)   \
+uint32_t os_messageQ_q_##name[4+(queue_sz)] = { 0 }; \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), (os_messageQ_q_##name) }
+#endif
+
+/// \brief Access a Message Queue Definition.
+/// \param         name          name of the queue
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+
+/// Create and Initialize a Message Queue.
+/// \param[in]     queue_def     queue definition referenced with \ref osMessageQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+/// Put a Message to a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     info          message information.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Get a Message or Wait for a Message from a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event information that includes status code.
+os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+
+#endif     // Message Queues available
+
+
+//  ==== Mail Queue Management Functions ====
+
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))     // Mail Queues available
+
+/// \brief Create a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \param         queue_sz      maximum number of messages in queue
+/// \param         type          data type of a single message element
+#if defined (osObjectsExternal)  // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern const osMailQDef_t os_mailQ_def_##name
+#else                            // define the object
+#define osMailQDef(name, queue_sz, type) \
+uint32_t os_mailQ_q_##name[4+(queue_sz)] = { 0 }; \
+uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \
+void *   os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \
+const osMailQDef_t os_mailQ_def_##name =  \
+{ (queue_sz), sizeof(type), (os_mailQ_p_##name) }
+#endif
+
+/// \brief Access a Mail Queue Definition.
+/// \param         name          name of the queue
+#define osMailQ(name)  \
+&os_mailQ_def_##name
+
+/// Create and Initialize mail queue.
+/// \param[in]     queue_def     reference to the mail queue definition obtain with \ref osMailQ
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+
+/// Allocate a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Allocate a memory block from a mail and set memory block to zero.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Put a mail to a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+/// \return status code that indicates the execution status of the function.
+osStatus osMailPut (osMailQId queue_id, void *mail);
+
+/// Get a mail from a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return event that contains mail information or error code.
+os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+
+/// Free a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to the memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+
+#endif  // Mail Queues available
+
+
+//  ==== Thread Enumeration Functions ====
+
+#if (defined (osFeature_ThreadEnum)  &&  (osFeature_ThreadEnum != 0))     // Thread enumeration available
+
+/// Start a thread enumeration.
+/// \return an enumeration ID or NULL on error.
+osThreadEnumId _osThreadsEnumStart(void);
+
+/// Get the next task ID in the enumeration.
+/// \return a thread ID or NULL on if the end of the enumeration has been reached.
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id);
+
+/// Free the enumeration structure.
+/// \param[in]     enum_id       pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart.
+/// \return status code that indicates the execution status of the function.
+osStatus _osThreadEnumFree(osThreadEnumId enum_id);
+
+#endif  // Thread Enumeration available
+
+
+//  ==== RTX Extensions ====
+
+/// Suspend the RTX task scheduler.
+/// \return number of ticks, for how long the system can sleep or power-down.
+uint32_t os_suspend (void);
+
+/// Resume the RTX task scheduler
+/// \param[in]     sleep_time    specifies how long the system was in sleep or power-down mode.
+void os_resume (uint32_t sleep_time);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // _CMSIS_OS_H
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,2344 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    rt_CMSIS.c
+ *      Purpose: CMSIS RTOS API
+ *      Rev.:    V4.80
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#define __CMSIS_GENERIC
+
+#if defined (__CORTEX_M4) || defined (__CORTEX_M4F)
+  #include "core_cm4.h"
+#elif defined (__CORTEX_M7) || defined (__CORTEX_M7F)
+  #include "core_cm7.h"
+#elif defined (__CORTEX_M3)
+  #include "core_cm3.h"
+#elif defined (__CORTEX_M0)
+  #include "core_cm0.h"
+#elif defined (__CORTEX_M0PLUS)
+  #include "core_cm0plus.h"
+#else
+  #error "Missing __CORTEX_Mx definition"
+#endif
+
+// This affects cmsis_os only, as it's not used anywhere else. This was left by kernel team
+// to suppress the warning in rt_tid2ptcb about incompatible pointer assignment.
+#define os_thread_cb OS_TCB
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_Task.h"
+#include "rt_Event.h"
+#include "rt_List.h"
+#include "rt_Time.h"
+#include "rt_Mutex.h"
+#include "rt_Semaphore.h"
+#include "rt_Mailbox.h"
+#include "rt_MemBox.h"
+#include "rt_Memory.h"
+#include "rt_HAL_CM.h"
+#include "rt_OsEventObserver.h"
+
+#include "cmsis_os.h"
+
+#if (osFeature_Signals != 16)
+#error Invalid "osFeature_Signals" value!
+#endif
+#if (osFeature_Semaphore > 65535)
+#error Invalid "osFeature_Semaphore" value!
+#endif
+#if (osFeature_Wait != 0)
+#error osWait not supported!
+#endif
+
+
+// ==== Enumeration, structures, defines ====
+
+// Service Calls defines
+
+#if defined (__CC_ARM)          /* ARM Compiler */
+
+#define __NO_RETURN __declspec(noreturn)
+
+#define osEvent_type       osEvent
+#define osEvent_ret_status ret
+#define osEvent_ret_value  ret
+#define osEvent_ret_msg    ret
+#define osEvent_ret_mail   ret
+
+#define osCallback_type    osCallback
+#define osCallback_ret     ret
+
+#define SVC_0_1(f,t,...)                                                       \
+__svc_indirect(0) t  _##f (t(*)());                                            \
+                  t     f (void);                                              \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (void) {                                             \
+  return _##f(f);                                                              \
+}
+
+#define SVC_1_0(f,t,t1,...)                                                    \
+__svc_indirect(0) t  _##f (t(*)(t1),t1);                                       \
+                  t     f (t1 a1);                                             \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (t1 a1) {                                            \
+  _##f(f,a1);                                                                  \
+}
+
+#define SVC_1_1(f,t,t1,...)                                                    \
+__svc_indirect(0) t  _##f (t(*)(t1),t1);                                       \
+                  t     f (t1 a1);                                             \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (t1 a1) {                                            \
+  return _##f(f,a1);                                                           \
+}
+
+#define SVC_2_1(f,t,t1,t2,...)                                                 \
+__svc_indirect(0) t  _##f (t(*)(t1,t2),t1,t2);                                 \
+                  t     f (t1 a1, t2 a2);                                      \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (t1 a1, t2 a2) {                                     \
+  return _##f(f,a1,a2);                                                        \
+}
+
+#define SVC_3_1(f,t,t1,t2,t3,...)                                              \
+__svc_indirect(0) t  _##f (t(*)(t1,t2,t3),t1,t2,t3);                           \
+                  t     f (t1 a1, t2 a2, t3 a3);                               \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (t1 a1, t2 a2, t3 a3) {                              \
+  return _##f(f,a1,a2,a3);                                                     \
+}
+
+#define SVC_4_1(f,t,t1,t2,t3,t4,...)                                           \
+__svc_indirect(0) t  _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4);                     \
+                  t     f (t1 a1, t2 a2, t3 a3, t4 a4);                        \
+__attribute__((always_inline))                                                 \
+static __inline   t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                       \
+  return _##f(f,a1,a2,a3,a4);                                                  \
+}
+
+#define SVC_1_2 SVC_1_1 
+#define SVC_1_3 SVC_1_1 
+#define SVC_2_3 SVC_2_1 
+
+#elif defined (__GNUC__)        /* GNU Compiler */
+
+#define __NO_RETURN __attribute__((noreturn))
+
+typedef uint32_t __attribute__((vector_size(8)))  ret64;
+typedef uint32_t __attribute__((vector_size(16))) ret128;
+
+#define RET_pointer    __r0
+#define RET_int32_t    __r0
+#define RET_uint32_t   __r0
+#define RET_osStatus   __r0
+#define RET_osPriority __r0
+#define RET_osEvent    {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}}
+#define RET_osCallback {(void *)__r0, (void *)__r1}
+
+#define osEvent_type       __attribute__((pcs("aapcs"))) ret128
+#define osEvent_ret_status (ret128){ret.status}
+#define osEvent_ret_value  (ret128){ret.status, ret.value.v}
+#define osEvent_ret_msg    (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id}
+#define osEvent_ret_mail   (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id}
+
+#define osCallback_type    __attribute__((pcs("aapcs"))) ret64
+#define osCallback_ret     (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}
+
+#define SVC_ArgN(n) \
+  register int __r##n __asm("r"#n);
+
+#define SVC_ArgR(n,t,a) \
+  register t   __r##n __asm("r"#n) = a;
+
+#define SVC_Arg0()                                                             \
+  SVC_ArgN(0)                                                                  \
+  SVC_ArgN(1)                                                                  \
+  SVC_ArgN(2)                                                                  \
+  SVC_ArgN(3)
+
+#define SVC_Arg1(t1)                                                           \
+  SVC_ArgR(0,t1,a1)                                                            \
+  SVC_ArgN(1)                                                                  \
+  SVC_ArgN(2)                                                                  \
+  SVC_ArgN(3)
+
+#define SVC_Arg2(t1,t2)                                                        \
+  SVC_ArgR(0,t1,a1)                                                            \
+  SVC_ArgR(1,t2,a2)                                                            \
+  SVC_ArgN(2)                                                                  \
+  SVC_ArgN(3)
+
+#define SVC_Arg3(t1,t2,t3)                                                     \
+  SVC_ArgR(0,t1,a1)                                                            \
+  SVC_ArgR(1,t2,a2)                                                            \
+  SVC_ArgR(2,t3,a3)                                                            \
+  SVC_ArgN(3)
+
+#define SVC_Arg4(t1,t2,t3,t4)                                                  \
+  SVC_ArgR(0,t1,a1)                                                            \
+  SVC_ArgR(1,t2,a2)                                                            \
+  SVC_ArgR(2,t3,a3)                                                            \
+  SVC_ArgR(3,t4,a4)
+
+#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS)
+#define SVC_Call(f)                                                            \
+  __asm volatile                                                               \
+  (                                                                            \
+    "ldr r7,="#f"\n\t"                                                         \
+    "mov r12,r7\n\t"                                                           \
+    "svc 0"                                                                    \
+    :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)         \
+    :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)         \
+    : "r7", "r12", "lr", "cc"                                                  \
+  );
+#else
+#define SVC_Call(f)                                                            \
+  __asm volatile                                                               \
+  (                                                                            \
+    "ldr r12,="#f"\n\t"                                                        \
+    "svc 0"                                                                    \
+    :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)         \
+    :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)         \
+    : "r12", "lr", "cc"                                                        \
+  );
+#endif
+
+#define SVC_0_1(f,t,rv)                                                        \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (void) {                                                \
+  SVC_Arg0();                                                                  \
+  SVC_Call(f);                                                                 \
+  return (t) rv;                                                               \
+}
+
+#define SVC_1_0(f,t,t1)                                                        \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (t1 a1) {                                               \
+  SVC_Arg1(t1);                                                                \
+  SVC_Call(f);                                                                 \
+}
+
+#define SVC_1_1(f,t,t1,rv)                                                     \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (t1 a1) {                                               \
+  SVC_Arg1(t1);                                                                \
+  SVC_Call(f);                                                                 \
+  return (t) rv;                                                               \
+}
+
+#define SVC_2_1(f,t,t1,t2,rv)                                                  \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (t1 a1, t2 a2) {                                        \
+  SVC_Arg2(t1,t2);                                                             \
+  SVC_Call(f);                                                                 \
+  return (t) rv;                                                               \
+}
+
+#define SVC_3_1(f,t,t1,t2,t3,rv)                                               \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (t1 a1, t2 a2, t3 a3) {                                 \
+  SVC_Arg3(t1,t2,t3);                                                          \
+  SVC_Call(f);                                                                 \
+  return (t) rv;                                                               \
+}
+
+#define SVC_4_1(f,t,t1,t2,t3,t4,rv)                                            \
+__attribute__((always_inline))                                                 \
+static inline  t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                          \
+  SVC_Arg4(t1,t2,t3,t4);                                                       \
+  SVC_Call(f);                                                                 \
+  return (t) rv;                                                               \
+}
+
+#define SVC_1_2 SVC_1_1 
+#define SVC_1_3 SVC_1_1 
+#define SVC_2_3 SVC_2_1 
+
+#elif defined (__ICCARM__)      /* IAR Compiler */
+
+#define __NO_RETURN __noreturn
+
+#define osEvent_type       osEvent
+#define osEvent_ret_status ret
+#define osEvent_ret_value  ret
+#define osEvent_ret_msg    ret
+#define osEvent_ret_mail   ret
+
+#define osCallback_type    osCallback
+#define osCallback_ret     ret
+
+#define RET_osEvent     osEvent
+#define RET_osCallback  osCallback
+
+#define SVC_Setup(f)                                                           \
+  __asm(                                                                       \
+    "mov r12,%0\n"                                                             \
+    :: "r"(&f): "r0", "r1", "r2", "r3", "r12"                                  \
+  );
+
+#define SVC_Ret3()                                                             \
+  __asm(                                                                       \
+    "ldr r0,[sp,#0]\n"                                                         \
+    "ldr r1,[sp,#4]\n"                                                         \
+    "ldr r2,[sp,#8]\n"                                                         \
+  );
+
+#define SVC_0_1(f,t,...)                                                       \
+t f (void);                                                                    \
+_Pragma("swi_number=0") __swi t _##f (void);                                   \
+static inline t __##f (void) {                                                 \
+  SVC_Setup(f);                                                                \
+  return _##f();                                                               \
+}
+
+#define SVC_1_0(f,t,t1,...)                                                    \
+t f (t1 a1);                                                                   \
+_Pragma("swi_number=0") __swi t _##f (t1 a1);                                  \
+static inline t __##f (t1 a1) {                                                \
+  SVC_Setup(f);                                                                \
+  _##f(a1);                                                                    \
+}
+
+#define SVC_1_1(f,t,t1,...)                                                    \
+t f (t1 a1);                                                                   \
+_Pragma("swi_number=0") __swi t _##f (t1 a1);                                  \
+static inline t __##f (t1 a1) {                                                \
+  SVC_Setup(f);                                                                \
+  return _##f(a1);                                                             \
+}
+
+#define SVC_2_1(f,t,t1,t2,...)                                                 \
+t f (t1 a1, t2 a2);                                                            \
+_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2);                           \
+static inline t __##f (t1 a1, t2 a2) {                                         \
+  SVC_Setup(f);                                                                \
+  return _##f(a1,a2);                                                          \
+}
+
+#define SVC_3_1(f,t,t1,t2,t3,...)                                              \
+t f (t1 a1, t2 a2, t3 a3);                                                     \
+_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3);                    \
+static inline t __##f (t1 a1, t2 a2, t3 a3) {                                  \
+  SVC_Setup(f);                                                                \
+  return _##f(a1,a2,a3);                                                       \
+}
+
+#define SVC_4_1(f,t,t1,t2,t3,t4,...)                                           \
+t f (t1 a1, t2 a2, t3 a3, t4 a4);                                              \
+_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4);             \
+static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                           \
+  SVC_Setup(f);                                                                \
+  return _##f(a1,a2,a3,a4);                                                    \
+}
+
+#define SVC_1_2 SVC_1_1
+#define SVC_1_3 SVC_1_1
+#define SVC_2_3 SVC_2_1
+
+#endif
+
+
+// Callback structure
+typedef struct {
+  void *fp;             // Function pointer
+  void *arg;            // Function argument
+} osCallback;
+
+
+// OS Section definitions
+#ifdef OS_SECTIONS_LINK_INFO
+extern const uint32_t  os_section_id$$Base;
+extern const uint32_t  os_section_id$$Limit;
+#endif
+
+#ifndef __MBED_CMSIS_RTOS_CM
+// OS Stack Memory for Threads definitions
+extern       uint64_t  os_stack_mem[];
+extern const uint32_t  os_stack_sz;
+#endif
+
+// OS Timers external resources
+extern const osThreadDef_t   os_thread_def_osTimerThread;
+extern       osThreadId      osThreadId_osTimerThread;
+extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
+extern       osMessageQId    osMessageQId_osTimerMessageQ;
+
+// Thread creation and destruction
+osMutexDef(osThreadMutex);
+osMutexId osMutexId_osThreadMutex;
+void sysThreadTerminate(osThreadId id);
+
+// ==== Helper Functions ====
+
+/// Convert timeout in millisec to system ticks
+static uint16_t rt_ms2tick (uint32_t millisec) {
+  uint32_t tick;
+
+  if (millisec == 0U) { return 0x0U; }                  // No timeout
+  if (millisec == osWaitForever) { return 0xFFFFU; }    // Indefinite timeout
+  if (millisec > 4000000U) { return 0xFFFEU; }          // Max ticks supported
+
+  tick = ((1000U * millisec) + os_clockrate - 1U)  / os_clockrate;
+  if (tick > 0xFFFEU) { return 0xFFFEU; }
+  
+  return (uint16_t)tick;
+}
+
+/// Convert Thread ID to TCB pointer
+P_TCB rt_tid2ptcb (osThreadId thread_id) {
+  P_TCB ptcb;
+
+  if (thread_id == NULL) { return NULL; }
+
+  if ((uint32_t)thread_id & 3U) { return NULL; }
+
+#ifdef OS_SECTIONS_LINK_INFO
+  if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) {
+    if (thread_id  < (osThreadId)os_section_id$$Base)  { return NULL; }
+    if (thread_id >= (osThreadId)os_section_id$$Limit) { return NULL; }
+  }
+#endif
+
+  ptcb = thread_id;
+
+  if (ptcb->cb_type != TCB) { return NULL; }
+
+  return ptcb;
+}
+
+/// Convert ID pointer to Object pointer
+static void *rt_id2obj (void *id) {
+
+  if ((uint32_t)id & 3U) { return NULL; }
+
+#ifdef OS_SECTIONS_LINK_INFO
+  if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) {
+    if (id  < (void *)os_section_id$$Base)  { return NULL; }
+    if (id >= (void *)os_section_id$$Limit) { return NULL; }
+  }
+#endif
+
+  return id;
+}
+
+
+// ==== Kernel Control ====
+
+uint8_t os_initialized;                         // Kernel Initialized flag
+uint8_t os_running;                             // Kernel Running flag
+
+// Kernel Control Service Calls declarations
+SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus)
+SVC_0_1(svcKernelStart,      osStatus, RET_osStatus)
+SVC_0_1(svcKernelRunning,    int32_t,  RET_int32_t)
+SVC_0_1(svcKernelSysTick,    uint32_t, RET_uint32_t)
+
+static void  sysThreadError   (osStatus status);
+osThreadId   svcThreadCreate  (const osThreadDef_t *thread_def, void *argument, void *context);
+osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+// Kernel Control Service Calls
+
+/// Initialize the RTOS Kernel for creating objects
+osStatus svcKernelInitialize (void) {
+#ifdef __MBED_CMSIS_RTOS_CM
+  if (!os_initialized) {
+    rt_sys_init();                              // RTX System Initialization
+  }
+#else
+  uint32_t ret;
+
+  if (os_initialized == 0U) {
+
+    // Init Thread Stack Memory (must be 8-byte aligned)
+    if (((uint32_t)os_stack_mem & 7U) != 0U) { return osErrorNoMemory; }
+    ret = rt_init_mem(os_stack_mem, os_stack_sz);
+    if (ret != 0U) { return osErrorNoMemory; }
+
+    rt_sys_init();                              // RTX System Initialization
+  }
+#endif
+
+  os_tsk.run->prio = 255U;                      // Highest priority
+
+  if (os_initialized == 0U) {
+    // Create OS Timers resources (Message Queue & Thread)
+    osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
+    osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL, NULL);
+    // Initialize thread mutex
+    osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
+  }
+
+  sysThreadError(osOK);
+
+  os_initialized = 1U;
+  os_running = 0U;
+
+  return osOK;
+}
+
+/// Start the RTOS Kernel
+osStatus svcKernelStart (void) {
+
+  if (os_running) { return osOK; }
+
+  rt_tsk_prio(0U, os_tsk.run->prio_base);       // Restore priority
+  if (os_tsk.run->task_id == 0xFFU) {           // Idle Thread
+    __set_PSP(os_tsk.run->tsk_stack + (8U*4U)); // Setup PSP
+  }
+  if (os_tsk.new_tsk == NULL) {                     // Force context switch
+    os_tsk.new_tsk = os_tsk.run;
+    os_tsk.run = NULL;
+  }
+
+  rt_sys_start();
+
+  os_running = 1U;
+
+  return osOK;
+}
+
+/// Check if the RTOS kernel is already started
+int32_t svcKernelRunning (void) {
+  return (int32_t)os_running;
+}
+
+/// Get the RTOS kernel system timer counter
+uint32_t svcKernelSysTick (void) {
+  uint32_t tick, tick0;
+
+  tick = os_tick_val();
+  if (os_tick_ovf()) {
+    tick0 = os_tick_val();
+    if (tick0 < tick) { tick = tick0; }
+    tick += (os_trv + 1U) * (os_time + 1U);
+  } else {
+    tick += (os_trv + 1U) *  os_time;
+  }
+
+  return tick;
+}
+
+// Kernel Control Public API
+
+/// Initialize the RTOS Kernel for creating objects
+osStatus osKernelInitialize (void) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  if ((__get_CONTROL() & 1U) == 0U) {           // Privileged mode
+    return   svcKernelInitialize();
+  } else {
+    return __svcKernelInitialize();
+  }
+}
+
+/// Start the RTOS Kernel
+osStatus osKernelStart (void) {
+  uint32_t stack[8];
+
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+
+  /* Call the pre-start event (from unprivileged mode) if the handler exists
+   * and the kernel is not running. */
+  /* FIXME osEventObs needs to be readable but not writable from unprivileged
+   * code. */
+  if (!osKernelRunning() && osEventObs && osEventObs->pre_start) {
+    osEventObs->pre_start();
+  }
+
+  switch (__get_CONTROL() & 0x03U) {
+    case 0x00U:                                 // Privileged Thread mode & MSP
+      __set_PSP((uint32_t)(stack + 8));         // Initial PSP
+      if (os_flags & 1U) {                       
+        __set_CONTROL(0x02U);                   // Set Privileged Thread mode & PSP
+      } else {
+        __set_CONTROL(0x03U);                   // Set Unprivileged Thread mode & PSP
+      }
+      __DSB();
+      __ISB();
+      break;
+    case 0x01U:                                 // Unprivileged Thread mode & MSP
+      return osErrorOS;
+    case 0x02U:                                 // Privileged Thread mode & PSP
+      if ((os_flags & 1U) == 0U) {              // Unprivileged Thread mode requested
+        __set_CONTROL(0x03U);                   // Set Unprivileged Thread mode & PSP
+        __DSB();
+        __ISB();
+      }
+      break;
+    case 0x03U:                                 // Unprivileged Thread mode & PSP
+      if  (os_flags & 1U) { return osErrorOS; } // Privileged Thread mode requested
+      break;
+  }
+  return __svcKernelStart();
+}
+
+/// Check if the RTOS kernel is already started
+int32_t osKernelRunning (void) {
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
+    // in ISR or Privileged
+    return (int32_t)os_running;
+  } else {
+    return __svcKernelRunning();
+  }
+}
+
+/// Get the RTOS kernel system timer counter
+uint32_t osKernelSysTick (void) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { return 0U; }        // Not allowed in ISR
+  return __svcKernelSysTick();
+}
+
+
+// ==== Thread Management ====
+
+/// Set Thread Error (for Create functions which return IDs)
+static void sysThreadError (osStatus status) {
+  // To Do
+}
+
+__NO_RETURN void osThreadExit (void);
+
+// Thread Service Calls declarations
+SVC_3_1(svcThreadCreate,      osThreadId, const osThreadDef_t *, void *, void *, RET_pointer)
+SVC_0_1(svcThreadGetId,       osThreadId,                                    RET_pointer)
+SVC_1_1(svcThreadTerminate,   osStatus,         osThreadId,                  RET_osStatus)
+SVC_0_1(svcThreadYield,       osStatus,                                      RET_osStatus)
+SVC_2_1(svcThreadSetPriority, osStatus,         osThreadId,      osPriority, RET_osStatus)
+SVC_1_1(svcThreadGetPriority, osPriority,       osThreadId,                  RET_osPriority)
+SVC_2_3(svcThreadGetInfo,    os_InRegs osEvent, osThreadId,    osThreadInfo, RET_osEvent)
+
+// Thread Service Calls
+
+/// Create a thread and add it to Active Threads and set it to state READY
+osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument, void *context) {
+  P_TCB  ptcb;
+  OS_TID tsk;
+  void  *stk;
+
+  if ((thread_def == NULL) ||
+      (thread_def->pthread == NULL) ||
+      (thread_def->tpriority < osPriorityIdle) ||
+      (thread_def->tpriority > osPriorityRealtime)) {
+    sysThreadError(osErrorParameter); 
+    return NULL; 
+  }
+
+#ifdef __MBED_CMSIS_RTOS_CM
+  if (thread_def->stacksize != 0) {             // Custom stack size
+    stk = (void *)thread_def->stack_pointer;
+  } else {                                      // Default stack size
+    stk = NULL;
+  }
+#else
+  if (thread_def->stacksize != 0) {             // Custom stack size
+    stk = rt_alloc_mem(                         // Allocate stack
+      os_stack_mem,
+      thread_def->stacksize
+    );
+    if (stk == NULL) { 
+      sysThreadError(osErrorNoMemory);          // Out of memory
+      return NULL;
+    }
+  } else {                                      // Default stack size
+    stk = NULL;
+  }
+#endif
+
+  tsk = rt_tsk_create(                          // Create task
+    (FUNCP)thread_def->pthread,                 // Task function pointer
+    (uint32_t)
+    (thread_def->tpriority-osPriorityIdle+1) |  // Task priority
+    (thread_def->stacksize << 8),               // Task stack size in bytes
+    stk,                                        // Pointer to task's stack
+    argument                                    // Argument to the task
+  );
+
+  if (tsk == 0U) {                              // Invalid task ID
+#ifndef __MBED_CMSIS_RTOS_CM
+    if (stk != NULL) {
+      rt_free_mem(os_stack_mem, stk);           // Free allocated stack
+    }
+#endif
+    sysThreadError(osErrorNoMemory);            // Create task failed (Out of memory)
+    return NULL;
+  }
+
+  ptcb = (P_TCB)os_active_TCB[tsk - 1U];        // TCB pointer
+
+  *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit;
+
+  if (osEventObs && osEventObs->thread_create) {
+    ptcb->context = osEventObs->thread_create(ptcb->task_id, context);
+  } else {
+    ptcb->context = context;
+  }
+
+  return ptcb;
+}
+
+/// Return the thread ID of the current running thread
+osThreadId svcThreadGetId (void) {
+  OS_TID tsk;
+
+  tsk = rt_tsk_self();
+  if (tsk == 0U) { return NULL; }
+  return (P_TCB)os_active_TCB[tsk - 1U];
+}
+
+/// Terminate execution of a thread and remove it from ActiveThreads
+osStatus svcThreadTerminate (osThreadId thread_id) {
+  OS_RESULT res;
+  P_TCB     ptcb;
+#ifndef __MBED_CMSIS_RTOS_CM
+  void     *stk;
+#endif
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) { 
+    return osErrorParameter;
+  }
+
+#ifndef __MBED_CMSIS_RTOS_CM
+  stk = ptcb->priv_stack ? ptcb->stack : NULL;  // Private stack
+#endif
+
+  if (osEventObs && osEventObs->thread_destroy) {
+    osEventObs->thread_destroy(ptcb->context);
+  }
+
+  res = rt_tsk_delete(ptcb->task_id);           // Delete task
+
+  if (res == OS_R_NOK) {
+    return osErrorResource;                     // Delete task failed
+  }
+
+#ifndef __MBED_CMSIS_RTOS_CM
+  if (stk != NULL) {                            
+    rt_free_mem(os_stack_mem, stk);             // Free private stack
+  }
+#endif
+
+  return osOK;
+}
+
+/// Pass control to next thread that is in state READY
+osStatus svcThreadYield (void) {
+  rt_tsk_pass();                                // Pass control to next task
+  return osOK;
+}
+
+/// Change priority of an active thread
+osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) {
+  OS_RESULT res;
+  P_TCB     ptcb;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) { 
+    return osErrorParameter; 
+  }
+
+  if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) {
+    return osErrorValue;
+  }
+
+  res = rt_tsk_prio(                            // Change task priority
+    ptcb->task_id,                              // Task ID
+    (uint8_t)(priority - osPriorityIdle + 1)    // New task priority
+  );
+
+  if (res == OS_R_NOK) {
+    return osErrorResource;                     // Change task priority failed
+  }
+
+  return osOK;
+}
+
+/// Get current priority of an active thread
+osPriority svcThreadGetPriority (osThreadId thread_id) {
+  P_TCB ptcb;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    return osPriorityError;
+  }
+
+  return (osPriority)(ptcb->prio - 1 + osPriorityIdle); 
+}
+
+/// Get info from an active thread
+os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
+  P_TCB ptcb;
+  osEvent ret;
+  ret.status = osOK;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    ret.status = osErrorValue;
+    return osEvent_ret_status;
+  }
+
+  if (osThreadInfoStackSize == info) {
+    uint32_t size;
+    size = ptcb->priv_stack;
+    if (0 == size) {
+      // This is an OS task - always a fixed size
+      size = os_stackinfo & 0x3FFFF;
+    }
+    ret.value.v = size;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoStackMax == info) {
+    uint32_t i;
+    uint32_t *stack_ptr;
+    uint32_t stack_size;
+    if (!(os_stackinfo & (1 << 28))) {
+      // Stack init must be turned on for max stack usage
+      ret.status = osErrorResource;
+      return osEvent_ret_status;
+    }
+    stack_ptr = (uint32_t*)ptcb->stack;
+    stack_size = ptcb->priv_stack;
+    if (0 == stack_size) {
+      // This is an OS task - always a fixed size
+      stack_size = os_stackinfo & 0x3FFFF;
+    }
+    for (i = 1; i <stack_size / 4; i++) {
+      if (stack_ptr[i] != MAGIC_PATTERN) {
+        break;
+      }
+    }
+    ret.value.v = stack_size - i * 4;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoEntry == info) {
+    ret.value.p = (void*)ptcb->ptask;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoArg == info) {
+    ret.value.p = (void*)ptcb->argv;
+    return osEvent_ret_value;
+  }
+
+  // Unsupported option so return error
+  ret.status = osErrorParameter;
+  return osEvent_ret_status;
+}
+
+// Thread Public API
+
+/// Create a thread and add it to Active Threads and set it to state READY
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) {
+  return osThreadContextCreate(thread_def, argument, NULL);
+}
+osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcThreadCreate(thread_def, argument, context);
+  } else {
+    osThreadId id;
+    osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+    // Thread mutex must be held when a thread is created or terminated
+    id = __svcThreadCreate(thread_def, argument, context);
+    osMutexRelease(osMutexId_osThreadMutex);
+    return id;
+  }
+}
+
+/// Return the thread ID of the current running thread
+osThreadId osThreadGetId (void) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  return __svcThreadGetId();
+}
+
+/// Terminate execution of a thread and remove it from ActiveThreads
+osStatus osThreadTerminate (osThreadId thread_id) {
+  osStatus status;
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  sysThreadTerminate(thread_id);
+  // Thread mutex must be held when a thread is created or terminated
+  status = __svcThreadTerminate(thread_id);
+  osMutexRelease(osMutexId_osThreadMutex);
+  return status;
+}
+
+/// Pass control to next thread that is in state READY
+osStatus osThreadYield (void) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadYield();
+}
+
+/// Change priority of an active thread
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadSetPriority(thread_id, priority);
+}
+
+/// Get current priority of an active thread
+osPriority osThreadGetPriority (osThreadId thread_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osPriorityError;                     // Not allowed in ISR
+  }
+  return __svcThreadGetPriority(thread_id);
+}
+
+/// INTERNAL - Not Public
+/// Auto Terminate Thread on exit (used implicitly when thread exists)
+__NO_RETURN void osThreadExit (void) {
+  osThreadId id;
+  // Thread mutex must be held when a thread is created or terminated
+  // Note - the mutex will be released automatically by the os when
+  //        the thread is terminated
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  id = __svcThreadGetId();
+  sysThreadTerminate(id);
+  __svcThreadTerminate(id);
+  for (;;);                                     // Should never come here
+}
+
+#ifdef __MBED_CMSIS_RTOS_CM
+/// Get current thread state
+uint8_t osThreadGetState (osThreadId thread_id) {
+  P_TCB ptcb;
+
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) return osErrorISR;     // Not allowed in ISR
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) return INACTIVE;
+
+  return ptcb->state;
+}
+#endif
+
+/// Get the requested info from the specified active thread
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
+  osEvent ret;
+
+  if (__get_IPSR() != 0U) {                     // Not allowed in ISR
+    ret.status = osErrorISR;
+    return ret;
+  }
+  return __svcThreadGetInfo(thread_id, info);
+}
+
+osThreadEnumId _osThreadsEnumStart() {
+  static uint32_t thread_enum_index;
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  thread_enum_index = 0;
+  return &thread_enum_index;
+}
+
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
+  uint32_t i;
+  osThreadId id = NULL;
+  uint32_t *index = (uint32_t*)enum_id;
+  for (i = *index; i < os_maxtaskrun; i++) {
+    if (os_active_TCB[i] != NULL) {
+      id = (osThreadId)os_active_TCB[i];
+      break;
+    }
+  }
+  if (i == os_maxtaskrun) {
+    // Include the idle task at the end of the enumeration
+    id = &os_idle_TCB;
+  }
+  *index = i + 1;
+  return id;
+}
+
+osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
+  uint32_t *index = (uint32_t*)enum_id;
+  *index = 0;
+  osMutexRelease(osMutexId_osThreadMutex);
+  return osOK;
+}
+
+// ==== Generic Wait Functions ====
+
+// Generic Wait Service Calls declarations
+SVC_1_1(svcDelay,           osStatus, uint32_t, RET_osStatus)
+#if osFeature_Wait != 0
+SVC_1_3(svcWait,  os_InRegs osEvent,  uint32_t, RET_osEvent)
+#endif
+
+// Generic Wait Service Calls
+
+/// Wait for Timeout (Time Delay)
+osStatus svcDelay (uint32_t millisec) {
+  if (millisec == 0U) { return osOK; }
+  rt_dly_wait(rt_ms2tick(millisec));
+  return osEventTimeout;
+}
+
+/// Wait for Signal, Message, Mail, or Timeout
+#if osFeature_Wait != 0
+os_InRegs osEvent_type svcWait (uint32_t millisec) {
+  osEvent ret;
+
+  if (millisec == 0U) {
+    ret.status = osOK;
+    return osEvent_ret_status;
+  }
+
+  /* To Do: osEventSignal, osEventMessage, osEventMail */
+  rt_dly_wait(rt_ms2tick(millisec));
+  ret.status = osEventTimeout;
+
+  return osEvent_ret_status;
+}
+#endif
+
+
+// Generic Wait API
+
+/// Wait for Timeout (Time Delay)
+osStatus osDelay (uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcDelay(millisec);
+}
+
+/// Wait for Signal, Message, Mail, or Timeout
+os_InRegs osEvent osWait (uint32_t millisec) {
+  osEvent ret;
+
+#if osFeature_Wait == 0
+  ret.status = osErrorOS;
+  return ret;
+#else
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // Not allowed in ISR
+    ret.status = osErrorISR;
+    return ret;
+  }
+  return __svcWait(millisec);
+#endif
+}
+
+
+// ==== Timer Management ====
+
+// Timer definitions
+#define osTimerInvalid  0U
+#define osTimerStopped  1U
+#define osTimerRunning  2U
+
+// Timer structures 
+
+typedef struct os_timer_cb_ {                   // Timer Control Block
+  struct os_timer_cb_ *next;                    // Pointer to next active Timer
+  uint8_t             state;                    // Timer State
+  uint8_t              type;                    // Timer Type (Periodic/One-shot)
+  uint16_t         reserved;                    // Reserved
+  uint32_t             tcnt;                    // Timer Delay Count
+  uint32_t             icnt;                    // Timer Initial Count 
+  void                 *arg;                    // Timer Function Argument
+  const osTimerDef_t *timer;                    // Pointer to Timer definition
+} os_timer_cb;
+
+// Timer variables
+os_timer_cb *os_timer_head;                     // Pointer to first active Timer
+
+
+// Timer Helper Functions
+
+// Insert Timer into the list sorted by time
+static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) {
+  os_timer_cb *p, *prev;
+
+  prev = NULL;
+  p = os_timer_head;
+  while (p != NULL) {
+    if (tcnt < p->tcnt) { break; }
+    tcnt -= p->tcnt;
+    prev = p;
+    p = p->next;
+  }
+  pt->next = p;
+  pt->tcnt = tcnt;
+  if (p != NULL) {
+    p->tcnt -= pt->tcnt;
+  }
+  if (prev != NULL) {
+    prev->next = pt;
+  } else {
+    os_timer_head = pt;
+  }
+}
+
+// Remove Timer from the list
+static int32_t rt_timer_remove (os_timer_cb *pt) {
+  os_timer_cb *p, *prev;
+
+  prev = NULL;
+  p = os_timer_head;
+  while (p != NULL) {
+    if (p == pt) { break; }
+    prev = p;
+    p = p->next;
+  }
+  if (p == NULL) { return -1; }
+  if (prev != NULL) {
+    prev->next = pt->next;
+  } else {
+    os_timer_head = pt->next;
+  }
+  if (pt->next != NULL) {
+    pt->next->tcnt += pt->tcnt;
+  }
+
+  return 0;
+}
+
+
+// Timer Service Calls declarations
+SVC_3_1(svcTimerCreate,           osTimerId,  const osTimerDef_t *, os_timer_type, void *, RET_pointer)
+SVC_2_1(svcTimerStart,            osStatus,         osTimerId,      uint32_t,              RET_osStatus)
+SVC_1_1(svcTimerStop,             osStatus,         osTimerId,                             RET_osStatus)
+SVC_1_1(svcTimerDelete,           osStatus,         osTimerId,                             RET_osStatus)
+SVC_1_2(svcTimerCall,   os_InRegs osCallback,       osTimerId,                             RET_osCallback)
+
+// Timer Management Service Calls
+
+/// Create timer
+osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
+  os_timer_cb *pt;
+
+  if ((timer_def == NULL) || (timer_def->ptimer == NULL)) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  pt = timer_def->timer;
+  if (pt == NULL) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  if ((type != osTimerOnce) && (type != osTimerPeriodic)) {
+    sysThreadError(osErrorValue);
+    return NULL;
+  }
+
+  if (osThreadId_osTimerThread == NULL) {
+    sysThreadError(osErrorResource);
+    return NULL;
+  }
+
+  if (pt->state != osTimerInvalid){
+    sysThreadError(osErrorResource);
+    return NULL;
+  }
+
+  pt->next  = NULL;
+  pt->state = osTimerStopped;
+  pt->type  =  (uint8_t)type;
+  pt->arg   = argument;
+  pt->timer = timer_def;
+
+  return (osTimerId)pt;
+}
+
+/// Start or restart timer
+osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) {
+  os_timer_cb *pt;
+  uint32_t     tcnt;
+
+  pt = rt_id2obj(timer_id);
+  if (pt == NULL) {
+    return osErrorParameter;
+  }
+
+  if (millisec == 0U) { return osErrorValue; }
+
+  tcnt = (uint32_t)(((1000U * (uint64_t)millisec) + os_clockrate - 1U)  / os_clockrate);
+
+  switch (pt->state) {
+    case osTimerRunning:
+      if (rt_timer_remove(pt) != 0) {
+        return osErrorResource;
+      }
+      break;
+    case osTimerStopped:
+      pt->state = osTimerRunning;
+      pt->icnt  = tcnt;
+      break;
+    default:
+      return osErrorResource;
+  }
+  
+  rt_timer_insert(pt, tcnt);
+
+  return osOK;
+}
+
+/// Stop timer
+osStatus svcTimerStop (osTimerId timer_id) {
+  os_timer_cb *pt;
+
+  pt = rt_id2obj(timer_id);
+  if (pt == NULL) {
+    return osErrorParameter;
+  }
+
+  if (pt->state != osTimerRunning) { return osErrorResource; }
+
+  pt->state = osTimerStopped;
+
+  if (rt_timer_remove(pt) != 0) {
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+/// Delete timer
+osStatus svcTimerDelete (osTimerId timer_id) {
+  os_timer_cb *pt;
+
+  pt = rt_id2obj(timer_id);
+  if (pt == NULL) {
+    return osErrorParameter;
+  }
+
+  switch (pt->state) {
+    case osTimerRunning:
+      rt_timer_remove(pt);
+      break;
+    case osTimerStopped:
+      break;
+    default:
+      return osErrorResource;
+  }
+
+  pt->state = osTimerInvalid;
+
+  return osOK;
+}
+
+/// Get timer callback parameters
+os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
+  os_timer_cb *pt;
+  osCallback   ret;
+
+  pt = rt_id2obj(timer_id);
+  if (pt == NULL) {
+    ret.fp  = NULL;
+    ret.arg = NULL;
+    return osCallback_ret;
+  }
+
+  ret.fp  = (void *)pt->timer->ptimer;
+  ret.arg = pt->arg;
+
+  return osCallback_ret;
+}
+
+osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Timer Tick (called each SysTick)
+void sysTimerTick (void) {
+  os_timer_cb *pt, *p;
+  osStatus     status;
+
+  p = os_timer_head;
+  if (p == NULL) { return; }
+
+  p->tcnt--;
+  while ((p != NULL) && (p->tcnt == 0U)) {
+    pt = p;
+    p = p->next;
+    os_timer_head = p;
+    status = isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0U);
+    if (status != osOK) {
+      os_error(OS_ERR_TIMER_OVF);
+    }
+    if (pt->type == (uint8_t)osTimerPeriodic) {
+      rt_timer_insert(pt, pt->icnt);
+    } else {
+      pt->state = osTimerStopped;
+    }
+  }
+}
+
+/// Get user timers wake-up time 
+uint32_t sysUserTimerWakeupTime (void) {
+
+  if (os_timer_head) {
+    return os_timer_head->tcnt;
+  }
+  return 0xFFFFFFFFU;
+}
+
+/// Update user timers on resume
+void sysUserTimerUpdate (uint32_t sleep_time) {
+
+  while ((os_timer_head != NULL) && (sleep_time != 0U)) {
+    if (sleep_time >= os_timer_head->tcnt) {
+      sleep_time -= os_timer_head->tcnt;
+      os_timer_head->tcnt = 1U;
+      sysTimerTick();
+    } else {
+      os_timer_head->tcnt -= sleep_time;
+      break;
+    }
+  }
+}
+
+
+// Timer Management Public API
+
+/// Create timer
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcTimerCreate(timer_def, type, argument);
+  } else {
+    return __svcTimerCreate(timer_def, type, argument);
+  }
+}
+
+/// Start or restart timer
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerStart(timer_id, millisec);
+}
+
+/// Stop timer
+osStatus osTimerStop (osTimerId timer_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerStop(timer_id);
+}
+
+/// Delete timer
+osStatus osTimerDelete (osTimerId timer_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerDelete(timer_id);
+}
+
+/// INTERNAL - Not Public
+/// Get timer callback parameters (used by OS Timer Thread)
+os_InRegs osCallback osTimerCall (osTimerId timer_id) { 
+  return __svcTimerCall(timer_id); 
+}
+
+
+// Timer Thread
+__NO_RETURN void osTimerThread (void const *argument) {
+  osCallback cb;
+  osEvent    evt;
+
+  for (;;) {
+    evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever);
+    if (evt.status == osEventMessage) {
+      cb = osTimerCall(evt.value.p);
+      if (cb.fp != NULL) {
+        (*(os_ptimer)cb.fp)(cb.arg);
+      }
+    }
+  }
+}
+
+
+// ==== Signal Management ====
+
+// Signal Service Calls declarations
+SVC_2_1(svcSignalSet,             int32_t, osThreadId, int32_t,  RET_int32_t)
+SVC_2_1(svcSignalClear,           int32_t, osThreadId, int32_t,  RET_int32_t)
+SVC_2_3(svcSignalWait,  os_InRegs osEvent, int32_t,    uint32_t, RET_osEvent)
+
+// Signal Service Calls
+
+/// Set the specified Signal Flags of an active thread
+int32_t svcSignalSet (osThreadId thread_id, int32_t signals) {
+  P_TCB   ptcb;
+  int32_t sig;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    return (int32_t)0x80000000U;
+  }
+
+  if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) {
+    return (int32_t)0x80000000U;
+  }
+
+  sig = (int32_t)ptcb->events;                  // Previous signal flags
+
+  rt_evt_set((uint16_t)signals, ptcb->task_id); // Set event flags
+
+  return sig;
+}
+
+/// Clear the specified Signal Flags of an active thread
+int32_t svcSignalClear (osThreadId thread_id, int32_t signals) {
+  P_TCB   ptcb;
+  int32_t sig;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    return (int32_t)0x80000000U;
+  }
+
+  if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) {
+    return (int32_t)0x80000000U;
+  }
+
+  sig = (int32_t)ptcb->events;                  // Previous signal flags
+
+  rt_evt_clr((uint16_t)signals, ptcb->task_id); // Clear event flags
+
+  return sig;
+}
+
+/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
+os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) {
+  OS_RESULT res;
+  osEvent   ret;
+
+  if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) {
+    ret.status = osErrorValue;
+    return osEvent_ret_status;
+  }
+
+  if (signals != 0) {                           // Wait for all specified signals
+    res = rt_evt_wait((uint16_t)signals, rt_ms2tick(millisec), __TRUE);
+  } else {                                      // Wait for any signal
+    res = rt_evt_wait(0xFFFFU,           rt_ms2tick(millisec), __FALSE);
+  }
+
+  if (res == OS_R_EVT) {
+    ret.status = osEventSignal;
+    ret.value.signals = (signals != 0) ? signals : (int32_t)os_tsk.run->waits;
+  } else {
+    ret.status = (millisec != 0U) ? osEventTimeout : osOK;
+    ret.value.signals = 0;
+  }
+
+  return osEvent_ret_value;
+}
+
+
+// Signal ISR Calls
+
+/// Set the specified Signal Flags of an active thread
+int32_t isrSignalSet (osThreadId thread_id, int32_t signals) {
+  P_TCB   ptcb;
+  int32_t sig;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    return (int32_t)0x80000000U;
+  }
+
+  if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) {
+    return (int32_t)0x80000000U;
+  }
+
+  sig = (int32_t)ptcb->events;                  // Previous signal flags
+
+  isr_evt_set((uint16_t)signals, ptcb->task_id);// Set event flags
+
+  return sig;
+}
+
+
+// Signal Public API
+
+/// Set the specified Signal Flags of an active thread
+int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    return   isrSignalSet(thread_id, signals); 
+  } else {                                      // in Thread
+    return __svcSignalSet(thread_id, signals);
+  }
+}
+
+/// Clear the specified Signal Flags of an active thread
+int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return (int32_t)0x80000000U;                // Not allowed in ISR
+  }
+  return __svcSignalClear(thread_id, signals);
+}
+
+/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
+os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
+  osEvent ret;
+
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // Not allowed in ISR
+    ret.status = osErrorISR;
+    return ret;
+  }
+  return __svcSignalWait(signals, millisec);
+}
+
+
+// ==== Mutex Management ====
+
+// Mutex Service Calls declarations
+SVC_1_1(svcMutexCreate,  osMutexId, const osMutexDef_t *,           RET_pointer)
+SVC_2_1(svcMutexWait,    osStatus,        osMutexId,      uint32_t, RET_osStatus)
+SVC_1_1(svcMutexRelease, osStatus,        osMutexId,                RET_osStatus)
+SVC_1_1(svcMutexDelete,  osStatus,        osMutexId,                RET_osStatus)
+
+// Mutex Service Calls
+
+/// Create and Initialize a Mutex object
+osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) {
+  OS_ID mut;
+
+  if (mutex_def == NULL) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  mut = mutex_def->mutex;
+  if (mut == NULL) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  if (((P_MUCB)mut)->cb_type != 0U) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  rt_mut_init(mut);                             // Initialize Mutex
+
+  return mut;
+}
+
+/// Wait until a Mutex becomes available
+osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) {
+  OS_ID     mut;
+  OS_RESULT res;
+
+  mut = rt_id2obj(mutex_id);
+  if (mut == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_MUCB)mut)->cb_type != MUCB) {
+    return osErrorParameter;
+  }
+
+  res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex
+
+  if (res == OS_R_TMO) {
+    return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource);
+  }
+
+  return osOK;
+}
+
+/// Release a Mutex that was obtained with osMutexWait
+osStatus svcMutexRelease (osMutexId mutex_id) {
+  OS_ID     mut;
+  OS_RESULT res;
+
+  mut = rt_id2obj(mutex_id);
+  if (mut == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_MUCB)mut)->cb_type != MUCB) {
+    return osErrorParameter;
+  }
+
+  res = rt_mut_release(mut);                    // Release Mutex
+
+  if (res == OS_R_NOK) {
+    return osErrorResource;                     // Thread not owner or Zero Counter
+  }
+
+  return osOK;
+}
+
+/// Delete a Mutex that was created by osMutexCreate
+osStatus svcMutexDelete (osMutexId mutex_id) {
+  OS_ID mut;
+
+  mut = rt_id2obj(mutex_id);
+  if (mut == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_MUCB)mut)->cb_type != MUCB) {
+    return osErrorParameter;
+  }
+
+  rt_mut_delete(mut);                           // Release Mutex
+
+  return osOK;
+}
+
+
+// Mutex Public API
+
+/// Create and Initialize a Mutex object
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return    svcMutexCreate(mutex_def);
+  } else {
+    return __svcMutexCreate(mutex_def);
+  }
+}
+
+/// Wait until a Mutex becomes available
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMutexWait(mutex_id, millisec);
+}
+
+/// Release a Mutex that was obtained with osMutexWait
+osStatus osMutexRelease (osMutexId mutex_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMutexRelease(mutex_id);
+}
+
+/// Delete a Mutex that was created by osMutexCreate
+osStatus osMutexDelete (osMutexId mutex_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMutexDelete(mutex_id);
+}
+
+
+// ==== Semaphore Management ====
+
+// Semaphore Service Calls declarations
+SVC_2_1(svcSemaphoreCreate,  osSemaphoreId, const osSemaphoreDef_t *,  int32_t, RET_pointer)
+SVC_2_1(svcSemaphoreWait,    int32_t,             osSemaphoreId,      uint32_t, RET_int32_t)
+SVC_1_1(svcSemaphoreRelease, osStatus,            osSemaphoreId,                RET_osStatus)
+SVC_1_1(svcSemaphoreDelete,  osStatus,            osSemaphoreId,                RET_osStatus)
+
+// Semaphore Service Calls
+
+/// Create and Initialize a Semaphore object
+osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
+  OS_ID sem;
+
+  if (semaphore_def == NULL) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  sem = semaphore_def->semaphore;
+  if (sem == NULL) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  if (((P_SCB)sem)->cb_type != 0U) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  if (count > osFeature_Semaphore) {
+    sysThreadError(osErrorValue);
+    return NULL;
+  }
+
+  rt_sem_init(sem, (uint16_t)count);            // Initialize Semaphore
+  
+  return sem;
+}
+
+/// Wait until a Semaphore becomes available
+int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
+  OS_ID     sem;
+  OS_RESULT res;
+
+  sem = rt_id2obj(semaphore_id);
+  if (sem == NULL) {
+    return -1;
+  }
+
+  if (((P_SCB)sem)->cb_type != SCB) {
+    return -1;
+  }
+
+  res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore
+
+  if (res == OS_R_TMO) { return 0; }            // Timeout
+
+  return (int32_t)(((P_SCB)sem)->tokens + 1U);
+}
+
+/// Release a Semaphore
+osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) {
+  OS_ID sem;
+
+  sem = rt_id2obj(semaphore_id);
+  if (sem == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_SCB)sem)->cb_type != SCB) {
+    return osErrorParameter;
+  }
+
+  if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) {
+    return osErrorResource;
+  }
+  
+  rt_sem_send(sem);                             // Release Semaphore
+
+  return osOK;
+}
+
+/// Delete a Semaphore that was created by osSemaphoreCreate
+osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) {
+  OS_ID sem;
+
+  sem = rt_id2obj(semaphore_id);
+  if (sem == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_SCB)sem)->cb_type != SCB) {
+    return osErrorParameter;
+  }
+
+  rt_sem_delete(sem);                           // Delete Semaphore
+
+  return osOK;
+}
+
+
+// Semaphore ISR Calls
+
+/// Release a Semaphore
+osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) {
+  OS_ID sem;
+
+  sem = rt_id2obj(semaphore_id);
+  if (sem == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_SCB)sem)->cb_type != SCB) {
+    return osErrorParameter;
+  }
+
+  if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) {
+    return osErrorResource;
+  }
+
+  isr_sem_send(sem);                            // Release Semaphore
+
+  return osOK;
+}
+
+
+// Semaphore Public API
+
+/// Create and Initialize a Semaphore object
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcSemaphoreCreate(semaphore_def, count);
+  } else {
+    return __svcSemaphoreCreate(semaphore_def, count);
+  }
+}
+
+/// Wait until a Semaphore becomes available
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return -1;                                  // Not allowed in ISR
+  }
+  return __svcSemaphoreWait(semaphore_id, millisec);
+}
+
+/// Release a Semaphore
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {    // in ISR
+    return   isrSemaphoreRelease(semaphore_id);
+  } else {                                              // in Thread
+    return __svcSemaphoreRelease(semaphore_id);
+  }
+}
+
+/// Delete a Semaphore that was created by osSemaphoreCreate
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcSemaphoreDelete(semaphore_id);
+}
+
+
+// ==== Memory Management Functions ====
+
+// Memory Management Helper Functions
+
+// Clear Memory Box (Zero init)
+static void rt_clr_box (void *box_mem, void *box) {
+  uint32_t *p, n;
+
+  if ((box_mem != NULL) && (box != NULL)) {
+    p = box;
+    for (n = ((P_BM)box_mem)->blk_size; n; n -= 4U) {
+      *p++ = 0U;
+    }
+  }
+}
+
+// Memory Management Service Calls declarations
+SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *,         RET_pointer)
+SVC_1_1(sysPoolAlloc,  void *,         osPoolId,              RET_pointer)
+SVC_2_1(sysPoolFree,   osStatus,       osPoolId,      void *, RET_osStatus)
+
+// Memory Management Service & ISR Calls
+
+/// Create and Initialize memory pool
+osPoolId svcPoolCreate (const osPoolDef_t *pool_def) {
+  uint32_t blk_sz;
+
+  if ((pool_def == NULL) ||
+      (pool_def->pool_sz == 0U) ||
+      (pool_def->item_sz == 0U) ||
+      (pool_def->pool == NULL)) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  blk_sz = (pool_def->item_sz + 3U) & (uint32_t)~3U;
+
+  _init_box(pool_def->pool, sizeof(struct OS_BM) + (pool_def->pool_sz * blk_sz), blk_sz);
+
+  return pool_def->pool;
+}
+
+/// Allocate a memory block from a memory pool
+void *sysPoolAlloc (osPoolId pool_id) {
+  void *mem;
+
+  if (pool_id == NULL) {
+    return NULL;
+  }
+
+  mem = rt_alloc_box(pool_id);
+
+  return mem;
+}
+
+/// Return an allocated memory block back to a specific memory pool
+osStatus sysPoolFree (osPoolId pool_id, void *block) {
+  uint32_t res;
+    
+  if (pool_id == NULL) {
+    return osErrorParameter;
+  }
+
+  res = rt_free_box(pool_id, block);
+  if (res != 0) {
+    return osErrorValue;
+  }
+
+  return osOK;
+}
+
+
+// Memory Management Public API
+
+/// Create and Initialize memory pool
+osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcPoolCreate(pool_def);
+  } else {
+    return __svcPoolCreate(pool_def);
+  }
+}
+
+/// Allocate a memory block from a memory pool
+void *osPoolAlloc (osPoolId pool_id) {
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+    return   sysPoolAlloc(pool_id);
+  } else {                                      // in Thread
+    return __sysPoolAlloc(pool_id);
+  }
+}
+
+/// Allocate a memory block from a memory pool and set memory block to zero
+void *osPoolCAlloc (osPoolId pool_id) {
+  void *mem;
+
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+    mem =   sysPoolAlloc(pool_id);
+  } else {                                      // in Thread
+    mem = __sysPoolAlloc(pool_id);
+  }
+
+  rt_clr_box(pool_id, mem);
+
+  return mem;
+}
+
+/// Return an allocated memory block back to a specific memory pool
+osStatus osPoolFree (osPoolId pool_id, void *block) {
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+    return   sysPoolFree(pool_id, block);
+  } else {                                      // in Thread
+    return __sysPoolFree(pool_id, block);
+  }
+}
+
+
+// ==== Message Queue Management Functions ====
+
+// Message Queue Management Service Calls declarations
+SVC_2_1(svcMessageCreate,        osMessageQId, const osMessageQDef_t *, osThreadId,           RET_pointer)
+SVC_3_1(svcMessagePut,           osStatus,           osMessageQId,      uint32_t,   uint32_t, RET_osStatus)
+SVC_2_3(svcMessageGet, os_InRegs osEvent,            osMessageQId,      uint32_t,             RET_osEvent)
+
+// Message Queue Service Calls
+
+/// Create and Initialize Message Queue
+osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
+
+  if ((queue_def == NULL) ||
+      (queue_def->queue_sz == 0U) ||
+      (queue_def->pool == NULL)) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+  
+  if (((P_MCB)queue_def->pool)->cb_type != 0U) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  rt_mbx_init(queue_def->pool, (uint16_t)(4U*(queue_def->queue_sz + 4U)));
+
+  return queue_def->pool;
+}
+
+/// Put a Message to a Queue
+osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
+  OS_RESULT res;
+
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+
+  if (((P_MCB)queue_id)->cb_type != MCB) {
+    return osErrorParameter;
+  }
+
+  res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec));
+
+  if (res == OS_R_TMO) {
+    return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource);
+  }
+
+  return osOK;
+}
+
+/// Get a Message or Wait for a Message from a Queue
+os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) {
+  OS_RESULT res;
+  osEvent   ret;
+
+  if (queue_id == NULL) {
+    ret.status = osErrorParameter;
+    return osEvent_ret_status;
+  }
+
+  if (((P_MCB)queue_id)->cb_type != MCB) {
+    ret.status = osErrorParameter;
+    return osEvent_ret_status;
+  }
+
+  res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec));
+  
+  if (res == OS_R_TMO) {
+    ret.status = (millisec != 0U) ? osEventTimeout : osOK;
+    return osEvent_ret_value;
+  }
+
+  ret.status = osEventMessage;
+
+  return osEvent_ret_value;
+}
+
+
+// Message Queue ISR Calls
+
+/// Put a Message to a Queue
+osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
+
+  if ((queue_id == NULL) || (millisec != 0U)) {
+    return osErrorParameter;
+  }
+
+  if (((P_MCB)queue_id)->cb_type != MCB) {
+    return osErrorParameter;
+  }
+
+  if (rt_mbx_check(queue_id) == 0U) {           // Check if Queue is full
+    return osErrorResource;
+  }
+
+  isr_mbx_send(queue_id, (void *)info);
+
+  return osOK;
+}
+
+/// Get a Message or Wait for a Message from a Queue
+os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
+  OS_RESULT res;
+  osEvent   ret;
+
+  if ((queue_id == NULL) || (millisec != 0U)) {
+    ret.status = osErrorParameter;
+    return ret;
+  }
+
+  if (((P_MCB)queue_id)->cb_type != MCB) {
+    ret.status = osErrorParameter;
+    return ret;
+  }
+
+  res = isr_mbx_receive(queue_id, &ret.value.p);
+  
+  if (res != OS_R_MBX) {
+    ret.status = osOK;
+    return ret;
+  }
+
+  ret.status = osEventMessage; 
+
+  return ret;
+}
+
+
+// Message Queue Management Public API
+
+/// Create and Initialize Message Queue
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcMessageCreate(queue_def, thread_id);
+  } else {
+    return __svcMessageCreate(queue_def, thread_id);
+  }
+}
+
+/// Put a Message to a Queue
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    return   isrMessagePut(queue_id, info, millisec);
+  } else {                                      // in Thread
+    return __svcMessagePut(queue_id, info, millisec);
+  }
+}
+
+/// Get a Message or Wait for a Message from a Queue
+os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    return   isrMessageGet(queue_id, millisec);
+  } else {                                      // in Thread
+    return __svcMessageGet(queue_id, millisec);
+  }
+}
+
+
+// ==== Mail Queue Management Functions ====
+
+// Mail Queue Management Service Calls declarations
+SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId,         RET_pointer)
+SVC_3_1(sysMailAlloc,  void *,          osMailQId,      uint32_t, uint32_t, RET_pointer)
+SVC_3_1(sysMailFree,   osStatus,        osMailQId,      void *,   uint32_t, RET_osStatus)
+
+// Mail Queue Management Service & ISR Calls
+
+/// Create and Initialize mail queue
+osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
+  uint32_t blk_sz;
+  P_MCB    pmcb;
+  void    *pool;
+
+  if ((queue_def == NULL) ||
+      (queue_def->queue_sz == 0U) ||
+      (queue_def->item_sz  == 0U) ||
+      (queue_def->pool == NULL)) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  pmcb = *(((void **)queue_def->pool) + 0);
+  pool = *(((void **)queue_def->pool) + 1);
+
+  if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0U)) {
+    sysThreadError(osErrorParameter);
+    return NULL;
+  }
+
+  blk_sz = (queue_def->item_sz + 3U) & (uint32_t)~3U;
+
+  _init_box(pool, sizeof(struct OS_BM) + (queue_def->queue_sz * blk_sz), blk_sz);
+
+  rt_mbx_init(pmcb, (uint16_t)(4U*(queue_def->queue_sz + 4U)));
+
+  return queue_def->pool;
+}
+
+/// Allocate a memory block from a mail
+void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr) {
+  P_MCB pmcb;
+  void *pool;
+  void *mem;
+
+  if (queue_id == NULL) {
+    return NULL;
+  }
+
+  pmcb = *(((void **)queue_id) + 0);
+  pool = *(((void **)queue_id) + 1);
+
+  if ((pool == NULL) || (pmcb == NULL)) {
+    return NULL; 
+  }
+
+  if ((isr != 0U) && (millisec != 0U)) {
+    return NULL;
+  }
+
+  mem = rt_alloc_box(pool);
+
+  if ((mem == NULL) && (millisec != 0U)) {
+    // Put Task to sleep when Memory not available
+    if (pmcb->p_lnk != NULL) {
+      rt_put_prio((P_XCB)pmcb, os_tsk.run);
+    } else {
+      pmcb->p_lnk = os_tsk.run;
+      os_tsk.run->p_lnk = NULL;
+      os_tsk.run->p_rlnk = (P_TCB)pmcb;
+      // Task is waiting to allocate a message
+      pmcb->state = 3U;
+    }
+    rt_block(rt_ms2tick(millisec), WAIT_MBX);
+  }
+
+  return mem;  
+}
+
+/// Free a memory block from a mail
+osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
+  P_MCB    pmcb;
+  P_TCB    ptcb;
+  void    *pool;
+  void    *mem;
+  uint32_t res;
+
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+
+  pmcb = *(((void **)queue_id) + 0);
+  pool = *(((void **)queue_id) + 1);
+
+  if ((pmcb == NULL) || (pool == NULL)) {
+    return osErrorParameter;
+  }
+
+  res = rt_free_box(pool, mail);
+
+  if (res != 0U) {
+    return osErrorValue;
+  }
+
+  if ((pmcb->p_lnk != NULL) && (pmcb->state == 3U)) {
+    // Task is waiting to allocate a message
+    if (isr != 0U) {
+      rt_psq_enq (pmcb, (U32)pool);
+      rt_psh_req ();
+    } else {
+      mem = rt_alloc_box(pool);
+      if (mem != NULL) {
+        ptcb = rt_get_first((P_XCB)pmcb);
+        rt_ret_val(ptcb, (U32)mem);
+        rt_rmv_dly(ptcb);
+        rt_dispatch(ptcb);
+      }
+    }
+  }
+
+  return osOK;
+}
+
+
+// Mail Queue Management Public API
+
+/// Create and Initialize mail queue
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
+    return NULL;                                // Not allowed in ISR
+  }
+  if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
+    // Privileged and not running
+    return   svcMailCreate(queue_def, thread_id);
+  } else {
+    return __svcMailCreate(queue_def, thread_id);
+  }
+}
+
+/// Allocate a memory block from a mail
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    return   sysMailAlloc(queue_id, millisec, 1U);
+  } else {                                      // in Thread
+    return __sysMailAlloc(queue_id, millisec, 0U);
+  }
+}
+
+/// Allocate a memory block from a mail and set memory block to zero
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
+  void *pool;
+  void *mem;
+
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    mem =   sysMailAlloc(queue_id, millisec, 1U);
+  } else {                                      // in Thread
+    mem = __sysMailAlloc(queue_id, millisec, 0U);
+  }
+
+  pool = *(((void **)queue_id) + 1);
+
+  rt_clr_box(pool, mem);
+
+  return mem;
+}
+
+/// Free a memory block from a mail
+osStatus osMailFree (osMailQId queue_id, void *mail) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
+    return   sysMailFree(queue_id, mail, 1U);
+  } else {                                      // in Thread
+    return __sysMailFree(queue_id, mail, 0U);
+  }
+}
+
+/// Put a mail to a queue
+osStatus osMailPut (osMailQId queue_id, void *mail) {
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+  if (mail == NULL) {
+    return osErrorValue;
+  }
+  return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0U);
+}
+
+/// Get a mail from a queue
+os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
+  osEvent ret;
+
+  if (queue_id == NULL) {
+    ret.status = osErrorParameter;
+    return ret;
+  }
+
+  ret = osMessageGet(*((void **)queue_id), millisec);
+  if (ret.status == osEventMessage) ret.status = osEventMail;
+
+  return ret;
+}
+
+
+//  ==== RTX Extensions ====
+
+// Service Calls declarations
+SVC_0_1(rt_suspend, uint32_t, RET_uint32_t)
+SVC_1_0(rt_resume,  void,     uint32_t)
+
+
+// Public API
+
+/// Suspends the OS task scheduler
+uint32_t os_suspend (void) {
+  return __rt_suspend();
+}
+
+/// Resumes the OS task scheduler
+void os_resume (uint32_t sleep_time) {
+  __rt_resume(sleep_time);
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,190 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_EVENT.C
+ *      Purpose: Implements waits and wake-ups for event flags
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_Event.h"
+#include "rt_List.h"
+#include "rt_Task.h"
+#include "rt_HAL_CM.h"
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_evt_wait -----------------------------------*/
+
+OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) {
+  /* Wait for one or more event flags with optional time-out.                */
+  /* "wait_flags" identifies the flags to wait for.                          */
+  /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */
+  /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */
+  /* to complete the wait. (OR-ing if set to 0).                             */
+  U32 block_state;
+
+  if (and_wait) {
+    /* Check for AND-connected events */
+    if ((os_tsk.run->events & wait_flags) == wait_flags) {
+      os_tsk.run->events &= ~wait_flags;
+      return (OS_R_EVT);
+    }
+    block_state = WAIT_AND;
+  }
+  else {
+    /* Check for OR-connected events */
+    if (os_tsk.run->events & wait_flags) {
+      os_tsk.run->waits = os_tsk.run->events & wait_flags;
+      os_tsk.run->events &= ~wait_flags;
+      return (OS_R_EVT);
+    }
+    block_state = WAIT_OR;
+  }
+  /* Task has to wait */
+  os_tsk.run->waits = wait_flags;
+  rt_block (timeout, (U8)block_state);
+  return (OS_R_TMO);
+}
+
+
+/*--------------------------- rt_evt_set ------------------------------------*/
+
+void rt_evt_set (U16 event_flags, OS_TID task_id) {
+  /* Set one or more event flags of a selectable task. */
+  P_TCB p_tcb;
+
+  p_tcb = os_active_TCB[task_id-1U];
+  if (p_tcb == NULL) {
+    return;
+  }
+  p_tcb->events |= event_flags;
+  event_flags    = p_tcb->waits;
+  /* If the task is not waiting for an event, it should not be put */
+  /* to ready state. */
+  if (p_tcb->state == WAIT_AND) {
+    /* Check for AND-connected events */
+    if ((p_tcb->events & event_flags) == event_flags) {
+      goto wkup;
+    }
+  }
+  if (p_tcb->state == WAIT_OR) {
+    /* Check for OR-connected events */
+    if (p_tcb->events & event_flags) {
+      p_tcb->waits  &= p_tcb->events;
+wkup: p_tcb->events &= ~event_flags;
+      rt_rmv_dly (p_tcb);
+      p_tcb->state   = READY;
+#ifdef __CMSIS_RTOS
+      rt_ret_val2(p_tcb, 0x08U/*osEventSignal*/, p_tcb->waits);
+#else
+      rt_ret_val (p_tcb, OS_R_EVT);
+#endif
+      rt_dispatch (p_tcb);
+    }
+  }
+}
+
+
+/*--------------------------- rt_evt_clr ------------------------------------*/
+
+void rt_evt_clr (U16 clear_flags, OS_TID task_id) {
+  /* Clear one or more event flags (identified by "clear_flags") of a */
+  /* selectable task (identified by "task"). */
+  P_TCB task = os_active_TCB[task_id-1U];
+
+  if (task == NULL) {
+    return;
+  }
+  task->events &= ~clear_flags;
+}
+
+
+/*--------------------------- isr_evt_set -----------------------------------*/
+
+void isr_evt_set (U16 event_flags, OS_TID task_id) {
+  /* Same function as "os_evt_set", but to be called by ISRs. */
+  P_TCB p_tcb = os_active_TCB[task_id-1U];
+
+  if (p_tcb == NULL) {
+    return;
+  }
+  rt_psq_enq (p_tcb, event_flags);
+  rt_psh_req ();
+}
+
+
+/*--------------------------- rt_evt_get ------------------------------------*/
+
+U16 rt_evt_get (void) {
+  /* Get events of a running task after waiting for OR connected events. */
+  return (os_tsk.run->waits);
+}
+
+
+/*--------------------------- rt_evt_psh ------------------------------------*/
+
+void rt_evt_psh (P_TCB p_CB, U16 set_flags) {
+  /* Check if task has to be waken up */
+  U16 event_flags;
+
+  p_CB->events |= set_flags;
+  event_flags = p_CB->waits;
+  if (p_CB->state == WAIT_AND) {
+    /* Check for AND-connected events */
+    if ((p_CB->events & event_flags) == event_flags) {
+      goto rdy;
+    }
+  }
+  if (p_CB->state == WAIT_OR) {
+    /* Check for OR-connected events */
+    if (p_CB->events & event_flags) {
+      p_CB->waits  &= p_CB->events;
+rdy:  p_CB->events &= ~event_flags;
+      rt_rmv_dly (p_CB);
+      p_CB->state   = READY;
+#ifdef __CMSIS_RTOS
+      rt_ret_val2(p_CB, 0x08U/*osEventSignal*/, p_CB->waits); 
+#else
+      rt_ret_val (p_CB, OS_R_EVT);
+#endif
+      rt_put_prio (&os_rdy, p_CB);
+    }
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Event.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,51 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_EVENT.H
+ *      Purpose: Implements waits and wake-ups for event flags
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Functions */
+extern OS_RESULT rt_evt_wait (U16 wait_flags,  U16 timeout, BOOL and_wait);
+extern void      rt_evt_set  (U16 event_flags, OS_TID task_id);
+extern void      rt_evt_clr  (U16 clear_flags, OS_TID task_id);
+extern void      isr_evt_set (U16 event_flags, OS_TID task_id);
+extern U16       rt_evt_get  (void);
+extern void      rt_evt_psh  (P_TCB p_CB, U16 set_flags);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,344 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_HAL_CM.H
+ *      Purpose: Hardware Abstraction Layer for Cortex-M definitions
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Definitions */
+#define INITIAL_xPSR    0x01000000U
+#define DEMCR_TRCENA    0x01000000U
+#define ITM_ITMENA      0x00000001U
+#define MAGIC_WORD      0xE25A2EA5U
+#define MAGIC_PATTERN   0xCCCCCCCCU
+
+#if defined (__CC_ARM)          /* ARM Compiler */
+
+#if ((defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) && !defined(NO_EXCLUSIVE_ACCESS))
+ #define __USE_EXCLUSIVE_ACCESS
+#else
+ #undef  __USE_EXCLUSIVE_ACCESS
+#endif
+
+/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
+#ifdef __USE_EXCLUSIVE_ACCESS
+#pragma diag_suppress 3731
+#endif
+
+#ifndef __CMSIS_GENERIC
+
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+    register U32 primask __asm("primask");
+    return primask;
+}
+
+#define __DMB() do {\
+                   __schedule_barrier();\
+                   __dmb(0xF);\
+                   __schedule_barrier();\
+                } while (0)
+
+#endif
+
+#elif defined (__GNUC__)        /* GNU Compiler */
+
+#undef  __USE_EXCLUSIVE_ACCESS
+
+#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS)
+#define __TARGET_ARCH_6S_M
+#endif
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+#define __TARGET_FPU_VFP
+#endif
+
+#define __inline inline
+#define __weak   __attribute__((weak))
+
+#ifndef __CMSIS_GENERIC
+
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+  U32 result;
+
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  return result;
+}
+
+__attribute__((always_inline)) static inline void __enable_irq(void)
+{
+  __asm volatile ("cpsie i");
+}
+
+__attribute__((always_inline)) static inline U32 __disable_irq(void)
+{
+  U32 result;
+
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  __asm volatile ("cpsid i");
+  return(result & 1);
+}
+
+__attribute__((always_inline)) static inline void __DMB(void)
+{
+  __asm volatile ("dmb 0xF":::"memory");
+}
+
+#endif
+
+__attribute__(( always_inline)) static inline U8 __clz(U32 value)
+{
+  U8 result;
+
+  __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value));
+  return(result);
+}
+
+#elif defined (__ICCARM__)      /* IAR Compiler */
+
+#undef  __USE_EXCLUSIVE_ACCESS
+
+#if (__CORE__ == __ARM6M__)
+#define __TARGET_ARCH_6S_M 1
+#endif
+
+#if defined __ARMVFP__
+#define __TARGET_FPU_VFP 1
+#endif
+
+#define __inline inline
+
+#ifndef __CMSIS_GENERIC
+
+static inline U32 __get_PRIMASK(void)
+{
+  U32 result;
+  
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  return result;
+}
+
+static inline void __enable_irq(void)
+{
+  __asm volatile ("cpsie i");
+}
+
+static inline U32 __disable_irq(void)
+{
+  U32 result;
+  
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  __asm volatile ("cpsid i");
+  return(result & 1);
+}
+
+#endif
+
+static inline U8 __clz(U32 value)
+{
+  U8 result;
+  
+  __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value));
+  return(result);
+}
+
+#endif
+
+/* NVIC registers */
+#define NVIC_ST_CTRL    (*((volatile U32 *)0xE000E010U))
+#define NVIC_ST_RELOAD  (*((volatile U32 *)0xE000E014U))
+#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018U))
+#define NVIC_ISER         ((volatile U32 *)0xE000E100U)
+#define NVIC_ICER         ((volatile U32 *)0xE000E180U)
+#if defined(__TARGET_ARCH_6S_M)
+#define NVIC_IP           ((volatile U32 *)0xE000E400U)
+#else
+#define NVIC_IP           ((volatile U8  *)0xE000E400U)
+#endif
+#define NVIC_INT_CTRL   (*((volatile U32 *)0xE000ED04U))
+#define NVIC_AIR_CTRL   (*((volatile U32 *)0xE000ED0CU))
+#define NVIC_SYS_PRI2   (*((volatile U32 *)0xE000ED1CU))
+#define NVIC_SYS_PRI3   (*((volatile U32 *)0xE000ED20U))
+
+#define OS_PEND_IRQ()   NVIC_INT_CTRL  = (1UL<<28)
+#define OS_PENDING      ((NVIC_INT_CTRL >> 26) & 5U)
+#define OS_UNPEND(fl)   NVIC_INT_CTRL  = (U32)(fl = (U8)OS_PENDING) << 25
+#define OS_PEND(fl,p)   NVIC_INT_CTRL  = (U32)(fl | (U8)(p<<2)) << 26
+#define OS_LOCK()       NVIC_ST_CTRL   =  0x0005U
+#define OS_UNLOCK()     NVIC_ST_CTRL   =  0x0007U
+
+#define OS_X_PENDING    ((NVIC_INT_CTRL >> 28) & 1U)
+#define OS_X_UNPEND(fl) NVIC_INT_CTRL  = (U32)(fl = (U8)OS_X_PENDING) << 27
+#define OS_X_PEND(fl,p) NVIC_INT_CTRL  = (U32)(fl | p) << 28
+#if defined(__TARGET_ARCH_6S_M)
+#define OS_X_INIT(n)    NVIC_IP[n>>2] |=  (U32)0xFFU << ((n & 0x03U) << 3); \
+                        NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU)
+#else
+#define OS_X_INIT(n)    NVIC_IP[n] = 0xFFU; \
+                        NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU)
+#endif
+#define OS_X_LOCK(n)    NVIC_ICER[n>>5] = (U32)1U << (n & 0x1FU)
+#define OS_X_UNLOCK(n)  NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU)
+
+/* Core Debug registers */
+#define DEMCR           (*((volatile U32 *)0xE000EDFCU))
+
+/* ITM registers */
+#define ITM_CONTROL     (*((volatile U32 *)0xE0000E80U))
+#define ITM_ENABLE      (*((volatile U32 *)0xE0000E00U))
+#define ITM_PORT30_U32  (*((volatile U32 *)0xE0000078U))
+#define ITM_PORT31_U32  (*((volatile U32 *)0xE000007CU))
+#define ITM_PORT31_U16  (*((volatile U16 *)0xE000007CU))
+#define ITM_PORT31_U8   (*((volatile U8  *)0xE000007CU))
+
+/* Variables */
+extern BIT dbg_msg;
+
+/* Functions */
+#ifdef __USE_EXCLUSIVE_ACCESS
+ #define rt_inc(p)     while(__strex((__ldrex(p)+1U),p))
+ #define rt_dec(p)     while(__strex((__ldrex(p)-1U),p))
+#else
+ #define rt_inc(p) do {\
+                     U32 primask = __get_PRIMASK();\
+                     __disable_irq();\
+                     (*p)++;\
+                     if (!primask) {\
+                       __enable_irq();\
+                     }\
+                   } while (0)
+ #define rt_dec(p) do {\
+                     U32 primask = __get_PRIMASK();\
+                     __disable_irq();\
+                     (*p)--;\
+                     if (!primask) {\
+                       __enable_irq();\
+                     }\
+                   } while (0)
+#endif
+
+__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) {
+  U32 cnt,c2;
+#ifdef __USE_EXCLUSIVE_ACCESS
+  do {
+    if ((cnt = __ldrex(count)) == size) {
+      __clrex();
+      return (cnt); }
+  } while (__strex(cnt+1U, count));
+  do {
+    c2 = (cnt = __ldrex(first)) + 1U;
+    if (c2 == size) { c2 = 0U; }
+  } while (__strex(c2, first));
+#else
+  U32 primask = __get_PRIMASK();
+  __disable_irq();
+  if ((cnt = *count) < size) {
+    *count = (U8)(cnt+1U);
+    c2 = (cnt = *first) + 1U;
+    if (c2 == size) { c2 = 0U; }
+    *first = (U8)c2; 
+  }
+  if (!primask) {
+    __enable_irq ();
+  }
+#endif
+  return (cnt);
+}
+
+__inline static void rt_systick_init (void) {
+  NVIC_ST_RELOAD  = os_trv;
+  NVIC_ST_CURRENT = 0U;
+  NVIC_ST_CTRL    = 0x0007U;
+  NVIC_SYS_PRI3  |= 0xFF000000U;
+}
+
+__inline static U32 rt_systick_val (void) {
+  return (os_trv - NVIC_ST_CURRENT);
+}
+
+__inline static U32 rt_systick_ovf (void) {
+  return ((NVIC_INT_CTRL >> 26) & 1U);
+}
+
+__inline static void rt_svc_init (void) {
+#if !defined(__TARGET_ARCH_6S_M)
+  U32 sh,prigroup;
+#endif
+  NVIC_SYS_PRI3 |= 0x00FF0000U;
+#if defined(__TARGET_ARCH_6S_M)
+  NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000U;
+#else
+  sh       = 8U - __clz(~((NVIC_SYS_PRI3 << 8) & 0xFF000000U));
+  prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07U);
+  if (prigroup >= sh) {
+    sh = prigroup + 1U;
+  }
+
+/* Only change the SVCall priority if uVisor is not present. */
+#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
+  NVIC_SYS_PRI2 = ((0xFEFFFFFFU << sh) & 0xFF000000U) | (NVIC_SYS_PRI2 & 0x00FFFFFFU);
+#endif /* !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) */
+#endif
+}
+
+extern void rt_set_PSP (U32 stack);
+extern U32  rt_get_PSP (void);
+extern void os_set_env (void);
+extern void *_alloc_box (void *box_mem);
+extern U32  _free_box (void *box_mem, void *box);
+
+extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body);
+extern void rt_ret_val  (P_TCB p_TCB, U32 v0);
+extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1);
+
+extern void dbg_init (void);
+extern void dbg_task_notify (P_TCB p_tcb, BOOL create);
+extern void dbg_task_switch (U32 task_id);
+
+#ifdef DBG_MSG
+#define DBG_INIT() dbg_init()
+#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create)
+#define DBG_TASK_SWITCH(task_id)      if (dbg_msg && (os_tsk.new_tsk!=os_tsk.run)) \
+                                        dbg_task_switch(task_id)
+#else
+#define DBG_INIT()
+#define DBG_TASK_NOTIFY(p_tcb,create)
+#define DBG_TASK_SWITCH(task_id)
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,318 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_LIST.C
+ *      Purpose: Functions for the management of different lists
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_List.h"
+#include "rt_Task.h"
+#include "rt_Time.h"
+#include "rt_HAL_CM.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+/* List head of chained ready tasks */
+struct OS_XCB  os_rdy;
+/* List head of chained delay tasks */
+struct OS_XCB  os_dly;
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_put_prio -----------------------------------*/
+
+void rt_put_prio (P_XCB p_CB, P_TCB p_task) {
+  /* Put task identified with "p_task" into list ordered by priority.       */
+  /* "p_CB" points to head of list; list has always an element at end with  */
+  /* a priority less than "p_task->prio".                                   */
+  P_TCB p_CB2;
+  U32 prio;
+  BOOL sem_mbx = __FALSE;
+
+  if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) {
+    sem_mbx = __TRUE;
+  }
+  prio = p_task->prio;
+  p_CB2 = p_CB->p_lnk;
+  /* Search for an entry in the list */
+  while ((p_CB2 != NULL) && (prio <= p_CB2->prio)) {
+    p_CB = (P_XCB)p_CB2;
+    p_CB2 = p_CB2->p_lnk;
+  }
+  /* Entry found, insert the task into the list */
+  p_task->p_lnk = p_CB2;
+  p_CB->p_lnk = p_task;
+  if (sem_mbx) {
+    if (p_CB2 != NULL) {
+      p_CB2->p_rlnk = p_task;
+    }
+    p_task->p_rlnk = (P_TCB)p_CB;
+  }
+  else {
+    p_task->p_rlnk = NULL;
+  }
+}
+
+
+/*--------------------------- rt_get_first ----------------------------------*/
+
+P_TCB rt_get_first (P_XCB p_CB) {
+  /* Get task at head of list: it is the task with highest priority. */
+  /* "p_CB" points to head of list. */
+  P_TCB p_first;
+
+  p_first = p_CB->p_lnk;
+  p_CB->p_lnk = p_first->p_lnk;
+  if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) {
+    if (p_first->p_lnk != NULL) {
+      p_first->p_lnk->p_rlnk = (P_TCB)p_CB;
+      p_first->p_lnk = NULL;
+    }
+    p_first->p_rlnk = NULL;
+  }
+  else {
+    p_first->p_lnk = NULL;
+  }
+  return (p_first);
+}
+
+
+/*--------------------------- rt_put_rdy_first ------------------------------*/
+
+void rt_put_rdy_first (P_TCB p_task) {
+  /* Put task identified with "p_task" at the head of the ready list. The   */
+  /* task must have at least a priority equal to highest priority in list.  */
+  p_task->p_lnk = os_rdy.p_lnk;
+  p_task->p_rlnk = NULL;
+  os_rdy.p_lnk = p_task;
+}
+
+
+/*--------------------------- rt_get_same_rdy_prio --------------------------*/
+
+P_TCB rt_get_same_rdy_prio (void) {
+  /* Remove a task of same priority from ready list if any exists. Other-   */
+  /* wise return NULL.                                                      */
+  P_TCB p_first;
+
+  p_first = os_rdy.p_lnk;
+  if (p_first->prio == os_tsk.run->prio) {
+    os_rdy.p_lnk = os_rdy.p_lnk->p_lnk;
+    return (p_first);
+  }
+  return (NULL);
+}
+
+
+/*--------------------------- rt_resort_prio --------------------------------*/
+
+void rt_resort_prio (P_TCB p_task) {
+  /* Re-sort ordered lists after the priority of 'p_task' has changed.      */
+  P_TCB p_CB;
+
+  if (p_task->p_rlnk == NULL) {
+    if (p_task->state == READY) {
+      /* Task is chained into READY list. */
+      p_CB = (P_TCB)&os_rdy;
+      goto res;
+    }
+  }
+  else {
+    p_CB = p_task->p_rlnk;
+    while (p_CB->cb_type == TCB) {
+      /* Find a header of this task chain list. */
+      p_CB = p_CB->p_rlnk;
+    }
+res:rt_rmv_list (p_task);
+    rt_put_prio ((P_XCB)p_CB, p_task);
+  }
+}
+
+
+/*--------------------------- rt_put_dly ------------------------------------*/
+
+void rt_put_dly (P_TCB p_task, U16 delay) {
+  /* Put a task identified with "p_task" into chained delay wait list using */
+  /* a delay value of "delay".                                              */
+  P_TCB p;
+  U32 delta,idelay = delay;
+
+  p = (P_TCB)&os_dly;
+  if (p->p_dlnk == NULL) {
+    /* Delay list empty */
+    delta = 0U;
+    goto last;
+  }
+  delta = os_dly.delta_time;
+  while (delta < idelay) {
+    if (p->p_dlnk == NULL) {
+      /* End of list found */
+last: p_task->p_dlnk = NULL;
+      p->p_dlnk = p_task;
+      p_task->p_blnk = p;
+      p->delta_time = (U16)(idelay - delta);
+      p_task->delta_time = 0U;
+      return;
+    }
+    p = p->p_dlnk;
+    delta += p->delta_time;
+  }
+  /* Right place found */
+  p_task->p_dlnk = p->p_dlnk;
+  p->p_dlnk = p_task;
+  p_task->p_blnk = p;
+  if (p_task->p_dlnk != NULL) {
+    p_task->p_dlnk->p_blnk = p_task;
+  }
+  p_task->delta_time = (U16)(delta - idelay);
+  p->delta_time -= p_task->delta_time;
+}
+
+
+/*--------------------------- rt_dec_dly ------------------------------------*/
+
+void rt_dec_dly (void) {
+  /* Decrement delta time of list head: remove tasks having a value of zero.*/
+  P_TCB p_rdy;
+
+  if (os_dly.p_dlnk == NULL) {
+    return;
+  }
+  os_dly.delta_time--;
+  while ((os_dly.delta_time == 0U) && (os_dly.p_dlnk != NULL)) {
+    p_rdy = os_dly.p_dlnk;
+    if (p_rdy->p_rlnk != NULL) {
+      /* Task is really enqueued, remove task from semaphore/mailbox */
+      /* timeout waiting list. */
+      p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk;
+      if (p_rdy->p_lnk != NULL) {
+        p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk;
+        p_rdy->p_lnk = NULL;
+      }
+      p_rdy->p_rlnk = NULL;
+    }
+    rt_put_prio (&os_rdy, p_rdy);
+    os_dly.delta_time = p_rdy->delta_time;
+    if (p_rdy->state == WAIT_ITV) {
+      /* Calculate the next time for interval wait. */
+      p_rdy->delta_time = p_rdy->interval_time + (U16)os_time;
+    }
+    p_rdy->state   = READY;
+    os_dly.p_dlnk = p_rdy->p_dlnk;
+    if (p_rdy->p_dlnk != NULL) {
+      p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly;
+      p_rdy->p_dlnk = NULL;
+    }
+    p_rdy->p_blnk = NULL;
+  }
+}
+
+
+/*--------------------------- rt_rmv_list -----------------------------------*/
+
+void rt_rmv_list (P_TCB p_task) {
+  /* Remove task identified with "p_task" from ready, semaphore or mailbox  */
+  /* waiting list if enqueued.                                              */
+  P_TCB p_b;
+
+  if (p_task->p_rlnk != NULL) {
+    /* A task is enqueued in semaphore / mailbox waiting list. */
+    p_task->p_rlnk->p_lnk = p_task->p_lnk;
+    if (p_task->p_lnk != NULL) {
+      p_task->p_lnk->p_rlnk = p_task->p_rlnk;
+    }
+    return;
+  }
+
+  p_b = (P_TCB)&os_rdy;
+  while (p_b != NULL) {
+    /* Search the ready list for task "p_task" */
+    if (p_b->p_lnk == p_task) {
+      p_b->p_lnk = p_task->p_lnk;
+      return;
+    }
+    p_b = p_b->p_lnk;
+  }
+}
+
+
+/*--------------------------- rt_rmv_dly ------------------------------------*/
+
+void rt_rmv_dly (P_TCB p_task) {
+  /* Remove task identified with "p_task" from delay list if enqueued.      */
+  P_TCB p_b;
+
+  p_b = p_task->p_blnk;
+  if (p_b != NULL) {
+    /* Task is really enqueued */
+    p_b->p_dlnk = p_task->p_dlnk;
+    if (p_task->p_dlnk != NULL) {
+      /* 'p_task' is in the middle of list */
+      p_b->delta_time += p_task->delta_time;
+      p_task->p_dlnk->p_blnk = p_b;
+      p_task->p_dlnk = NULL;
+    }
+    else {
+      /* 'p_task' is at the end of list */
+      p_b->delta_time = 0U;
+    }
+    p_task->p_blnk = NULL;
+  }
+}
+
+
+/*--------------------------- rt_psq_enq ------------------------------------*/
+
+void rt_psq_enq (OS_ID entry, U32 arg) {
+  /* Insert post service request "entry" into ps-queue. */
+  U32 idx;
+
+  idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first);
+  if (idx < os_psq->size) {
+    os_psq->q[idx].id  = entry;
+    os_psq->q[idx].arg = arg;
+  }
+  else {
+    os_error (OS_ERR_FIFO_OVF);
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_List.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,72 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_LIST.H
+ *      Purpose: Functions for the management of different lists
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Definitions */
+
+/* Values for 'cb_type' */
+#define TCB             0U
+#define MCB             1U
+#define SCB             2U
+#define MUCB            3U
+#define HCB             4U
+
+/* Variables */
+extern struct OS_XCB os_rdy;
+extern struct OS_XCB os_dly;
+
+/* Functions */
+extern void  rt_put_prio      (P_XCB p_CB, P_TCB p_task);
+extern P_TCB rt_get_first     (P_XCB p_CB);
+extern void  rt_put_rdy_first (P_TCB p_task);
+extern P_TCB rt_get_same_rdy_prio (void);
+extern void  rt_resort_prio   (P_TCB p_task);
+extern void  rt_put_dly       (P_TCB p_task, U16 delay);
+extern void  rt_dec_dly       (void);
+extern void  rt_rmv_list      (P_TCB p_task);
+extern void  rt_rmv_dly       (P_TCB p_task);
+extern void  rt_psq_enq       (OS_ID entry, U32 arg);
+
+/* This is a fast macro generating in-line code */
+#define rt_rdy_prio(void) (os_rdy.p_lnk->prio)
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,293 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MAILBOX.C
+ *      Purpose: Implements waits and wake-ups for mailbox messages
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_List.h"
+#include "rt_Mailbox.h"
+#include "rt_MemBox.h"
+#include "rt_Task.h"
+#include "rt_HAL_CM.h"
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_mbx_init -----------------------------------*/
+
+void rt_mbx_init (OS_ID mailbox, U16 mbx_size) {
+  /* Initialize a mailbox */
+  P_MCB p_MCB = mailbox;
+
+  p_MCB->cb_type = MCB;
+  p_MCB->state   = 0U;
+  p_MCB->isr_st  = 0U;
+  p_MCB->p_lnk   = NULL;
+  p_MCB->first   = 0U;
+  p_MCB->last    = 0U;
+  p_MCB->count   = 0U;
+  p_MCB->size    = (U16)((mbx_size - (sizeof(struct OS_MCB) - (sizeof(void *))))
+                         / sizeof(void *));
+}
+
+
+/*--------------------------- rt_mbx_send -----------------------------------*/
+
+OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) {
+  /* Send message to a mailbox */
+  P_MCB p_MCB = mailbox;
+  P_TCB p_TCB;
+
+  if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1U)) {
+    /* A task is waiting for message */
+    p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+    rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg);
+#else
+    *p_TCB->msg = p_msg;
+    rt_ret_val (p_TCB, OS_R_MBX);
+#endif
+    rt_rmv_dly (p_TCB);
+    rt_dispatch (p_TCB);
+  }
+  else {
+    /* Store message in mailbox queue */
+    if (p_MCB->count == p_MCB->size) {
+      /* No free message entry, wait for one. If message queue is full, */
+      /* then no task is waiting for message. The 'p_MCB->p_lnk' list   */
+      /* pointer can now be reused for send message waits task list.    */
+      if (timeout == 0U) {
+        return (OS_R_TMO);
+      }
+      if (p_MCB->p_lnk != NULL) {
+        rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
+      }
+      else {
+        p_MCB->p_lnk = os_tsk.run;
+        os_tsk.run->p_lnk  = NULL;
+        os_tsk.run->p_rlnk = (P_TCB)p_MCB;
+        /* Task is waiting to send a message */      
+        p_MCB->state = 2U;
+      }
+      os_tsk.run->msg = p_msg;
+      rt_block (timeout, WAIT_MBX);
+      return (OS_R_TMO);
+    }
+    /* Yes, there is a free entry in a mailbox. */
+    p_MCB->msg[p_MCB->first] = p_msg;
+    rt_inc (&p_MCB->count);
+    if (++p_MCB->first == p_MCB->size) {
+      p_MCB->first = 0U;
+    }
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_mbx_wait -----------------------------------*/
+
+OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) {
+  /* Receive a message; possibly wait for it */
+  P_MCB p_MCB = mailbox;
+  P_TCB p_TCB;
+
+  /* If a message is available in the fifo buffer */
+  /* remove it from the fifo buffer and return. */
+  if (p_MCB->count) {
+    *message = p_MCB->msg[p_MCB->last];
+    if (++p_MCB->last == p_MCB->size) {
+      p_MCB->last = 0U;
+    }
+    if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2U)) {
+      /* A task is waiting to send message */
+      p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+      rt_ret_val(p_TCB, 0U/*osOK*/);
+#else
+      rt_ret_val(p_TCB, OS_R_OK);
+#endif
+      p_MCB->msg[p_MCB->first] = p_TCB->msg;
+      if (++p_MCB->first == p_MCB->size) {
+        p_MCB->first = 0U;
+      }
+      rt_rmv_dly (p_TCB);
+      rt_dispatch (p_TCB);
+    }
+    else {
+      rt_dec (&p_MCB->count);
+    }
+    return (OS_R_OK);
+  }
+  /* No message available: wait for one */
+  if (timeout == 0U) {
+    return (OS_R_TMO);
+  }
+  if (p_MCB->p_lnk != NULL) {
+    rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
+  }
+  else {
+    p_MCB->p_lnk = os_tsk.run;
+    os_tsk.run->p_lnk = NULL;
+    os_tsk.run->p_rlnk = (P_TCB)p_MCB;
+    /* Task is waiting to receive a message */      
+    p_MCB->state = 1U;
+  }
+  rt_block(timeout, WAIT_MBX);
+#ifndef __CMSIS_RTOS
+  os_tsk.run->msg = message;
+#endif
+  return (OS_R_TMO);
+}
+
+
+/*--------------------------- rt_mbx_check ----------------------------------*/
+
+OS_RESULT rt_mbx_check (OS_ID mailbox) {
+  /* Check for free space in a mailbox. Returns the number of messages     */
+  /* that can be stored to a mailbox. It returns 0 when mailbox is full.   */
+  P_MCB p_MCB = mailbox;
+
+  return ((U32)(p_MCB->size - p_MCB->count));
+}
+
+
+/*--------------------------- isr_mbx_send ----------------------------------*/
+
+void isr_mbx_send (OS_ID mailbox, void *p_msg) {
+  /* Same function as "os_mbx_send", but to be called by ISRs. */
+  P_MCB p_MCB = mailbox;
+
+  rt_psq_enq (p_MCB, (U32)p_msg);
+  rt_psh_req ();
+}
+
+
+/*--------------------------- isr_mbx_receive -------------------------------*/
+
+OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) {
+  /* Receive a message in the interrupt function. The interrupt function   */
+  /* should not wait for a message since this would block the rtx os.      */
+  P_MCB p_MCB = mailbox;
+
+  if (p_MCB->count) {
+    /* A message is available in the fifo buffer. */
+    *message = p_MCB->msg[p_MCB->last];
+    if (p_MCB->state == 2U) {
+      /* A task is locked waiting to send message */
+      rt_psq_enq (p_MCB, 0U);
+      rt_psh_req ();
+    }
+    rt_dec (&p_MCB->count);
+    if (++p_MCB->last == p_MCB->size) {
+      p_MCB->last = 0U;
+    }
+    return (OS_R_MBX);
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_mbx_psh ------------------------------------*/
+
+void rt_mbx_psh (P_MCB p_CB, void *p_msg) {
+  /* Store the message to the mailbox queue or pass it to task directly. */
+  P_TCB p_TCB;
+  void *mem;
+
+  if (p_CB->p_lnk != NULL) switch (p_CB->state) {
+#ifdef __CMSIS_RTOS
+    case 3:
+      /* Task is waiting to allocate memory, remove it from the waiting list */
+      mem = rt_alloc_box(p_msg);
+      if (mem == NULL) { break; }
+      p_TCB = rt_get_first ((P_XCB)p_CB);
+      rt_ret_val(p_TCB, (U32)mem);
+      p_TCB->state = READY;
+      rt_rmv_dly (p_TCB);
+      rt_put_prio (&os_rdy, p_TCB);
+      break;
+#endif
+    case 2:
+      /* Task is waiting to send a message, remove it from the waiting list */
+      p_TCB = rt_get_first ((P_XCB)p_CB);
+#ifdef __CMSIS_RTOS
+      rt_ret_val(p_TCB, 0U/*osOK*/);
+#else
+      rt_ret_val(p_TCB, OS_R_OK);
+#endif
+      p_CB->msg[p_CB->first] = p_TCB->msg;
+      rt_inc (&p_CB->count);
+      if (++p_CB->first == p_CB->size) {
+        p_CB->first = 0U;
+      }
+      p_TCB->state = READY;
+      rt_rmv_dly (p_TCB);
+      rt_put_prio (&os_rdy, p_TCB);
+      break;
+    case 1:
+      /* Task is waiting for a message, pass the message to the task directly */
+      p_TCB = rt_get_first ((P_XCB)p_CB);
+#ifdef __CMSIS_RTOS
+      rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg);
+#else
+      *p_TCB->msg = p_msg;
+      rt_ret_val (p_TCB, OS_R_MBX);
+#endif
+      p_TCB->state = READY;
+      rt_rmv_dly (p_TCB);
+      rt_put_prio (&os_rdy, p_TCB);
+      break;
+    default:
+      break;
+  } else {
+    /* No task is waiting for a message, store it to the mailbox queue */
+    if (p_CB->count < p_CB->size) {
+      p_CB->msg[p_CB->first] = p_msg;
+      rt_inc (&p_CB->count);
+      if (++p_CB->first == p_CB->size) {
+        p_CB->first = 0U;
+      }
+    }
+    else {
+      os_error (OS_ERR_MBX_OVF);
+    }
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,53 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MAILBOX.H
+ *      Purpose: Implements waits and wake-ups for mailbox messages
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Functions */
+extern void      rt_mbx_init  (OS_ID mailbox, U16 mbx_size);
+extern OS_RESULT rt_mbx_send  (OS_ID mailbox, void *p_msg,    U16 timeout);
+extern OS_RESULT rt_mbx_wait  (OS_ID mailbox, void **message, U16 timeout);
+extern OS_RESULT rt_mbx_check (OS_ID mailbox);
+extern void      isr_mbx_send (OS_ID mailbox, void *p_msg);
+extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message);
+extern void      rt_mbx_psh   (P_MCB p_CB,    void *p_msg);
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,168 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MEMBOX.C
+ *      Purpose: Interface functions for fixed memory block management system
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_MemBox.h"
+#include "rt_HAL_CM.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- _init_box -------------------------------------*/
+
+U32 _init_box  (void *box_mem, U32 box_size, U32 blk_size) {
+  /* Initialize memory block system, returns 0 if OK, 1 if fails. */
+  void *end;
+  void *blk;
+  void *next;
+  U32  sizeof_bm;
+
+  /* Create memory structure. */
+  if (blk_size & BOX_ALIGN_8) {
+    /* Memory blocks 8-byte aligned. */ 
+    blk_size = ((blk_size & ~BOX_ALIGN_8) + 7U) & ~(U32)7U;
+    sizeof_bm = (sizeof (struct OS_BM) + 7U) & ~(U32)7U;
+  }
+  else {
+    /* Memory blocks 4-byte aligned. */
+    blk_size = (blk_size + 3U) & ~(U32)3U;
+    sizeof_bm = sizeof (struct OS_BM);
+  }
+  if (blk_size == 0U) {
+    return (1U);
+  }
+  if ((blk_size + sizeof_bm) > box_size) {
+    return (1U);
+  }
+  /* Create a Memory structure. */
+  blk = ((U8 *) box_mem) + sizeof_bm;
+  ((P_BM) box_mem)->free = blk;
+  end = ((U8 *) box_mem) + box_size;
+  ((P_BM) box_mem)->end      = end;
+  ((P_BM) box_mem)->blk_size = blk_size;
+
+  /* Link all free blocks using offsets. */
+  end = ((U8 *) end) - blk_size;
+  while (1)  {
+    next = ((U8 *) blk) + blk_size;
+    if (next > end) { break; }
+    *((void **)blk) = next;
+    blk = next;
+  }
+  /* end marker */
+  *((void **)blk) = 0U;
+  return (0U);
+}
+
+/*--------------------------- rt_alloc_box ----------------------------------*/
+
+void *rt_alloc_box (void *box_mem) {
+  /* Allocate a memory block and return start address. */
+  void **free;
+#ifndef __USE_EXCLUSIVE_ACCESS
+  U32  irq_mask;
+
+  irq_mask = (U32)__disable_irq ();
+  free = ((P_BM) box_mem)->free;
+  if (free) {
+    ((P_BM) box_mem)->free = *free;
+  }
+  if (irq_mask == 0U) { __enable_irq (); }
+#else
+  do {
+    if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0U) {
+      __clrex();
+      break;
+    }
+  } while (__strex((U32)*free, &((P_BM) box_mem)->free));
+#endif
+  return (free);
+}
+
+
+/*--------------------------- _calloc_box -----------------------------------*/
+
+void *_calloc_box (void *box_mem)  {
+  /* Allocate a 0-initialized memory block and return start address. */
+  void *free;
+  U32 *p;
+  U32 i;
+
+  free = _alloc_box (box_mem);
+  if (free)  {
+    p = free;
+    for (i = ((P_BM) box_mem)->blk_size; i; i -= 4U)  {
+      *p = 0U;
+      p++;
+    }
+  }
+  return (free);
+}
+
+
+/*--------------------------- rt_free_box -----------------------------------*/
+
+U32 rt_free_box (void *box_mem, void *box) {
+  /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */
+#ifndef __USE_EXCLUSIVE_ACCESS
+  U32 irq_mask;
+#endif
+
+  if ((box < box_mem) || (box >= ((P_BM) box_mem)->end)) {
+    return (1U);
+  }
+
+#ifndef __USE_EXCLUSIVE_ACCESS
+  irq_mask = (U32)__disable_irq ();
+  *((void **)box) = ((P_BM) box_mem)->free;
+  ((P_BM) box_mem)->free = box;
+  if (irq_mask == 0U) { __enable_irq (); }
+#else
+  do {
+    do {
+      *((void **)box) = ((P_BM) box_mem)->free;
+      __DMB();
+    } while (*(void**)box != (void *)__ldrex(&((P_BM) box_mem)->free));
+  } while (__strex ((U32)box, &((P_BM) box_mem)->free));
+#endif
+  return (0U);
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,50 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MEMBOX.H
+ *      Purpose: Interface functions for fixed memory block management system
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Functions */
+#define rt_init_box     _init_box
+#define rt_calloc_box   _calloc_box
+extern U32     _init_box   (void *box_mem, U32 box_size, U32 blk_size);
+extern void *rt_alloc_box  (void *box_mem);
+extern void *  _calloc_box (void *box_mem);
+extern U32   rt_free_box   (void *box_mem, void *box);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,140 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MEMORY.C
+ *      Purpose: Interface functions for Dynamic Memory Management System
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "rt_Memory.h"
+
+
+/* Functions */
+
+// Initialize Dynamic Memory pool
+//   Parameters:
+//     pool:    Pointer to memory pool
+//     size:    Size of memory pool in bytes
+//   Return:    0 - OK, 1 - Error
+
+U32 rt_init_mem (void *pool, U32 size) {
+  MEMP *ptr;
+
+  if ((pool == NULL) || (size < sizeof(MEMP))) { return (1U); }
+
+  ptr = (MEMP *)pool;
+  ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *));
+  ptr->next->next = NULL;
+  ptr->len = 0U; 
+
+  return (0U);
+}
+
+// Allocate Memory from Memory pool
+//   Parameters:
+//     pool:    Pointer to memory pool
+//     size:    Size of memory in bytes to allocate
+//   Return:    Pointer to allocated memory
+
+void *rt_alloc_mem (void *pool, U32 size) {
+  MEMP *p, *p_search, *p_new;
+  U32   hole_size;
+
+  if ((pool == NULL) || (size == 0U)) { return NULL; }
+
+  /* Add header offset to 'size' */
+  size += sizeof(MEMP);
+  /* Make sure that block is 4-byte aligned  */
+  size = (size + 3U) & ~(U32)3U;
+
+  p_search = (MEMP *)pool;
+  while (1) {
+    hole_size  = (U32)p_search->next - (U32)p_search;
+    hole_size -= p_search->len;
+    /* Check if hole size is big enough */
+    if (hole_size >= size) { break; }
+    p_search = p_search->next;
+    if (p_search->next == NULL) {
+      /* Failed, we are at the end of the list */
+      return NULL;
+    }
+  }
+
+  if (p_search->len == 0U) {
+    /* No block is allocated, set the Length of the first element */
+    p_search->len = size;
+    p = (MEMP *)(((U32)p_search) + sizeof(MEMP));
+  } else {
+    /* Insert new list element into the memory list */
+    p_new       = (MEMP *)((U32)p_search + p_search->len);
+    p_new->next = p_search->next;
+    p_new->len  = size;
+    p_search->next = p_new;
+    p = (MEMP *)(((U32)p_new) + sizeof(MEMP));
+  }
+
+  return (p);
+}
+
+// Free Memory and return it to Memory pool
+//   Parameters:
+//     pool:    Pointer to memory pool
+//     mem:     Pointer to memory to free
+//   Return:    0 - OK, 1 - Error
+
+U32 rt_free_mem (void *pool, void *mem) {
+  MEMP *p_search, *p_prev, *p_return;
+
+  if ((pool == NULL) || (mem == NULL)) { return (1U); }
+
+  p_return = (MEMP *)((U32)mem - sizeof(MEMP));
+  
+  /* Set list header */
+  p_prev = NULL;
+  p_search = (MEMP *)pool;
+  while (p_search != p_return) {
+    p_prev   = p_search;
+    p_search = p_search->next;
+    if (p_search == NULL) {
+      /* Valid Memory block not found */
+      return (1U);
+    }
+  }
+
+  if (p_prev == NULL) {
+    /* First block to be released, only set length to 0 */
+    p_search->len = 0U;
+  } else {
+    /* Discard block from chain list */
+    p_prev->next = p_search->next;
+  }
+
+  return (0U);
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Memory.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,49 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MEMORY.H
+ *      Purpose: Interface functions for Dynamic Memory Management System
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Types */
+typedef struct mem {              /* << Memory Pool management struct >>     */
+  struct mem *next;               /* Next Memory Block in the list           */
+  U32         len;                /* Length of data block                    */
+} MEMP;
+
+/* Functions */
+extern U32   rt_init_mem  (void *pool, U32  size);
+extern void *rt_alloc_mem (void *pool, U32  size);
+extern U32   rt_free_mem  (void *pool, void *mem);
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,259 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MUTEX.C
+ *      Purpose: Implements mutex synchronization objects
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_List.h"
+#include "rt_Task.h"
+#include "rt_Mutex.h"
+#include "rt_HAL_CM.h"
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_mut_init -----------------------------------*/
+
+void rt_mut_init (OS_ID mutex) {
+  /* Initialize a mutex object */
+  P_MUCB p_MCB = mutex;
+
+  p_MCB->cb_type = MUCB;
+  p_MCB->level   = 0U;
+  p_MCB->p_lnk   = NULL;
+  p_MCB->owner   = NULL;
+  p_MCB->p_mlnk  = NULL;
+}
+
+
+/*--------------------------- rt_mut_delete ---------------------------------*/
+
+#ifdef __CMSIS_RTOS
+OS_RESULT rt_mut_delete (OS_ID mutex) {
+  /* Delete a mutex object */
+  P_MUCB p_MCB = mutex;
+  P_TCB  p_TCB;
+  P_MUCB p_mlnk;
+  U8     prio;
+
+  if (p_MCB->level != 0U) {
+
+    p_TCB = p_MCB->owner;
+
+    /* Remove mutex from task mutex owner list. */
+    p_mlnk = p_TCB->p_mlnk;
+    if (p_mlnk == p_MCB) {
+      p_TCB->p_mlnk = p_MCB->p_mlnk;
+    }
+    else {
+      while (p_mlnk) {
+        if (p_mlnk->p_mlnk == p_MCB) {
+          p_mlnk->p_mlnk = p_MCB->p_mlnk;
+          break;
+        }
+        p_mlnk = p_mlnk->p_mlnk;
+      }
+    }
+
+    /* Restore owner task's priority. */
+    prio = p_TCB->prio_base;
+    p_mlnk = p_TCB->p_mlnk;
+    while (p_mlnk) {
+      if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) {
+        /* A task with higher priority is waiting for mutex. */
+        prio = p_mlnk->p_lnk->prio;
+      }
+      p_mlnk = p_mlnk->p_mlnk;
+    }
+    if (p_TCB->prio != prio) {
+      p_TCB->prio = prio;
+      if (p_TCB != os_tsk.run) {
+        rt_resort_prio (p_TCB);
+      }
+    }
+
+  }
+
+  while (p_MCB->p_lnk != NULL) {
+    /* A task is waiting for mutex. */
+    p_TCB = rt_get_first ((P_XCB)p_MCB);
+    rt_ret_val(p_TCB, 0U/*osOK*/);
+    rt_rmv_dly(p_TCB);
+    p_TCB->state = READY;
+    rt_put_prio (&os_rdy, p_TCB);
+  }
+
+  if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) {
+    /* preempt running task */
+    rt_put_prio (&os_rdy, os_tsk.run);
+    os_tsk.run->state = READY;
+    rt_dispatch (NULL);
+  }
+
+  p_MCB->cb_type = 0U;
+
+  return (OS_R_OK);
+}
+#endif
+
+
+/*--------------------------- rt_mut_release --------------------------------*/
+
+OS_RESULT rt_mut_release (OS_ID mutex) {
+  /* Release a mutex object */
+  P_MUCB p_MCB = mutex;
+  P_TCB  p_TCB;
+  P_MUCB p_mlnk;
+  U8     prio;
+
+  if ((p_MCB->level == 0U) || (p_MCB->owner != os_tsk.run)) {
+    /* Unbalanced mutex release or task is not the owner */
+    return (OS_R_NOK);
+  }
+  if (--p_MCB->level != 0U) {
+    return (OS_R_OK);
+  }
+
+  /* Remove mutex from task mutex owner list. */
+  p_mlnk = os_tsk.run->p_mlnk;
+  if (p_mlnk == p_MCB) {
+    os_tsk.run->p_mlnk = p_MCB->p_mlnk;
+  }
+  else {
+    while (p_mlnk) {
+      if (p_mlnk->p_mlnk == p_MCB) {
+        p_mlnk->p_mlnk = p_MCB->p_mlnk;
+        break;
+      }
+      p_mlnk = p_mlnk->p_mlnk;
+    }
+  }
+
+  /* Restore owner task's priority. */
+  prio = os_tsk.run->prio_base;
+  p_mlnk = os_tsk.run->p_mlnk;
+  while (p_mlnk) {
+    if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) {
+      /* A task with higher priority is waiting for mutex. */
+      prio = p_mlnk->p_lnk->prio;
+    }
+    p_mlnk = p_mlnk->p_mlnk;
+  }
+  os_tsk.run->prio = prio;
+
+  if (p_MCB->p_lnk != NULL) {
+    /* A task is waiting for mutex. */
+    p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+    rt_ret_val(p_TCB, 0U/*osOK*/);
+#else
+    rt_ret_val(p_TCB, OS_R_MUT); 
+#endif
+    rt_rmv_dly (p_TCB);
+    /* A waiting task becomes the owner of this mutex. */
+    p_MCB->level  = 1U;
+    p_MCB->owner  = p_TCB;
+    p_MCB->p_mlnk = p_TCB->p_mlnk;
+    p_TCB->p_mlnk = p_MCB; 
+    /* Priority inversion, check which task continues. */
+    if (os_tsk.run->prio >= rt_rdy_prio()) {
+      rt_dispatch (p_TCB);
+    }
+    else {
+      /* Ready task has higher priority than running task. */
+      rt_put_prio (&os_rdy, os_tsk.run);
+      rt_put_prio (&os_rdy, p_TCB);
+      os_tsk.run->state = READY;
+      p_TCB->state      = READY;
+      rt_dispatch (NULL);
+    }
+  }
+  else {
+    /* Check if own priority lowered by priority inversion. */
+    if (rt_rdy_prio() > os_tsk.run->prio) {
+      rt_put_prio (&os_rdy, os_tsk.run);
+      os_tsk.run->state = READY;
+      rt_dispatch (NULL);
+    }
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_mut_wait -----------------------------------*/
+
+OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) {
+  /* Wait for a mutex, continue when mutex is free. */
+  P_MUCB p_MCB = mutex;
+
+  if (p_MCB->level == 0U) {
+    p_MCB->owner  = os_tsk.run;
+    p_MCB->p_mlnk = os_tsk.run->p_mlnk;
+    os_tsk.run->p_mlnk = p_MCB; 
+    goto inc;
+  }
+  if (p_MCB->owner == os_tsk.run) {
+    /* OK, running task is the owner of this mutex. */
+inc:p_MCB->level++;
+    return (OS_R_OK);
+  }
+  /* Mutex owned by another task, wait until released. */
+  if (timeout == 0U) {
+    return (OS_R_TMO);
+  }
+  /* Raise the owner task priority if lower than current priority. */
+  /* This priority inversion is called priority inheritance.       */
+  if (p_MCB->owner->prio < os_tsk.run->prio) {
+    p_MCB->owner->prio = os_tsk.run->prio;
+    rt_resort_prio (p_MCB->owner);
+  }
+  if (p_MCB->p_lnk != NULL) {
+    rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
+  }
+  else {
+    p_MCB->p_lnk = os_tsk.run;
+    os_tsk.run->p_lnk  = NULL;
+    os_tsk.run->p_rlnk = (P_TCB)p_MCB;
+  }
+  rt_block(timeout, WAIT_MUT);
+  return (OS_R_TMO);
+}
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,49 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_MUTEX.H
+ *      Purpose: Implements mutex synchronization objects
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Functions */
+extern void      rt_mut_init    (OS_ID mutex);
+extern OS_RESULT rt_mut_delete  (OS_ID mutex);
+extern OS_RESULT rt_mut_release (OS_ID mutex);
+extern OS_RESULT rt_mut_wait    (OS_ID mutex, U16 timeout);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,61 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    rt_OsEventObserver.c
+ *      Purpose: OS Event Callbacks for CMSIS RTOS
+ *      Rev.:    VX.XX
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_OsEventObserver.h"
+
+/*
+ *  _____ _____  ____  __ _____
+ * |  ___|_ _\ \/ /  \/  | ____|
+ * | |_   | | \  /| |\/| |  _|
+ * |  _|  | | /  \| |  | | |___
+ * |_|   |___/_/\_\_|  |_|_____|
+ *
+ * FIXME:
+ * The osEventObs variable must be in protected memory. If not every box
+ * and box 0 can modify osEventObs to point to any handler to run code
+ * privileged. This issue is tracked at
+ * <https://github.com/ARMmbed/uvisor/issues/235>.
+ */
+const OsEventObserver *osEventObs;
+
+void osRegisterForOsEvents(const OsEventObserver *observer)
+{
+    static uint8_t has_been_called = 0;
+    if (has_been_called) {
+        return;
+    }
+    has_been_called = 1;
+
+    osEventObs = observer;
+}
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,63 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    os_events.h
+ *      Purpose: OS Event Callbacks for CMSIS RTOS
+ *      Rev.:    VX.XX
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2016 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+#ifndef _RT_OS_EVENT_OBSERVER_H
+#define _RT_OS_EVENT_OBSERVER_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    uint32_t version;
+    void (*pre_start)(void);
+    void *(*thread_create)(int thread_id, void *context);
+    void (*thread_destroy)(void *context);
+    void (*thread_switch)(void *context);
+} OsEventObserver;
+extern const OsEventObserver *osEventObs;
+
+void osRegisterForOsEvents(const OsEventObserver *observer);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,83 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_ROBIN.C
+ *      Purpose: Round Robin Task switching
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_List.h"
+#include "rt_Task.h"
+#include "rt_Time.h"
+#include "rt_Robin.h"
+#include "rt_HAL_CM.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+struct OS_ROBIN os_robin;
+
+
+/*----------------------------------------------------------------------------
+ *      Global Functions
+ *---------------------------------------------------------------------------*/
+
+/*--------------------------- rt_init_robin ---------------------------------*/
+
+__weak void rt_init_robin (void) {
+  /* Initialize Round Robin variables. */
+  os_robin.task = NULL;
+  os_robin.tout = (U16)os_rrobin;
+}
+
+/*--------------------------- rt_chk_robin ----------------------------------*/
+
+__weak void rt_chk_robin (void) {
+  /* Check if Round Robin timeout expired and switch to the next ready task.*/
+  P_TCB p_new;
+
+  if (os_robin.task != os_rdy.p_lnk) {
+    /* New task was suspended, reset Round Robin timeout. */
+    os_robin.task = os_rdy.p_lnk;
+    os_robin.time = (U16)os_time + os_robin.tout - 1U;
+  }
+  if (os_robin.time == (U16)os_time) {
+    /* Round Robin timeout has expired, swap Robin tasks. */
+    os_robin.task = NULL;
+    p_new = rt_get_first (&os_rdy);
+    rt_put_prio ((P_XCB)&os_rdy, p_new);
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Robin.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,50 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_ROBIN.H
+ *      Purpose: Round Robin Task switching definitions
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Variables */
+extern struct OS_ROBIN os_robin;
+
+/* Functions */
+extern void rt_init_robin (void);
+extern void rt_chk_robin  (void);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,182 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_SEMAPHORE.C
+ *      Purpose: Implements binary and counting semaphores
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_List.h"
+#include "rt_Task.h"
+#include "rt_Semaphore.h"
+#include "rt_HAL_CM.h"
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_sem_init -----------------------------------*/
+
+void rt_sem_init (OS_ID semaphore, U16 token_count) {
+  /* Initialize a semaphore */
+  P_SCB p_SCB = semaphore;
+
+  p_SCB->cb_type = SCB;
+  p_SCB->p_lnk  = NULL;
+  p_SCB->tokens = token_count;
+}
+
+
+/*--------------------------- rt_sem_delete ---------------------------------*/
+
+#ifdef __CMSIS_RTOS
+OS_RESULT rt_sem_delete (OS_ID semaphore) {
+  /* Delete semaphore */
+  P_SCB p_SCB = semaphore;
+  P_TCB p_TCB;
+
+  while (p_SCB->p_lnk != NULL) {
+    /* A task is waiting for token */
+    p_TCB = rt_get_first ((P_XCB)p_SCB);
+    rt_ret_val(p_TCB, 0U);
+    rt_rmv_dly(p_TCB);
+    p_TCB->state = READY;
+    rt_put_prio (&os_rdy, p_TCB);
+  }
+
+  if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) {
+    /* preempt running task */
+    rt_put_prio (&os_rdy, os_tsk.run);
+    os_tsk.run->state = READY;
+    rt_dispatch (NULL);
+  }
+
+  p_SCB->cb_type = 0U;
+
+  return (OS_R_OK);
+}
+#endif
+
+
+/*--------------------------- rt_sem_send -----------------------------------*/
+
+OS_RESULT rt_sem_send (OS_ID semaphore) {
+  /* Return a token to semaphore */
+  P_SCB p_SCB = semaphore;
+  P_TCB p_TCB;
+
+  if (p_SCB->p_lnk != NULL) {
+    /* A task is waiting for token */
+    p_TCB = rt_get_first ((P_XCB)p_SCB);
+#ifdef __CMSIS_RTOS
+    rt_ret_val(p_TCB, 1U);
+#else
+    rt_ret_val(p_TCB, OS_R_SEM);
+#endif
+    rt_rmv_dly (p_TCB);
+    rt_dispatch (p_TCB);
+  }
+  else {
+    /* Store token. */
+    p_SCB->tokens++;
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_sem_wait -----------------------------------*/
+
+OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) {
+  /* Obtain a token; possibly wait for it */
+  P_SCB p_SCB = semaphore;
+
+  if (p_SCB->tokens) {
+    p_SCB->tokens--;
+    return (OS_R_OK);
+  }
+  /* No token available: wait for one */
+  if (timeout == 0U) {
+    return (OS_R_TMO);
+  }
+  if (p_SCB->p_lnk != NULL) {
+    rt_put_prio ((P_XCB)p_SCB, os_tsk.run);
+  }
+  else {
+    p_SCB->p_lnk = os_tsk.run;
+    os_tsk.run->p_lnk = NULL;
+    os_tsk.run->p_rlnk = (P_TCB)p_SCB;
+  }
+  rt_block(timeout, WAIT_SEM);
+  return (OS_R_TMO);
+}
+
+
+/*--------------------------- isr_sem_send ----------------------------------*/
+
+void isr_sem_send (OS_ID semaphore) {
+  /* Same function as "os_sem_send", but to be called by ISRs */
+  P_SCB p_SCB = semaphore;
+
+  rt_psq_enq (p_SCB, 0U);
+  rt_psh_req ();
+}
+
+
+/*--------------------------- rt_sem_psh ------------------------------------*/
+
+void rt_sem_psh (P_SCB p_CB) {
+  /* Check if task has to be waken up */
+  P_TCB p_TCB;
+
+  if (p_CB->p_lnk != NULL) {
+    /* A task is waiting for token */
+    p_TCB = rt_get_first ((P_XCB)p_CB);
+    rt_rmv_dly (p_TCB);
+    p_TCB->state   = READY;
+#ifdef __CMSIS_RTOS
+    rt_ret_val(p_TCB, 1U);
+#else
+    rt_ret_val(p_TCB, OS_R_SEM);
+#endif
+    rt_put_prio (&os_rdy, p_TCB);
+  }
+  else {
+    /* Store token */
+    p_CB->tokens++;
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,51 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_SEMAPHORE.H
+ *      Purpose: Implements binary and counting semaphores
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Functions */
+extern void      rt_sem_init  (OS_ID semaphore, U16 token_count);
+extern OS_RESULT rt_sem_delete(OS_ID semaphore);
+extern OS_RESULT rt_sem_send  (OS_ID semaphore);
+extern OS_RESULT rt_sem_wait  (OS_ID semaphore, U16 timeout);
+extern void      isr_sem_send (OS_ID semaphore);
+extern void      rt_sem_psh (P_SCB p_CB);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,337 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_SYSTEM.C
+ *      Purpose: System Task Manager
+ *      Rev.:    V4.80
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_Task.h"
+#include "rt_System.h"
+#include "rt_Event.h"
+#include "rt_List.h"
+#include "rt_Mailbox.h"
+#include "rt_Semaphore.h"
+#include "rt_Time.h"
+#include "rt_Timer.h"
+#include "rt_Robin.h"
+#include "rt_HAL_CM.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+S32 os_tick_irqn;
+
+/*----------------------------------------------------------------------------
+ *      Local Variables
+ *---------------------------------------------------------------------------*/
+
+static volatile BIT os_lock;
+static volatile BIT os_psh_flag;
+static          U8  pend_flags;
+
+/*----------------------------------------------------------------------------
+ *      Global Functions
+ *---------------------------------------------------------------------------*/
+
+#define RL_RTX_VER      0x480
+
+#if defined (__CC_ARM)
+__asm void $$RTX$$version (void) {
+   /* Export a version number symbol for a version control. */
+
+                EXPORT  __RL_RTX_VER
+
+__RL_RTX_VER    EQU     RL_RTX_VER
+}
+#endif
+
+
+/*--------------------------- rt_suspend ------------------------------------*/
+
+extern U32 sysUserTimerWakeupTime(void);
+
+U32 rt_suspend (void) {
+  /* Suspend OS scheduler */
+  U32 delta = 0xFFFFU;
+#ifdef __CMSIS_RTOS
+  U32 sleep;
+#endif
+
+  rt_tsk_lock();
+  
+  if (os_dly.p_dlnk) {
+    delta = os_dly.delta_time;
+  }
+#ifdef __CMSIS_RTOS
+  sleep = sysUserTimerWakeupTime();
+  if (sleep < delta) { delta = sleep; }
+#else
+  if (os_tmr.next) {
+    if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
+  }
+#endif
+
+  return (delta);
+}
+
+
+/*--------------------------- rt_resume -------------------------------------*/
+
+extern void sysUserTimerUpdate (U32 sleep_time);
+
+void rt_resume (U32 sleep_time) {
+  /* Resume OS scheduler after suspend */
+  P_TCB next;
+  U32   delta;
+
+  os_tsk.run->state = READY;
+  rt_put_rdy_first (os_tsk.run);
+
+  os_robin.task = NULL;
+
+  /* Update delays. */
+  if (os_dly.p_dlnk) {
+    delta = sleep_time;
+    if (delta >= os_dly.delta_time) {
+      delta   -= os_dly.delta_time;
+      os_time += os_dly.delta_time;
+      os_dly.delta_time = 1U;
+      while (os_dly.p_dlnk) {
+        rt_dec_dly();
+        if (delta == 0U) { break; }
+        delta--;
+        os_time++;
+      }
+    } else {
+      os_time           +=      delta;
+      os_dly.delta_time -= (U16)delta;
+    }
+  } else {
+    os_time += sleep_time;
+  }
+
+  /* Check the user timers. */
+#ifdef __CMSIS_RTOS
+  sysUserTimerUpdate(sleep_time);
+#else
+  if (os_tmr.next) {
+    delta = sleep_time;
+    if (delta >= os_tmr.tcnt) {
+      delta   -= os_tmr.tcnt;
+      os_tmr.tcnt = 1U;
+      while (os_tmr.next) {
+        rt_tmr_tick();
+        if (delta == 0U) { break; }
+        delta--;
+      }
+    } else {
+      os_tmr.tcnt -= delta;
+    }
+  }
+#endif
+
+  /* Switch back to highest ready task */
+  next = rt_get_first (&os_rdy);
+  rt_switch_req (next);
+
+  rt_tsk_unlock();
+}
+
+
+/*--------------------------- rt_tsk_lock -----------------------------------*/
+
+void rt_tsk_lock (void) {
+  /* Prevent task switching by locking out scheduler */
+  if (os_tick_irqn < 0) {
+    OS_LOCK();
+    os_lock = __TRUE;
+    OS_UNPEND(pend_flags);
+  } else {
+    OS_X_LOCK((U32)os_tick_irqn);
+    os_lock = __TRUE;
+    OS_X_UNPEND(pend_flags);
+  }
+}
+
+
+/*--------------------------- rt_tsk_unlock ---------------------------------*/
+
+void rt_tsk_unlock (void) {
+  /* Unlock scheduler and re-enable task switching */
+  if (os_tick_irqn < 0) {
+    OS_UNLOCK();
+    os_lock = __FALSE;
+    OS_PEND(pend_flags, os_psh_flag);
+    os_psh_flag = __FALSE;
+  } else {
+    OS_X_UNLOCK((U32)os_tick_irqn);
+    os_lock = __FALSE;
+    OS_X_PEND(pend_flags, os_psh_flag);
+    os_psh_flag = __FALSE;
+  }
+}
+
+
+/*--------------------------- rt_psh_req ------------------------------------*/
+
+void rt_psh_req (void) {
+  /* Initiate a post service handling request if required. */
+  if (os_lock == __FALSE) {
+    OS_PEND_IRQ();
+  }
+  else {
+    os_psh_flag = __TRUE;
+  }
+}
+
+
+/*--------------------------- rt_pop_req ------------------------------------*/
+
+void rt_pop_req (void) {
+  /* Process an ISR post service requests. */
+  struct OS_XCB *p_CB;
+  P_TCB next;
+  U32  idx;
+
+  os_tsk.run->state = READY;
+  rt_put_rdy_first (os_tsk.run);
+
+  idx = os_psq->last;
+  while (os_psq->count) {
+    p_CB = os_psq->q[idx].id;
+    if (p_CB->cb_type == TCB) {
+      /* Is of TCB type */
+      rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
+    }
+    else if (p_CB->cb_type == MCB) {
+      /* Is of MCB type */
+      rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
+    }
+    else {
+      /* Must be of SCB type */
+      rt_sem_psh ((P_SCB)p_CB);
+    }
+    if (++idx == os_psq->size) { idx = 0U; }
+    rt_dec (&os_psq->count);
+  }
+  os_psq->last = (U8)idx;
+
+  next = rt_get_first (&os_rdy);
+  rt_switch_req (next);
+}
+
+
+/*--------------------------- os_tick_init ----------------------------------*/
+
+__weak S32 os_tick_init (void) {
+  /* Initialize SysTick timer as system tick timer. */
+  rt_systick_init();
+  return (-1);  /* Return IRQ number of SysTick timer */
+}
+
+/*--------------------------- os_tick_val -----------------------------------*/
+
+__weak U32 os_tick_val (void) {
+  /* Get SysTick timer current value (0 .. OS_TRV). */
+  return rt_systick_val();
+}
+
+/*--------------------------- os_tick_ovf -----------------------------------*/
+
+__weak U32 os_tick_ovf (void) {
+  /* Get SysTick timer overflow flag */
+  return rt_systick_ovf();
+}
+
+/*--------------------------- os_tick_irqack --------------------------------*/
+
+__weak void os_tick_irqack (void) {
+  /* Acknowledge timer interrupt. */
+}
+
+
+/*--------------------------- rt_systick ------------------------------------*/
+
+extern void sysTimerTick(void);
+
+void rt_systick (void) {
+  /* Check for system clock update, suspend running task. */
+  P_TCB next;
+
+  os_tsk.run->state = READY;
+  rt_put_rdy_first (os_tsk.run);
+
+  /* Check Round Robin timeout. */
+  rt_chk_robin ();
+
+  /* Update delays. */
+  os_time++;
+  rt_dec_dly ();
+
+  /* Check the user timers. */
+#ifdef __CMSIS_RTOS
+  sysTimerTick();
+#else
+  rt_tmr_tick ();
+#endif
+
+  /* Switch back to highest ready task */
+  next = rt_get_first (&os_rdy);
+  rt_switch_req (next);
+}
+
+/*--------------------------- rt_stk_check ----------------------------------*/
+
+__weak void rt_stk_check (void) {
+#ifdef __MBED_CMSIS_RTOS_CM
+    /* Check for stack overflow. */
+    if (os_tsk.run->task_id == MAIN_THREAD_ID) {
+        // TODO: For the main thread the check should be done against the main heap pointer
+    } else {
+        if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
+            (os_tsk.run->stack[0] != MAGIC_WORD)) {
+            os_error (OS_ERR_STK_OVF);
+        }
+    }
+#else
+    if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
+        (os_tsk.run->stack[0] != MAGIC_WORD)) {
+        os_error (OS_ERR_STK_OVF);
+    }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_System.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,57 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_SYSTEM.H
+ *      Purpose: System Task Manager definitions
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Variables */
+#define os_psq  ((P_PSQ)&os_fifo)
+extern S32 os_tick_irqn;
+
+/* Functions */
+extern U32  rt_suspend    (void);
+extern void rt_resume     (U32 sleep_time);
+extern void rt_tsk_lock   (void);
+extern void rt_tsk_unlock (void);
+extern void rt_psh_req    (void);
+extern void rt_pop_req    (void);
+extern void rt_systick    (void);
+extern void rt_stk_check  (void);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,456 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TASK.C
+ *      Purpose: Task functions and system start up.
+ *      Rev.:    V4.80
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_System.h"
+#include "rt_Task.h"
+#include "rt_List.h"
+#include "rt_MemBox.h"
+#include "rt_Robin.h"
+#include "rt_HAL_CM.h"
+#include "rt_OsEventObserver.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+/* Running and next task info. */
+struct OS_TSK os_tsk;
+
+/* Task Control Blocks of idle demon */
+struct OS_TCB os_idle_TCB;
+
+
+/*----------------------------------------------------------------------------
+ *      Local Functions
+ *---------------------------------------------------------------------------*/
+
+static OS_TID rt_get_TID (void) {
+  U32 tid;
+
+  for (tid = 1U; tid <= os_maxtaskrun; tid++) {
+    if (os_active_TCB[tid-1U] == NULL) {
+      return ((OS_TID)tid);
+    }
+  }
+  return (0U);
+}
+
+
+/*--------------------------- rt_init_context -------------------------------*/
+
+static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) {
+  /* Initialize general part of the Task Control Block. */
+  p_TCB->cb_type   = TCB;
+  p_TCB->state     = READY;
+  p_TCB->prio      = priority;
+  p_TCB->prio_base = priority;
+  p_TCB->p_lnk     = NULL;
+  p_TCB->p_rlnk    = NULL;
+  p_TCB->p_dlnk    = NULL;
+  p_TCB->p_blnk    = NULL;
+  p_TCB->p_mlnk    = NULL;
+  p_TCB->delta_time    = 0U;
+  p_TCB->interval_time = 0U;
+  p_TCB->events  = 0U;
+  p_TCB->waits   = 0U;
+  p_TCB->stack_frame = 0U;
+
+  if (p_TCB->priv_stack == 0U) {
+    /* Allocate the memory space for the stack. */
+    p_TCB->stack = rt_alloc_box (mp_stk);
+  }
+  rt_init_stack (p_TCB, task_body);
+}
+
+
+/*--------------------------- rt_switch_req ---------------------------------*/
+
+void rt_switch_req (P_TCB p_new) {
+  /* Switch to next task (identified by "p_new"). */
+  os_tsk.new_tsk   = p_new;
+  p_new->state = RUNNING;
+  if (osEventObs && osEventObs->thread_switch) {
+    osEventObs->thread_switch(p_new->context);
+  }
+  DBG_TASK_SWITCH(p_new->task_id);
+}
+
+
+/*--------------------------- rt_dispatch -----------------------------------*/
+
+void rt_dispatch (P_TCB next_TCB) {
+  /* Dispatch next task if any identified or dispatch highest ready task    */
+  /* "next_TCB" identifies a task to run or has value NULL (=no next task)  */
+  if (next_TCB == NULL) {
+    /* Running task was blocked: continue with highest ready task */
+    next_TCB = rt_get_first (&os_rdy);
+    rt_switch_req (next_TCB);
+  }
+  else {
+    /* Check which task continues */
+    if (next_TCB->prio > os_tsk.run->prio) {
+      /* preempt running task */
+      rt_put_rdy_first (os_tsk.run);
+      os_tsk.run->state = READY;
+      rt_switch_req (next_TCB);
+    }
+    else {
+      /* put next task into ready list, no task switch takes place */
+      next_TCB->state = READY;
+      rt_put_prio (&os_rdy, next_TCB);
+    }
+  }
+}
+
+
+/*--------------------------- rt_block --------------------------------------*/
+
+void rt_block (U16 timeout, U8 block_state) {
+  /* Block running task and choose next ready task.                         */
+  /* "timeout" sets a time-out value or is 0xffff (=no time-out).           */
+  /* "block_state" defines the appropriate task state */
+  P_TCB next_TCB;
+
+  if (timeout) {
+    if (timeout < 0xFFFFU) {
+      rt_put_dly (os_tsk.run, timeout);
+    }
+    os_tsk.run->state = block_state;
+    next_TCB = rt_get_first (&os_rdy);
+    rt_switch_req (next_TCB);
+  }
+}
+
+
+/*--------------------------- rt_tsk_pass -----------------------------------*/
+
+void rt_tsk_pass (void) {
+  /* Allow tasks of same priority level to run cooperatively.*/
+  P_TCB p_new;
+
+  p_new = rt_get_same_rdy_prio();
+  if (p_new != NULL) {
+    rt_put_prio ((P_XCB)&os_rdy, os_tsk.run);
+    os_tsk.run->state = READY;
+    rt_switch_req (p_new);
+  }
+}
+
+
+/*--------------------------- rt_tsk_self -----------------------------------*/
+
+OS_TID rt_tsk_self (void) {
+  /* Return own task identifier value. */
+  if (os_tsk.run == NULL) {
+    return (0U);
+  }
+  return ((OS_TID)os_tsk.run->task_id);
+}
+
+
+/*--------------------------- rt_tsk_prio -----------------------------------*/
+
+OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) {
+  /* Change execution priority of a task to "new_prio". */
+  P_TCB p_task;
+
+  if (task_id == 0U) {
+    /* Change execution priority of calling task. */
+    os_tsk.run->prio      = new_prio;
+    os_tsk.run->prio_base = new_prio;
+run:if (rt_rdy_prio() > new_prio) {
+      rt_put_prio (&os_rdy, os_tsk.run);
+      os_tsk.run->state   = READY;
+      rt_dispatch (NULL);
+    }
+    return (OS_R_OK);
+  }
+
+  /* Find the task in the "os_active_TCB" array. */
+  if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) {
+    /* Task with "task_id" not found or not started. */
+    return (OS_R_NOK);
+  }
+  p_task = os_active_TCB[task_id-1U];
+  p_task->prio      = new_prio;
+  p_task->prio_base = new_prio;
+  if (p_task == os_tsk.run) {
+    goto run;
+  }
+  rt_resort_prio (p_task);
+  if (p_task->state == READY) {
+    /* Task enqueued in a ready list. */
+    p_task = rt_get_first (&os_rdy);
+    rt_dispatch (p_task);
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_tsk_create ---------------------------------*/
+
+OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) {
+  /* Start a new task declared with "task". */
+  P_TCB task_context;
+  U32 i;
+
+  /* Priority 0 is reserved for idle task! */
+  if ((prio_stksz & 0xFFU) == 0U) {
+    prio_stksz += 1U;
+  }
+  task_context = rt_alloc_box (mp_tcb);
+  if (task_context == NULL) {
+    return (0U);
+  }
+  /* If "size != 0" use a private user provided stack. */
+  task_context->stack      = stk;
+  task_context->priv_stack = prio_stksz >> 8;
+
+  /* Find a free entry in 'os_active_TCB' table. */
+  i = rt_get_TID ();
+  if (i == 0U) {
+    return (0U);
+  }
+  task_context->task_id = (U8)i;
+  /* Pass parameter 'argv' to 'rt_init_context' */
+  task_context->msg = argv;
+  task_context->argv = argv;
+  /* For 'size == 0' system allocates the user stack from the memory pool. */
+  rt_init_context (task_context, (U8)(prio_stksz & 0xFFU), task);
+
+  os_active_TCB[i-1U] = task_context;
+  DBG_TASK_NOTIFY(task_context, __TRUE);
+  rt_dispatch (task_context);
+  return ((OS_TID)i);
+}
+
+
+/*--------------------------- rt_tsk_delete ---------------------------------*/
+
+OS_RESULT rt_tsk_delete (OS_TID task_id) {
+  /* Terminate the task identified with "task_id". */
+  P_TCB  task_context;
+  P_TCB  p_TCB;
+  P_MUCB p_MCB, p_MCB0;
+
+  if ((task_id == 0U) || (task_id == os_tsk.run->task_id)) {
+    /* Terminate itself. */
+    os_tsk.run->state     = INACTIVE;
+    os_tsk.run->tsk_stack = rt_get_PSP ();
+    rt_stk_check ();
+    p_MCB = os_tsk.run->p_mlnk;
+    while (p_MCB) {
+      /* Release mutexes owned by this task */
+      if (p_MCB->p_lnk) {
+        /* A task is waiting for mutex. */
+        p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+        rt_ret_val (p_TCB, 0U/*osOK*/);
+#else
+        rt_ret_val (p_TCB, OS_R_MUT); 
+#endif
+        rt_rmv_dly (p_TCB);
+        p_TCB->state = READY;
+        rt_put_prio (&os_rdy, p_TCB);
+        /* A waiting task becomes the owner of this mutex. */
+        p_MCB0 = p_MCB->p_mlnk;
+        p_MCB->level  = 1U;
+        p_MCB->owner  = p_TCB;
+        p_MCB->p_mlnk = p_TCB->p_mlnk;
+        p_TCB->p_mlnk = p_MCB; 
+        p_MCB = p_MCB0;
+      }
+      else {
+        p_MCB0 = p_MCB->p_mlnk;
+        p_MCB->level  = 0U;
+        p_MCB->owner  = NULL;
+        p_MCB->p_mlnk = NULL;
+        p_MCB = p_MCB0;
+      }
+    }
+    os_active_TCB[os_tsk.run->task_id-1U] = NULL;
+    rt_free_box (mp_stk, os_tsk.run->stack);
+    os_tsk.run->stack = NULL;
+    DBG_TASK_NOTIFY(os_tsk.run, __FALSE);
+    rt_free_box (mp_tcb, os_tsk.run);
+    os_tsk.run = NULL;
+    rt_dispatch (NULL);
+    /* The program should never come to this point. */
+  }
+  else {
+    /* Find the task in the "os_active_TCB" array. */
+    if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) {
+      /* Task with "task_id" not found or not started. */
+      return (OS_R_NOK);
+    }
+    task_context = os_active_TCB[task_id-1U];
+    rt_rmv_list (task_context);
+    rt_rmv_dly (task_context);
+    p_MCB = task_context->p_mlnk;
+    while (p_MCB) {
+      /* Release mutexes owned by this task */
+      if (p_MCB->p_lnk) {
+        /* A task is waiting for mutex. */
+        p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+        rt_ret_val (p_TCB, 0U/*osOK*/);
+#else
+        rt_ret_val (p_TCB, OS_R_MUT); 
+#endif
+        rt_rmv_dly (p_TCB);
+        p_TCB->state = READY;
+        rt_put_prio (&os_rdy, p_TCB);
+        /* A waiting task becomes the owner of this mutex. */
+        p_MCB0 = p_MCB->p_mlnk;
+        p_MCB->level  = 1U;
+        p_MCB->owner  = p_TCB;
+        p_MCB->p_mlnk = p_TCB->p_mlnk;
+        p_TCB->p_mlnk = p_MCB; 
+        p_MCB = p_MCB0;
+      }
+      else {
+        p_MCB0 = p_MCB->p_mlnk;
+        p_MCB->level  = 0U;
+        p_MCB->owner  = NULL;
+        p_MCB->p_mlnk = NULL;
+        p_MCB = p_MCB0;
+      }
+    }
+    os_active_TCB[task_id-1U] = NULL;
+    rt_free_box (mp_stk, task_context->stack);
+    task_context->stack = NULL;
+    DBG_TASK_NOTIFY(task_context, __FALSE);
+    rt_free_box (mp_tcb, task_context);
+    if (rt_rdy_prio() > os_tsk.run->prio) {
+      /* Ready task has higher priority than running task. */
+      os_tsk.run->state = READY;
+      rt_put_prio (&os_rdy, os_tsk.run);
+      rt_dispatch (NULL);
+    }
+  }
+  return (OS_R_OK);
+}
+
+
+/*--------------------------- rt_sys_init -----------------------------------*/
+
+#ifdef __CMSIS_RTOS
+void rt_sys_init (void) {
+#else
+void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) {
+#endif
+  /* Initialize system and start up task declared with "first_task". */
+  U32 i;
+
+  DBG_INIT();
+
+  /* Initialize dynamic memory and task TCB pointers to NULL. */
+  for (i = 0U; i < os_maxtaskrun; i++) {
+    os_active_TCB[i] = NULL;
+  }
+  rt_init_box (mp_tcb, (U32)mp_tcb_size, sizeof(struct OS_TCB));
+  rt_init_box (mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo));
+  rt_init_box ((U32 *)m_tmr, (U32)mp_tmr_size, sizeof(struct OS_TMR));
+
+  /* Set up TCB of idle demon */
+  os_idle_TCB.task_id    = 255U;
+  os_idle_TCB.priv_stack = 0U;
+  rt_init_context (&os_idle_TCB, 0U, os_idle_demon);
+
+  /* Set up ready list: initially empty */
+  os_rdy.cb_type = HCB;
+  os_rdy.p_lnk   = NULL;
+  /* Set up delay list: initially empty */
+  os_dly.cb_type = HCB;
+  os_dly.p_dlnk  = NULL;
+  os_dly.p_blnk  = NULL;
+  os_dly.delta_time = 0U;
+
+  /* Fix SP and system variables to assume idle task is running */
+  /* Transform main program into idle task by assuming idle TCB */
+#ifndef __CMSIS_RTOS
+  rt_set_PSP (os_idle_TCB.tsk_stack+32U);
+#endif
+  os_tsk.run = &os_idle_TCB;
+  os_tsk.run->state = RUNNING;
+
+  /* Set the current thread to idle, so that on exit from this SVCall we do not
+   * de-reference a NULL TCB. */
+  rt_switch_req(&os_idle_TCB);
+
+  /* Initialize ps queue */
+  os_psq->first = 0U;
+  os_psq->last  = 0U;
+  os_psq->size  = os_fifo_size;
+
+  rt_init_robin ();
+
+#ifndef __CMSIS_RTOS
+  /* Initialize SVC and PendSV */
+  rt_svc_init ();
+
+  /* Initialize and start system clock timer */
+  os_tick_irqn = os_tick_init ();
+  if (os_tick_irqn >= 0) {
+    OS_X_INIT((U32)os_tick_irqn);
+  }
+
+  /* Start up first user task before entering the endless loop */
+  rt_tsk_create (first_task, prio_stksz, stk, NULL);
+#endif
+}
+
+
+/*--------------------------- rt_sys_start ----------------------------------*/
+
+#ifdef __CMSIS_RTOS
+void rt_sys_start (void) {
+  /* Start system */
+
+  /* Initialize SVC and PendSV */
+  rt_svc_init ();
+
+  /* Initialize and start system clock timer */
+  os_tick_irqn = os_tick_init ();
+  if (os_tick_irqn >= 0) {
+    OS_X_INIT((U32)os_tick_irqn);
+  }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Task.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,88 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TASK.H
+ *      Purpose: Task functions and system start up.
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Definitions */
+
+#include "cmsis_os.h"
+
+/* Values for 'state'   */
+#define INACTIVE        0U
+#define READY           1U
+#define RUNNING         2U
+#define WAIT_DLY        3U
+#define WAIT_ITV        4U
+#define WAIT_OR         5U
+#define WAIT_AND        6U
+#define WAIT_SEM        7U
+#define WAIT_MBX        8U
+#define WAIT_MUT        9U
+
+/* Return codes */
+#define OS_R_TMO        0x01U
+#define OS_R_EVT        0x02U
+#define OS_R_SEM        0x03U
+#define OS_R_MBX        0x04U
+#define OS_R_MUT        0x05U
+
+#define OS_R_OK         0x00U
+#define OS_R_NOK        0xFFU
+
+/* Variables */
+extern struct OS_TSK os_tsk;
+extern struct OS_TCB os_idle_TCB;
+
+/* Functions */
+extern void      rt_switch_req (P_TCB p_new);
+extern void      rt_dispatch   (P_TCB next_TCB);
+extern void      rt_block      (U16 timeout, U8 block_state);
+extern void      rt_tsk_pass   (void);
+extern OS_TID    rt_tsk_self   (void);
+extern OS_RESULT rt_tsk_prio   (OS_TID task_id, U8 new_prio);
+extern OS_TID    rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv);
+extern OS_RESULT rt_tsk_delete (OS_TID task_id);
+#ifdef __CMSIS_RTOS
+extern void      rt_sys_init   (void);
+extern void      rt_sys_start  (void);
+#else
+extern void      rt_sys_init   (FUNCP first_task, U32 prio_stksz, void *stk);
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TIME.C
+ *      Purpose: Delay and interval wait functions
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_Task.h"
+#include "rt_Time.h"
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+/* Free running system tick counter */
+U32 os_time;
+
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+
+/*--------------------------- rt_time_get -----------------------------------*/
+
+U32 rt_time_get (void) {
+  /* Get system time tick */
+  return (os_time);
+}
+
+
+/*--------------------------- rt_dly_wait -----------------------------------*/
+
+void rt_dly_wait (U16 delay_time) {
+  /* Delay task by "delay_time" */
+  rt_block (delay_time, WAIT_DLY);
+}
+
+
+/*--------------------------- rt_itv_set ------------------------------------*/
+
+void rt_itv_set (U16 interval_time) {
+  /* Set interval length and define start of first interval */
+  os_tsk.run->interval_time = interval_time;
+  os_tsk.run->delta_time = interval_time + (U16)os_time;
+}
+
+
+/*--------------------------- rt_itv_wait -----------------------------------*/
+
+void rt_itv_wait (void) {
+  /* Wait for interval end and define start of next one */
+  U16 delta;
+
+  delta = os_tsk.run->delta_time - (U16)os_time;
+  os_tsk.run->delta_time += os_tsk.run->interval_time;
+  if ((delta & 0x8000U) == 0U) {
+    rt_block (delta, WAIT_ITV);
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Time.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,52 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TIME.H
+ *      Purpose: Delay and interval wait functions definitions
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Variables */
+extern U32 os_time;
+
+/* Functions */
+extern U32  rt_time_get (void);
+extern void rt_dly_wait (U16 delay_time);
+extern void rt_itv_set  (U16 interval_time);
+extern void rt_itv_wait (void);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.c	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,135 @@
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TIMER.C
+ *      Purpose: User timer functions
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "rt_TypeDef.h"
+#include "RTX_Config.h"
+#include "rt_Timer.h"
+#include "rt_MemBox.h"
+#include "cmsis_os.h"
+
+#ifndef __CMSIS_RTOS
+
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+/* User Timer list pointer */
+struct OS_XTMR os_tmr;
+
+/*----------------------------------------------------------------------------
+ *      Functions
+ *---------------------------------------------------------------------------*/
+
+/*--------------------------- rt_tmr_tick -----------------------------------*/
+
+void rt_tmr_tick (void) {
+  /* Decrement delta count of timer list head. Timers having the value of   */
+  /* zero are removed from the list and the callback function is called.    */
+  P_TMR p;
+
+  if (os_tmr.next == NULL) {
+    return;
+  }
+  os_tmr.tcnt--;
+  while ((os_tmr.tcnt == 0U) && ((p = os_tmr.next) != NULL)) {
+    /* Call a user provided function to handle an elapsed timer */
+    os_tmr_call (p->info);
+    os_tmr.tcnt = p->tcnt;
+    os_tmr.next = p->next;
+    rt_free_box ((U32 *)m_tmr, p);
+  }
+}
+
+/*--------------------------- rt_tmr_create ---------------------------------*/
+
+OS_ID rt_tmr_create (U16 tcnt, U16 info)  {
+  /* Create an user timer and put it into the chained timer list using      */
+  /* a timeout count value of "tcnt". User parameter "info" is used as a    */
+  /* parameter for the user provided callback function "os_tmr_call ()".    */
+  P_TMR p_tmr, p;
+  U32 delta,itcnt = tcnt;
+
+  if ((tcnt == 0U) || (m_tmr == NULL)) {
+    return (NULL);
+  }
+  p_tmr = rt_alloc_box ((U32 *)m_tmr);
+  if (!p_tmr)  {
+    return (NULL);
+  }
+  p_tmr->info = info;
+  p = (P_TMR)&os_tmr;
+  delta = p->tcnt;
+  while ((delta < itcnt) && (p->next != NULL)) {
+    p = p->next;
+    delta += p->tcnt;
+  }
+  /* Right place found, insert timer into the list */
+  p_tmr->next = p->next;
+  p_tmr->tcnt = (U16)(delta - itcnt);
+  p->next = p_tmr;
+  p->tcnt -= p_tmr->tcnt;
+  return (p_tmr);
+}
+
+/*--------------------------- rt_tmr_kill -----------------------------------*/
+
+OS_ID rt_tmr_kill (OS_ID timer)  {
+  /* Remove user timer from the chained timer list. */
+  P_TMR p, p_tmr;
+
+  p_tmr = (P_TMR)timer;
+  p = (P_TMR)&os_tmr;
+  /* Search timer list for requested timer */
+  while (p->next != p_tmr)  {
+    if (p->next == NULL) {
+      /* Failed, "timer" is not in the timer list */
+      return (p_tmr);
+    }
+    p = p->next;
+  }
+  /* Timer was found, remove it from the list */
+  p->next = p_tmr->next;
+  p->tcnt += p_tmr->tcnt;
+  rt_free_box ((U32 *)m_tmr, p_tmr);
+  /* Timer killed */
+  return (NULL);
+}
+
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_Timer.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,50 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TIMER.H
+ *      Purpose: User timer functions
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/* Variables */
+extern struct OS_XTMR os_tmr;
+
+/* Functions */
+extern void  rt_tmr_tick   (void);
+extern OS_ID rt_tmr_create (U16 tcnt, U16 info);
+extern OS_ID rt_tmr_kill   (OS_ID timer);
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,175 @@
+
+/** \addtogroup rtos */
+/** @{*/
+/*----------------------------------------------------------------------------
+ *      CMSIS-RTOS  -  RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RT_TYPEDEF.H
+ *      Purpose: Type Definitions
+ *      Rev.:    V4.79
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+#ifndef RT_TYPE_DEF_H
+#define RT_TYPE_DEF_H
+
+/* Types */
+typedef char               S8;
+typedef unsigned char      U8;
+typedef short              S16;
+typedef unsigned short     U16;
+typedef int                S32;
+typedef unsigned int       U32;
+typedef long long          S64;
+typedef unsigned long long U64;
+typedef unsigned char      BIT;
+typedef unsigned int       BOOL;
+typedef void               (*FUNCP)(void);
+
+typedef U32     OS_TID;
+typedef void    *OS_ID;
+typedef U32     OS_RESULT;
+
+typedef struct OS_TCB {
+  /* General part: identical for all implementations.                        */
+  U8     cb_type;                 /* Control Block Type                      */
+  U8     state;                   /* Task state                              */
+  U8     prio;                    /* Execution priority                      */
+  U8     task_id;                 /* Task ID value for optimized TCB access  */
+  struct OS_TCB *p_lnk;           /* Link pointer for ready/sem. wait list   */
+  struct OS_TCB *p_rlnk;          /* Link pointer for sem./mbx lst backwards */
+  struct OS_TCB *p_dlnk;          /* Link pointer for delay list             */
+  struct OS_TCB *p_blnk;          /* Link pointer for delay list backwards   */
+  U16    delta_time;              /* Time until time out                     */
+  U16    interval_time;           /* Time interval for periodic waits        */
+  U16    events;                  /* Event flags                             */
+  U16    waits;                   /* Wait flags                              */
+  void   **msg;                   /* Direct message passing when task waits  */
+  struct OS_MUCB *p_mlnk;         /* Link pointer for mutex owner list       */
+  U8     prio_base;               /* Base priority                           */
+
+  /* Hardware dependant part: specific for CM processor                      */
+  U8     stack_frame;             /* Stack frame: 0=Basic, 1=Extended,       */
+  U16    reserved;                /* Two reserved bytes for alignment        */
+                                  /* (2=VFP/D16 stacked, 4=NEON/D32 stacked) */
+  U32    priv_stack;              /* Private stack size, 0= system assigned  */
+  U32    tsk_stack;               /* Current task Stack pointer (R13)        */
+  U32    *stack;                  /* Pointer to Task Stack memory block      */
+
+  /* Task entry point used for uVision debugger                              */
+  FUNCP  ptask;                   /* Task entry address                      */
+  void   *argv;                   /* Task argument                           */
+  void   *context;                /* Pointer to thread context               */
+} *P_TCB;
+#define TCB_STACKF      37        /* 'stack_frame' offset                    */
+#define TCB_TSTACK      44        /* 'tsk_stack' offset                      */
+
+typedef struct OS_PSFE {          /* Post Service Fifo Entry                 */
+  void  *id;                      /* Object Identification                   */
+  U32    arg;                     /* Object Argument                         */
+} *P_PSFE;
+
+typedef struct OS_PSQ {           /* Post Service Queue                      */
+  U8     first;                   /* FIFO Head Index                         */
+  U8     last;                    /* FIFO Tail Index                         */
+  U8     count;                   /* Number of stored items in FIFO          */
+  U8     size;                    /* FIFO Size                               */
+  struct OS_PSFE q[1];            /* FIFO Content                            */
+} *P_PSQ;
+
+typedef struct OS_TSK {
+  P_TCB  run;                     /* Current running task                    */
+  P_TCB  new_tsk;                /* Scheduled task to run                   */
+} *P_TSK;
+
+typedef struct OS_ROBIN {         /* Round Robin Control                     */
+  P_TCB  task;                    /* Round Robin task                        */
+  U16    time;                    /* Round Robin switch time                 */
+  U16    tout;                    /* Round Robin timeout                     */
+} *P_ROBIN;
+
+typedef struct OS_XCB {
+  U8     cb_type;                 /* Control Block Type                      */
+  struct OS_TCB *p_lnk;           /* Link pointer for ready/sem. wait list   */
+  struct OS_TCB *p_rlnk;          /* Link pointer for sem./mbx lst backwards */
+  struct OS_TCB *p_dlnk;          /* Link pointer for delay list             */
+  struct OS_TCB *p_blnk;          /* Link pointer for delay list backwards   */
+  U16    delta_time;              /* Time until time out                     */
+} *P_XCB;
+
+typedef struct OS_MCB {
+  U8     cb_type;                 /* Control Block Type                      */
+  U8     state;                   /* State flag variable                     */
+  U8     isr_st;                  /* State flag variable for isr functions   */
+  struct OS_TCB *p_lnk;           /* Chain of tasks waiting for message      */
+  U16    first;                   /* Index of the message list begin         */
+  U16    last;                    /* Index of the message list end           */
+  U16    count;                   /* Actual number of stored messages        */
+  U16    size;                    /* Maximum number of stored messages       */
+  void   *msg[1];                 /* FIFO for Message pointers 1st element   */
+} *P_MCB;
+
+typedef struct OS_SCB {
+  U8     cb_type;                 /* Control Block Type                      */
+  U8     mask;                    /* Semaphore token mask                    */
+  U16    tokens;                  /* Semaphore tokens                        */
+  struct OS_TCB *p_lnk;           /* Chain of tasks waiting for tokens       */
+} *P_SCB;
+
+typedef struct OS_MUCB {
+  U8     cb_type;                 /* Control Block Type                      */
+  U16    level;                   /* Call nesting level                      */
+  struct OS_TCB *p_lnk;           /* Chain of tasks waiting for mutex        */
+  struct OS_TCB *owner;           /* Mutex owner task                        */
+  struct OS_MUCB *p_mlnk;         /* Chain of mutexes by owner task          */
+} *P_MUCB;
+
+typedef struct OS_XTMR {
+  struct OS_TMR  *next;
+  U16    tcnt;
+} *P_XTMR;
+
+typedef struct OS_TMR {
+  struct OS_TMR  *next;           /* Link pointer to Next timer              */
+  U16    tcnt;                    /* Timer delay count                       */
+  U16    info;                    /* User defined call info                  */
+} *P_TMR;
+
+typedef struct OS_BM {
+  void *free;                     /* Pointer to first free memory block      */
+  void *end;                      /* Pointer to memory block end             */
+  U32  blk_size;                  /* Memory block size                       */
+} *P_BM;
+
+/* Definitions */
+#define __TRUE          1U
+#define __FALSE         0U
+#define NULL            ((void *) 0)
+
+#endif
+
+/** @}*/
diff -r 000000000000 -r fc74113aca28 mbed-rtos/targets/TARGET_NXP/mbed_rtx4.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos/targets/TARGET_NXP/mbed_rtx4.h	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,205 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBED_MBED_RTX_H
+#define MBED_MBED_RTX_H
+
+#if defined(TARGET_LPC11U68)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10008000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                48000000
+#endif
+
+#elif defined(TARGET_LPC11U24)        \
+     || defined(TARGET_LPC11U35_401)  \
+     || defined(TARGET_LPC11U35_501)  \
+     || defined(TARGET_LPCCAPPUCCINO)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10002000UL)
+#endif
+
+     // RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              6
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          128
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                48000000
+#endif
+
+#elif defined(TARGET_LPC1114)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10001000UL)
+#endif
+
+ // RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              6
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          128
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                48000000
+#endif
+
+#elif defined(TARGET_LPC1347)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10002000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                72000000
+#endif
+
+#elif defined(TARGET_LPC1549)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x02009000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                72000000
+#endif
+
+#elif defined(TARGET_LPC1768)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10008000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                96000000
+#endif
+
+#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10010000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                120000000
+#endif
+
+#elif defined(TARGET_LPC4330) || defined(TARGET_LPC4337)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10008000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              14
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          256
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                204000000
+#endif
+
+#elif defined(TARGET_LPC812)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10001000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              6
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          128
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                36000000
+#endif
+
+#elif defined(TARGET_LPC824) || defined(TARGET_SSCI824)
+
+#ifndef INITIAL_SP
+#define INITIAL_SP              (0x10002000UL)
+#endif
+
+// RTX 4 only config below, for backward-compability
+
+#ifndef OS_TASKCNT
+#define OS_TASKCNT              6
+#endif
+#ifndef OS_MAINSTKSIZE
+#define OS_MAINSTKSIZE          128
+#endif
+#ifndef OS_CLOCK
+#define OS_CLOCK                30000000
+#endif
+
+#endif
+
+#endif  // MBED_MBED_RTX_H
diff -r 000000000000 -r fc74113aca28 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Apr 14 20:21:15 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file