Compare commits
	
		
			5 Commits
		
	
	
		
			3c05763086
			...
			feature/rt
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b585be12c2 | |||
| 0039954bd8 | |||
| 58e7081738 | |||
| e0ea7d4cc2 | |||
| b3d64c8ee4 | 
							
								
								
									
										29
									
								
								.cproject
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								.cproject
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.1647005419" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv5-sp-d16" valueType="enumerated"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.250397381" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1505368498" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="STM32F746G-DISCO" valueType="string"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.464483919" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F746G-DISCO || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Drivers/CMSIS/Device/ST/STM32F7xx/Include | ../Core/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy ||  ||  || USE_HAL_DRIVER | STM32F746xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32F746NGHX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.464483919" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F746G-DISCO || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Drivers/CMSIS/Device/ST/STM32F7xx/Include | ../Core/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy | ../Middlewares/Third_Party/FreeRTOS/Source/include | ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 | ../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1 ||  ||  || USE_HAL_DRIVER | STM32F746xx ||  || Drivers | Core/Startup | Middlewares | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32F746NGHX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/> | ||||
| 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1466792025" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/> | ||||
| 							<builder buildPath="${workspace_loc:/RealtimeOscilloscope}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.10376157" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/> | ||||
| 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1308839655" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler"> | ||||
| @@ -59,6 +59,9 @@ | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/mdw""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/ide-touchgfx-gen/TouchGFX/App""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/ide-touchgfx-gen/Drivers/Components""/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1"/> | ||||
| 								</option> | ||||
| 								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.55642111" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/> | ||||
| 							</tool> | ||||
| @@ -81,7 +84,6 @@ | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/config""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/xf/include""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/xf/port""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/xf/port/default-idf""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/platform/f7-disco-gcc""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/platform/f7-disco-gcc/mcu""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/mdw""/> | ||||
| @@ -96,6 +98,11 @@ | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/ide-touchgfx-gen/Middlewares/ST/touchgfx/framework/include""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/ide-touchgfx-gen/TouchGFX/gui/include""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/ide-touchgfx-gen/TouchGFX/generated/gui_generated/include""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/xf/port/default-cmsis-os""/> | ||||
| 									<listOptionValue builtIn="false" value=""${ProjDirPath}/src/xf/port/stm32cube-cmsis-freertos""/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1"/> | ||||
| 								</option> | ||||
| 								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.1647398535" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/> | ||||
| 							</tool> | ||||
| @@ -126,6 +133,7 @@ | ||||
| 					<sourceEntries> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/> | ||||
| 						<entry excluding="generated/simulator" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="TouchGFX"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="app"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="event"/> | ||||
| @@ -134,7 +142,9 @@ | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="mdw/ext-freqgen"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/core"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/include"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port"/> | ||||
| 						<entry excluding="stm32cube-cmsis-freertos|default-cmsis-os" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port/default-cmsis-os"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port/stm32cube-cmsis-freertos"/> | ||||
| 					</sourceEntries> | ||||
| 				</configuration> | ||||
| 			</storageModule> | ||||
| @@ -162,7 +172,7 @@ | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.728042019" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv5-sp-d16" valueType="enumerated"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.1060964587" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.20764220" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="STM32F746G-DISCO" valueType="string"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1485083547" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F746G-DISCO || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Drivers/CMSIS/Device/ST/STM32F7xx/Include | ../Core/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy ||  ||  || USE_HAL_DRIVER | STM32F746xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32F746NGHX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/> | ||||
| 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1485083547" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F746G-DISCO || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Drivers/CMSIS/Device/ST/STM32F7xx/Include | ../Core/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc | ../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy | ../Middlewares/Third_Party/FreeRTOS/Source/include | ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 | ../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1 ||  ||  || USE_HAL_DRIVER | STM32F746xx ||  || Drivers | Core/Startup | Middlewares | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32F746NGHX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/> | ||||
| 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.906133983" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/> | ||||
| 							<builder buildPath="${workspace_loc:/RealtimeOscilloscope}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.362615635" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/> | ||||
| 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.297130526" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler"> | ||||
| @@ -182,6 +192,9 @@ | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy"/> | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32F7xx/Include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1"/> | ||||
| 								</option> | ||||
| 								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1021742110" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/> | ||||
| 							</tool> | ||||
| @@ -198,6 +211,9 @@ | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy"/> | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32F7xx/Include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/include"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2"/> | ||||
| 									<listOptionValue builtIn="false" value="../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1"/> | ||||
| 								</option> | ||||
| 								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.54987871" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/> | ||||
| 							</tool> | ||||
| @@ -222,6 +238,7 @@ | ||||
| 					<sourceEntries> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/> | ||||
| 						<entry excluding="generated/simulator" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="TouchGFX"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="app"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="event"/> | ||||
| @@ -230,7 +247,9 @@ | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="mdw/ext-freqgen"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/core"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/include"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port"/> | ||||
| 						<entry excluding="stm32cube-cmsis-freertos|default-cmsis-os" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port/default-cmsis-os"/> | ||||
| 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="xf/port/stm32cube-cmsis-freertos"/> | ||||
| 					</sourceEntries> | ||||
| 				</configuration> | ||||
| 			</storageModule> | ||||
|   | ||||
							
								
								
									
										161
									
								
								Core/Inc/FreeRTOSConfig.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								Core/Inc/FreeRTOSConfig.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | ||||
| /* USER CODE BEGIN Header */ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * Portion Copyright (C) 2019 StMicroelectronics, Inc.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
| /* USER CODE END Header */ | ||||
|  | ||||
| #ifndef FREERTOS_CONFIG_H | ||||
| #define FREERTOS_CONFIG_H | ||||
|  | ||||
| /*----------------------------------------------------------- | ||||
|  * Application specific definitions. | ||||
|  * | ||||
|  * These definitions should be adjusted for your particular hardware and | ||||
|  * application requirements. | ||||
|  * | ||||
|  * These parameters and more are described within the 'configuration' section of the | ||||
|  * FreeRTOS API documentation available on the FreeRTOS.org web site. | ||||
|  * | ||||
|  * See http://www.freertos.org/a00110.html | ||||
|  *----------------------------------------------------------*/ | ||||
|  | ||||
| /* USER CODE BEGIN Includes */ | ||||
| /* Section where include file can be added */ | ||||
| /* USER CODE END Includes */ | ||||
|  | ||||
| /* Ensure definitions are only used by the compiler, and not by the assembler. */ | ||||
| #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) | ||||
|   #include <stdint.h> | ||||
|   extern uint32_t SystemCoreClock; | ||||
| #endif | ||||
| #define configENABLE_FPU                         0 | ||||
| #define configENABLE_MPU                         0 | ||||
|  | ||||
| #define configUSE_PREEMPTION                     1 | ||||
| #define configSUPPORT_STATIC_ALLOCATION          1 | ||||
| #define configSUPPORT_DYNAMIC_ALLOCATION         1 | ||||
| #define configUSE_IDLE_HOOK                      0 | ||||
| #define configUSE_TICK_HOOK                      0 | ||||
| #define configCPU_CLOCK_HZ                       ( SystemCoreClock ) | ||||
| #define configTICK_RATE_HZ                       ((TickType_t)1000) | ||||
| #define configMAX_PRIORITIES                     ( 56 ) | ||||
| #define configMINIMAL_STACK_SIZE                 ((uint16_t)2048) | ||||
| #define configTOTAL_HEAP_SIZE                    ((size_t)65536) | ||||
| #define configMAX_TASK_NAME_LEN                  ( 16 ) | ||||
| #define configUSE_TRACE_FACILITY                 1 | ||||
| #define configUSE_16_BIT_TICKS                   0 | ||||
| #define configUSE_MUTEXES                        1 | ||||
| #define configQUEUE_REGISTRY_SIZE                8 | ||||
| #define configUSE_RECURSIVE_MUTEXES              1 | ||||
| #define configUSE_COUNTING_SEMAPHORES            1 | ||||
| #define configUSE_PORT_OPTIMISED_TASK_SELECTION  0 | ||||
| /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ | ||||
| /* Defaults to size_t for backward compatibility, but can be changed | ||||
|    if lengths will always be less than the number of bytes in a size_t. */ | ||||
| #define configMESSAGE_BUFFER_LENGTH_TYPE         size_t | ||||
| /* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ | ||||
|  | ||||
| /* Co-routine definitions. */ | ||||
| #define configUSE_CO_ROUTINES                    0 | ||||
| #define configMAX_CO_ROUTINE_PRIORITIES          ( 2 ) | ||||
|  | ||||
| /* Software timer definitions. */ | ||||
| #define configUSE_TIMERS                         1 | ||||
| #define configTIMER_TASK_PRIORITY                ( 2 ) | ||||
| #define configTIMER_QUEUE_LENGTH                 10 | ||||
| #define configTIMER_TASK_STACK_DEPTH             4096 | ||||
|  | ||||
| /* The following flag must be enabled only when using newlib */ | ||||
| #define configUSE_NEWLIB_REENTRANT          1 | ||||
|  | ||||
| /* Set the following definitions to 1 to include the API function, or zero | ||||
| to exclude the API function. */ | ||||
| #define INCLUDE_vTaskPrioritySet             1 | ||||
| #define INCLUDE_uxTaskPriorityGet            1 | ||||
| #define INCLUDE_vTaskDelete                  1 | ||||
| #define INCLUDE_vTaskCleanUpResources        0 | ||||
| #define INCLUDE_vTaskSuspend                 1 | ||||
| #define INCLUDE_vTaskDelayUntil              1 | ||||
| #define INCLUDE_vTaskDelay                   1 | ||||
| #define INCLUDE_xTaskGetSchedulerState       1 | ||||
| #define INCLUDE_xTimerPendFunctionCall       1 | ||||
| #define INCLUDE_xQueueGetMutexHolder         1 | ||||
| #define INCLUDE_uxTaskGetStackHighWaterMark  1 | ||||
| #define INCLUDE_eTaskGetState                1 | ||||
|  | ||||
| /* | ||||
|  * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used | ||||
|  * by the application thus the correct define need to be enabled below | ||||
|  */ | ||||
| #define USE_FreeRTOS_HEAP_4 | ||||
|  | ||||
| /* Cortex-M specific definitions. */ | ||||
| #ifdef __NVIC_PRIO_BITS | ||||
|  /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ | ||||
|  #define configPRIO_BITS         __NVIC_PRIO_BITS | ||||
| #else | ||||
|  #define configPRIO_BITS         4 | ||||
| #endif | ||||
|  | ||||
| /* The lowest interrupt priority that can be used in a call to a "set priority" | ||||
| function. */ | ||||
| #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15 | ||||
|  | ||||
| /* The highest interrupt priority that can be used by any interrupt service | ||||
| routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL | ||||
| INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER | ||||
| PRIORITY THAN THIS! (higher priorities are lower numeric values. */ | ||||
| #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 | ||||
|  | ||||
| /* Interrupt priorities used by the kernel port layer itself.  These are generic | ||||
| to all Cortex-M ports, and do not rely on any particular library functions. */ | ||||
| #define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) | ||||
| /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! | ||||
| See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ | ||||
| #define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) | ||||
|  | ||||
| /* Normal assert() semantics without relying on the provision of an assert.h | ||||
| header file. */ | ||||
| /* USER CODE BEGIN 1 */ | ||||
| #define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} | ||||
| /* USER CODE END 1 */ | ||||
|  | ||||
| /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS | ||||
| standard names. */ | ||||
| #define vPortSVCHandler    SVC_Handler | ||||
| #define xPortPendSVHandler PendSV_Handler | ||||
|  | ||||
| /* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick, | ||||
|               to prevent overwriting SysTick_Handler defined within STM32Cube HAL */ | ||||
|  | ||||
| #define xPortSysTickHandler SysTick_Handler | ||||
|  | ||||
| /* USER CODE BEGIN Defines */ | ||||
| /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ | ||||
| /* USER CODE END Defines */ | ||||
|  | ||||
| #endif /* FREERTOS_CONFIG_H */ | ||||
| @@ -51,10 +51,7 @@ void HardFault_Handler(void); | ||||
| void MemManage_Handler(void); | ||||
| void BusFault_Handler(void); | ||||
| void UsageFault_Handler(void); | ||||
| void SVC_Handler(void); | ||||
| void DebugMon_Handler(void); | ||||
| void PendSV_Handler(void); | ||||
| void SysTick_Handler(void); | ||||
| void EXTI2_IRQHandler(void); | ||||
| void EXTI3_IRQHandler(void); | ||||
| void ADC_IRQHandler(void); | ||||
|   | ||||
							
								
								
									
										59
									
								
								Core/Src/freertos.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Core/Src/freertos.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* USER CODE BEGIN Header */ | ||||
| /** | ||||
|   ****************************************************************************** | ||||
|   * File Name          : freertos.c | ||||
|   * Description        : Code for freertos applications | ||||
|   ****************************************************************************** | ||||
|   * @attention | ||||
|   * | ||||
|   * Copyright (c) 2024 STMicroelectronics. | ||||
|   * All rights reserved. | ||||
|   * | ||||
|   * This software is licensed under terms that can be found in the LICENSE file | ||||
|   * in the root directory of this software component. | ||||
|   * If no LICENSE file comes with this software, it is provided AS-IS. | ||||
|   * | ||||
|   ****************************************************************************** | ||||
|   */ | ||||
| /* USER CODE END Header */ | ||||
|  | ||||
| /* Includes ------------------------------------------------------------------*/ | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
| #include "main.h" | ||||
|  | ||||
| /* Private includes ----------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN Includes */ | ||||
|  | ||||
| /* USER CODE END Includes */ | ||||
|  | ||||
| /* Private typedef -----------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN PTD */ | ||||
|  | ||||
| /* USER CODE END PTD */ | ||||
|  | ||||
| /* Private define ------------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN PD */ | ||||
|  | ||||
| /* USER CODE END PD */ | ||||
|  | ||||
| /* Private macro -------------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN PM */ | ||||
|  | ||||
| /* USER CODE END PM */ | ||||
|  | ||||
| /* Private variables ---------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN Variables */ | ||||
|  | ||||
| /* USER CODE END Variables */ | ||||
|  | ||||
| /* Private function prototypes -----------------------------------------------*/ | ||||
| /* USER CODE BEGIN FunctionPrototypes */ | ||||
|  | ||||
| /* USER CODE END FunctionPrototypes */ | ||||
|  | ||||
| /* Private application code --------------------------------------------------*/ | ||||
| /* USER CODE BEGIN Application */ | ||||
|  | ||||
| /* USER CODE END Application */ | ||||
|  | ||||
| @@ -18,7 +18,7 @@ | ||||
| /* USER CODE END Header */ | ||||
| /* Includes ------------------------------------------------------------------*/ | ||||
| #include "main.h" | ||||
| #include "app_touchgfx.h" | ||||
| #include "cmsis_os.h" | ||||
|  | ||||
| /* Private includes ----------------------------------------------------------*/ | ||||
| /* USER CODE BEGIN Includes */ | ||||
| @@ -84,6 +84,13 @@ UART_HandleTypeDef huart1; | ||||
|  | ||||
| SDRAM_HandleTypeDef hsdram1; | ||||
|  | ||||
| /* Definitions for TouchGFXTask */ | ||||
| osThreadId_t defaultTaskHandle; | ||||
| const osThreadAttr_t defaultTask_attributes = { | ||||
|   .name = "TouchGFXTask", | ||||
|   .priority = (osPriority_t) osPriorityNormal, | ||||
|   .stack_size = 4096 * 4 | ||||
| }; | ||||
| /* USER CODE BEGIN PV */ | ||||
| static FMC_SDRAM_CommandTypeDef Command; | ||||
| /* USER CODE END PV */ | ||||
| @@ -105,7 +112,9 @@ static void MX_TIM3_Init(void); | ||||
| static void MX_TIM5_Init(void); | ||||
| static void MX_TIM8_Init(void); | ||||
| static void MX_USART1_UART_Init(void); | ||||
| void StartDefaultTask(void *argument); | ||||
| void TouchGFX_Task(void *argument); | ||||
|  | ||||
| /* USER CODE BEGIN PFP */ | ||||
|  | ||||
| /* USER CODE END PFP */ | ||||
| @@ -127,6 +136,12 @@ int main(void) | ||||
|  | ||||
|   /* USER CODE END 1 */ | ||||
|  | ||||
|   /* Enable I-Cache---------------------------------------------------------*/ | ||||
|   SCB_EnableICache(); | ||||
|  | ||||
|   /* Enable D-Cache---------------------------------------------------------*/ | ||||
|   SCB_EnableDCache(); | ||||
|  | ||||
|   /* MCU Configuration--------------------------------------------------------*/ | ||||
|  | ||||
|   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ | ||||
| @@ -173,6 +188,41 @@ int main(void) | ||||
|  | ||||
|   /* USER CODE END 2 */ | ||||
|  | ||||
|   /* Init scheduler */ | ||||
|   osKernelInitialize(); | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_MUTEX */ | ||||
|   /* add mutexes, ... */ | ||||
|   /* USER CODE END RTOS_MUTEX */ | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_SEMAPHORES */ | ||||
|   /* add semaphores, ... */ | ||||
|   /* USER CODE END RTOS_SEMAPHORES */ | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_TIMERS */ | ||||
|   /* start timers, add new ones, ... */ | ||||
|   /* USER CODE END RTOS_TIMERS */ | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_QUEUES */ | ||||
|   /* add queues, ... */ | ||||
|   /* USER CODE END RTOS_QUEUES */ | ||||
|  | ||||
|   /* Create the thread(s) */ | ||||
|   /* creation of defaultTask */ | ||||
|   defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_THREADS */ | ||||
|   /* add threads, ... */ | ||||
|   /* USER CODE END RTOS_THREADS */ | ||||
|  | ||||
|   /* USER CODE BEGIN RTOS_EVENTS */ | ||||
|   /* add events, ... */ | ||||
|   /* USER CODE END RTOS_EVENTS */ | ||||
|  | ||||
|   /* Start scheduler */ | ||||
|   osKernelStart(); | ||||
|  | ||||
|   /* We should never get here as control is now taken by the scheduler */ | ||||
|   /* Infinite loop */ | ||||
|   /* USER CODE BEGIN WHILE */ | ||||
|   while (1) { | ||||
| @@ -630,7 +680,7 @@ static void MX_TIM1_Init(void) | ||||
|  | ||||
|   /* USER CODE END TIM1_Init 1 */ | ||||
|   htim1.Instance = TIM1; | ||||
|   htim1.Init.Prescaler = 199; | ||||
|   htim1.Init.Prescaler = 19; | ||||
|   htim1.Init.CounterMode = TIM_COUNTERMODE_UP; | ||||
|   htim1.Init.Period = 99; | ||||
|   htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; | ||||
| @@ -1376,13 +1426,13 @@ static void MX_GPIO_Init(void) | ||||
|   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); | ||||
|  | ||||
|   /* EXTI interrupt init*/ | ||||
|   HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0); | ||||
|   HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0); | ||||
|   HAL_NVIC_EnableIRQ(EXTI2_IRQn); | ||||
|  | ||||
|   HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0); | ||||
|   HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0); | ||||
|   HAL_NVIC_EnableIRQ(EXTI3_IRQn); | ||||
|  | ||||
|   HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0); | ||||
|   HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0); | ||||
|   HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); | ||||
|  | ||||
| } | ||||
| @@ -1391,6 +1441,27 @@ static void MX_GPIO_Init(void) | ||||
|  | ||||
| /* USER CODE END 4 */ | ||||
|  | ||||
|  | ||||
|  | ||||
| /* USER CODE BEGIN Header_StartDefaultTask */ | ||||
| /** | ||||
|   * @brief  Function implementing the defaultTask thread. | ||||
|   * @param  argument: Not used | ||||
|   * @retval None | ||||
|   */ | ||||
| /* USER CODE END Header_StartDefaultTask */ | ||||
| void StartDefaultTask(void *argument) | ||||
| { | ||||
|   /* USER CODE BEGIN 5 */ | ||||
| 	MX_TouchGFX_Process(); | ||||
|   /* Infinite loop */ | ||||
|   for(;;) | ||||
|   { | ||||
|     osDelay(1); | ||||
|   } | ||||
|   /* USER CODE END 5 */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * @brief  Period elapsed callback in non blocking mode | ||||
|   * @note   This function is called  when TIM6 interrupt took place, inside | ||||
|   | ||||
| @@ -72,6 +72,8 @@ void HAL_MspInit(void) | ||||
|   __HAL_RCC_SYSCFG_CLK_ENABLE(); | ||||
|  | ||||
|   /* System interrupt init*/ | ||||
|   /* PendSV_IRQn interrupt configuration */ | ||||
|   HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); | ||||
|  | ||||
|   /* USER CODE BEGIN MspInit 1 */ | ||||
|  | ||||
| @@ -115,7 +117,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) | ||||
|     HAL_GPIO_Init(ARDUINO_A0_GPIO_Port, &GPIO_InitStruct); | ||||
|  | ||||
|     /* ADC3 interrupt Init */ | ||||
|     HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); | ||||
|     HAL_NVIC_SetPriority(ADC_IRQn, 5, 0); | ||||
|     HAL_NVIC_EnableIRQ(ADC_IRQn); | ||||
|   /* USER CODE BEGIN ADC3_MspInit 1 */ | ||||
|  | ||||
| @@ -220,7 +222,7 @@ void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d) | ||||
|     /* Peripheral clock enable */ | ||||
|     __HAL_RCC_DMA2D_CLK_ENABLE(); | ||||
|     /* DMA2D interrupt Init */ | ||||
|     HAL_NVIC_SetPriority(DMA2D_IRQn, 0, 0); | ||||
|     HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0); | ||||
|     HAL_NVIC_EnableIRQ(DMA2D_IRQn); | ||||
|   /* USER CODE BEGIN DMA2D_MspInit 1 */ | ||||
|  | ||||
| @@ -439,7 +441,7 @@ void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc) | ||||
|     HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); | ||||
|  | ||||
|     /* LTDC interrupt Init */ | ||||
|     HAL_NVIC_SetPriority(LTDC_IRQn, 0, 0); | ||||
|     HAL_NVIC_SetPriority(LTDC_IRQn, 5, 0); | ||||
|     HAL_NVIC_EnableIRQ(LTDC_IRQn); | ||||
|   /* USER CODE BEGIN LTDC_MspInit 1 */ | ||||
|  | ||||
|   | ||||
| @@ -142,19 +142,6 @@ void UsageFault_Handler(void) | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * @brief This function handles System service call via SWI instruction. | ||||
|   */ | ||||
| void SVC_Handler(void) | ||||
| { | ||||
|   /* USER CODE BEGIN SVCall_IRQn 0 */ | ||||
|  | ||||
|   /* USER CODE END SVCall_IRQn 0 */ | ||||
|   /* USER CODE BEGIN SVCall_IRQn 1 */ | ||||
|  | ||||
|   /* USER CODE END SVCall_IRQn 1 */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * @brief This function handles Debug monitor. | ||||
|   */ | ||||
| @@ -168,33 +155,6 @@ void DebugMon_Handler(void) | ||||
|   /* USER CODE END DebugMonitor_IRQn 1 */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * @brief This function handles Pendable request for system service. | ||||
|   */ | ||||
| void PendSV_Handler(void) | ||||
| { | ||||
|   /* USER CODE BEGIN PendSV_IRQn 0 */ | ||||
|  | ||||
|   /* USER CODE END PendSV_IRQn 0 */ | ||||
|   /* USER CODE BEGIN PendSV_IRQn 1 */ | ||||
|  | ||||
|   /* USER CODE END PendSV_IRQn 1 */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * @brief This function handles System tick timer. | ||||
|   */ | ||||
| void SysTick_Handler(void) | ||||
| { | ||||
|   /* USER CODE BEGIN SysTick_IRQn 0 */ | ||||
|  | ||||
|   /* USER CODE END SysTick_IRQn 0 */ | ||||
|  | ||||
|   /* USER CODE BEGIN SysTick_IRQn 1 */ | ||||
|  | ||||
|   /* USER CODE END SysTick_IRQn 1 */ | ||||
| } | ||||
|  | ||||
| /******************************************************************************/ | ||||
| /* STM32F7xx Peripheral Interrupt Handlers                                    */ | ||||
| /* Add here the Interrupt Handlers for the used peripherals.                  */ | ||||
|   | ||||
							
								
								
									
										846
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										846
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,846 @@ | ||||
| /* | ||||
|  * Copyright (c) 2013-2019 ARM Limited. All rights reserved. | ||||
|  * | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  * | ||||
|  * 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 | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * ---------------------------------------------------------------------- | ||||
|  * | ||||
|  * $Date:        10. January 2017 | ||||
|  * $Revision:    V2.1.0 | ||||
|  * | ||||
|  * Project:      CMSIS-RTOS API | ||||
|  * Title:        cmsis_os.h FreeRTOS 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 typedefs | ||||
|  *     - 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  | ||||
|  * Version 2.0.0 | ||||
|  *    OS objects creation without macros (dynamic creation and resource allocation): | ||||
|  *     - added: osXxxxNew functions which replace osXxxxCreate | ||||
|  *     - added: osXxxxAttr_t structures | ||||
|  *     - deprecated: osXxxxCreate functions, osXxxxDef_t structures | ||||
|  *     - deprecated: osXxxxDef and osXxxx macros | ||||
|  *    osStatus codes simplified and renamed to osStatus_t | ||||
|  *    osEvent return structure deprecated | ||||
|  *    Kernel: | ||||
|  *     - added: osKernelInfo_t and osKernelGetInfo | ||||
|  *     - added: osKernelState_t and osKernelGetState (replaces osKernelRunning) | ||||
|  *     - added: osKernelLock, osKernelUnlock | ||||
|  *     - added: osKernelSuspend, osKernelResume | ||||
|  *     - added: osKernelGetTickCount, osKernelGetTickFreq | ||||
|  *     - renamed osKernelSysTick to osKernelGetSysTimerCount | ||||
|  *     - replaced osKernelSysTickFrequency with osKernelGetSysTimerFreq | ||||
|  *     - deprecated osKernelSysTickMicroSec | ||||
|  *    Thread: | ||||
|  *     - extended number of thread priorities | ||||
|  *     - renamed osPrioriry to osPrioriry_t | ||||
|  *     - replaced osThreadCreate with osThreadNew | ||||
|  *     - added: osThreadGetName | ||||
|  *     - added: osThreadState_t and osThreadGetState | ||||
|  *     - added: osThreadGetStackSize, osThreadGetStackSpace | ||||
|  *     - added: osThreadSuspend, osThreadResume | ||||
|  *     - added: osThreadJoin, osThreadDetach, osThreadExit | ||||
|  *     - added: osThreadGetCount, osThreadEnumerate | ||||
|  *     - added: Thread Flags (moved from Signals)  | ||||
|  *    Signals: | ||||
|  *     - renamed osSignals to osThreadFlags (moved to Thread Flags) | ||||
|  *     - changed return value of Set/Clear/Wait functions | ||||
|  *     - Clear function limited to current running thread | ||||
|  *     - extended Wait function (options) | ||||
|  *     - added: osThreadFlagsGet | ||||
|  *    Event Flags: | ||||
|  *     - added new independent object for handling Event Flags | ||||
|  *    Delay and Wait functions: | ||||
|  *     - added: osDelayUntil | ||||
|  *     - deprecated: osWait | ||||
|  *    Timer: | ||||
|  *     - replaced osTimerCreate with osTimerNew | ||||
|  *     - added: osTimerGetName, osTimerIsRunning | ||||
|  *    Mutex: | ||||
|  *     - extended: attributes (Recursive, Priority Inherit, Robust) | ||||
|  *     - replaced osMutexCreate with osMutexNew | ||||
|  *     - renamed osMutexWait to osMutexAcquire | ||||
|  *     - added: osMutexGetName, osMutexGetOwner | ||||
|  *    Semaphore: | ||||
|  *     - extended: maximum and initial token count | ||||
|  *     - replaced osSemaphoreCreate with osSemaphoreNew | ||||
|  *     - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value) | ||||
|  *     - added: osSemaphoreGetName, osSemaphoreGetCount | ||||
|  *    Memory Pool: | ||||
|  *     - using osMemoryPool prefix instead of osPool | ||||
|  *     - replaced osPoolCreate with osMemoryPoolNew | ||||
|  *     - extended osMemoryPoolAlloc (timeout) | ||||
|  *     - added: osMemoryPoolGetName | ||||
|  *     - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize | ||||
|  *     - added: osMemoryPoolGetCount, osMemoryPoolGetSpace | ||||
|  *     - added: osMemoryPoolDelete | ||||
|  *     - deprecated: osPoolCAlloc | ||||
|  *    Message Queue: | ||||
|  *     - extended: fixed size message instead of a single 32-bit value | ||||
|  *     - using osMessageQueue prefix instead of osMessage | ||||
|  *     - replaced osMessageCreate with osMessageQueueNew | ||||
|  *     - updated: osMessageQueuePut, osMessageQueueGet | ||||
|  *     - added: osMessageQueueGetName | ||||
|  *     - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize | ||||
|  *     - added: osMessageQueueGetCount, osMessageQueueGetSpace | ||||
|  *     - added: osMessageQueueReset, osMessageQueueDelete | ||||
|  *    Mail Queue:  | ||||
|  *     - deprecated (superseded by extended Message Queue functionality) | ||||
|  * Version 2.1.0 | ||||
|  *    Support for critical and uncritical sections (nesting safe): | ||||
|  *    - updated: osKernelLock, osKernelUnlock | ||||
|  *    - added: osKernelRestoreLock | ||||
|  *    Updated Thread and Event Flags: | ||||
|  *    - changed flags parameter and return type from int32_t to uint32_t | ||||
|  *---------------------------------------------------------------------------*/ | ||||
|   | ||||
| #ifndef CMSIS_OS_H_ | ||||
| #define CMSIS_OS_H_ | ||||
|  | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
|  | ||||
| #define RTOS_ID_n             ((tskKERNEL_VERSION_MAJOR << 16) | (tskKERNEL_VERSION_MINOR)) | ||||
| #define RTOS_ID_s             ("FreeRTOS " tskKERNEL_VERSION_NUMBER) | ||||
|  | ||||
| #define osCMSIS               0x20001U  ///< API version (main[31:16].sub[15:0]) | ||||
|  | ||||
| #define osCMSIS_FreeRTOS      RTOS_ID_n ///< RTOS identification and version (main[31:16].sub[15:0]) | ||||
|   | ||||
| #define osKernelSystemId      RTOS_ID_s ///< RTOS identification string | ||||
|   | ||||
| #define osFeature_MainThread  0         ///< main thread      1=main can be thread, 0=not available | ||||
| #define osFeature_Signals     24U       ///< maximum number of Signal Flags available per thread | ||||
| #define osFeature_Semaphore   65535U    ///< maximum count for \ref osSemaphoreCreate function | ||||
| #define osFeature_Wait        0         ///< osWait function: 1=available, 0=not available | ||||
| #define osFeature_SysTick     1         ///< osKernelSysTick functions: 1=available, 0=not available | ||||
| #define osFeature_Pool        0         ///< Memory Pools:    1=available, 0=not available | ||||
| #define osFeature_MessageQ    1         ///< Message Queues:  1=available, 0=not available | ||||
| #define osFeature_MailQ       0         ///< Mail Queues:     1=available, 0=not available | ||||
|   | ||||
| #if   defined(__CC_ARM) | ||||
| #define os_InRegs __value_in_regs | ||||
| #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||
| #define os_InRegs __attribute__((value_in_regs)) | ||||
| #else | ||||
| #define os_InRegs | ||||
| #endif | ||||
|   | ||||
| #include "cmsis_os2.h" | ||||
|   | ||||
| #ifdef  __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
|   | ||||
|   | ||||
| // ==== Enumerations, structures, defines ==== | ||||
|   | ||||
| /// Priority values. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| 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 illegal priority. | ||||
|   osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization. | ||||
| } osPriority; | ||||
| #else | ||||
| #define osPriority osPriority_t | ||||
| #endif | ||||
|  | ||||
| /// 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); | ||||
|   | ||||
| /// Timer type. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef enum { | ||||
|   osTimerOnce             = 0,          ///< One-shot timer. | ||||
|   osTimerPeriodic         = 1           ///< Repeating timer. | ||||
| } os_timer_type; | ||||
| #else | ||||
| #define os_timer_type osTimerType_t | ||||
| #endif | ||||
|   | ||||
| /// Timeout value. | ||||
| #define osWaitForever       0xFFFFFFFFU ///< Wait forever timeout value. | ||||
|   | ||||
| /// Status code values returned by CMSIS-RTOS functions. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| 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. | ||||
|   osStatusReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization. | ||||
| } osStatus; | ||||
| #else | ||||
| typedef int32_t                  osStatus; | ||||
| #define osEventSignal           (0x08) | ||||
| #define osEventMessage          (0x10) | ||||
| #define osEventMail             (0x20) | ||||
| #define osEventTimeout          (0x40) | ||||
| #define osErrorOS               osError | ||||
| #define osErrorTimeoutResource  osErrorTimeout | ||||
| #define osErrorISRRecursive     (-126) | ||||
| #define osErrorValue            (-127) | ||||
| #define osErrorPriority         (-128) | ||||
| #endif | ||||
|   | ||||
|   | ||||
| // >>> the following data type definitions may be adapted towards a specific RTOS | ||||
|   | ||||
| /// Thread ID identifies the thread. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef void *osThreadId; | ||||
| #else | ||||
| #define osThreadId osThreadId_t | ||||
| #endif | ||||
|   | ||||
| /// Timer ID identifies the timer. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef void *osTimerId; | ||||
| #else | ||||
| #define osTimerId osTimerId_t | ||||
| #endif | ||||
|   | ||||
| /// Mutex ID identifies the mutex. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef void *osMutexId; | ||||
| #else | ||||
| #define osMutexId osMutexId_t | ||||
| #endif | ||||
|   | ||||
| /// Semaphore ID identifies the semaphore. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef void *osSemaphoreId; | ||||
| #else | ||||
| #define osSemaphoreId osSemaphoreId_t | ||||
| #endif | ||||
|   | ||||
| /// Pool ID identifies the memory pool. | ||||
| typedef void *osPoolId; | ||||
|   | ||||
| /// Message ID identifies the message queue. | ||||
| typedef void *osMessageQId; | ||||
|   | ||||
| /// Mail ID identifies the mail queue. | ||||
| typedef void *osMailQId; | ||||
|   | ||||
|   | ||||
| /// Thread Definition structure contains startup information of a thread. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| 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 | ||||
| } osThreadDef_t; | ||||
| #else | ||||
| typedef struct os_thread_def { | ||||
|   os_pthread                 pthread;   ///< start address of thread function | ||||
|   osThreadAttr_t                attr;   ///< thread attributes | ||||
| } osThreadDef_t; | ||||
| #endif | ||||
|   | ||||
| /// Timer Definition structure contains timer parameters. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef struct os_timer_def { | ||||
|   os_ptimer                   ptimer;   ///< start address of a timer function | ||||
| } osTimerDef_t; | ||||
| #else | ||||
| typedef struct os_timer_def { | ||||
|   os_ptimer                   ptimer;   ///< start address of a timer function | ||||
|   osTimerAttr_t                 attr;   ///< timer attributes | ||||
| } osTimerDef_t; | ||||
| #endif | ||||
|   | ||||
| /// Mutex Definition structure contains setup information for a mutex. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef struct os_mutex_def { | ||||
|   uint32_t                     dummy;   ///< dummy value | ||||
| } osMutexDef_t; | ||||
| #else | ||||
| #define osMutexDef_t osMutexAttr_t | ||||
| #endif | ||||
|   | ||||
| /// Semaphore Definition structure contains setup information for a semaphore. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef struct os_semaphore_def { | ||||
|   uint32_t                     dummy;   ///< dummy value | ||||
| } osSemaphoreDef_t; | ||||
| #else | ||||
| #define osSemaphoreDef_t osSemaphoreAttr_t | ||||
| #endif | ||||
|   | ||||
| /// Definition structure for memory block allocation. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| 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; | ||||
| #else | ||||
| typedef struct os_pool_def { | ||||
|   uint32_t                   pool_sz;   ///< number of items (elements) in the pool | ||||
|   uint32_t                   item_sz;   ///< size of an item | ||||
|   osMemoryPoolAttr_t            attr;   ///< memory pool attributes | ||||
| } osPoolDef_t; | ||||
| #endif | ||||
|   | ||||
| /// Definition structure for message queue. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| typedef struct os_messageQ_def { | ||||
|   uint32_t                  queue_sz;   ///< number of elements in the queue | ||||
|   void                         *pool;   ///< memory array for messages | ||||
| } osMessageQDef_t; | ||||
| #else | ||||
| typedef struct os_messageQ_def { | ||||
|   uint32_t                  queue_sz;   ///< number of elements in the queue | ||||
|   osMessageQueueAttr_t          attr;   ///< message queue attributes | ||||
| } osMessageQDef_t; | ||||
| #endif | ||||
|   | ||||
| /// Definition structure for mail queue. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| 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; | ||||
| #else | ||||
| typedef struct os_mailQ_def { | ||||
|   uint32_t                  queue_sz;   ///< number of elements in the queue | ||||
|   uint32_t                   item_sz;   ///< size of an item | ||||
|   void                         *mail;   ///< pointer to mail | ||||
|   osMemoryPoolAttr_t         mp_attr;   ///< memory pool attributes | ||||
|   osMessageQueueAttr_t       mq_attr;   ///< message queue attributes | ||||
| } osMailQDef_t; | ||||
| #endif | ||||
|   | ||||
|   | ||||
| /// 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 Management Functions ==== | ||||
|   | ||||
| /// Initialize the RTOS Kernel for creating objects. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osKernelInitialize (void); | ||||
| #endif | ||||
|   | ||||
| /// Start the RTOS Kernel scheduler. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osKernelStart (void); | ||||
| #endif | ||||
|   | ||||
| /// Check if the RTOS kernel is already started. | ||||
| /// \return 0 RTOS is not started, 1 RTOS is started. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| int32_t osKernelRunning(void); | ||||
| #endif | ||||
|   | ||||
| #if (defined(osFeature_SysTick) && (osFeature_SysTick != 0))  // System Timer available | ||||
|   | ||||
| /// Get the RTOS kernel system timer counter. | ||||
| /// \return RTOS kernel system timer as 32-bit value  | ||||
| #if (osCMSIS < 0x20000U) | ||||
| uint32_t osKernelSysTick (void); | ||||
| #else | ||||
| #define  osKernelSysTick osKernelGetSysTimerCount | ||||
| #endif | ||||
|   | ||||
| /// The RTOS kernel system timer frequency in Hz. | ||||
| /// \note Reflects the system timer setting and is typically defined in a configuration file. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| #define osKernelSysTickFrequency 100000000 | ||||
| #endif | ||||
|   | ||||
| /// 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 | ||||
| #if (osCMSIS < 0x20000U) | ||||
| #define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) | ||||
| #else | ||||
| #define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec *  osKernelGetSysTimerFreq()) / 1000000) | ||||
| #endif | ||||
|   | ||||
| #endif  // System Timer available | ||||
|   | ||||
|   | ||||
| //  ==== Thread Management Functions ==== | ||||
|   | ||||
| /// 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. | ||||
| #if defined (osObjectsExternal)  // object is external | ||||
| #define osThreadDef(name, priority, instances, stacksz) \ | ||||
| extern const osThreadDef_t os_thread_def_##name | ||||
| #else                            // define the object | ||||
| #define osThreadDef(name, priority, instances, stacksz) \ | ||||
| static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1]; \ | ||||
| static StaticTask_t os_thread_cb_##name; \ | ||||
| const osThreadDef_t os_thread_def_##name = \ | ||||
| { (name), \ | ||||
|   { NULL, osThreadDetached, \ | ||||
|     (instances == 1) ? (&os_thread_cb_##name) : NULL,\ | ||||
|     (instances == 1) ? sizeof(StaticTask_t) : 0U, \ | ||||
|     ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ | ||||
|     8*((stacksz+7)/8), \ | ||||
|     (priority), 0U, 0U } } | ||||
| #endif | ||||
|   | ||||
| /// Access a Thread definition. | ||||
| /// \param         name          name of the thread definition object. | ||||
| #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); | ||||
|   | ||||
| /// Return the thread ID of the current running thread. | ||||
| /// \return thread ID for reference by other functions or NULL in case of error. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osThreadId osThreadGetId (void); | ||||
| #endif | ||||
|   | ||||
| /// Change priority of a 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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); | ||||
| #endif | ||||
|   | ||||
| /// Get current priority of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. | ||||
| /// \return current priority value of the specified thread. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osPriority osThreadGetPriority (osThreadId thread_id); | ||||
| #endif | ||||
|   | ||||
| /// Pass control to next thread that is in state \b READY. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osThreadYield (void); | ||||
| #endif | ||||
|   | ||||
| /// Terminate execution of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osThreadTerminate (osThreadId thread_id); | ||||
| #endif | ||||
|   | ||||
|   | ||||
| //  ==== 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); | ||||
|   | ||||
|   | ||||
| //  ==== 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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osDelay (uint32_t millisec); | ||||
| #endif | ||||
|   | ||||
| #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) \ | ||||
| static StaticTimer_t os_timer_cb_##name; \ | ||||
| const osTimerDef_t os_timer_def_##name = \ | ||||
| { (function), { NULL, 0U, (&os_timer_cb_##name), sizeof(StaticTimer_t) } } | ||||
| #endif | ||||
|   | ||||
| /// Access a Timer definition. | ||||
| /// \param         name          name of the timer object. | ||||
| #define osTimer(name) \ | ||||
| &os_timer_def_##name | ||||
|   | ||||
| /// Create and Initialize 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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); | ||||
| #endif | ||||
|   | ||||
| /// Stop a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osTimerStop (osTimerId timer_id); | ||||
| #endif | ||||
|   | ||||
| /// Delete a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osTimerDelete (osTimerId timer_id); | ||||
| #endif | ||||
|   | ||||
|   | ||||
| //  ==== Mutex Management Functions ==== | ||||
|   | ||||
| /// 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) \ | ||||
| static StaticSemaphore_t os_mutex_cb_##name; \ | ||||
| const osMutexDef_t os_mutex_def_##name = \ | ||||
| { NULL, osMutexRecursive | osMutexPrioInherit, (&os_mutex_cb_##name), sizeof(StaticSemaphore_t) } | ||||
| #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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); | ||||
| #else | ||||
| #define  osMutexWait osMutexAcquire | ||||
| #endif | ||||
|   | ||||
| /// 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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osMutexRelease (osMutexId mutex_id); | ||||
| #endif | ||||
|   | ||||
| /// Delete a Mutex object. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osMutexDelete (osMutexId mutex_id); | ||||
| #endif | ||||
|   | ||||
|   | ||||
| //  ==== Semaphore Management Functions ==== | ||||
|   | ||||
| #if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U))  // 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) \ | ||||
| static StaticSemaphore_t os_semaphore_cb_##name; \ | ||||
| const osSemaphoreDef_t os_semaphore_def_##name = \ | ||||
| { NULL, 0U, (&os_semaphore_cb_##name), sizeof(StaticSemaphore_t) } | ||||
| #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. | ||||
| /// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore. | ||||
| /// \param[in]     count         maximum and initial number of available tokens. | ||||
| /// \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. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); | ||||
| #endif | ||||
|   | ||||
| /// Delete a Semaphore object. | ||||
| /// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| #if (osCMSIS < 0x20000U) | ||||
| osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); | ||||
| #endif | ||||
|   | ||||
| #endif  // Semaphore available | ||||
|   | ||||
|   | ||||
| //  ==== Memory Pool Management Functions ==== | ||||
|  | ||||
| #if (defined(osFeature_Pool) && (osFeature_Pool != 0))  // Memory Pool 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) \ | ||||
| const osPoolDef_t os_pool_def_##name = \ | ||||
| { (no), sizeof(type), {NULL} } | ||||
| #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 object. | ||||
| /// \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 Memory Pool. | ||||
| /// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate. | ||||
| /// \param[in]     block         address of the allocated memory block to be 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 available | ||||
|   | ||||
|   | ||||
| //  ==== Message Queue Management Functions ==== | ||||
|   | ||||
| #if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0))  // Message Queue 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) \ | ||||
| static StaticQueue_t os_mq_cb_##name; \ | ||||
| static uint32_t os_mq_data_##name[(queue_sz) * sizeof(type)]; \ | ||||
| const osMessageQDef_t os_messageQ_def_##name = \ | ||||
| { (queue_sz), \ | ||||
|   { NULL, 0U, (&os_mq_cb_##name), sizeof(StaticQueue_t), \ | ||||
|               (&os_mq_data_##name), sizeof(os_mq_data_##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 object. | ||||
| /// \param[in]     queue_def     message 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 from a Queue or timeout if Queue is empty. | ||||
| /// \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 Queue available | ||||
|   | ||||
|   | ||||
| //  ==== Mail Queue Management Functions ==== | ||||
|   | ||||
| #if (defined(osFeature_MailQ) && (osFeature_MailQ != 0))  // Mail Queue available | ||||
|   | ||||
| /// \brief Create a Mail Queue Definition. | ||||
| /// \param         name          name of the queue. | ||||
| /// \param         queue_sz      maximum number of mails in the queue. | ||||
| /// \param         type          data type of a single mail 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) \ | ||||
| const osMailQDef_t os_mailQ_def_##name = \ | ||||
| { (queue_sz), sizeof(type), NULL } | ||||
| #endif | ||||
|   | ||||
| /// \brief Access a Mail Queue Definition. | ||||
| /// \param         name          name of the queue | ||||
| #define osMailQ(name) \ | ||||
| &os_mailQ_def_##name | ||||
|   | ||||
| /// Create and Initialize a Mail Queue object. | ||||
| /// \param[in]     queue_def     mail queue definition referenced 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 for mail from a mail memory pool. | ||||
| /// \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 for mail from a mail memory pool 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 into a Queue. | ||||
| /// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate. | ||||
| /// \param[in]     mail          pointer to memory with mail to put into a queue. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus osMailPut (osMailQId queue_id, const void *mail); | ||||
|   | ||||
| /// Get a Mail from a Queue or timeout if Queue is empty. | ||||
| /// \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 information that includes status code. | ||||
| os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); | ||||
|   | ||||
| /// Free a memory block by returning it to a mail memory pool. | ||||
| /// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate. | ||||
| /// \param[in]     mail          pointer to 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 Queue available | ||||
|   | ||||
|   | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
|   | ||||
| #endif  // CMSIS_OS_H_ | ||||
							
								
								
									
										1924
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1924
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										734
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										734
									
								
								Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,734 @@ | ||||
| /* -------------------------------------------------------------------------- | ||||
|  * Portions Copyright © 2017 STMicroelectronics International N.V. All rights reserved. | ||||
|  * Portions Copyright (c) 2013-2017 ARM Limited. All rights reserved. | ||||
|  * -------------------------------------------------------------------------- | ||||
|  * | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  * | ||||
|  * 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 | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  *      Name:    cmsis_os2.h | ||||
|  *      Purpose: CMSIS RTOS2 wrapper for FreeRTOS | ||||
|  * | ||||
|  *---------------------------------------------------------------------------*/ | ||||
|  | ||||
| #ifndef CMSIS_OS2_H_ | ||||
| #define CMSIS_OS2_H_ | ||||
|  | ||||
| #ifndef __NO_RETURN | ||||
| #if   defined(__CC_ARM) | ||||
| #define __NO_RETURN __declspec(noreturn) | ||||
| #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||
| #define __NO_RETURN __attribute__((__noreturn__)) | ||||
| #elif defined(__GNUC__) | ||||
| #define __NO_RETURN __attribute__((__noreturn__)) | ||||
| #elif defined(__ICCARM__) | ||||
| #define __NO_RETURN __noreturn | ||||
| #else | ||||
| #define __NO_RETURN | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
|  | ||||
|  | ||||
| //  ==== Enumerations, structures, defines ==== | ||||
|  | ||||
| /// Version information. | ||||
| typedef struct { | ||||
|   uint32_t                       api;   ///< API version (major.minor.rev: mmnnnrrrr dec). | ||||
|   uint32_t                    kernel;   ///< Kernel version (major.minor.rev: mmnnnrrrr dec). | ||||
| } osVersion_t; | ||||
|  | ||||
| /// Kernel state. | ||||
| typedef enum { | ||||
|   osKernelInactive        =  0,         ///< Inactive. | ||||
|   osKernelReady           =  1,         ///< Ready. | ||||
|   osKernelRunning         =  2,         ///< Running. | ||||
|   osKernelLocked          =  3,         ///< Locked. | ||||
|   osKernelSuspended       =  4,         ///< Suspended. | ||||
|   osKernelError           = -1,         ///< Error. | ||||
|   osKernelReserved        = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. | ||||
| } osKernelState_t; | ||||
|  | ||||
| /// Thread state. | ||||
| typedef enum { | ||||
|   osThreadInactive        =  0,         ///< Inactive. | ||||
|   osThreadReady           =  1,         ///< Ready. | ||||
|   osThreadRunning         =  2,         ///< Running. | ||||
|   osThreadBlocked         =  3,         ///< Blocked. | ||||
|   osThreadTerminated      =  4,         ///< Terminated. | ||||
|   osThreadError           = -1,         ///< Error. | ||||
|   osThreadReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization. | ||||
| } osThreadState_t; | ||||
|  | ||||
| /// Priority values. | ||||
| typedef enum { | ||||
|   osPriorityNone          =  0,         ///< No priority (not initialized). | ||||
|   osPriorityIdle          =  1,         ///< Reserved for Idle thread. | ||||
|   osPriorityLow           =  8,         ///< Priority: low | ||||
|   osPriorityLow1          =  8+1,       ///< Priority: low + 1 | ||||
|   osPriorityLow2          =  8+2,       ///< Priority: low + 2 | ||||
|   osPriorityLow3          =  8+3,       ///< Priority: low + 3 | ||||
|   osPriorityLow4          =  8+4,       ///< Priority: low + 4 | ||||
|   osPriorityLow5          =  8+5,       ///< Priority: low + 5 | ||||
|   osPriorityLow6          =  8+6,       ///< Priority: low + 6 | ||||
|   osPriorityLow7          =  8+7,       ///< Priority: low + 7 | ||||
|   osPriorityBelowNormal   = 16,         ///< Priority: below normal | ||||
|   osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1 | ||||
|   osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2 | ||||
|   osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3 | ||||
|   osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4 | ||||
|   osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5 | ||||
|   osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6 | ||||
|   osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7 | ||||
|   osPriorityNormal        = 24,         ///< Priority: normal | ||||
|   osPriorityNormal1       = 24+1,       ///< Priority: normal + 1 | ||||
|   osPriorityNormal2       = 24+2,       ///< Priority: normal + 2 | ||||
|   osPriorityNormal3       = 24+3,       ///< Priority: normal + 3 | ||||
|   osPriorityNormal4       = 24+4,       ///< Priority: normal + 4 | ||||
|   osPriorityNormal5       = 24+5,       ///< Priority: normal + 5 | ||||
|   osPriorityNormal6       = 24+6,       ///< Priority: normal + 6 | ||||
|   osPriorityNormal7       = 24+7,       ///< Priority: normal + 7 | ||||
|   osPriorityAboveNormal   = 32,         ///< Priority: above normal | ||||
|   osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1 | ||||
|   osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2 | ||||
|   osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3 | ||||
|   osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4 | ||||
|   osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5 | ||||
|   osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6 | ||||
|   osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7 | ||||
|   osPriorityHigh          = 40,         ///< Priority: high | ||||
|   osPriorityHigh1         = 40+1,       ///< Priority: high + 1 | ||||
|   osPriorityHigh2         = 40+2,       ///< Priority: high + 2 | ||||
|   osPriorityHigh3         = 40+3,       ///< Priority: high + 3 | ||||
|   osPriorityHigh4         = 40+4,       ///< Priority: high + 4 | ||||
|   osPriorityHigh5         = 40+5,       ///< Priority: high + 5 | ||||
|   osPriorityHigh6         = 40+6,       ///< Priority: high + 6 | ||||
|   osPriorityHigh7         = 40+7,       ///< Priority: high + 7 | ||||
|   osPriorityRealtime      = 48,         ///< Priority: realtime | ||||
|   osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1 | ||||
|   osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2 | ||||
|   osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3 | ||||
|   osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4 | ||||
|   osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5 | ||||
|   osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6 | ||||
|   osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7 | ||||
|   osPriorityISR           = 56,         ///< Reserved for ISR deferred thread. | ||||
|   osPriorityError         = -1,         ///< System cannot determine priority or illegal priority. | ||||
|   osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization. | ||||
| } osPriority_t; | ||||
|  | ||||
| /// Entry point of a thread. | ||||
| typedef void (*osThreadFunc_t) (void *argument); | ||||
|  | ||||
| /// Timer callback function. | ||||
| typedef void (*osTimerFunc_t) (void *argument); | ||||
|  | ||||
| /// Timer type. | ||||
| typedef enum { | ||||
|   osTimerOnce               = 0,          ///< One-shot timer. | ||||
|   osTimerPeriodic           = 1           ///< Repeating timer. | ||||
| } osTimerType_t; | ||||
|  | ||||
| // Timeout value. | ||||
| #define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value. | ||||
|  | ||||
| // Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). | ||||
| #define osFlagsWaitAny        0x00000000U ///< Wait for any flag (default). | ||||
| #define osFlagsWaitAll        0x00000001U ///< Wait for all flags. | ||||
| #define osFlagsNoClear        0x00000002U ///< Do not clear flags which have been specified to wait for. | ||||
|  | ||||
| // Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). | ||||
| #define osFlagsError          0x80000000U ///< Error indicator. | ||||
| #define osFlagsErrorUnknown   0xFFFFFFFFU ///< osError (-1). | ||||
| #define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2). | ||||
| #define osFlagsErrorResource  0xFFFFFFFDU ///< osErrorResource (-3). | ||||
| #define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). | ||||
| #define osFlagsErrorISR       0xFFFFFFFAU ///< osErrorISR (-6). | ||||
|  | ||||
| // Thread attributes (attr_bits in \ref osThreadAttr_t). | ||||
| #define osThreadDetached      0x00000000U ///< Thread created in detached mode (default) | ||||
| #define osThreadJoinable      0x00000001U ///< Thread created in joinable mode | ||||
|  | ||||
| // Mutex attributes (attr_bits in \ref osMutexAttr_t). | ||||
| #define osMutexRecursive      0x00000001U ///< Recursive mutex. | ||||
| #define osMutexPrioInherit    0x00000002U ///< Priority inherit protocol. | ||||
| #define osMutexRobust         0x00000008U ///< Robust mutex. | ||||
|  | ||||
| /// Status code values returned by CMSIS-RTOS functions. | ||||
| typedef enum { | ||||
|   osOK                      =  0,         ///< Operation completed successfully. | ||||
|   osError                   = -1,         ///< Unspecified RTOS error: run-time error but no other error message fits. | ||||
|   osErrorTimeout            = -2,         ///< Operation not completed within the timeout period. | ||||
|   osErrorResource           = -3,         ///< Resource not available. | ||||
|   osErrorParameter          = -4,         ///< Parameter error. | ||||
|   osErrorNoMemory           = -5,         ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. | ||||
|   osErrorISR                = -6,         ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. | ||||
|   osStatusReserved          = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization. | ||||
| } osStatus_t; | ||||
|  | ||||
|  | ||||
| /// \details Thread ID identifies the thread. | ||||
| typedef void *osThreadId_t; | ||||
|  | ||||
| /// \details Timer ID identifies the timer. | ||||
| typedef void *osTimerId_t; | ||||
|  | ||||
| /// \details Event Flags ID identifies the event flags. | ||||
| typedef void *osEventFlagsId_t; | ||||
|  | ||||
| /// \details Mutex ID identifies the mutex. | ||||
| typedef void *osMutexId_t; | ||||
|  | ||||
| /// \details Semaphore ID identifies the semaphore. | ||||
| typedef void *osSemaphoreId_t; | ||||
|  | ||||
| /// \details Memory Pool ID identifies the memory pool. | ||||
| typedef void *osMemoryPoolId_t; | ||||
|  | ||||
| /// \details Message Queue ID identifies the message queue. | ||||
| typedef void *osMessageQueueId_t; | ||||
|  | ||||
|  | ||||
| #ifndef TZ_MODULEID_T | ||||
| #define TZ_MODULEID_T | ||||
| /// \details Data type that identifies secure software modules called by a process. | ||||
| typedef uint32_t TZ_ModuleId_t; | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /// Attributes structure for thread. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the thread | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
|   void                   *stack_mem;    ///< memory for stack | ||||
|   uint32_t                stack_size;   ///< size of stack | ||||
|   osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal) | ||||
|   TZ_ModuleId_t            tz_module;   ///< TrustZone module identifier | ||||
|   uint32_t                  reserved;   ///< reserved (must be 0) | ||||
| } osThreadAttr_t; | ||||
|  | ||||
| /// Attributes structure for timer. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the timer | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
| } osTimerAttr_t; | ||||
|  | ||||
| /// Attributes structure for event flags. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the event flags | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
| } osEventFlagsAttr_t; | ||||
|  | ||||
| /// Attributes structure for mutex. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the mutex | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
| } osMutexAttr_t; | ||||
|  | ||||
| /// Attributes structure for semaphore. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the semaphore | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
| } osSemaphoreAttr_t; | ||||
|  | ||||
| /// Attributes structure for memory pool. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the memory pool | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
|   void                      *mp_mem;    ///< memory for data storage | ||||
|   uint32_t                   mp_size;   ///< size of provided memory for data storage | ||||
| } osMemoryPoolAttr_t; | ||||
|  | ||||
| /// Attributes structure for message queue. | ||||
| typedef struct { | ||||
|   const char                   *name;   ///< name of the message queue | ||||
|   uint32_t                 attr_bits;   ///< attribute bits | ||||
|   void                      *cb_mem;    ///< memory for control block | ||||
|   uint32_t                   cb_size;   ///< size of provided memory for control block | ||||
|   void                      *mq_mem;    ///< memory for data storage | ||||
|   uint32_t                   mq_size;   ///< size of provided memory for data storage | ||||
| } osMessageQueueAttr_t; | ||||
|  | ||||
|  | ||||
| //  ==== Kernel Management Functions ==== | ||||
|  | ||||
| /// Initialize the RTOS Kernel. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osKernelInitialize (void); | ||||
|  | ||||
| ///  Get RTOS Kernel Information. | ||||
| /// \param[out]    version       pointer to buffer for retrieving version information. | ||||
| /// \param[out]    id_buf        pointer to buffer for retrieving kernel identification string. | ||||
| /// \param[in]     id_size       size of buffer for kernel identification string. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); | ||||
|  | ||||
| /// Get the current RTOS Kernel state. | ||||
| /// \return current RTOS Kernel state. | ||||
| osKernelState_t osKernelGetState (void); | ||||
|  | ||||
| /// Start the RTOS Kernel scheduler. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osKernelStart (void); | ||||
|  | ||||
| /// Lock the RTOS Kernel scheduler. | ||||
| /// \return previous lock state (1 - locked, 0 - not locked, error code if negative). | ||||
| int32_t osKernelLock (void); | ||||
|  | ||||
| /// Unlock the RTOS Kernel scheduler. | ||||
| /// \return previous lock state (1 - locked, 0 - not locked, error code if negative). | ||||
| int32_t osKernelUnlock (void); | ||||
|  | ||||
| /// Restore the RTOS Kernel scheduler lock state. | ||||
| /// \param[in]     lock          lock state obtained by \ref osKernelLock or \ref osKernelUnlock. | ||||
| /// \return new lock state (1 - locked, 0 - not locked, error code if negative). | ||||
| int32_t osKernelRestoreLock (int32_t lock); | ||||
|  | ||||
| /// Suspend the RTOS Kernel scheduler. | ||||
| /// \return time in ticks, for how long the system can sleep or power-down. | ||||
| uint32_t osKernelSuspend (void); | ||||
|  | ||||
| /// Resume the RTOS Kernel scheduler. | ||||
| /// \param[in]     sleep_ticks   time in ticks for how long the system was in sleep or power-down mode. | ||||
| void osKernelResume (uint32_t sleep_ticks); | ||||
|  | ||||
| /// Get the RTOS kernel tick count. | ||||
| /// \return RTOS kernel current tick count. | ||||
| uint32_t osKernelGetTickCount (void); | ||||
|  | ||||
| /// Get the RTOS kernel tick frequency. | ||||
| /// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. | ||||
| uint32_t osKernelGetTickFreq (void); | ||||
|  | ||||
| /// Get the RTOS kernel system timer count. | ||||
| /// \return RTOS kernel current system timer count as 32-bit value. | ||||
| uint32_t osKernelGetSysTimerCount (void); | ||||
|  | ||||
| /// Get the RTOS kernel system timer frequency. | ||||
| /// \return frequency of the system timer in hertz, i.e. timer ticks per second. | ||||
| uint32_t osKernelGetSysTimerFreq (void); | ||||
|  | ||||
|  | ||||
| //  ==== Thread Management Functions ==== | ||||
|  | ||||
| /// Create a thread and add it to Active Threads. | ||||
| /// \param[in]     func          thread function. | ||||
| /// \param[in]     argument      pointer that is passed to the thread function as start argument. | ||||
| /// \param[in]     attr          thread attributes; NULL: default values. | ||||
| /// \return thread ID for reference by other functions or NULL in case of error. | ||||
| osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); | ||||
|  | ||||
| /// Get name of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osThreadGetName (osThreadId_t thread_id); | ||||
|  | ||||
| /// Return the thread ID of the current running thread. | ||||
| /// \return thread ID for reference by other functions or NULL in case of error. | ||||
| osThreadId_t osThreadGetId (void); | ||||
|  | ||||
| /// Get current thread state of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return current thread state of the specified thread. | ||||
| osThreadState_t osThreadGetState (osThreadId_t thread_id); | ||||
|  | ||||
| /// Get stack size of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return stack size in bytes. | ||||
| uint32_t osThreadGetStackSize (osThreadId_t thread_id); | ||||
|  | ||||
| /// Get available stack space of a thread based on stack watermark recording during execution. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return remaining stack space in bytes. | ||||
| uint32_t osThreadGetStackSpace (osThreadId_t thread_id); | ||||
|  | ||||
| /// Change priority of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew 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_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); | ||||
|  | ||||
| /// Get current priority of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return current priority value of the specified thread. | ||||
| osPriority_t osThreadGetPriority (osThreadId_t 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_t osThreadYield (void); | ||||
|  | ||||
| /// Suspend execution of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osThreadSuspend (osThreadId_t thread_id); | ||||
|  | ||||
| /// Resume execution of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osThreadResume (osThreadId_t thread_id); | ||||
|  | ||||
| /// Detach a thread (thread storage can be reclaimed when thread terminates). | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osThreadDetach (osThreadId_t thread_id); | ||||
|  | ||||
| /// Wait for specified thread to terminate. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osThreadJoin (osThreadId_t thread_id); | ||||
|  | ||||
| /// Terminate execution of current running thread. | ||||
| __NO_RETURN void osThreadExit (void); | ||||
|  | ||||
| /// Terminate execution of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osThreadTerminate (osThreadId_t thread_id); | ||||
|  | ||||
| /// Get number of active threads. | ||||
| /// \return number of active threads. | ||||
| uint32_t osThreadGetCount (void); | ||||
|  | ||||
| /// Enumerate active threads. | ||||
| /// \param[out]    thread_array  pointer to array for retrieving thread IDs. | ||||
| /// \param[in]     array_items   maximum number of items in array for retrieving thread IDs. | ||||
| /// \return number of enumerated threads. | ||||
| uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); | ||||
|  | ||||
|  | ||||
| //  ==== Thread Flags Functions ==== | ||||
|  | ||||
| /// Set the specified Thread Flags of a thread. | ||||
| /// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId. | ||||
| /// \param[in]     flags         specifies the flags of the thread that shall be set. | ||||
| /// \return thread flags after setting or error code if highest bit set. | ||||
| uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); | ||||
|  | ||||
| /// Clear the specified Thread Flags of current running thread. | ||||
| /// \param[in]     flags         specifies the flags of the thread that shall be cleared. | ||||
| /// \return thread flags before clearing or error code if highest bit set. | ||||
| uint32_t osThreadFlagsClear (uint32_t flags); | ||||
|  | ||||
| /// Get the current Thread Flags of current running thread. | ||||
| /// \return current thread flags. | ||||
| uint32_t osThreadFlagsGet (void); | ||||
|  | ||||
| /// Wait for one or more Thread Flags of the current running thread to become signaled. | ||||
| /// \param[in]     flags         specifies the flags to wait for. | ||||
| /// \param[in]     options       specifies flags options (osFlagsXxxx). | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return thread flags before clearing or error code if highest bit set. | ||||
| uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); | ||||
|  | ||||
|  | ||||
| //  ==== Generic Wait Functions ==== | ||||
|  | ||||
| /// Wait for Timeout (Time Delay). | ||||
| /// \param[in]     ticks         \ref CMSIS_RTOS_TimeOutValue "time ticks" value | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osDelay (uint32_t ticks); | ||||
|  | ||||
| /// Wait until specified time. | ||||
| /// \param[in]     ticks         absolute time in ticks | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osDelayUntil (uint32_t ticks); | ||||
|  | ||||
|  | ||||
| //  ==== Timer Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize a timer. | ||||
| /// \param[in]     func          function pointer to callback function. | ||||
| /// \param[in]     type          \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. | ||||
| /// \param[in]     argument      argument to the timer callback function. | ||||
| /// \param[in]     attr          timer attributes; NULL: default values. | ||||
| /// \return timer ID for reference by other functions or NULL in case of error. | ||||
| osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); | ||||
|  | ||||
| /// Get name of a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osTimerGetName (osTimerId_t timer_id); | ||||
|  | ||||
| /// Start or restart a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerNew. | ||||
| /// \param[in]     ticks         \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); | ||||
|  | ||||
| /// Stop a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osTimerStop (osTimerId_t timer_id); | ||||
|  | ||||
| /// Check if a timer is running. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerNew. | ||||
| /// \return 0 not running, 1 running. | ||||
| uint32_t osTimerIsRunning (osTimerId_t timer_id); | ||||
|  | ||||
| /// Delete a timer. | ||||
| /// \param[in]     timer_id      timer ID obtained by \ref osTimerNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osTimerDelete (osTimerId_t timer_id); | ||||
|  | ||||
|  | ||||
| //  ==== Event Flags Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize an Event Flags object. | ||||
| /// \param[in]     attr          event flags attributes; NULL: default values. | ||||
| /// \return event flags ID for reference by other functions or NULL in case of error. | ||||
| osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); | ||||
|  | ||||
| /// Get name of an Event Flags object. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osEventFlagsGetName (osEventFlagsId_t ef_id); | ||||
|  | ||||
| /// Set the specified Event Flags. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \param[in]     flags         specifies the flags that shall be set. | ||||
| /// \return event flags after setting or error code if highest bit set. | ||||
| uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); | ||||
|  | ||||
| /// Clear the specified Event Flags. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \param[in]     flags         specifies the flags that shall be cleared. | ||||
| /// \return event flags before clearing or error code if highest bit set. | ||||
| uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); | ||||
|  | ||||
| /// Get the current Event Flags. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \return current event flags. | ||||
| uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); | ||||
|  | ||||
| /// Wait for one or more Event Flags to become signaled. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \param[in]     flags         specifies the flags to wait for. | ||||
| /// \param[in]     options       specifies flags options (osFlagsXxxx). | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return event flags before clearing or error code if highest bit set. | ||||
| uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); | ||||
|  | ||||
| /// Delete an Event Flags object. | ||||
| /// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); | ||||
|  | ||||
|  | ||||
| //  ==== Mutex Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize a Mutex object. | ||||
| /// \param[in]     attr          mutex attributes; NULL: default values. | ||||
| /// \return mutex ID for reference by other functions or NULL in case of error. | ||||
| osMutexId_t osMutexNew (const osMutexAttr_t *attr); | ||||
|  | ||||
| /// Get name of a Mutex object. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osMutexGetName (osMutexId_t mutex_id); | ||||
|  | ||||
| /// Acquire a Mutex or timeout if it is locked. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew. | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); | ||||
|  | ||||
| /// Release a Mutex that was acquired by \ref osMutexAcquire. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMutexRelease (osMutexId_t mutex_id); | ||||
|  | ||||
| /// Get Thread which owns a Mutex object. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew. | ||||
| /// \return thread ID of owner thread or NULL when mutex was not acquired. | ||||
| osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); | ||||
|  | ||||
| /// Delete a Mutex object. | ||||
| /// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMutexDelete (osMutexId_t mutex_id); | ||||
|  | ||||
|  | ||||
| //  ==== Semaphore Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize a Semaphore object. | ||||
| /// \param[in]     max_count     maximum number of available tokens. | ||||
| /// \param[in]     initial_count initial number of available tokens. | ||||
| /// \param[in]     attr          semaphore attributes; NULL: default values. | ||||
| /// \return semaphore ID for reference by other functions or NULL in case of error. | ||||
| osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); | ||||
|  | ||||
| /// Get name of a Semaphore object. | ||||
| /// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); | ||||
|  | ||||
| /// Acquire a Semaphore token or timeout if no tokens are available. | ||||
| /// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew. | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); | ||||
|  | ||||
| /// Release a Semaphore token up to the initial maximum count. | ||||
| /// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); | ||||
|  | ||||
| /// Get current Semaphore token count. | ||||
| /// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew. | ||||
| /// \return number of tokens available. | ||||
| uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); | ||||
|  | ||||
| /// Delete a Semaphore object. | ||||
| /// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); | ||||
|  | ||||
|  | ||||
| //  ==== Memory Pool Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize a Memory Pool object. | ||||
| /// \param[in]     block_count   maximum number of memory blocks in memory pool. | ||||
| /// \param[in]     block_size    memory block size in bytes. | ||||
| /// \param[in]     attr          memory pool attributes; NULL: default values. | ||||
| /// \return memory pool ID for reference by other functions or NULL in case of error. | ||||
| osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); | ||||
|  | ||||
| /// Get name of a Memory Pool object. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); | ||||
|  | ||||
| /// Allocate a memory block from a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return address of the allocated memory block or NULL in case of no memory is available. | ||||
| void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); | ||||
|  | ||||
| /// Return an allocated memory block back to a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \param[in]     block         address of the allocated memory block to be returned to the memory pool. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); | ||||
|  | ||||
| /// Get maximum number of memory blocks in a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return maximum number of memory blocks. | ||||
| uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); | ||||
|  | ||||
| /// Get memory block size in a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return memory block size in bytes. | ||||
| uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); | ||||
|  | ||||
| /// Get number of memory blocks used in a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return number of memory blocks used. | ||||
| uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); | ||||
|  | ||||
| /// Get number of memory blocks available in a Memory Pool. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return number of memory blocks available. | ||||
| uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); | ||||
|  | ||||
| /// Delete a Memory Pool object. | ||||
| /// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); | ||||
|  | ||||
|  | ||||
| //  ==== Message Queue Management Functions ==== | ||||
|  | ||||
| /// Create and Initialize a Message Queue object. | ||||
| /// \param[in]     msg_count     maximum number of messages in queue. | ||||
| /// \param[in]     msg_size      maximum message size in bytes. | ||||
| /// \param[in]     attr          message queue attributes; NULL: default values. | ||||
| /// \return message queue ID for reference by other functions or NULL in case of error. | ||||
| osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); | ||||
|  | ||||
| /// Get name of a Message Queue object. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return name as NULL terminated string. | ||||
| const char *osMessageQueueGetName (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Put a Message into a Queue or timeout if Queue is full. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \param[in]     msg_ptr       pointer to buffer with message to put into a queue. | ||||
| /// \param[in]     msg_prio      message priority. | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); | ||||
|  | ||||
| /// Get a Message from a Queue or timeout if Queue is empty. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \param[out]    msg_ptr       pointer to buffer for message to get from a queue. | ||||
| /// \param[out]    msg_prio      pointer to buffer for message priority or NULL. | ||||
| /// \param[in]     timeout       \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); | ||||
|  | ||||
| /// Get maximum number of messages in a Message Queue. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return maximum number of messages. | ||||
| uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Get maximum message size in a Memory Pool. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return maximum message size in bytes. | ||||
| uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Get number of queued messages in a Message Queue. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return number of queued messages. | ||||
| uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Get number of available slots for messages in a Message Queue. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return number of available slots for messages. | ||||
| uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Reset a Message Queue to initial empty state. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); | ||||
|  | ||||
| /// Delete a Message Queue object. | ||||
| /// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew. | ||||
| /// \return status code that indicates the execution status of the function. | ||||
| osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); | ||||
|  | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif  // CMSIS_OS2_H_ | ||||
							
								
								
									
										353
									
								
								Middlewares/Third_Party/FreeRTOS/Source/croutine.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								Middlewares/Third_Party/FreeRTOS/Source/croutine.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,353 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
| #include "croutine.h" | ||||
|  | ||||
| /* Remove the whole file is co-routines are not being used. */ | ||||
| #if( configUSE_CO_ROUTINES != 0 ) | ||||
|  | ||||
| /* | ||||
|  * Some kernel aware debuggers require data to be viewed to be global, rather | ||||
|  * than file scope. | ||||
|  */ | ||||
| #ifdef portREMOVE_STATIC_QUALIFIER | ||||
| 	#define static | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Lists for ready and blocked co-routines. --------------------*/ | ||||
| static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ];	/*< Prioritised ready co-routines. */ | ||||
| static List_t xDelayedCoRoutineList1;									/*< Delayed co-routines. */ | ||||
| static List_t xDelayedCoRoutineList2;									/*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ | ||||
| static List_t * pxDelayedCoRoutineList;									/*< Points to the delayed co-routine list currently being used. */ | ||||
| static List_t * pxOverflowDelayedCoRoutineList;							/*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ | ||||
| static List_t xPendingReadyCoRoutineList;								/*< Holds co-routines that have been readied by an external event.  They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ | ||||
|  | ||||
| /* Other file private variables. --------------------------------*/ | ||||
| CRCB_t * pxCurrentCoRoutine = NULL; | ||||
| static UBaseType_t uxTopCoRoutineReadyPriority = 0; | ||||
| static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; | ||||
|  | ||||
| /* The initial state of the co-routine when it is created. */ | ||||
| #define corINITIAL_STATE	( 0 ) | ||||
|  | ||||
| /* | ||||
|  * Place the co-routine represented by pxCRCB into the appropriate ready queue | ||||
|  * for the priority.  It is inserted at the end of the list. | ||||
|  * | ||||
|  * This macro accesses the co-routine ready lists and therefore must not be | ||||
|  * used from within an ISR. | ||||
|  */ | ||||
| #define prvAddCoRoutineToReadyQueue( pxCRCB )																		\ | ||||
| {																													\ | ||||
| 	if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority )															\ | ||||
| 	{																												\ | ||||
| 		uxTopCoRoutineReadyPriority = pxCRCB->uxPriority;															\ | ||||
| 	}																												\ | ||||
| 	vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) );	\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Utility to ready all the lists used by the scheduler.  This is called | ||||
|  * automatically upon the creation of the first co-routine. | ||||
|  */ | ||||
| static void prvInitialiseCoRoutineLists( void ); | ||||
|  | ||||
| /* | ||||
|  * Co-routines that are readied by an interrupt cannot be placed directly into | ||||
|  * the ready lists (there is no mutual exclusion).  Instead they are placed in | ||||
|  * in the pending ready list in order that they can later be moved to the ready | ||||
|  * list by the co-routine scheduler. | ||||
|  */ | ||||
| static void prvCheckPendingReadyList( void ); | ||||
|  | ||||
| /* | ||||
|  * Macro that looks at the list of co-routines that are currently delayed to | ||||
|  * see if any require waking. | ||||
|  * | ||||
|  * Co-routines are stored in the queue in the order of their wake time - | ||||
|  * meaning once one co-routine has been found whose timer has not expired | ||||
|  * we need not look any further down the list. | ||||
|  */ | ||||
| static void prvCheckDelayedList( void ); | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) | ||||
| { | ||||
| BaseType_t xReturn; | ||||
| CRCB_t *pxCoRoutine; | ||||
|  | ||||
| 	/* Allocate the memory that will store the co-routine control block. */ | ||||
| 	pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); | ||||
| 	if( pxCoRoutine ) | ||||
| 	{ | ||||
| 		/* If pxCurrentCoRoutine is NULL then this is the first co-routine to | ||||
| 		be created and the co-routine data structures need initialising. */ | ||||
| 		if( pxCurrentCoRoutine == NULL ) | ||||
| 		{ | ||||
| 			pxCurrentCoRoutine = pxCoRoutine; | ||||
| 			prvInitialiseCoRoutineLists(); | ||||
| 		} | ||||
|  | ||||
| 		/* Check the priority is within limits. */ | ||||
| 		if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) | ||||
| 		{ | ||||
| 			uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; | ||||
| 		} | ||||
|  | ||||
| 		/* Fill out the co-routine control block from the function parameters. */ | ||||
| 		pxCoRoutine->uxState = corINITIAL_STATE; | ||||
| 		pxCoRoutine->uxPriority = uxPriority; | ||||
| 		pxCoRoutine->uxIndex = uxIndex; | ||||
| 		pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; | ||||
|  | ||||
| 		/* Initialise all the other co-routine control block parameters. */ | ||||
| 		vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); | ||||
| 		vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); | ||||
|  | ||||
| 		/* Set the co-routine control block as a link back from the ListItem_t. | ||||
| 		This is so we can get back to the containing CRCB from a generic item | ||||
| 		in a list. */ | ||||
| 		listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); | ||||
| 		listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); | ||||
|  | ||||
| 		/* Event lists are always in priority order. */ | ||||
| 		listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); | ||||
|  | ||||
| 		/* Now the co-routine has been initialised it can be added to the ready | ||||
| 		list at the correct priority. */ | ||||
| 		prvAddCoRoutineToReadyQueue( pxCoRoutine ); | ||||
|  | ||||
| 		xReturn = pdPASS; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; | ||||
| 	} | ||||
|  | ||||
| 	return xReturn; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) | ||||
| { | ||||
| TickType_t xTimeToWake; | ||||
|  | ||||
| 	/* Calculate the time to wake - this may overflow but this is | ||||
| 	not a problem. */ | ||||
| 	xTimeToWake = xCoRoutineTickCount + xTicksToDelay; | ||||
|  | ||||
| 	/* We must remove ourselves from the ready list before adding | ||||
| 	ourselves to the blocked list as the same list item is used for | ||||
| 	both lists. */ | ||||
| 	( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); | ||||
|  | ||||
| 	/* The list item will be inserted in wake time order. */ | ||||
| 	listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); | ||||
|  | ||||
| 	if( xTimeToWake < xCoRoutineTickCount ) | ||||
| 	{ | ||||
| 		/* Wake time has overflowed.  Place this item in the | ||||
| 		overflow list. */ | ||||
| 		vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* The wake time has not overflowed, so we can use the | ||||
| 		current block list. */ | ||||
| 		vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); | ||||
| 	} | ||||
|  | ||||
| 	if( pxEventList ) | ||||
| 	{ | ||||
| 		/* Also add the co-routine to an event list.  If this is done then the | ||||
| 		function must be called with interrupts disabled. */ | ||||
| 		vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvCheckPendingReadyList( void ) | ||||
| { | ||||
| 	/* Are there any co-routines waiting to get moved to the ready list?  These | ||||
| 	are co-routines that have been readied by an ISR.  The ISR cannot access | ||||
| 	the	ready lists itself. */ | ||||
| 	while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) | ||||
| 	{ | ||||
| 		CRCB_t *pxUnblockedCRCB; | ||||
|  | ||||
| 		/* The pending ready list can be accessed by an ISR. */ | ||||
| 		portDISABLE_INTERRUPTS(); | ||||
| 		{ | ||||
| 			pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); | ||||
| 			( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); | ||||
| 		} | ||||
| 		portENABLE_INTERRUPTS(); | ||||
|  | ||||
| 		( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); | ||||
| 		prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvCheckDelayedList( void ) | ||||
| { | ||||
| CRCB_t *pxCRCB; | ||||
|  | ||||
| 	xPassedTicks = xTaskGetTickCount() - xLastTickCount; | ||||
| 	while( xPassedTicks ) | ||||
| 	{ | ||||
| 		xCoRoutineTickCount++; | ||||
| 		xPassedTicks--; | ||||
|  | ||||
| 		/* If the tick count has overflowed we need to swap the ready lists. */ | ||||
| 		if( xCoRoutineTickCount == 0 ) | ||||
| 		{ | ||||
| 			List_t * pxTemp; | ||||
|  | ||||
| 			/* Tick count has overflowed so we need to swap the delay lists.  If there are | ||||
| 			any items in pxDelayedCoRoutineList here then there is an error! */ | ||||
| 			pxTemp = pxDelayedCoRoutineList; | ||||
| 			pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; | ||||
| 			pxOverflowDelayedCoRoutineList = pxTemp; | ||||
| 		} | ||||
|  | ||||
| 		/* See if this tick has made a timeout expire. */ | ||||
| 		while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) | ||||
| 		{ | ||||
| 			pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); | ||||
|  | ||||
| 			if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) | ||||
| 			{ | ||||
| 				/* Timeout not yet expired. */ | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			portDISABLE_INTERRUPTS(); | ||||
| 			{ | ||||
| 				/* The event could have occurred just before this critical | ||||
| 				section.  If this is the case then the generic list item will | ||||
| 				have been moved to the pending ready list and the following | ||||
| 				line is still valid.  Also the pvContainer parameter will have | ||||
| 				been set to NULL so the following lines are also valid. */ | ||||
| 				( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); | ||||
|  | ||||
| 				/* Is the co-routine waiting on an event also? */ | ||||
| 				if( pxCRCB->xEventListItem.pxContainer ) | ||||
| 				{ | ||||
| 					( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); | ||||
| 				} | ||||
| 			} | ||||
| 			portENABLE_INTERRUPTS(); | ||||
|  | ||||
| 			prvAddCoRoutineToReadyQueue( pxCRCB ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	xLastTickCount = xCoRoutineTickCount; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vCoRoutineSchedule( void ) | ||||
| { | ||||
| 	/* See if any co-routines readied by events need moving to the ready lists. */ | ||||
| 	prvCheckPendingReadyList(); | ||||
|  | ||||
| 	/* See if any delayed co-routines have timed out. */ | ||||
| 	prvCheckDelayedList(); | ||||
|  | ||||
| 	/* Find the highest priority queue that contains ready co-routines. */ | ||||
| 	while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) | ||||
| 	{ | ||||
| 		if( uxTopCoRoutineReadyPriority == 0 ) | ||||
| 		{ | ||||
| 			/* No more co-routines to check. */ | ||||
| 			return; | ||||
| 		} | ||||
| 		--uxTopCoRoutineReadyPriority; | ||||
| 	} | ||||
|  | ||||
| 	/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines | ||||
| 	 of the	same priority get an equal share of the processor time. */ | ||||
| 	listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); | ||||
|  | ||||
| 	/* Call the co-routine. */ | ||||
| 	( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvInitialiseCoRoutineLists( void ) | ||||
| { | ||||
| UBaseType_t uxPriority; | ||||
|  | ||||
| 	for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) | ||||
| 	{ | ||||
| 		vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); | ||||
| 	} | ||||
|  | ||||
| 	vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); | ||||
| 	vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); | ||||
| 	vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); | ||||
|  | ||||
| 	/* Start with pxDelayedCoRoutineList using list1 and the | ||||
| 	pxOverflowDelayedCoRoutineList using list2. */ | ||||
| 	pxDelayedCoRoutineList = &xDelayedCoRoutineList1; | ||||
| 	pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) | ||||
| { | ||||
| CRCB_t *pxUnblockedCRCB; | ||||
| BaseType_t xReturn; | ||||
|  | ||||
| 	/* This function is called from within an interrupt.  It can only access | ||||
| 	event lists and the pending ready list.  This function assumes that a | ||||
| 	check has already been made to ensure pxEventList is not empty. */ | ||||
| 	pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); | ||||
| 	( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); | ||||
| 	vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); | ||||
|  | ||||
| 	if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) | ||||
| 	{ | ||||
| 		xReturn = pdTRUE; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		xReturn = pdFALSE; | ||||
| 	} | ||||
|  | ||||
| 	return xReturn; | ||||
| } | ||||
|  | ||||
| #endif /* configUSE_CO_ROUTINES == 0 */ | ||||
|  | ||||
							
								
								
									
										753
									
								
								Middlewares/Third_Party/FreeRTOS/Source/event_groups.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										753
									
								
								Middlewares/Third_Party/FreeRTOS/Source/event_groups.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,753 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /* Standard includes. */ | ||||
| #include <stdlib.h> | ||||
|  | ||||
| /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining | ||||
| all the API functions to use the MPU wrappers.  That should only be done when | ||||
| task.h is included from an application file. */ | ||||
| #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE | ||||
|  | ||||
| /* FreeRTOS includes. */ | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
| #include "timers.h" | ||||
| #include "event_groups.h" | ||||
|  | ||||
| /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified | ||||
| because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined | ||||
| for the header files above, but not in this file, in order to generate the | ||||
| correct privileged Vs unprivileged linkage and placement. */ | ||||
| #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ | ||||
|  | ||||
| /* The following bit fields convey control information in a task's event list | ||||
| item value.  It is important they don't clash with the | ||||
| taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ | ||||
| #if configUSE_16_BIT_TICKS == 1 | ||||
| 	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x0100U | ||||
| 	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x0200U | ||||
| 	#define eventWAIT_FOR_ALL_BITS			0x0400U | ||||
| 	#define eventEVENT_BITS_CONTROL_BYTES	0xff00U | ||||
| #else | ||||
| 	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x01000000UL | ||||
| 	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x02000000UL | ||||
| 	#define eventWAIT_FOR_ALL_BITS			0x04000000UL | ||||
| 	#define eventEVENT_BITS_CONTROL_BYTES	0xff000000UL | ||||
| #endif | ||||
|  | ||||
| typedef struct EventGroupDef_t | ||||
| { | ||||
| 	EventBits_t uxEventBits; | ||||
| 	List_t xTasksWaitingForBits;		/*< List of tasks waiting for a bit to be set. */ | ||||
|  | ||||
| 	#if( configUSE_TRACE_FACILITY == 1 ) | ||||
| 		UBaseType_t uxEventGroupNumber; | ||||
| 	#endif | ||||
|  | ||||
| 	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) | ||||
| 		uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ | ||||
| 	#endif | ||||
| } EventGroup_t; | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * Test the bits set in uxCurrentEventBits to see if the wait condition is met. | ||||
|  * The wait condition is defined by xWaitForAllBits.  If xWaitForAllBits is | ||||
|  * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor | ||||
|  * are also set in uxCurrentEventBits.  If xWaitForAllBits is pdFALSE then the | ||||
|  * wait condition is met if any of the bits set in uxBitsToWait for are also set | ||||
|  * in uxCurrentEventBits. | ||||
|  */ | ||||
| static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( configSUPPORT_STATIC_ALLOCATION == 1 ) | ||||
|  | ||||
| 	EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) | ||||
| 	{ | ||||
| 	EventGroup_t *pxEventBits; | ||||
|  | ||||
| 		/* A StaticEventGroup_t object must be provided. */ | ||||
| 		configASSERT( pxEventGroupBuffer ); | ||||
|  | ||||
| 		#if( configASSERT_DEFINED == 1 ) | ||||
| 		{ | ||||
| 			/* Sanity check that the size of the structure used to declare a | ||||
| 			variable of type StaticEventGroup_t equals the size of the real | ||||
| 			event group structure. */ | ||||
| 			volatile size_t xSize = sizeof( StaticEventGroup_t ); | ||||
| 			configASSERT( xSize == sizeof( EventGroup_t ) ); | ||||
| 		} /*lint !e529 xSize is referenced if configASSERT() is defined. */ | ||||
| 		#endif /* configASSERT_DEFINED */ | ||||
|  | ||||
| 		/* The user has provided a statically allocated event group - use it. */ | ||||
| 		pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ | ||||
|  | ||||
| 		if( pxEventBits != NULL ) | ||||
| 		{ | ||||
| 			pxEventBits->uxEventBits = 0; | ||||
| 			vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); | ||||
|  | ||||
| 			#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) | ||||
| 			{ | ||||
| 				/* Both static and dynamic allocation can be used, so note that | ||||
| 				this event group was created statically in case the event group | ||||
| 				is later deleted. */ | ||||
| 				pxEventBits->ucStaticallyAllocated = pdTRUE; | ||||
| 			} | ||||
| 			#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ | ||||
|  | ||||
| 			traceEVENT_GROUP_CREATE( pxEventBits ); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* xEventGroupCreateStatic should only ever be called with | ||||
| 			pxEventGroupBuffer pointing to a pre-allocated (compile time | ||||
| 			allocated) StaticEventGroup_t variable. */ | ||||
| 			traceEVENT_GROUP_CREATE_FAILED(); | ||||
| 		} | ||||
|  | ||||
| 		return pxEventBits; | ||||
| 	} | ||||
|  | ||||
| #endif /* configSUPPORT_STATIC_ALLOCATION */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) | ||||
|  | ||||
| 	EventGroupHandle_t xEventGroupCreate( void ) | ||||
| 	{ | ||||
| 	EventGroup_t *pxEventBits; | ||||
|  | ||||
| 		/* Allocate the event group.  Justification for MISRA deviation as | ||||
| 		follows:  pvPortMalloc() always ensures returned memory blocks are | ||||
| 		aligned per the requirements of the MCU stack.  In this case | ||||
| 		pvPortMalloc() must return a pointer that is guaranteed to meet the | ||||
| 		alignment requirements of the EventGroup_t structure - which (if you | ||||
| 		follow it through) is the alignment requirements of the TickType_t type | ||||
| 		(EventBits_t being of TickType_t itself).  Therefore, whenever the | ||||
| 		stack alignment requirements are greater than or equal to the | ||||
| 		TickType_t alignment requirements the cast is safe.  In other cases, | ||||
| 		where the natural word size of the architecture is less than | ||||
| 		sizeof( TickType_t ), the TickType_t variables will be accessed in two | ||||
| 		or more reads operations, and the alignment requirements is only that | ||||
| 		of each individual read. */ | ||||
| 		pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ | ||||
|  | ||||
| 		if( pxEventBits != NULL ) | ||||
| 		{ | ||||
| 			pxEventBits->uxEventBits = 0; | ||||
| 			vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); | ||||
|  | ||||
| 			#if( configSUPPORT_STATIC_ALLOCATION == 1 ) | ||||
| 			{ | ||||
| 				/* Both static and dynamic allocation can be used, so note this | ||||
| 				event group was allocated statically in case the event group is | ||||
| 				later deleted. */ | ||||
| 				pxEventBits->ucStaticallyAllocated = pdFALSE; | ||||
| 			} | ||||
| 			#endif /* configSUPPORT_STATIC_ALLOCATION */ | ||||
|  | ||||
| 			traceEVENT_GROUP_CREATE( pxEventBits ); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ | ||||
| 		} | ||||
|  | ||||
| 		return pxEventBits; | ||||
| 	} | ||||
|  | ||||
| #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) | ||||
| { | ||||
| EventBits_t uxOriginalBitValue, uxReturn; | ||||
| EventGroup_t *pxEventBits = xEventGroup; | ||||
| BaseType_t xAlreadyYielded; | ||||
| BaseType_t xTimeoutOccurred = pdFALSE; | ||||
|  | ||||
| 	configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); | ||||
| 	configASSERT( uxBitsToWaitFor != 0 ); | ||||
| 	#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) | ||||
| 	{ | ||||
| 		configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	vTaskSuspendAll(); | ||||
| 	{ | ||||
| 		uxOriginalBitValue = pxEventBits->uxEventBits; | ||||
|  | ||||
| 		( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); | ||||
|  | ||||
| 		if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) | ||||
| 		{ | ||||
| 			/* All the rendezvous bits are now set - no need to block. */ | ||||
| 			uxReturn = ( uxOriginalBitValue | uxBitsToSet ); | ||||
|  | ||||
| 			/* Rendezvous always clear the bits.  They will have been cleared | ||||
| 			already unless this is the only task in the rendezvous. */ | ||||
| 			pxEventBits->uxEventBits &= ~uxBitsToWaitFor; | ||||
|  | ||||
| 			xTicksToWait = 0; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if( xTicksToWait != ( TickType_t ) 0 ) | ||||
| 			{ | ||||
| 				traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); | ||||
|  | ||||
| 				/* Store the bits that the calling task is waiting for in the | ||||
| 				task's event list item so the kernel knows when a match is | ||||
| 				found.  Then enter the blocked state. */ | ||||
| 				vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); | ||||
|  | ||||
| 				/* This assignment is obsolete as uxReturn will get set after | ||||
| 				the task unblocks, but some compilers mistakenly generate a | ||||
| 				warning about uxReturn being returned without being set if the | ||||
| 				assignment is omitted. */ | ||||
| 				uxReturn = 0; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* The rendezvous bits were not set, but no block time was | ||||
| 				specified - just return the current event bit value. */ | ||||
| 				uxReturn = pxEventBits->uxEventBits; | ||||
| 				xTimeoutOccurred = pdTRUE; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	xAlreadyYielded = xTaskResumeAll(); | ||||
|  | ||||
| 	if( xTicksToWait != ( TickType_t ) 0 ) | ||||
| 	{ | ||||
| 		if( xAlreadyYielded == pdFALSE ) | ||||
| 		{ | ||||
| 			portYIELD_WITHIN_API(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
|  | ||||
| 		/* The task blocked to wait for its required bits to be set - at this | ||||
| 		point either the required bits were set or the block time expired.  If | ||||
| 		the required bits were set they will have been stored in the task's | ||||
| 		event list item, and they should now be retrieved then cleared. */ | ||||
| 		uxReturn = uxTaskResetEventItemValue(); | ||||
|  | ||||
| 		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) | ||||
| 		{ | ||||
| 			/* The task timed out, just return the current event bit value. */ | ||||
| 			taskENTER_CRITICAL(); | ||||
| 			{ | ||||
| 				uxReturn = pxEventBits->uxEventBits; | ||||
|  | ||||
| 				/* Although the task got here because it timed out before the | ||||
| 				bits it was waiting for were set, it is possible that since it | ||||
| 				unblocked another task has set the bits.  If this is the case | ||||
| 				then it needs to clear the bits before exiting. */ | ||||
| 				if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) | ||||
| 				{ | ||||
| 					pxEventBits->uxEventBits &= ~uxBitsToWaitFor; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
| 			} | ||||
| 			taskEXIT_CRITICAL(); | ||||
|  | ||||
| 			xTimeoutOccurred = pdTRUE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* The task unblocked because the bits were set. */ | ||||
| 		} | ||||
|  | ||||
| 		/* Control bits might be set as the task had blocked should not be | ||||
| 		returned. */ | ||||
| 		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; | ||||
| 	} | ||||
|  | ||||
| 	traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); | ||||
|  | ||||
| 	/* Prevent compiler warnings when trace macros are not used. */ | ||||
| 	( void ) xTimeoutOccurred; | ||||
|  | ||||
| 	return uxReturn; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) | ||||
| { | ||||
| EventGroup_t *pxEventBits = xEventGroup; | ||||
| EventBits_t uxReturn, uxControlBits = 0; | ||||
| BaseType_t xWaitConditionMet, xAlreadyYielded; | ||||
| BaseType_t xTimeoutOccurred = pdFALSE; | ||||
|  | ||||
| 	/* Check the user is not attempting to wait on the bits used by the kernel | ||||
| 	itself, and that at least one bit is being requested. */ | ||||
| 	configASSERT( xEventGroup ); | ||||
| 	configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); | ||||
| 	configASSERT( uxBitsToWaitFor != 0 ); | ||||
| 	#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) | ||||
| 	{ | ||||
| 		configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	vTaskSuspendAll(); | ||||
| 	{ | ||||
| 		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; | ||||
|  | ||||
| 		/* Check to see if the wait condition is already met or not. */ | ||||
| 		xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); | ||||
|  | ||||
| 		if( xWaitConditionMet != pdFALSE ) | ||||
| 		{ | ||||
| 			/* The wait condition has already been met so there is no need to | ||||
| 			block. */ | ||||
| 			uxReturn = uxCurrentEventBits; | ||||
| 			xTicksToWait = ( TickType_t ) 0; | ||||
|  | ||||
| 			/* Clear the wait bits if requested to do so. */ | ||||
| 			if( xClearOnExit != pdFALSE ) | ||||
| 			{ | ||||
| 				pxEventBits->uxEventBits &= ~uxBitsToWaitFor; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
| 		} | ||||
| 		else if( xTicksToWait == ( TickType_t ) 0 ) | ||||
| 		{ | ||||
| 			/* The wait condition has not been met, but no block time was | ||||
| 			specified, so just return the current value. */ | ||||
| 			uxReturn = uxCurrentEventBits; | ||||
| 			xTimeoutOccurred = pdTRUE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* The task is going to block to wait for its required bits to be | ||||
| 			set.  uxControlBits are used to remember the specified behaviour of | ||||
| 			this call to xEventGroupWaitBits() - for use when the event bits | ||||
| 			unblock the task. */ | ||||
| 			if( xClearOnExit != pdFALSE ) | ||||
| 			{ | ||||
| 				uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
|  | ||||
| 			if( xWaitForAllBits != pdFALSE ) | ||||
| 			{ | ||||
| 				uxControlBits |= eventWAIT_FOR_ALL_BITS; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
|  | ||||
| 			/* Store the bits that the calling task is waiting for in the | ||||
| 			task's event list item so the kernel knows when a match is | ||||
| 			found.  Then enter the blocked state. */ | ||||
| 			vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); | ||||
|  | ||||
| 			/* This is obsolete as it will get set after the task unblocks, but | ||||
| 			some compilers mistakenly generate a warning about the variable | ||||
| 			being returned without being set if it is not done. */ | ||||
| 			uxReturn = 0; | ||||
|  | ||||
| 			traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); | ||||
| 		} | ||||
| 	} | ||||
| 	xAlreadyYielded = xTaskResumeAll(); | ||||
|  | ||||
| 	if( xTicksToWait != ( TickType_t ) 0 ) | ||||
| 	{ | ||||
| 		if( xAlreadyYielded == pdFALSE ) | ||||
| 		{ | ||||
| 			portYIELD_WITHIN_API(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
|  | ||||
| 		/* The task blocked to wait for its required bits to be set - at this | ||||
| 		point either the required bits were set or the block time expired.  If | ||||
| 		the required bits were set they will have been stored in the task's | ||||
| 		event list item, and they should now be retrieved then cleared. */ | ||||
| 		uxReturn = uxTaskResetEventItemValue(); | ||||
|  | ||||
| 		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) | ||||
| 		{ | ||||
| 			taskENTER_CRITICAL(); | ||||
| 			{ | ||||
| 				/* The task timed out, just return the current event bit value. */ | ||||
| 				uxReturn = pxEventBits->uxEventBits; | ||||
|  | ||||
| 				/* It is possible that the event bits were updated between this | ||||
| 				task leaving the Blocked state and running again. */ | ||||
| 				if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) | ||||
| 				{ | ||||
| 					if( xClearOnExit != pdFALSE ) | ||||
| 					{ | ||||
| 						pxEventBits->uxEventBits &= ~uxBitsToWaitFor; | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						mtCOVERAGE_TEST_MARKER(); | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
| 				xTimeoutOccurred = pdTRUE; | ||||
| 			} | ||||
| 			taskEXIT_CRITICAL(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* The task unblocked because the bits were set. */ | ||||
| 		} | ||||
|  | ||||
| 		/* The task blocked so control bits may have been set. */ | ||||
| 		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; | ||||
| 	} | ||||
| 	traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); | ||||
|  | ||||
| 	/* Prevent compiler warnings when trace macros are not used. */ | ||||
| 	( void ) xTimeoutOccurred; | ||||
|  | ||||
| 	return uxReturn; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) | ||||
| { | ||||
| EventGroup_t *pxEventBits = xEventGroup; | ||||
| EventBits_t uxReturn; | ||||
|  | ||||
| 	/* Check the user is not attempting to clear the bits used by the kernel | ||||
| 	itself. */ | ||||
| 	configASSERT( xEventGroup ); | ||||
| 	configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); | ||||
|  | ||||
| 	taskENTER_CRITICAL(); | ||||
| 	{ | ||||
| 		traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); | ||||
|  | ||||
| 		/* The value returned is the event group value prior to the bits being | ||||
| 		cleared. */ | ||||
| 		uxReturn = pxEventBits->uxEventBits; | ||||
|  | ||||
| 		/* Clear the bits. */ | ||||
| 		pxEventBits->uxEventBits &= ~uxBitsToClear; | ||||
| 	} | ||||
| 	taskEXIT_CRITICAL(); | ||||
|  | ||||
| 	return uxReturn; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) | ||||
|  | ||||
| 	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) | ||||
| 	{ | ||||
| 		BaseType_t xReturn; | ||||
|  | ||||
| 		traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); | ||||
| 		xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ | ||||
|  | ||||
| 		return xReturn; | ||||
| 	} | ||||
|  | ||||
| #endif | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) | ||||
| { | ||||
| UBaseType_t uxSavedInterruptStatus; | ||||
| EventGroup_t const * const pxEventBits = xEventGroup; | ||||
| EventBits_t uxReturn; | ||||
|  | ||||
| 	uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); | ||||
| 	{ | ||||
| 		uxReturn = pxEventBits->uxEventBits; | ||||
| 	} | ||||
| 	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); | ||||
|  | ||||
| 	return uxReturn; | ||||
| } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) | ||||
| { | ||||
| ListItem_t *pxListItem, *pxNext; | ||||
| ListItem_t const *pxListEnd; | ||||
| List_t const * pxList; | ||||
| EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; | ||||
| EventGroup_t *pxEventBits = xEventGroup; | ||||
| BaseType_t xMatchFound = pdFALSE; | ||||
|  | ||||
| 	/* Check the user is not attempting to set the bits used by the kernel | ||||
| 	itself. */ | ||||
| 	configASSERT( xEventGroup ); | ||||
| 	configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); | ||||
|  | ||||
| 	pxList = &( pxEventBits->xTasksWaitingForBits ); | ||||
| 	pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */ | ||||
| 	vTaskSuspendAll(); | ||||
| 	{ | ||||
| 		traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); | ||||
|  | ||||
| 		pxListItem = listGET_HEAD_ENTRY( pxList ); | ||||
|  | ||||
| 		/* Set the bits. */ | ||||
| 		pxEventBits->uxEventBits |= uxBitsToSet; | ||||
|  | ||||
| 		/* See if the new bit value should unblock any tasks. */ | ||||
| 		while( pxListItem != pxListEnd ) | ||||
| 		{ | ||||
| 			pxNext = listGET_NEXT( pxListItem ); | ||||
| 			uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); | ||||
| 			xMatchFound = pdFALSE; | ||||
|  | ||||
| 			/* Split the bits waited for from the control bits. */ | ||||
| 			uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; | ||||
| 			uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; | ||||
|  | ||||
| 			if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) | ||||
| 			{ | ||||
| 				/* Just looking for single bit being set. */ | ||||
| 				if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) | ||||
| 				{ | ||||
| 					xMatchFound = pdTRUE; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
| 			} | ||||
| 			else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) | ||||
| 			{ | ||||
| 				/* All bits are set. */ | ||||
| 				xMatchFound = pdTRUE; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* Need all bits to be set, but not all the bits were set. */ | ||||
| 			} | ||||
|  | ||||
| 			if( xMatchFound != pdFALSE ) | ||||
| 			{ | ||||
| 				/* The bits match.  Should the bits be cleared on exit? */ | ||||
| 				if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) | ||||
| 				{ | ||||
| 					uxBitsToClear |= uxBitsWaitedFor; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
|  | ||||
| 				/* Store the actual event flag value in the task's event list | ||||
| 				item before removing the task from the event list.  The | ||||
| 				eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows | ||||
| 				that is was unblocked due to its required bits matching, rather | ||||
| 				than because it timed out. */ | ||||
| 				vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); | ||||
| 			} | ||||
|  | ||||
| 			/* Move onto the next list item.  Note pxListItem->pxNext is not | ||||
| 			used here as the list item may have been removed from the event list | ||||
| 			and inserted into the ready/pending reading list. */ | ||||
| 			pxListItem = pxNext; | ||||
| 		} | ||||
|  | ||||
| 		/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT | ||||
| 		bit was set in the control word. */ | ||||
| 		pxEventBits->uxEventBits &= ~uxBitsToClear; | ||||
| 	} | ||||
| 	( void ) xTaskResumeAll(); | ||||
|  | ||||
| 	return pxEventBits->uxEventBits; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vEventGroupDelete( EventGroupHandle_t xEventGroup ) | ||||
| { | ||||
| EventGroup_t *pxEventBits = xEventGroup; | ||||
| const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); | ||||
|  | ||||
| 	vTaskSuspendAll(); | ||||
| 	{ | ||||
| 		traceEVENT_GROUP_DELETE( xEventGroup ); | ||||
|  | ||||
| 		while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) | ||||
| 		{ | ||||
| 			/* Unblock the task, returning 0 as the event list is being deleted | ||||
| 			and cannot therefore have any bits set. */ | ||||
| 			configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); | ||||
| 			vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); | ||||
| 		} | ||||
|  | ||||
| 		#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) | ||||
| 		{ | ||||
| 			/* The event group can only have been allocated dynamically - free | ||||
| 			it again. */ | ||||
| 			vPortFree( pxEventBits ); | ||||
| 		} | ||||
| 		#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) | ||||
| 		{ | ||||
| 			/* The event group could have been allocated statically or | ||||
| 			dynamically, so check before attempting to free the memory. */ | ||||
| 			if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) | ||||
| 			{ | ||||
| 				vPortFree( pxEventBits ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
| 		} | ||||
| 		#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ | ||||
| 	} | ||||
| 	( void ) xTaskResumeAll(); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* For internal use only - execute a 'set bits' command that was pended from | ||||
| an interrupt. */ | ||||
| void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) | ||||
| { | ||||
| 	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* For internal use only - execute a 'clear bits' command that was pended from | ||||
| an interrupt. */ | ||||
| void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) | ||||
| { | ||||
| 	( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) | ||||
| { | ||||
| BaseType_t xWaitConditionMet = pdFALSE; | ||||
|  | ||||
| 	if( xWaitForAllBits == pdFALSE ) | ||||
| 	{ | ||||
| 		/* Task only has to wait for one bit within uxBitsToWaitFor to be | ||||
| 		set.  Is one already set? */ | ||||
| 		if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) | ||||
| 		{ | ||||
| 			xWaitConditionMet = pdTRUE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* Task has to wait for all the bits in uxBitsToWaitFor to be set. | ||||
| 		Are they set already? */ | ||||
| 		if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) | ||||
| 		{ | ||||
| 			xWaitConditionMet = pdTRUE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return xWaitConditionMet; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) | ||||
|  | ||||
| 	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) | ||||
| 	{ | ||||
| 	BaseType_t xReturn; | ||||
|  | ||||
| 		traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); | ||||
| 		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ | ||||
|  | ||||
| 		return xReturn; | ||||
| 	} | ||||
|  | ||||
| #endif | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if (configUSE_TRACE_FACILITY == 1) | ||||
|  | ||||
| 	UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) | ||||
| 	{ | ||||
| 	UBaseType_t xReturn; | ||||
| 	EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ | ||||
|  | ||||
| 		if( xEventGroup == NULL ) | ||||
| 		{ | ||||
| 			xReturn = 0; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			xReturn = pxEventBits->uxEventGroupNumber; | ||||
| 		} | ||||
|  | ||||
| 		return xReturn; | ||||
| 	} | ||||
|  | ||||
| #endif /* configUSE_TRACE_FACILITY */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if ( configUSE_TRACE_FACILITY == 1 ) | ||||
|  | ||||
| 	void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) | ||||
| 	{ | ||||
| 		( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ | ||||
| 	} | ||||
|  | ||||
| #endif /* configUSE_TRACE_FACILITY */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
|  | ||||
							
								
								
									
										1278
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1278
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										133
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef STACK_MACROS_H | ||||
| #define STACK_MACROS_H | ||||
|  | ||||
| #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ | ||||
| 	#warning The name of this file has changed to stack_macros.h.  Please update your code accordingly.  This source file (which has the original name) will be removed in future released. | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Call the stack overflow hook function if the stack of the task being swapped | ||||
|  * out is currently overflowed, or looks like it might have overflowed in the | ||||
|  * past. | ||||
|  * | ||||
|  * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check | ||||
|  * the current stack state only - comparing the current top of stack value to | ||||
|  * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 | ||||
|  * will also cause the last few stack bytes to be checked to ensure the value | ||||
|  * to which the bytes were set when the task was created have not been | ||||
|  * overwritten.  Note this second test does not guarantee that an overflowed | ||||
|  * stack will always be recognised. | ||||
|  */ | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) | ||||
|  | ||||
| 	/* Only the current stack state is to be checked. */ | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 		/* Is the currently saved stack pointer within the stack limit? */								\ | ||||
| 		if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )										\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) | ||||
|  | ||||
| 	/* Only the current stack state is to be checked. */ | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 																										\ | ||||
| 		/* Is the currently saved stack pointer within the stack limit? */								\ | ||||
| 		if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack )									\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) | ||||
|  | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 		const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack;							\ | ||||
| 		const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5;											\ | ||||
| 																										\ | ||||
| 		if( ( pulStack[ 0 ] != ulCheckValue ) ||												\ | ||||
| 			( pulStack[ 1 ] != ulCheckValue ) ||												\ | ||||
| 			( pulStack[ 2 ] != ulCheckValue ) ||												\ | ||||
| 			( pulStack[ 3 ] != ulCheckValue ) )												\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) | ||||
|  | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																								\ | ||||
| 	{																																	\ | ||||
| 	int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack;																		\ | ||||
| 	static const uint8_t ucExpectedStackBytes[] = {	tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };	\ | ||||
| 																																		\ | ||||
| 																																		\ | ||||
| 		pcEndOfStack -= sizeof( ucExpectedStackBytes );																					\ | ||||
| 																																		\ | ||||
| 		/* Has the extremity of the task stack ever been written over? */																\ | ||||
| 		if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )					\ | ||||
| 		{																																\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );									\ | ||||
| 		}																																\ | ||||
| 	} | ||||
|  | ||||
| #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Remove stack overflow macro if not being used. */ | ||||
| #ifndef taskCHECK_FOR_STACK_OVERFLOW | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW() | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* STACK_MACROS_H */ | ||||
|  | ||||
							
								
								
									
										720
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										720
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,720 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef CO_ROUTINE_H | ||||
| #define CO_ROUTINE_H | ||||
|  | ||||
| #ifndef INC_FREERTOS_H | ||||
| 	#error "include FreeRTOS.h must appear in source files before include croutine.h" | ||||
| #endif | ||||
|  | ||||
| #include "list.h" | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /* Used to hide the implementation of the co-routine control block.  The | ||||
| control block structure however has to be included in the header due to | ||||
| the macro implementation of the co-routine functionality. */ | ||||
| typedef void * CoRoutineHandle_t; | ||||
|  | ||||
| /* Defines the prototype to which co-routine functions must conform. */ | ||||
| typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); | ||||
|  | ||||
| typedef struct corCoRoutineControlBlock | ||||
| { | ||||
| 	crCOROUTINE_CODE 	pxCoRoutineFunction; | ||||
| 	ListItem_t			xGenericListItem;	/*< List item used to place the CRCB in ready and blocked queues. */ | ||||
| 	ListItem_t			xEventListItem;		/*< List item used to place the CRCB in event lists. */ | ||||
| 	UBaseType_t 		uxPriority;			/*< The priority of the co-routine in relation to other co-routines. */ | ||||
| 	UBaseType_t 		uxIndex;			/*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ | ||||
| 	uint16_t 			uxState;			/*< Used internally by the co-routine implementation. */ | ||||
| } CRCB_t; /* Co-routine control block.  Note must be identical in size down to uxPriority with TCB_t. */ | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  *<pre> | ||||
|  BaseType_t xCoRoutineCreate( | ||||
|                                  crCOROUTINE_CODE pxCoRoutineCode, | ||||
|                                  UBaseType_t uxPriority, | ||||
|                                  UBaseType_t uxIndex | ||||
|                                );</pre> | ||||
|  * | ||||
|  * Create a new co-routine and add it to the list of co-routines that are | ||||
|  * ready to run. | ||||
|  * | ||||
|  * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine | ||||
|  * functions require special syntax - see the co-routine section of the WEB | ||||
|  * documentation for more information. | ||||
|  * | ||||
|  * @param uxPriority The priority with respect to other co-routines at which | ||||
|  *  the co-routine will run. | ||||
|  * | ||||
|  * @param uxIndex Used to distinguish between different co-routines that | ||||
|  * execute the same function.  See the example below and the co-routine section | ||||
|  * of the WEB documentation for further information. | ||||
|  * | ||||
|  * @return pdPASS if the co-routine was successfully created and added to a ready | ||||
|  * list, otherwise an error code defined with ProjDefs.h. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // Co-routine to be created. | ||||
|  void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  // This may not be necessary for const variables. | ||||
|  static const char cLedToFlash[ 2 ] = { 5, 6 }; | ||||
|  static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; | ||||
|  | ||||
|      // Must start every co-routine with a call to crSTART(); | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|          // This co-routine just delays for a fixed period, then toggles | ||||
|          // an LED.  Two co-routines are created using this function, so | ||||
|          // the uxIndex parameter is used to tell the co-routine which | ||||
|          // LED to flash and how int32_t to delay.  This assumes xQueue has | ||||
|          // already been created. | ||||
|          vParTestToggleLED( cLedToFlash[ uxIndex ] ); | ||||
|          crDELAY( xHandle, uxFlashRates[ uxIndex ] ); | ||||
|      } | ||||
|  | ||||
|      // Must end every co-routine with a call to crEND(); | ||||
|      crEND(); | ||||
|  } | ||||
|  | ||||
|  // Function that creates two co-routines. | ||||
|  void vOtherFunction( void ) | ||||
|  { | ||||
|  uint8_t ucParameterToPass; | ||||
|  TaskHandle_t xHandle; | ||||
|  | ||||
|      // Create two co-routines at priority 0.  The first is given index 0 | ||||
|      // so (from the code above) toggles LED 5 every 200 ticks.  The second | ||||
|      // is given index 1 so toggles LED 6 every 400 ticks. | ||||
|      for( uxIndex = 0; uxIndex < 2; uxIndex++ ) | ||||
|      { | ||||
|          xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); | ||||
|      } | ||||
|  } | ||||
|    </pre> | ||||
|  * \defgroup xCoRoutineCreate xCoRoutineCreate | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  *<pre> | ||||
|  void vCoRoutineSchedule( void );</pre> | ||||
|  * | ||||
|  * Run a co-routine. | ||||
|  * | ||||
|  * vCoRoutineSchedule() executes the highest priority co-routine that is able | ||||
|  * to run.  The co-routine will execute until it either blocks, yields or is | ||||
|  * preempted by a task.  Co-routines execute cooperatively so one | ||||
|  * co-routine cannot be preempted by another, but can be preempted by a task. | ||||
|  * | ||||
|  * If an application comprises of both tasks and co-routines then | ||||
|  * vCoRoutineSchedule should be called from the idle task (in an idle task | ||||
|  * hook). | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // This idle task hook will schedule a co-routine each time it is called. | ||||
|  // The rest of the idle task will execute between co-routine calls. | ||||
|  void vApplicationIdleHook( void ) | ||||
|  { | ||||
| 	vCoRoutineSchedule(); | ||||
|  } | ||||
|  | ||||
|  // Alternatively, if you do not require any other part of the idle task to | ||||
|  // execute, the idle task hook can call vCoRoutineScheduler() within an | ||||
|  // infinite loop. | ||||
|  void vApplicationIdleHook( void ) | ||||
|  { | ||||
|     for( ;; ) | ||||
|     { | ||||
|         vCoRoutineSchedule(); | ||||
|     } | ||||
|  } | ||||
|  </pre> | ||||
|  * \defgroup vCoRoutineSchedule vCoRoutineSchedule | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| void vCoRoutineSchedule( void ); | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  * <pre> | ||||
|  crSTART( CoRoutineHandle_t xHandle );</pre> | ||||
|  * | ||||
|  * This macro MUST always be called at the start of a co-routine function. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // Co-routine to be created. | ||||
|  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  static int32_t ulAVariable; | ||||
|  | ||||
|      // Must start every co-routine with a call to crSTART(); | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|           // Co-routine functionality goes here. | ||||
|      } | ||||
|  | ||||
|      // Must end every co-routine with a call to crEND(); | ||||
|      crEND(); | ||||
|  }</pre> | ||||
|  * \defgroup crSTART crSTART | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  * <pre> | ||||
|  crEND();</pre> | ||||
|  * | ||||
|  * This macro MUST always be called at the end of a co-routine function. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // Co-routine to be created. | ||||
|  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  static int32_t ulAVariable; | ||||
|  | ||||
|      // Must start every co-routine with a call to crSTART(); | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|           // Co-routine functionality goes here. | ||||
|      } | ||||
|  | ||||
|      // Must end every co-routine with a call to crEND(); | ||||
|      crEND(); | ||||
|  }</pre> | ||||
|  * \defgroup crSTART crSTART | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crEND() } | ||||
|  | ||||
| /* | ||||
|  * These macros are intended for internal use by the co-routine implementation | ||||
|  * only.  The macros should not be used directly by application writers. | ||||
|  */ | ||||
| #define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): | ||||
| #define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  *<pre> | ||||
|  crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre> | ||||
|  * | ||||
|  * Delay a co-routine for a fixed period of time. | ||||
|  * | ||||
|  * crDELAY can only be called from the co-routine function itself - not | ||||
|  * from within a function called by the co-routine function.  This is because | ||||
|  * co-routines do not maintain their own stack. | ||||
|  * | ||||
|  * @param xHandle The handle of the co-routine to delay.  This is the xHandle | ||||
|  * parameter of the co-routine function. | ||||
|  * | ||||
|  * @param xTickToDelay The number of ticks that the co-routine should delay | ||||
|  * for.  The actual amount of time this equates to is defined by | ||||
|  * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_PERIOD_MS | ||||
|  * can be used to convert ticks to milliseconds. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // Co-routine to be created. | ||||
|  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  // This may not be necessary for const variables. | ||||
|  // We are to delay for 200ms. | ||||
|  static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; | ||||
|  | ||||
|      // Must start every co-routine with a call to crSTART(); | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|         // Delay for 200ms. | ||||
|         crDELAY( xHandle, xDelayTime ); | ||||
|  | ||||
|         // Do something here. | ||||
|      } | ||||
|  | ||||
|      // Must end every co-routine with a call to crEND(); | ||||
|      crEND(); | ||||
|  }</pre> | ||||
|  * \defgroup crDELAY crDELAY | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crDELAY( xHandle, xTicksToDelay )												\ | ||||
| 	if( ( xTicksToDelay ) > 0 )															\ | ||||
| 	{																					\ | ||||
| 		vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL );							\ | ||||
| 	}																					\ | ||||
| 	crSET_STATE0( ( xHandle ) ); | ||||
|  | ||||
| /** | ||||
|  * <pre> | ||||
|  crQUEUE_SEND( | ||||
|                   CoRoutineHandle_t xHandle, | ||||
|                   QueueHandle_t pxQueue, | ||||
|                   void *pvItemToQueue, | ||||
|                   TickType_t xTicksToWait, | ||||
|                   BaseType_t *pxResult | ||||
|              )</pre> | ||||
|  * | ||||
|  * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine | ||||
|  * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. | ||||
|  * | ||||
|  * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas | ||||
|  * xQueueSend() and xQueueReceive() can only be used from tasks. | ||||
|  * | ||||
|  * crQUEUE_SEND can only be called from the co-routine function itself - not | ||||
|  * from within a function called by the co-routine function.  This is because | ||||
|  * co-routines do not maintain their own stack. | ||||
|  * | ||||
|  * See the co-routine section of the WEB documentation for information on | ||||
|  * passing data between tasks and co-routines and between ISR's and | ||||
|  * co-routines. | ||||
|  * | ||||
|  * @param xHandle The handle of the calling co-routine.  This is the xHandle | ||||
|  * parameter of the co-routine function. | ||||
|  * | ||||
|  * @param pxQueue The handle of the queue on which the data will be posted. | ||||
|  * The handle is obtained as the return value when the queue is created using | ||||
|  * the xQueueCreate() API function. | ||||
|  * | ||||
|  * @param pvItemToQueue A pointer to the data being posted onto the queue. | ||||
|  * The number of bytes of each queued item is specified when the queue is | ||||
|  * created.  This number of bytes is copied from pvItemToQueue into the queue | ||||
|  * itself. | ||||
|  * | ||||
|  * @param xTickToDelay The number of ticks that the co-routine should block | ||||
|  * to wait for space to become available on the queue, should space not be | ||||
|  * available immediately. The actual amount of time this equates to is defined | ||||
|  * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant | ||||
|  * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example | ||||
|  * below). | ||||
|  * | ||||
|  * @param pxResult The variable pointed to by pxResult will be set to pdPASS if | ||||
|  * data was successfully posted onto the queue, otherwise it will be set to an | ||||
|  * error defined within ProjDefs.h. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|  // Co-routine function that blocks for a fixed period then posts a number onto | ||||
|  // a queue. | ||||
|  static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  static BaseType_t xNumberToPost = 0; | ||||
|  static BaseType_t xResult; | ||||
|  | ||||
|     // Co-routines must begin with a call to crSTART(). | ||||
|     crSTART( xHandle ); | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         // This assumes the queue has already been created. | ||||
|         crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); | ||||
|  | ||||
|         if( xResult != pdPASS ) | ||||
|         { | ||||
|             // The message was not posted! | ||||
|         } | ||||
|  | ||||
|         // Increment the number to be posted onto the queue. | ||||
|         xNumberToPost++; | ||||
|  | ||||
|         // Delay for 100 ticks. | ||||
|         crDELAY( xHandle, 100 ); | ||||
|     } | ||||
|  | ||||
|     // Co-routines must end with a call to crEND(). | ||||
|     crEND(); | ||||
|  }</pre> | ||||
|  * \defgroup crQUEUE_SEND crQUEUE_SEND | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )			\ | ||||
| {																						\ | ||||
| 	*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) );	\ | ||||
| 	if( *( pxResult ) == errQUEUE_BLOCKED )												\ | ||||
| 	{																					\ | ||||
| 		crSET_STATE0( ( xHandle ) );													\ | ||||
| 		*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 );					\ | ||||
| 	}																					\ | ||||
| 	if( *pxResult == errQUEUE_YIELD )													\ | ||||
| 	{																					\ | ||||
| 		crSET_STATE1( ( xHandle ) );													\ | ||||
| 		*pxResult = pdPASS;																\ | ||||
| 	}																					\ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  * <pre> | ||||
|   crQUEUE_RECEIVE( | ||||
|                      CoRoutineHandle_t xHandle, | ||||
|                      QueueHandle_t pxQueue, | ||||
|                      void *pvBuffer, | ||||
|                      TickType_t xTicksToWait, | ||||
|                      BaseType_t *pxResult | ||||
|                  )</pre> | ||||
|  * | ||||
|  * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine | ||||
|  * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. | ||||
|  * | ||||
|  * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas | ||||
|  * xQueueSend() and xQueueReceive() can only be used from tasks. | ||||
|  * | ||||
|  * crQUEUE_RECEIVE can only be called from the co-routine function itself - not | ||||
|  * from within a function called by the co-routine function.  This is because | ||||
|  * co-routines do not maintain their own stack. | ||||
|  * | ||||
|  * See the co-routine section of the WEB documentation for information on | ||||
|  * passing data between tasks and co-routines and between ISR's and | ||||
|  * co-routines. | ||||
|  * | ||||
|  * @param xHandle The handle of the calling co-routine.  This is the xHandle | ||||
|  * parameter of the co-routine function. | ||||
|  * | ||||
|  * @param pxQueue The handle of the queue from which the data will be received. | ||||
|  * The handle is obtained as the return value when the queue is created using | ||||
|  * the xQueueCreate() API function. | ||||
|  * | ||||
|  * @param pvBuffer The buffer into which the received item is to be copied. | ||||
|  * The number of bytes of each queued item is specified when the queue is | ||||
|  * created.  This number of bytes is copied into pvBuffer. | ||||
|  * | ||||
|  * @param xTickToDelay The number of ticks that the co-routine should block | ||||
|  * to wait for data to become available from the queue, should data not be | ||||
|  * available immediately. The actual amount of time this equates to is defined | ||||
|  * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant | ||||
|  * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the | ||||
|  * crQUEUE_SEND example). | ||||
|  * | ||||
|  * @param pxResult The variable pointed to by pxResult will be set to pdPASS if | ||||
|  * data was successfully retrieved from the queue, otherwise it will be set to | ||||
|  * an error code as defined within ProjDefs.h. | ||||
|  * | ||||
|  * Example usage: | ||||
|  <pre> | ||||
|  // A co-routine receives the number of an LED to flash from a queue.  It | ||||
|  // blocks on the queue until the number is received. | ||||
|  static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // Variables in co-routines must be declared static if they must maintain value across a blocking call. | ||||
|  static BaseType_t xResult; | ||||
|  static UBaseType_t uxLEDToFlash; | ||||
|  | ||||
|     // All co-routines must start with a call to crSTART(). | ||||
|     crSTART( xHandle ); | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         // Wait for data to become available on the queue. | ||||
|         crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); | ||||
|  | ||||
|         if( xResult == pdPASS ) | ||||
|         { | ||||
|             // We received the LED to flash - flash it! | ||||
|             vParTestToggleLED( uxLEDToFlash ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     crEND(); | ||||
|  }</pre> | ||||
|  * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )			\ | ||||
| {																						\ | ||||
| 	*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) );		\ | ||||
| 	if( *( pxResult ) == errQUEUE_BLOCKED ) 											\ | ||||
| 	{																					\ | ||||
| 		crSET_STATE0( ( xHandle ) );													\ | ||||
| 		*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 );				\ | ||||
| 	}																					\ | ||||
| 	if( *( pxResult ) == errQUEUE_YIELD )												\ | ||||
| 	{																					\ | ||||
| 		crSET_STATE1( ( xHandle ) );													\ | ||||
| 		*( pxResult ) = pdPASS;															\ | ||||
| 	}																					\ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  * <pre> | ||||
|   crQUEUE_SEND_FROM_ISR( | ||||
|                             QueueHandle_t pxQueue, | ||||
|                             void *pvItemToQueue, | ||||
|                             BaseType_t xCoRoutinePreviouslyWoken | ||||
|                        )</pre> | ||||
|  * | ||||
|  * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the | ||||
|  * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() | ||||
|  * functions used by tasks. | ||||
|  * | ||||
|  * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to | ||||
|  * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and | ||||
|  * xQueueReceiveFromISR() can only be used to pass data between a task and and | ||||
|  * ISR. | ||||
|  * | ||||
|  * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue | ||||
|  * that is being used from within a co-routine. | ||||
|  * | ||||
|  * See the co-routine section of the WEB documentation for information on | ||||
|  * passing data between tasks and co-routines and between ISR's and | ||||
|  * co-routines. | ||||
|  * | ||||
|  * @param xQueue The handle to the queue on which the item is to be posted. | ||||
|  * | ||||
|  * @param pvItemToQueue A pointer to the item that is to be placed on the | ||||
|  * queue.  The size of the items the queue will hold was defined when the | ||||
|  * queue was created, so this many bytes will be copied from pvItemToQueue | ||||
|  * into the queue storage area. | ||||
|  * | ||||
|  * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto | ||||
|  * the same queue multiple times from a single interrupt.  The first call | ||||
|  * should always pass in pdFALSE.  Subsequent calls should pass in | ||||
|  * the value returned from the previous call. | ||||
|  * | ||||
|  * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is | ||||
|  * used by the ISR to determine if a context switch may be required following | ||||
|  * the ISR. | ||||
|  * | ||||
|  * Example usage: | ||||
|  <pre> | ||||
|  // A co-routine that blocks on a queue waiting for characters to be received. | ||||
|  static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  char cRxedChar; | ||||
|  BaseType_t xResult; | ||||
|  | ||||
|      // All co-routines must start with a call to crSTART(). | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|          // Wait for data to become available on the queue.  This assumes the | ||||
|          // queue xCommsRxQueue has already been created! | ||||
|          crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); | ||||
|  | ||||
|          // Was a character received? | ||||
|          if( xResult == pdPASS ) | ||||
|          { | ||||
|              // Process the character here. | ||||
|          } | ||||
|      } | ||||
|  | ||||
|      // All co-routines must end with a call to crEND(). | ||||
|      crEND(); | ||||
|  } | ||||
|  | ||||
|  // An ISR that uses a queue to send characters received on a serial port to | ||||
|  // a co-routine. | ||||
|  void vUART_ISR( void ) | ||||
|  { | ||||
|  char cRxedChar; | ||||
|  BaseType_t xCRWokenByPost = pdFALSE; | ||||
|  | ||||
|      // We loop around reading characters until there are none left in the UART. | ||||
|      while( UART_RX_REG_NOT_EMPTY() ) | ||||
|      { | ||||
|          // Obtain the character from the UART. | ||||
|          cRxedChar = UART_RX_REG; | ||||
|  | ||||
|          // Post the character onto a queue.  xCRWokenByPost will be pdFALSE | ||||
|          // the first time around the loop.  If the post causes a co-routine | ||||
|          // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. | ||||
|          // In this manner we can ensure that if more than one co-routine is | ||||
|          // blocked on the queue only one is woken by this ISR no matter how | ||||
|          // many characters are posted to the queue. | ||||
|          xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); | ||||
|      } | ||||
|  }</pre> | ||||
|  * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * croutine. h | ||||
|  * <pre> | ||||
|   crQUEUE_SEND_FROM_ISR( | ||||
|                             QueueHandle_t pxQueue, | ||||
|                             void *pvBuffer, | ||||
|                             BaseType_t * pxCoRoutineWoken | ||||
|                        )</pre> | ||||
|  * | ||||
|  * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the | ||||
|  * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() | ||||
|  * functions used by tasks. | ||||
|  * | ||||
|  * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to | ||||
|  * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and | ||||
|  * xQueueReceiveFromISR() can only be used to pass data between a task and and | ||||
|  * ISR. | ||||
|  * | ||||
|  * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data | ||||
|  * from a queue that is being used from within a co-routine (a co-routine | ||||
|  * posted to the queue). | ||||
|  * | ||||
|  * See the co-routine section of the WEB documentation for information on | ||||
|  * passing data between tasks and co-routines and between ISR's and | ||||
|  * co-routines. | ||||
|  * | ||||
|  * @param xQueue The handle to the queue on which the item is to be posted. | ||||
|  * | ||||
|  * @param pvBuffer A pointer to a buffer into which the received item will be | ||||
|  * placed.  The size of the items the queue will hold was defined when the | ||||
|  * queue was created, so this many bytes will be copied from the queue into | ||||
|  * pvBuffer. | ||||
|  * | ||||
|  * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become | ||||
|  * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a | ||||
|  * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise | ||||
|  * *pxCoRoutineWoken will remain unchanged. | ||||
|  * | ||||
|  * @return pdTRUE an item was successfully received from the queue, otherwise | ||||
|  * pdFALSE. | ||||
|  * | ||||
|  * Example usage: | ||||
|  <pre> | ||||
|  // A co-routine that posts a character to a queue then blocks for a fixed | ||||
|  // period.  The character is incremented each time. | ||||
|  static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) | ||||
|  { | ||||
|  // cChar holds its value while this co-routine is blocked and must therefore | ||||
|  // be declared static. | ||||
|  static char cCharToTx = 'a'; | ||||
|  BaseType_t xResult; | ||||
|  | ||||
|      // All co-routines must start with a call to crSTART(). | ||||
|      crSTART( xHandle ); | ||||
|  | ||||
|      for( ;; ) | ||||
|      { | ||||
|          // Send the next character to the queue. | ||||
|          crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); | ||||
|  | ||||
|          if( xResult == pdPASS ) | ||||
|          { | ||||
|              // The character was successfully posted to the queue. | ||||
|          } | ||||
| 		 else | ||||
| 		 { | ||||
| 			// Could not post the character to the queue. | ||||
| 		 } | ||||
|  | ||||
|          // Enable the UART Tx interrupt to cause an interrupt in this | ||||
| 		 // hypothetical UART.  The interrupt will obtain the character | ||||
| 		 // from the queue and send it. | ||||
| 		 ENABLE_RX_INTERRUPT(); | ||||
|  | ||||
| 		 // Increment to the next character then block for a fixed period. | ||||
| 		 // cCharToTx will maintain its value across the delay as it is | ||||
| 		 // declared static. | ||||
| 		 cCharToTx++; | ||||
| 		 if( cCharToTx > 'x' ) | ||||
| 		 { | ||||
| 			cCharToTx = 'a'; | ||||
| 		 } | ||||
| 		 crDELAY( 100 ); | ||||
|      } | ||||
|  | ||||
|      // All co-routines must end with a call to crEND(). | ||||
|      crEND(); | ||||
|  } | ||||
|  | ||||
|  // An ISR that uses a queue to receive characters to send on a UART. | ||||
|  void vUART_ISR( void ) | ||||
|  { | ||||
|  char cCharToTx; | ||||
|  BaseType_t xCRWokenByPost = pdFALSE; | ||||
|  | ||||
|      while( UART_TX_REG_EMPTY() ) | ||||
|      { | ||||
|          // Are there any characters in the queue waiting to be sent? | ||||
| 		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine | ||||
| 		 // is woken by the post - ensuring that only a single co-routine is | ||||
| 		 // woken no matter how many times we go around this loop. | ||||
|          if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) | ||||
| 		 { | ||||
| 			 SEND_CHARACTER( cCharToTx ); | ||||
| 		 } | ||||
|      } | ||||
|  }</pre> | ||||
|  * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR | ||||
|  * \ingroup Tasks | ||||
|  */ | ||||
| #define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) | ||||
|  | ||||
| /* | ||||
|  * This function is intended for internal use by the co-routine macros only. | ||||
|  * The macro nature of the co-routine implementation requires that the | ||||
|  * prototype appears here.  The function should not be used by application | ||||
|  * writers. | ||||
|  * | ||||
|  * Removes the current co-routine from its ready list and places it in the | ||||
|  * appropriate delayed list. | ||||
|  */ | ||||
| void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); | ||||
|  | ||||
| /* | ||||
|  * This function is intended for internal use by the queue implementation only. | ||||
|  * The function should not be used by application writers. | ||||
|  * | ||||
|  * Removes the highest priority co-routine from the event list and places it in | ||||
|  * the pending ready list. | ||||
|  */ | ||||
| BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif /* CO_ROUTINE_H */ | ||||
							
								
								
									
										279
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,279 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef DEPRECATED_DEFINITIONS_H | ||||
| #define DEPRECATED_DEFINITIONS_H | ||||
|  | ||||
|  | ||||
| /* Each FreeRTOS port has a unique portmacro.h header file.  Originally a | ||||
| pre-processor definition was used to ensure the pre-processor found the correct | ||||
| portmacro.h file for the port being used.  That scheme was deprecated in favour | ||||
| of setting the compiler's include path such that it found the correct | ||||
| portmacro.h file - removing the need for the constant and allowing the | ||||
| portmacro.h file to be located anywhere in relation to the port being used.  The | ||||
| definitions below remain in the code for backward compatibility only.  New | ||||
| projects should not use them. */ | ||||
|  | ||||
| #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT | ||||
| 	#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" | ||||
| 	typedef void ( __interrupt __far *pxISR )(); | ||||
| #endif | ||||
|  | ||||
| #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT | ||||
| 	#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" | ||||
| 	typedef void ( __interrupt __far *pxISR )(); | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_MEGA_AVR | ||||
| 	#include "../portable/GCC/ATMega323/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef IAR_MEGA_AVR | ||||
| 	#include "../portable/IAR/ATMega323/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef MPLAB_PIC24_PORT | ||||
| 	#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef MPLAB_DSPIC_PORT | ||||
| 	#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef MPLAB_PIC18F_PORT | ||||
| 	#include "../../Source/portable/MPLAB/PIC18F/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef MPLAB_PIC32MX_PORT | ||||
| 	#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef _FEDPICC | ||||
| 	#include "libFreeRTOS/Include/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef SDCC_CYGNAL | ||||
| 	#include "../../Source/portable/SDCC/Cygnal/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_ARM7 | ||||
| 	#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_ARM7_ECLIPSE | ||||
| 	#include "portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef ROWLEY_LPC23xx | ||||
| 	#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef IAR_MSP430 | ||||
| 	#include "..\..\Source\portable\IAR\MSP430\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_MSP430 | ||||
| 	#include "../../Source/portable/GCC/MSP430F449/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef ROWLEY_MSP430 | ||||
| 	#include "../../Source/portable/Rowley/MSP430F449/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef ARM7_LPC21xx_KEIL_RVDS | ||||
| 	#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef SAM7_GCC | ||||
| 	#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef SAM7_IAR | ||||
| 	#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef SAM9XE_IAR | ||||
| 	#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef LPC2000_IAR | ||||
| 	#include "..\..\Source\portable\IAR\LPC2000\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef STR71X_IAR | ||||
| 	#include "..\..\Source\portable\IAR\STR71x\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef STR75X_IAR | ||||
| 	#include "..\..\Source\portable\IAR\STR75x\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef STR75X_GCC | ||||
| 	#include "..\..\Source\portable\GCC\STR75x\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef STR91X_IAR | ||||
| 	#include "..\..\Source\portable\IAR\STR91x\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_H8S | ||||
| 	#include "../../Source/portable/GCC/H8S2329/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_AT91FR40008 | ||||
| 	#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef RVDS_ARMCM3_LM3S102 | ||||
| 	#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_ARMCM3_LM3S102 | ||||
| 	#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_ARMCM3 | ||||
| 	#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef IAR_ARM_CM3 | ||||
| 	#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef IAR_ARMCM3_LM | ||||
| 	#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef HCS12_CODE_WARRIOR | ||||
| 	#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef MICROBLAZE_GCC | ||||
| 	#include "../../Source/portable/GCC/MicroBlaze/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef TERN_EE | ||||
| 	#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_HCS12 | ||||
| 	#include "../../Source/portable/GCC/HCS12/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_MCF5235 | ||||
|     #include "../../Source/portable/GCC/MCF5235/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef COLDFIRE_V2_GCC | ||||
| 	#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef COLDFIRE_V2_CODEWARRIOR | ||||
| 	#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_PPC405 | ||||
| 	#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef GCC_PPC440 | ||||
| 	#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef _16FX_SOFTUNE | ||||
| 	#include "..\..\Source\portable\Softune\MB96340\portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef BCC_INDUSTRIAL_PC_PORT | ||||
| 	/* A short file name has to be used in place of the normal | ||||
| 	FreeRTOSConfig.h when using the Borland compiler. */ | ||||
| 	#include "frconfig.h" | ||||
| 	#include "..\portable\BCC\16BitDOS\PC\prtmacro.h" | ||||
|     typedef void ( __interrupt __far *pxISR )(); | ||||
| #endif | ||||
|  | ||||
| #ifdef BCC_FLASH_LITE_186_PORT | ||||
| 	/* A short file name has to be used in place of the normal | ||||
| 	FreeRTOSConfig.h when using the Borland compiler. */ | ||||
| 	#include "frconfig.h" | ||||
| 	#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" | ||||
|     typedef void ( __interrupt __far *pxISR )(); | ||||
| #endif | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
|    #ifdef __AVR32_AVR32A__ | ||||
| 	   #include "portmacro.h" | ||||
|    #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef __ICCAVR32__ | ||||
|    #ifdef __CORE__ | ||||
|       #if __CORE__ == __AVR32A__ | ||||
| 	      #include "portmacro.h" | ||||
|       #endif | ||||
|    #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef __91467D | ||||
| 	#include "portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __96340 | ||||
| 	#include "portmacro.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef __IAR_V850ES_Fx3__ | ||||
| 	#include "../../Source/portable/IAR/V850ES/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_V850ES_Jx3__ | ||||
| 	#include "../../Source/portable/IAR/V850ES/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_V850ES_Jx3_L__ | ||||
| 	#include "../../Source/portable/IAR/V850ES/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_V850ES_Jx2__ | ||||
| 	#include "../../Source/portable/IAR/V850ES/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_V850ES_Hx2__ | ||||
| 	#include "../../Source/portable/IAR/V850ES/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_78K0R_Kx3__ | ||||
| 	#include "../../Source/portable/IAR/78K0R/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __IAR_78K0R_Kx3L__ | ||||
| 	#include "../../Source/portable/IAR/78K0R/portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* DEPRECATED_DEFINITIONS_H */ | ||||
|  | ||||
							
								
								
									
										757
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										757
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,757 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef EVENT_GROUPS_H | ||||
| #define EVENT_GROUPS_H | ||||
|  | ||||
| #ifndef INC_FREERTOS_H | ||||
| 	#error "include FreeRTOS.h" must appear in source files before "include event_groups.h" | ||||
| #endif | ||||
|  | ||||
| /* FreeRTOS includes. */ | ||||
| #include "timers.h" | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * An event group is a collection of bits to which an application can assign a | ||||
|  * meaning.  For example, an application may create an event group to convey | ||||
|  * the status of various CAN bus related events in which bit 0 might mean "A CAN | ||||
|  * message has been received and is ready for processing", bit 1 might mean "The | ||||
|  * application has queued a message that is ready for sending onto the CAN | ||||
|  * network", and bit 2 might mean "It is time to send a SYNC message onto the | ||||
|  * CAN network" etc.  A task can then test the bit values to see which events | ||||
|  * are active, and optionally enter the Blocked state to wait for a specified | ||||
|  * bit or a group of specified bits to be active.  To continue the CAN bus | ||||
|  * example, a CAN controlling task can enter the Blocked state (and therefore | ||||
|  * not consume any processing time) until either bit 0, bit 1 or bit 2 are | ||||
|  * active, at which time the bit that was actually active would inform the task | ||||
|  * which action it had to take (process a received message, send a message, or | ||||
|  * send a SYNC). | ||||
|  * | ||||
|  * The event groups implementation contains intelligence to avoid race | ||||
|  * conditions that would otherwise occur were an application to use a simple | ||||
|  * variable for the same purpose.  This is particularly important with respect | ||||
|  * to when a bit within an event group is to be cleared, and when bits have to | ||||
|  * be set and then tested atomically - as is the case where event groups are | ||||
|  * used to create a synchronisation point between multiple tasks (a | ||||
|  * 'rendezvous'). | ||||
|  * | ||||
|  * \defgroup EventGroup | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  * | ||||
|  * Type by which event groups are referenced.  For example, a call to | ||||
|  * xEventGroupCreate() returns an EventGroupHandle_t variable that can then | ||||
|  * be used as a parameter to other event group functions. | ||||
|  * | ||||
|  * \defgroup EventGroupHandle_t EventGroupHandle_t | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| struct EventGroupDef_t; | ||||
| typedef struct EventGroupDef_t * EventGroupHandle_t; | ||||
|  | ||||
| /* | ||||
|  * The type that holds event bits always matches TickType_t - therefore the | ||||
|  * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, | ||||
|  * 32 bits if set to 0. | ||||
|  * | ||||
|  * \defgroup EventBits_t EventBits_t | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| typedef TickType_t EventBits_t; | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
|  EventGroupHandle_t xEventGroupCreate( void ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Create a new event group. | ||||
|  * | ||||
|  * Internally, within the FreeRTOS implementation, event groups use a [small] | ||||
|  * block of memory, in which the event group's structure is stored.  If an event | ||||
|  * groups is created using xEventGropuCreate() then the required memory is | ||||
|  * automatically dynamically allocated inside the xEventGroupCreate() function. | ||||
|  * (see http://www.freertos.org/a00111.html).  If an event group is created | ||||
|  * using xEventGropuCreateStatic() then the application writer must instead | ||||
|  * provide the memory that will get used by the event group. | ||||
|  * xEventGroupCreateStatic() therefore allows an event group to be created | ||||
|  * without using any dynamic memory allocation. | ||||
|  * | ||||
|  * Although event groups are not related to ticks, for internal implementation | ||||
|  * reasons the number of bits available for use in an event group is dependent | ||||
|  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If | ||||
|  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit | ||||
|  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has | ||||
|  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store | ||||
|  * event bits within an event group. | ||||
|  * | ||||
|  * @return If the event group was created then a handle to the event group is | ||||
|  * returned.  If there was insufficient FreeRTOS heap available to create the | ||||
|  * event group then NULL is returned.  See http://www.freertos.org/a00111.html | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
| 	// Declare a variable to hold the created event group. | ||||
| 	EventGroupHandle_t xCreatedEventGroup; | ||||
|  | ||||
| 	// Attempt to create the event group. | ||||
| 	xCreatedEventGroup = xEventGroupCreate(); | ||||
|  | ||||
| 	// Was the event group created successfully? | ||||
| 	if( xCreatedEventGroup == NULL ) | ||||
| 	{ | ||||
| 		// The event group was not created because there was insufficient | ||||
| 		// FreeRTOS heap available. | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// The event group was created. | ||||
| 	} | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupCreate xEventGroupCreate | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) | ||||
| 	EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
|  EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Create a new event group. | ||||
|  * | ||||
|  * Internally, within the FreeRTOS implementation, event groups use a [small] | ||||
|  * block of memory, in which the event group's structure is stored.  If an event | ||||
|  * groups is created using xEventGropuCreate() then the required memory is | ||||
|  * automatically dynamically allocated inside the xEventGroupCreate() function. | ||||
|  * (see http://www.freertos.org/a00111.html).  If an event group is created | ||||
|  * using xEventGropuCreateStatic() then the application writer must instead | ||||
|  * provide the memory that will get used by the event group. | ||||
|  * xEventGroupCreateStatic() therefore allows an event group to be created | ||||
|  * without using any dynamic memory allocation. | ||||
|  * | ||||
|  * Although event groups are not related to ticks, for internal implementation | ||||
|  * reasons the number of bits available for use in an event group is dependent | ||||
|  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If | ||||
|  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit | ||||
|  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has | ||||
|  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store | ||||
|  * event bits within an event group. | ||||
|  * | ||||
|  * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type | ||||
|  * StaticEventGroup_t, which will be then be used to hold the event group's data | ||||
|  * structures, removing the need for the memory to be allocated dynamically. | ||||
|  * | ||||
|  * @return If the event group was created then a handle to the event group is | ||||
|  * returned.  If pxEventGroupBuffer was NULL then NULL is returned. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
| 	// StaticEventGroup_t is a publicly accessible structure that has the same | ||||
| 	// size and alignment requirements as the real event group structure.  It is | ||||
| 	// provided as a mechanism for applications to know the size of the event | ||||
| 	// group (which is dependent on the architecture and configuration file | ||||
| 	// settings) without breaking the strict data hiding policy by exposing the | ||||
| 	// real event group internals.  This StaticEventGroup_t variable is passed | ||||
| 	// into the xSemaphoreCreateEventGroupStatic() function and is used to store | ||||
| 	// the event group's data structures | ||||
| 	StaticEventGroup_t xEventGroupBuffer; | ||||
|  | ||||
| 	// Create the event group without dynamically allocating any memory. | ||||
| 	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); | ||||
|    </pre> | ||||
|  */ | ||||
| #if( configSUPPORT_STATIC_ALLOCATION == 1 ) | ||||
| 	EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup, | ||||
| 										const EventBits_t uxBitsToWaitFor, | ||||
| 										const BaseType_t xClearOnExit, | ||||
| 										const BaseType_t xWaitForAllBits, | ||||
| 										const TickType_t xTicksToWait ); | ||||
|  </pre> | ||||
|  * | ||||
|  * [Potentially] block to wait for one or more bits to be set within a | ||||
|  * previously created event group. | ||||
|  * | ||||
|  * This function cannot be called from an interrupt. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are being tested.  The | ||||
|  * event group must have previously been created using a call to | ||||
|  * xEventGroupCreate(). | ||||
|  * | ||||
|  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test | ||||
|  * inside the event group.  For example, to wait for bit 0 and/or bit 2 set | ||||
|  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set | ||||
|  * uxBitsToWaitFor to 0x07.  Etc. | ||||
|  * | ||||
|  * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within | ||||
|  * uxBitsToWaitFor that are set within the event group will be cleared before | ||||
|  * xEventGroupWaitBits() returns if the wait condition was met (if the function | ||||
|  * returns for a reason other than a timeout).  If xClearOnExit is set to | ||||
|  * pdFALSE then the bits set in the event group are not altered when the call to | ||||
|  * xEventGroupWaitBits() returns. | ||||
|  * | ||||
|  * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then | ||||
|  * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor | ||||
|  * are set or the specified block time expires.  If xWaitForAllBits is set to | ||||
|  * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set | ||||
|  * in uxBitsToWaitFor is set or the specified block time expires.  The block | ||||
|  * time is specified by the xTicksToWait parameter. | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait | ||||
|  * for one/all (depending on the xWaitForAllBits value) of the bits specified by | ||||
|  * uxBitsToWaitFor to become set. | ||||
|  * | ||||
|  * @return The value of the event group at the time either the bits being waited | ||||
|  * for became set, or the block time expired.  Test the return value to know | ||||
|  * which bits were set.  If xEventGroupWaitBits() returned because its timeout | ||||
|  * expired then not all the bits being waited for will be set.  If | ||||
|  * xEventGroupWaitBits() returned because the bits it was waiting for were set | ||||
|  * then the returned value is the event group value before any bits were | ||||
|  * automatically cleared in the case that xClearOnExit parameter was set to | ||||
|  * pdTRUE. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|    #define BIT_0	( 1 << 0 ) | ||||
|    #define BIT_4	( 1 << 4 ) | ||||
|  | ||||
|    void aFunction( EventGroupHandle_t xEventGroup ) | ||||
|    { | ||||
|    EventBits_t uxBits; | ||||
|    const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; | ||||
|  | ||||
| 		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within | ||||
| 		// the event group.  Clear the bits before exiting. | ||||
| 		uxBits = xEventGroupWaitBits( | ||||
| 					xEventGroup,	// The event group being tested. | ||||
| 					BIT_0 | BIT_4,	// The bits within the event group to wait for. | ||||
| 					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning. | ||||
| 					pdFALSE,		// Don't wait for both bits, either bit will do. | ||||
| 					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set. | ||||
|  | ||||
| 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | ||||
| 		{ | ||||
| 			// xEventGroupWaitBits() returned because both bits were set. | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_0 ) != 0 ) | ||||
| 		{ | ||||
| 			// xEventGroupWaitBits() returned because just BIT_0 was set. | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_4 ) != 0 ) | ||||
| 		{ | ||||
| 			// xEventGroupWaitBits() returned because just BIT_4 was set. | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// xEventGroupWaitBits() returned because xTicksToWait ticks passed | ||||
| 			// without either BIT_0 or BIT_4 becoming set. | ||||
| 		} | ||||
|    } | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupWaitBits xEventGroupWaitBits | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Clear bits within an event group.  This function cannot be called from an | ||||
|  * interrupt. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are to be cleared. | ||||
|  * | ||||
|  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear | ||||
|  * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to | ||||
|  * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09. | ||||
|  * | ||||
|  * @return The value of the event group before the specified bits were cleared. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|    #define BIT_0	( 1 << 0 ) | ||||
|    #define BIT_4	( 1 << 4 ) | ||||
|  | ||||
|    void aFunction( EventGroupHandle_t xEventGroup ) | ||||
|    { | ||||
|    EventBits_t uxBits; | ||||
|  | ||||
| 		// Clear bit 0 and bit 4 in xEventGroup. | ||||
| 		uxBits = xEventGroupClearBits( | ||||
| 								xEventGroup,	// The event group being updated. | ||||
| 								BIT_0 | BIT_4 );// The bits being cleared. | ||||
|  | ||||
| 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | ||||
| 		{ | ||||
| 			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was | ||||
| 			// called.  Both will now be clear (not set). | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_0 ) != 0 ) | ||||
| 		{ | ||||
| 			// Bit 0 was set before xEventGroupClearBits() was called.  It will | ||||
| 			// now be clear. | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_4 ) != 0 ) | ||||
| 		{ | ||||
| 			// Bit 4 was set before xEventGroupClearBits() was called.  It will | ||||
| 			// now be clear. | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Neither bit 0 nor bit 4 were set in the first place. | ||||
| 		} | ||||
|    } | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupClearBits xEventGroupClearBits | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); | ||||
|  </pre> | ||||
|  * | ||||
|  * A version of xEventGroupClearBits() that can be called from an interrupt. | ||||
|  * | ||||
|  * Setting bits in an event group is not a deterministic operation because there | ||||
|  * are an unknown number of tasks that may be waiting for the bit or bits being | ||||
|  * set.  FreeRTOS does not allow nondeterministic operations to be performed | ||||
|  * while interrupts are disabled, so protects event groups that are accessed | ||||
|  * from tasks by suspending the scheduler rather than disabling interrupts.  As | ||||
|  * a result event groups cannot be accessed directly from an interrupt service | ||||
|  * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the | ||||
|  * timer task to have the clear operation performed in the context of the timer | ||||
|  * task. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are to be cleared. | ||||
|  * | ||||
|  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. | ||||
|  * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3 | ||||
|  * and bit 0 set uxBitsToClear to 0x09. | ||||
|  * | ||||
|  * @return If the request to execute the function was posted successfully then | ||||
|  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned | ||||
|  * if the timer service queue was full. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|    #define BIT_0	( 1 << 0 ) | ||||
|    #define BIT_4	( 1 << 4 ) | ||||
|  | ||||
|    // An event group which it is assumed has already been created by a call to | ||||
|    // xEventGroupCreate(). | ||||
|    EventGroupHandle_t xEventGroup; | ||||
|  | ||||
|    void anInterruptHandler( void ) | ||||
|    { | ||||
| 		// Clear bit 0 and bit 4 in xEventGroup. | ||||
| 		xResult = xEventGroupClearBitsFromISR( | ||||
| 							xEventGroup,	 // The event group being updated. | ||||
| 							BIT_0 | BIT_4 ); // The bits being set. | ||||
|  | ||||
| 		if( xResult == pdPASS ) | ||||
| 		{ | ||||
| 			// The message was posted successfully. | ||||
| 		} | ||||
|   } | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| #if( configUSE_TRACE_FACILITY == 1 ) | ||||
| 	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; | ||||
| #else | ||||
| 	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Set bits within an event group. | ||||
|  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR() | ||||
|  * is a version that can be called from an interrupt. | ||||
|  * | ||||
|  * Setting bits in an event group will automatically unblock tasks that are | ||||
|  * blocked waiting for the bits. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are to be set. | ||||
|  * | ||||
|  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. | ||||
|  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3 | ||||
|  * and bit 0 set uxBitsToSet to 0x09. | ||||
|  * | ||||
|  * @return The value of the event group at the time the call to | ||||
|  * xEventGroupSetBits() returns.  There are two reasons why the returned value | ||||
|  * might have the bits specified by the uxBitsToSet parameter cleared.  First, | ||||
|  * if setting a bit results in a task that was waiting for the bit leaving the | ||||
|  * blocked state then it is possible the bit will be cleared automatically | ||||
|  * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any | ||||
|  * unblocked (or otherwise Ready state) task that has a priority above that of | ||||
|  * the task that called xEventGroupSetBits() will execute and may change the | ||||
|  * event group value before the call to xEventGroupSetBits() returns. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|    #define BIT_0	( 1 << 0 ) | ||||
|    #define BIT_4	( 1 << 4 ) | ||||
|  | ||||
|    void aFunction( EventGroupHandle_t xEventGroup ) | ||||
|    { | ||||
|    EventBits_t uxBits; | ||||
|  | ||||
| 		// Set bit 0 and bit 4 in xEventGroup. | ||||
| 		uxBits = xEventGroupSetBits( | ||||
| 							xEventGroup,	// The event group being updated. | ||||
| 							BIT_0 | BIT_4 );// The bits being set. | ||||
|  | ||||
| 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | ||||
| 		{ | ||||
| 			// Both bit 0 and bit 4 remained set when the function returned. | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_0 ) != 0 ) | ||||
| 		{ | ||||
| 			// Bit 0 remained set when the function returned, but bit 4 was | ||||
| 			// cleared.  It might be that bit 4 was cleared automatically as a | ||||
| 			// task that was waiting for bit 4 was removed from the Blocked | ||||
| 			// state. | ||||
| 		} | ||||
| 		else if( ( uxBits & BIT_4 ) != 0 ) | ||||
| 		{ | ||||
| 			// Bit 4 remained set when the function returned, but bit 0 was | ||||
| 			// cleared.  It might be that bit 0 was cleared automatically as a | ||||
| 			// task that was waiting for bit 0 was removed from the Blocked | ||||
| 			// state. | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Neither bit 0 nor bit 4 remained set.  It might be that a task | ||||
| 			// was waiting for both of the bits to be set, and the bits were | ||||
| 			// cleared as the task left the Blocked state. | ||||
| 		} | ||||
|    } | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupSetBits xEventGroupSetBits | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); | ||||
|  </pre> | ||||
|  * | ||||
|  * A version of xEventGroupSetBits() that can be called from an interrupt. | ||||
|  * | ||||
|  * Setting bits in an event group is not a deterministic operation because there | ||||
|  * are an unknown number of tasks that may be waiting for the bit or bits being | ||||
|  * set.  FreeRTOS does not allow nondeterministic operations to be performed in | ||||
|  * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR() | ||||
|  * sends a message to the timer task to have the set operation performed in the | ||||
|  * context of the timer task - where a scheduler lock is used in place of a | ||||
|  * critical section. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are to be set. | ||||
|  * | ||||
|  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. | ||||
|  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3 | ||||
|  * and bit 0 set uxBitsToSet to 0x09. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken As mentioned above, calling this function | ||||
|  * will result in a message being sent to the timer daemon task.  If the | ||||
|  * priority of the timer daemon task is higher than the priority of the | ||||
|  * currently running task (the task the interrupt interrupted) then | ||||
|  * *pxHigherPriorityTaskWoken will be set to pdTRUE by | ||||
|  * xEventGroupSetBitsFromISR(), indicating that a context switch should be | ||||
|  * requested before the interrupt exits.  For that reason | ||||
|  * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the | ||||
|  * example code below. | ||||
|  * | ||||
|  * @return If the request to execute the function was posted successfully then | ||||
|  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned | ||||
|  * if the timer service queue was full. | ||||
|  * | ||||
|  * Example usage: | ||||
|    <pre> | ||||
|    #define BIT_0	( 1 << 0 ) | ||||
|    #define BIT_4	( 1 << 4 ) | ||||
|  | ||||
|    // An event group which it is assumed has already been created by a call to | ||||
|    // xEventGroupCreate(). | ||||
|    EventGroupHandle_t xEventGroup; | ||||
|  | ||||
|    void anInterruptHandler( void ) | ||||
|    { | ||||
|    BaseType_t xHigherPriorityTaskWoken, xResult; | ||||
|  | ||||
| 		// xHigherPriorityTaskWoken must be initialised to pdFALSE. | ||||
| 		xHigherPriorityTaskWoken = pdFALSE; | ||||
|  | ||||
| 		// Set bit 0 and bit 4 in xEventGroup. | ||||
| 		xResult = xEventGroupSetBitsFromISR( | ||||
| 							xEventGroup,	// The event group being updated. | ||||
| 							BIT_0 | BIT_4   // The bits being set. | ||||
| 							&xHigherPriorityTaskWoken ); | ||||
|  | ||||
| 		// Was the message posted successfully? | ||||
| 		if( xResult == pdPASS ) | ||||
| 		{ | ||||
| 			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context | ||||
| 			// switch should be requested.  The macro used is port specific and | ||||
| 			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - | ||||
| 			// refer to the documentation page for the port being used. | ||||
| 			portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | ||||
| 		} | ||||
|   } | ||||
|    </pre> | ||||
|  * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| #if( configUSE_TRACE_FACILITY == 1 ) | ||||
| 	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | ||||
| #else | ||||
| 	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup, | ||||
| 									const EventBits_t uxBitsToSet, | ||||
| 									const EventBits_t uxBitsToWaitFor, | ||||
| 									TickType_t xTicksToWait ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Atomically set bits within an event group, then wait for a combination of | ||||
|  * bits to be set within the same event group.  This functionality is typically | ||||
|  * used to synchronise multiple tasks, where each task has to wait for the other | ||||
|  * tasks to reach a synchronisation point before proceeding. | ||||
|  * | ||||
|  * This function cannot be used from an interrupt. | ||||
|  * | ||||
|  * The function will return before its block time expires if the bits specified | ||||
|  * by the uxBitsToWait parameter are set, or become set within that time.  In | ||||
|  * this case all the bits specified by uxBitsToWait will be automatically | ||||
|  * cleared before the function returns. | ||||
|  * | ||||
|  * @param xEventGroup The event group in which the bits are being tested.  The | ||||
|  * event group must have previously been created using a call to | ||||
|  * xEventGroupCreate(). | ||||
|  * | ||||
|  * @param uxBitsToSet The bits to set in the event group before determining | ||||
|  * if, and possibly waiting for, all the bits specified by the uxBitsToWait | ||||
|  * parameter are set. | ||||
|  * | ||||
|  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test | ||||
|  * inside the event group.  For example, to wait for bit 0 and bit 2 set | ||||
|  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set | ||||
|  * uxBitsToWaitFor to 0x07.  Etc. | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait | ||||
|  * for all of the bits specified by uxBitsToWaitFor to become set. | ||||
|  * | ||||
|  * @return The value of the event group at the time either the bits being waited | ||||
|  * for became set, or the block time expired.  Test the return value to know | ||||
|  * which bits were set.  If xEventGroupSync() returned because its timeout | ||||
|  * expired then not all the bits being waited for will be set.  If | ||||
|  * xEventGroupSync() returned because all the bits it was waiting for were | ||||
|  * set then the returned value is the event group value before any bits were | ||||
|  * automatically cleared. | ||||
|  * | ||||
|  * Example usage: | ||||
|  <pre> | ||||
|  // Bits used by the three tasks. | ||||
|  #define TASK_0_BIT		( 1 << 0 ) | ||||
|  #define TASK_1_BIT		( 1 << 1 ) | ||||
|  #define TASK_2_BIT		( 1 << 2 ) | ||||
|  | ||||
|  #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) | ||||
|  | ||||
|  // Use an event group to synchronise three tasks.  It is assumed this event | ||||
|  // group has already been created elsewhere. | ||||
|  EventGroupHandle_t xEventBits; | ||||
|  | ||||
|  void vTask0( void *pvParameters ) | ||||
|  { | ||||
|  EventBits_t uxReturn; | ||||
|  TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; | ||||
|  | ||||
| 	 for( ;; ) | ||||
| 	 { | ||||
| 		// Perform task functionality here. | ||||
|  | ||||
| 		// Set bit 0 in the event flag to note this task has reached the | ||||
| 		// sync point.  The other two tasks will set the other two bits defined | ||||
| 		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation | ||||
| 		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms | ||||
| 		// for this to happen. | ||||
| 		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); | ||||
|  | ||||
| 		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) | ||||
| 		{ | ||||
| 			// All three tasks reached the synchronisation point before the call | ||||
| 			// to xEventGroupSync() timed out. | ||||
| 		} | ||||
| 	} | ||||
|  } | ||||
|  | ||||
|  void vTask1( void *pvParameters ) | ||||
|  { | ||||
| 	 for( ;; ) | ||||
| 	 { | ||||
| 		// Perform task functionality here. | ||||
|  | ||||
| 		// Set bit 1 in the event flag to note this task has reached the | ||||
| 		// synchronisation point.  The other two tasks will set the other two | ||||
| 		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the | ||||
| 		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait | ||||
| 		// indefinitely for this to happen. | ||||
| 		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); | ||||
|  | ||||
| 		// xEventGroupSync() was called with an indefinite block time, so | ||||
| 		// this task will only reach here if the syncrhonisation was made by all | ||||
| 		// three tasks, so there is no need to test the return value. | ||||
| 	 } | ||||
|  } | ||||
|  | ||||
|  void vTask2( void *pvParameters ) | ||||
|  { | ||||
| 	 for( ;; ) | ||||
| 	 { | ||||
| 		// Perform task functionality here. | ||||
|  | ||||
| 		// Set bit 2 in the event flag to note this task has reached the | ||||
| 		// synchronisation point.  The other two tasks will set the other two | ||||
| 		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the | ||||
| 		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait | ||||
| 		// indefinitely for this to happen. | ||||
| 		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); | ||||
|  | ||||
| 		// xEventGroupSync() was called with an indefinite block time, so | ||||
| 		// this task will only reach here if the syncrhonisation was made by all | ||||
| 		// three tasks, so there is no need to test the return value. | ||||
| 	} | ||||
|  } | ||||
|  | ||||
|  </pre> | ||||
|  * \defgroup xEventGroupSync xEventGroupSync | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Returns the current value of the bits in an event group.  This function | ||||
|  * cannot be used from an interrupt. | ||||
|  * | ||||
|  * @param xEventGroup The event group being queried. | ||||
|  * | ||||
|  * @return The event group bits at the time xEventGroupGetBits() was called. | ||||
|  * | ||||
|  * \defgroup xEventGroupGetBits xEventGroupGetBits | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); | ||||
|  </pre> | ||||
|  * | ||||
|  * A version of xEventGroupGetBits() that can be called from an ISR. | ||||
|  * | ||||
|  * @param xEventGroup The event group being queried. | ||||
|  * | ||||
|  * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. | ||||
|  * | ||||
|  * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR | ||||
|  * \ingroup EventGroup | ||||
|  */ | ||||
| EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * event_groups.h | ||||
|  *<pre> | ||||
| 	void xEventGroupDelete( EventGroupHandle_t xEventGroup ); | ||||
|  </pre> | ||||
|  * | ||||
|  * Delete an event group that was previously created by a call to | ||||
|  * xEventGroupCreate().  Tasks that are blocked on the event group will be | ||||
|  * unblocked and obtain 0 as the event group's value. | ||||
|  * | ||||
|  * @param xEventGroup The event group being deleted. | ||||
|  */ | ||||
| void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* For internal use only. */ | ||||
| void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; | ||||
| void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
|  | ||||
| #if (configUSE_TRACE_FACILITY == 1) | ||||
| 	UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; | ||||
| 	void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; | ||||
| #endif | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif /* EVENT_GROUPS_H */ | ||||
|  | ||||
|  | ||||
							
								
								
									
										412
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/list.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/list.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,412 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * This is the list implementation used by the scheduler.  While it is tailored | ||||
|  * heavily for the schedulers needs, it is also available for use by | ||||
|  * application code. | ||||
|  * | ||||
|  * list_ts can only store pointers to list_item_ts.  Each ListItem_t contains a | ||||
|  * numeric value (xItemValue).  Most of the time the lists are sorted in | ||||
|  * descending item value order. | ||||
|  * | ||||
|  * Lists are created already containing one list item.  The value of this | ||||
|  * item is the maximum possible that can be stored, it is therefore always at | ||||
|  * the end of the list and acts as a marker.  The list member pxHead always | ||||
|  * points to this marker - even though it is at the tail of the list.  This | ||||
|  * is because the tail contains a wrap back pointer to the true head of | ||||
|  * the list. | ||||
|  * | ||||
|  * In addition to it's value, each list item contains a pointer to the next | ||||
|  * item in the list (pxNext), a pointer to the list it is in (pxContainer) | ||||
|  * and a pointer to back to the object that contains it.  These later two | ||||
|  * pointers are included for efficiency of list manipulation.  There is | ||||
|  * effectively a two way link between the object containing the list item and | ||||
|  * the list item itself. | ||||
|  * | ||||
|  * | ||||
|  * \page ListIntroduction List Implementation | ||||
|  * \ingroup FreeRTOSIntro | ||||
|  */ | ||||
|  | ||||
| #ifndef INC_FREERTOS_H | ||||
| 	#error FreeRTOS.h must be included before list.h | ||||
| #endif | ||||
|  | ||||
| #ifndef LIST_H | ||||
| #define LIST_H | ||||
|  | ||||
| /* | ||||
|  * The list structure members are modified from within interrupts, and therefore | ||||
|  * by rights should be declared volatile.  However, they are only modified in a | ||||
|  * functionally atomic way (within critical sections of with the scheduler | ||||
|  * suspended) and are either passed by reference into a function or indexed via | ||||
|  * a volatile variable.  Therefore, in all use cases tested so far, the volatile | ||||
|  * qualifier can be omitted in order to provide a moderate performance | ||||
|  * improvement without adversely affecting functional behaviour.  The assembly | ||||
|  * instructions generated by the IAR, ARM and GCC compilers when the respective | ||||
|  * compiler's options were set for maximum optimisation has been inspected and | ||||
|  * deemed to be as intended.  That said, as compiler technology advances, and | ||||
|  * especially if aggressive cross module optimisation is used (a use case that | ||||
|  * has not been exercised to any great extend) then it is feasible that the | ||||
|  * volatile qualifier will be needed for correct optimisation.  It is expected | ||||
|  * that a compiler removing essential code because, without the volatile | ||||
|  * qualifier on the list structure members and with aggressive cross module | ||||
|  * optimisation, the compiler deemed the code unnecessary will result in | ||||
|  * complete and obvious failure of the scheduler.  If this is ever experienced | ||||
|  * then the volatile qualifier can be inserted in the relevant places within the | ||||
|  * list structures by simply defining configLIST_VOLATILE to volatile in | ||||
|  * FreeRTOSConfig.h (as per the example at the bottom of this comment block). | ||||
|  * If configLIST_VOLATILE is not defined then the preprocessor directives below | ||||
|  * will simply #define configLIST_VOLATILE away completely. | ||||
|  * | ||||
|  * To use volatile list structure members then add the following line to | ||||
|  * FreeRTOSConfig.h (without the quotes): | ||||
|  * "#define configLIST_VOLATILE volatile" | ||||
|  */ | ||||
| #ifndef configLIST_VOLATILE | ||||
| 	#define configLIST_VOLATILE | ||||
| #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /* Macros that can be used to place known values within the list structures, | ||||
| then check that the known values do not get corrupted during the execution of | ||||
| the application.   These may catch the list data structures being overwritten in | ||||
| memory.  They will not catch data errors caused by incorrect configuration or | ||||
| use of FreeRTOS.*/ | ||||
| #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) | ||||
| 	/* Define the macros to do nothing. */ | ||||
| 	#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE | ||||
| 	#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE | ||||
| 	#define listFIRST_LIST_INTEGRITY_CHECK_VALUE | ||||
| 	#define listSECOND_LIST_INTEGRITY_CHECK_VALUE | ||||
| 	#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) | ||||
| 	#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) | ||||
| 	#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) | ||||
| 	#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) | ||||
| 	#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) | ||||
| 	#define listTEST_LIST_INTEGRITY( pxList ) | ||||
| #else | ||||
| 	/* Define macros that add new members into the list structures. */ | ||||
| 	#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE				TickType_t xListItemIntegrityValue1; | ||||
| 	#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE				TickType_t xListItemIntegrityValue2; | ||||
| 	#define listFIRST_LIST_INTEGRITY_CHECK_VALUE					TickType_t xListIntegrityValue1; | ||||
| 	#define listSECOND_LIST_INTEGRITY_CHECK_VALUE					TickType_t xListIntegrityValue2; | ||||
|  | ||||
| 	/* Define macros that set the new structure members to known values. */ | ||||
| 	#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )		( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE | ||||
| 	#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )	( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE | ||||
| 	#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )		( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE | ||||
| 	#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )		( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE | ||||
|  | ||||
| 	/* Define macros that will assert if one of the structure members does not | ||||
| 	contain its expected value. */ | ||||
| 	#define listTEST_LIST_ITEM_INTEGRITY( pxItem )		configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) | ||||
| 	#define listTEST_LIST_INTEGRITY( pxList )			configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) | ||||
| #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Definition of the only type of object that a list can contain. | ||||
|  */ | ||||
| struct xLIST; | ||||
| struct xLIST_ITEM | ||||
| { | ||||
| 	listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| 	configLIST_VOLATILE TickType_t xItemValue;			/*< The value being listed.  In most cases this is used to sort the list in descending order. */ | ||||
| 	struct xLIST_ITEM * configLIST_VOLATILE pxNext;		/*< Pointer to the next ListItem_t in the list. */ | ||||
| 	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;	/*< Pointer to the previous ListItem_t in the list. */ | ||||
| 	void * pvOwner;										/*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */ | ||||
| 	struct xLIST * configLIST_VOLATILE pxContainer;		/*< Pointer to the list in which this list item is placed (if any). */ | ||||
| 	listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| }; | ||||
| typedef struct xLIST_ITEM ListItem_t;					/* For some reason lint wants this as two separate definitions. */ | ||||
|  | ||||
| struct xMINI_LIST_ITEM | ||||
| { | ||||
| 	listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| 	configLIST_VOLATILE TickType_t xItemValue; | ||||
| 	struct xLIST_ITEM * configLIST_VOLATILE pxNext; | ||||
| 	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; | ||||
| }; | ||||
| typedef struct xMINI_LIST_ITEM MiniListItem_t; | ||||
|  | ||||
| /* | ||||
|  * Definition of the type of queue used by the scheduler. | ||||
|  */ | ||||
| typedef struct xLIST | ||||
| { | ||||
| 	listFIRST_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| 	volatile UBaseType_t uxNumberOfItems; | ||||
| 	ListItem_t * configLIST_VOLATILE pxIndex;			/*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ | ||||
| 	MiniListItem_t xListEnd;							/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ | ||||
| 	listSECOND_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| } List_t; | ||||
|  | ||||
| /* | ||||
|  * Access macro to set the owner of a list item.  The owner of a list item | ||||
|  * is the object (usually a TCB) that contains the list item. | ||||
|  * | ||||
|  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )		( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to get the owner of a list item.  The owner of a list item | ||||
|  * is the object (usually a TCB) that contains the list item. | ||||
|  * | ||||
|  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_LIST_ITEM_OWNER( pxListItem )	( ( pxListItem )->pvOwner ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to set the value of the list item.  In most cases the value is | ||||
|  * used to sort the list in descending order. | ||||
|  * | ||||
|  * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listSET_LIST_ITEM_VALUE( pxListItem, xValue )	( ( pxListItem )->xItemValue = ( xValue ) ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to retrieve the value of the list item.  The value can | ||||
|  * represent anything - for example the priority of a task, or the time at | ||||
|  * which a task should be unblocked. | ||||
|  * | ||||
|  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_LIST_ITEM_VALUE( pxListItem )	( ( pxListItem )->xItemValue ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to retrieve the value of the list item at the head of a given | ||||
|  * list. | ||||
|  * | ||||
|  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext->xItemValue ) | ||||
|  | ||||
| /* | ||||
|  * Return the list item at the head of the list. | ||||
|  * | ||||
|  * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext ) | ||||
|  | ||||
| /* | ||||
|  * Return the list item at the head of the list. | ||||
|  * | ||||
|  * \page listGET_NEXT listGET_NEXT | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_NEXT( pxListItem )	( ( pxListItem )->pxNext ) | ||||
|  | ||||
| /* | ||||
|  * Return the list item that marks the end of the list | ||||
|  * | ||||
|  * \page listGET_END_MARKER listGET_END_MARKER | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_END_MARKER( pxList )	( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to determine if a list contains any items.  The macro will | ||||
|  * only have the value true if the list is empty. | ||||
|  * | ||||
|  * \page listLIST_IS_EMPTY listLIST_IS_EMPTY | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listLIST_IS_EMPTY( pxList )	( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) | ||||
|  | ||||
| /* | ||||
|  * Access macro to return the number of items in the list. | ||||
|  */ | ||||
| #define listCURRENT_LIST_LENGTH( pxList )	( ( pxList )->uxNumberOfItems ) | ||||
|  | ||||
| /* | ||||
|  * Access function to obtain the owner of the next entry in a list. | ||||
|  * | ||||
|  * The list member pxIndex is used to walk through a list.  Calling | ||||
|  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list | ||||
|  * and returns that entry's pxOwner parameter.  Using multiple calls to this | ||||
|  * function it is therefore possible to move through every item contained in | ||||
|  * a list. | ||||
|  * | ||||
|  * The pxOwner parameter of a list item is a pointer to the object that owns | ||||
|  * the list item.  In the scheduler this is normally a task control block. | ||||
|  * The pxOwner parameter effectively creates a two way link between the list | ||||
|  * item and its owner. | ||||
|  * | ||||
|  * @param pxTCB pxTCB is set to the address of the owner of the next list item. | ||||
|  * @param pxList The list from which the next item owner is to be returned. | ||||
|  * | ||||
|  * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\ | ||||
| {																							\ | ||||
| List_t * const pxConstList = ( pxList );													\ | ||||
| 	/* Increment the index to the next item and return the item, ensuring */				\ | ||||
| 	/* we don't return the marker used at the end of the list.  */							\ | ||||
| 	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;							\ | ||||
| 	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\ | ||||
| 	{																						\ | ||||
| 		( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\ | ||||
| 	}																						\ | ||||
| 	( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;											\ | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Access function to obtain the owner of the first entry in a list.  Lists | ||||
|  * are normally sorted in ascending item value order. | ||||
|  * | ||||
|  * This function returns the pxOwner member of the first item in the list. | ||||
|  * The pxOwner parameter of a list item is a pointer to the object that owns | ||||
|  * the list item.  In the scheduler this is normally a task control block. | ||||
|  * The pxOwner parameter effectively creates a two way link between the list | ||||
|  * item and its owner. | ||||
|  * | ||||
|  * @param pxList The list from which the owner of the head item is to be | ||||
|  * returned. | ||||
|  * | ||||
|  * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| #define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) | ||||
|  | ||||
| /* | ||||
|  * Check to see if a list item is within a list.  The list item maintains a | ||||
|  * "container" pointer that points to the list it is in.  All this macro does | ||||
|  * is check to see if the container and the list match. | ||||
|  * | ||||
|  * @param pxList The list we want to know if the list item is within. | ||||
|  * @param pxListItem The list item we want to know if is in the list. | ||||
|  * @return pdTRUE if the list item is in the list, otherwise pdFALSE. | ||||
|  */ | ||||
| #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) | ||||
|  | ||||
| /* | ||||
|  * Return the list a list item is contained within (referenced from). | ||||
|  * | ||||
|  * @param pxListItem The list item being queried. | ||||
|  * @return A pointer to the List_t object that references the pxListItem | ||||
|  */ | ||||
| #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) | ||||
|  | ||||
| /* | ||||
|  * This provides a crude means of knowing if a list has been initialised, as | ||||
|  * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() | ||||
|  * function. | ||||
|  */ | ||||
| #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) | ||||
|  | ||||
| /* | ||||
|  * Must be called before a list is used!  This initialises all the members | ||||
|  * of the list structure and inserts the xListEnd item into the list as a | ||||
|  * marker to the back of the list. | ||||
|  * | ||||
|  * @param pxList Pointer to the list being initialised. | ||||
|  * | ||||
|  * \page vListInitialise vListInitialise | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Must be called before a list item is used.  This sets the list container to | ||||
|  * null so the item does not think that it is already contained in a list. | ||||
|  * | ||||
|  * @param pxItem Pointer to the list item being initialised. | ||||
|  * | ||||
|  * \page vListInitialiseItem vListInitialiseItem | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Insert a list item into a list.  The item will be inserted into the list in | ||||
|  * a position determined by its item value (descending item value order). | ||||
|  * | ||||
|  * @param pxList The list into which the item is to be inserted. | ||||
|  * | ||||
|  * @param pxNewListItem The item that is to be placed in the list. | ||||
|  * | ||||
|  * \page vListInsert vListInsert | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Insert a list item into a list.  The item will be inserted in a position | ||||
|  * such that it will be the last item within the list returned by multiple | ||||
|  * calls to listGET_OWNER_OF_NEXT_ENTRY. | ||||
|  * | ||||
|  * The list member pxIndex is used to walk through a list.  Calling | ||||
|  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. | ||||
|  * Placing an item in a list using vListInsertEnd effectively places the item | ||||
|  * in the list position pointed to by pxIndex.  This means that every other | ||||
|  * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before | ||||
|  * the pxIndex parameter again points to the item being inserted. | ||||
|  * | ||||
|  * @param pxList The list into which the item is to be inserted. | ||||
|  * | ||||
|  * @param pxNewListItem The list item to be inserted into the list. | ||||
|  * | ||||
|  * \page vListInsertEnd vListInsertEnd | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Remove an item from a list.  The list item has a pointer to the list that | ||||
|  * it is in, so only the list item need be passed into the function. | ||||
|  * | ||||
|  * @param uxListRemove The item to be removed.  The item will remove itself from | ||||
|  * the list pointed to by it's pxContainer parameter. | ||||
|  * | ||||
|  * @return The number of items that remain in the list after the list item has | ||||
|  * been removed. | ||||
|  * | ||||
|  * \page uxListRemove uxListRemove | ||||
|  * \ingroup LinkedList | ||||
|  */ | ||||
| UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										799
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										799
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,799 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Message buffers build functionality on top of FreeRTOS stream buffers. | ||||
|  * Whereas stream buffers are used to send a continuous stream of data from one | ||||
|  * task or interrupt to another, message buffers are used to send variable | ||||
|  * length discrete messages from one task or interrupt to another.  Their | ||||
|  * implementation is light weight, making them particularly suited for interrupt | ||||
|  * to task and core to core communication scenarios. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xMessageBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xMessageBufferRead()) inside a critical section and set the receive | ||||
|  * timeout to 0. | ||||
|  * | ||||
|  * Message buffers hold variable length messages.  To enable that, when a | ||||
|  * message is written to the message buffer an additional sizeof( size_t ) bytes | ||||
|  * are also written to store the message's length (that happens internally, with | ||||
|  * the API function).  sizeof( size_t ) is typically 4 bytes on a 32-bit | ||||
|  * architecture, so writing a 10 byte message to a message buffer on a 32-bit | ||||
|  * architecture will actually reduce the available space in the message buffer | ||||
|  * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length | ||||
|  * of the message). | ||||
|  */ | ||||
|  | ||||
| #ifndef FREERTOS_MESSAGE_BUFFER_H | ||||
| #define FREERTOS_MESSAGE_BUFFER_H | ||||
|  | ||||
| /* Message buffers are built onto of stream buffers. */ | ||||
| #include "stream_buffer.h" | ||||
|  | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Type by which message buffers are referenced.  For example, a call to | ||||
|  * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can | ||||
|  * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), | ||||
|  * etc. | ||||
|  */ | ||||
| typedef void * MessageBufferHandle_t; | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes ); | ||||
| </pre> | ||||
|  * | ||||
|  * Creates a new message buffer using dynamically allocated memory.  See | ||||
|  * xMessageBufferCreateStatic() for a version that uses statically allocated | ||||
|  * memory (memory that is allocated at compile time). | ||||
|  * | ||||
|  * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in | ||||
|  * FreeRTOSConfig.h for xMessageBufferCreate() to be available. | ||||
|  * | ||||
|  * @param xBufferSizeBytes The total number of bytes (not messages) the message | ||||
|  * buffer will be able to hold at any one time.  When a message is written to | ||||
|  * the message buffer an additional sizeof( size_t ) bytes are also written to | ||||
|  * store the message's length.  sizeof( size_t ) is typically 4 bytes on a | ||||
|  * 32-bit architecture, so on most 32-bit architectures a 10 byte message will | ||||
|  * take up 14 bytes of message buffer space. | ||||
|  * | ||||
|  * @return If NULL is returned, then the message buffer cannot be created | ||||
|  * because there is insufficient heap memory available for FreeRTOS to allocate | ||||
|  * the message buffer data structures and storage area.  A non-NULL value being | ||||
|  * returned indicates that the message buffer has been created successfully - | ||||
|  * the returned value should be stored as the handle to the created message | ||||
|  * buffer. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
|  | ||||
| void vAFunction( void ) | ||||
| { | ||||
| MessageBufferHandle_t xMessageBuffer; | ||||
| const size_t xMessageBufferSizeBytes = 100; | ||||
|  | ||||
|     // Create a message buffer that can hold 100 bytes.  The memory used to hold | ||||
|     // both the message buffer structure and the messages themselves is allocated | ||||
|     // dynamically.  Each message added to the buffer consumes an additional 4 | ||||
|     // bytes which are used to hold the lengh of the message. | ||||
|     xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); | ||||
|  | ||||
|     if( xMessageBuffer == NULL ) | ||||
|     { | ||||
|         // There was not enough heap memory space available to create the | ||||
|         // message buffer. | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // The message buffer was created successfully and can now be used. | ||||
|     } | ||||
|  | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferCreate xMessageBufferCreate | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, | ||||
|                                                   uint8_t *pucMessageBufferStorageArea, | ||||
|                                                   StaticMessageBuffer_t *pxStaticMessageBuffer ); | ||||
| </pre> | ||||
|  * Creates a new message buffer using statically allocated memory.  See | ||||
|  * xMessageBufferCreate() for a version that uses dynamically allocated memory. | ||||
|  * | ||||
|  * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the | ||||
|  * pucMessageBufferStorageArea parameter.  When a message is written to the | ||||
|  * message buffer an additional sizeof( size_t ) bytes are also written to store | ||||
|  * the message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit | ||||
|  * architecture, so on most 32-bit architecture a 10 byte message will take up | ||||
|  * 14 bytes of message buffer space.  The maximum number of bytes that can be | ||||
|  * stored in the message buffer is actually (xBufferSizeBytes - 1). | ||||
|  * | ||||
|  * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at | ||||
|  * least xBufferSizeBytes + 1 big.  This is the array to which messages are | ||||
|  * copied when they are written to the message buffer. | ||||
|  * | ||||
|  * @param pxStaticMessageBuffer Must point to a variable of type | ||||
|  * StaticMessageBuffer_t, which will be used to hold the message buffer's data | ||||
|  * structure. | ||||
|  * | ||||
|  * @return If the message buffer is created successfully then a handle to the | ||||
|  * created message buffer is returned. If either pucMessageBufferStorageArea or | ||||
|  * pxStaticmessageBuffer are NULL then NULL is returned. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
|  | ||||
| // Used to dimension the array used to hold the messages.  The available space | ||||
| // will actually be one less than this, so 999. | ||||
| #define STORAGE_SIZE_BYTES 1000 | ||||
|  | ||||
| // Defines the memory that will actually hold the messages within the message | ||||
| // buffer. | ||||
| static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; | ||||
|  | ||||
| // The variable used to hold the message buffer structure. | ||||
| StaticMessageBuffer_t xMessageBufferStruct; | ||||
|  | ||||
| void MyFunction( void ) | ||||
| { | ||||
| MessageBufferHandle_t xMessageBuffer; | ||||
|  | ||||
|     xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ), | ||||
|                                                  ucBufferStorage, | ||||
|                                                  &xMessageBufferStruct ); | ||||
|  | ||||
|     // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer | ||||
|     // parameters were NULL, xMessageBuffer will not be NULL, and can be used to | ||||
|     // reference the created message buffer in other message buffer API calls. | ||||
|  | ||||
|     // Other code that uses the message buffer can go here. | ||||
| } | ||||
|  | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, | ||||
|                            const void *pvTxData, | ||||
|                            size_t xDataLengthBytes, | ||||
|                            TickType_t xTicksToWait ); | ||||
| <pre> | ||||
|  * | ||||
|  * Sends a discrete message to the message buffer.  The message can be any | ||||
|  * length that fits within the buffer's free space, and is copied into the | ||||
|  * buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xMessageBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xMessageBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xMessageBufferSend() to write to a message buffer from a task.  Use | ||||
|  * xMessageBufferSendFromISR() to write to a message buffer from an interrupt | ||||
|  * service routine (ISR). | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer to which a message is | ||||
|  * being sent. | ||||
|  * | ||||
|  * @param pvTxData A pointer to the message that is to be copied into the | ||||
|  * message buffer. | ||||
|  * | ||||
|  * @param xDataLengthBytes The length of the message.  That is, the number of | ||||
|  * bytes to copy from pvTxData into the message buffer.  When a message is | ||||
|  * written to the message buffer an additional sizeof( size_t ) bytes are also | ||||
|  * written to store the message's length.  sizeof( size_t ) is typically 4 bytes | ||||
|  * on a 32-bit architecture, so on most 32-bit architecture setting | ||||
|  * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 | ||||
|  * bytes (20 bytes of message data and 4 bytes to hold the message length). | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time the calling task should remain | ||||
|  * in the Blocked state to wait for enough space to become available in the | ||||
|  * message buffer, should the message buffer have insufficient space when | ||||
|  * xMessageBufferSend() is called.  The calling task will never block if | ||||
|  * xTicksToWait is zero.  The block time is specified in tick periods, so the | ||||
|  * absolute time it represents is dependent on the tick frequency.  The macro | ||||
|  * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into | ||||
|  * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause | ||||
|  * the task to wait indefinitely (without timing out), provided | ||||
|  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any | ||||
|  * CPU time when they are in the Blocked state. | ||||
|  * | ||||
|  * @return The number of bytes written to the message buffer.  If the call to | ||||
|  * xMessageBufferSend() times out before there was enough space to write the | ||||
|  * message into the message buffer then zero is returned.  If the call did not | ||||
|  * time out then xDataLengthBytes is returned. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| void vAFunction( MessageBufferHandle_t xMessageBuffer ) | ||||
| { | ||||
| size_t xBytesSent; | ||||
| uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; | ||||
| char *pcStringToSend = "String to send"; | ||||
| const TickType_t x100ms = pdMS_TO_TICKS( 100 ); | ||||
|  | ||||
|     // Send an array to the message buffer, blocking for a maximum of 100ms to | ||||
|     // wait for enough space to be available in the message buffer. | ||||
|     xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); | ||||
|  | ||||
|     if( xBytesSent != sizeof( ucArrayToSend ) ) | ||||
|     { | ||||
|         // The call to xMessageBufferSend() times out before there was enough | ||||
|         // space in the buffer for the data to be written. | ||||
|     } | ||||
|  | ||||
|     // Send the string to the message buffer.  Return immediately if there is | ||||
|     // not enough space in the buffer. | ||||
|     xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); | ||||
|  | ||||
|     if( xBytesSent != strlen( pcStringToSend ) ) | ||||
|     { | ||||
|         // The string could not be added to the message buffer because there was | ||||
|         // not enough free space in the buffer. | ||||
|     } | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferSend xMessageBufferSend | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, | ||||
|                                   const void *pvTxData, | ||||
|                                   size_t xDataLengthBytes, | ||||
|                                   BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| <pre> | ||||
|  * | ||||
|  * Interrupt safe version of the API function that sends a discrete message to | ||||
|  * the message buffer.  The message can be any length that fits within the | ||||
|  * buffer's free space, and is copied into the buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xMessageBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xMessageBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xMessageBufferSend() to write to a message buffer from a task.  Use | ||||
|  * xMessageBufferSendFromISR() to write to a message buffer from an interrupt | ||||
|  * service routine (ISR). | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer to which a message is | ||||
|  * being sent. | ||||
|  * | ||||
|  * @param pvTxData A pointer to the message that is to be copied into the | ||||
|  * message buffer. | ||||
|  * | ||||
|  * @param xDataLengthBytes The length of the message.  That is, the number of | ||||
|  * bytes to copy from pvTxData into the message buffer.  When a message is | ||||
|  * written to the message buffer an additional sizeof( size_t ) bytes are also | ||||
|  * written to store the message's length.  sizeof( size_t ) is typically 4 bytes | ||||
|  * on a 32-bit architecture, so on most 32-bit architecture setting | ||||
|  * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 | ||||
|  * bytes (20 bytes of message data and 4 bytes to hold the message length). | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will | ||||
|  * have a task blocked on it waiting for data.  Calling | ||||
|  * xMessageBufferSendFromISR() can make data available, and so cause a task that | ||||
|  * was waiting for data to leave the Blocked state.  If calling | ||||
|  * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the | ||||
|  * unblocked task has a priority higher than the currently executing task (the | ||||
|  * task that was interrupted), then, internally, xMessageBufferSendFromISR() | ||||
|  * will set *pxHigherPriorityTaskWoken to pdTRUE.  If | ||||
|  * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a | ||||
|  * context switch should be performed before the interrupt is exited.  This will | ||||
|  * ensure that the interrupt returns directly to the highest priority Ready | ||||
|  * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it | ||||
|  * is passed into the function.  See the code example below for an example. | ||||
|  * | ||||
|  * @return The number of bytes actually written to the message buffer.  If the | ||||
|  * message buffer didn't have enough free space for the message to be stored | ||||
|  * then 0 is returned, otherwise xDataLengthBytes is returned. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| // A message buffer that has already been created. | ||||
| MessageBufferHandle_t xMessageBuffer; | ||||
|  | ||||
| void vAnInterruptServiceRoutine( void ) | ||||
| { | ||||
| size_t xBytesSent; | ||||
| char *pcStringToSend = "String to send"; | ||||
| BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. | ||||
|  | ||||
|     // Attempt to send the string to the message buffer. | ||||
|     xBytesSent = xMessageBufferSendFromISR( xMessageBuffer, | ||||
|                                             ( void * ) pcStringToSend, | ||||
|                                             strlen( pcStringToSend ), | ||||
|                                             &xHigherPriorityTaskWoken ); | ||||
|  | ||||
|     if( xBytesSent != strlen( pcStringToSend ) ) | ||||
|     { | ||||
|         // The string could not be added to the message buffer because there was | ||||
|         // not enough free space in the buffer. | ||||
|     } | ||||
|  | ||||
|     // If xHigherPriorityTaskWoken was set to pdTRUE inside | ||||
|     // xMessageBufferSendFromISR() then a task that has a priority above the | ||||
|     // priority of the currently executing task was unblocked and a context | ||||
|     // switch should be performed to ensure the ISR returns to the unblocked | ||||
|     // task.  In most FreeRTOS ports this is done by simply passing | ||||
|     // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the | ||||
|     // variables value, and perform the context switch if necessary.  Check the | ||||
|     // documentation for the port in use for port specific instructions. | ||||
|     taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, | ||||
|                               void *pvRxData, | ||||
|                               size_t xBufferLengthBytes, | ||||
|                               TickType_t xTicksToWait ); | ||||
| </pre> | ||||
|  * | ||||
|  * Receives a discrete message from a message buffer.  Messages can be of | ||||
|  * variable length and are copied out of the buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xMessageBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xMessageBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xMessageBufferReceive() to read from a message buffer from a task.  Use | ||||
|  * xMessageBufferReceiveFromISR() to read from a message buffer from an | ||||
|  * interrupt service routine (ISR). | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer from which a message | ||||
|  * is being received. | ||||
|  * | ||||
|  * @param pvRxData A pointer to the buffer into which the received message is | ||||
|  * to be copied. | ||||
|  * | ||||
|  * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData | ||||
|  * parameter.  This sets the maximum length of the message that can be received. | ||||
|  * If xBufferLengthBytes is too small to hold the next message then the message | ||||
|  * will be left in the message buffer and 0 will be returned. | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time the task should remain in the | ||||
|  * Blocked state to wait for a message, should the message buffer be empty. | ||||
|  * xMessageBufferReceive() will return immediately if xTicksToWait is zero and | ||||
|  * the message buffer is empty.  The block time is specified in tick periods, so | ||||
|  * the absolute time it represents is dependent on the tick frequency.  The | ||||
|  * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds | ||||
|  * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will | ||||
|  * cause the task to wait indefinitely (without timing out), provided | ||||
|  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any | ||||
|  * CPU time when they are in the Blocked state. | ||||
|  * | ||||
|  * @return The length, in bytes, of the message read from the message buffer, if | ||||
|  * any.  If xMessageBufferReceive() times out before a message became available | ||||
|  * then zero is returned.  If the length of the message is greater than | ||||
|  * xBufferLengthBytes then the message will be left in the message buffer and | ||||
|  * zero is returned. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| void vAFunction( MessageBuffer_t xMessageBuffer ) | ||||
| { | ||||
| uint8_t ucRxData[ 20 ]; | ||||
| size_t xReceivedBytes; | ||||
| const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); | ||||
|  | ||||
|     // Receive the next message from the message buffer.  Wait in the Blocked | ||||
|     // state (so not using any CPU processing time) for a maximum of 100ms for | ||||
|     // a message to become available. | ||||
|     xReceivedBytes = xMessageBufferReceive( xMessageBuffer, | ||||
|                                             ( void * ) ucRxData, | ||||
|                                             sizeof( ucRxData ), | ||||
|                                             xBlockTime ); | ||||
|  | ||||
|     if( xReceivedBytes > 0 ) | ||||
|     { | ||||
|         // A ucRxData contains a message that is xReceivedBytes long.  Process | ||||
|         // the message here.... | ||||
|     } | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferReceive xMessageBufferReceive | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, | ||||
|                                      void *pvRxData, | ||||
|                                      size_t xBufferLengthBytes, | ||||
|                                      BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * An interrupt safe version of the API function that receives a discrete | ||||
|  * message from a message buffer.  Messages can be of variable length and are | ||||
|  * copied out of the buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xMessageBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xMessageBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xMessageBufferReceive() to read from a message buffer from a task.  Use | ||||
|  * xMessageBufferReceiveFromISR() to read from a message buffer from an | ||||
|  * interrupt service routine (ISR). | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer from which a message | ||||
|  * is being received. | ||||
|  * | ||||
|  * @param pvRxData A pointer to the buffer into which the received message is | ||||
|  * to be copied. | ||||
|  * | ||||
|  * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData | ||||
|  * parameter.  This sets the maximum length of the message that can be received. | ||||
|  * If xBufferLengthBytes is too small to hold the next message then the message | ||||
|  * will be left in the message buffer and 0 will be returned. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will | ||||
|  * have a task blocked on it waiting for space to become available.  Calling | ||||
|  * xMessageBufferReceiveFromISR() can make space available, and so cause a task | ||||
|  * that is waiting for space to leave the Blocked state.  If calling | ||||
|  * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and | ||||
|  * the unblocked task has a priority higher than the currently executing task | ||||
|  * (the task that was interrupted), then, internally, | ||||
|  * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. | ||||
|  * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a | ||||
|  * context switch should be performed before the interrupt is exited.  That will | ||||
|  * ensure the interrupt returns directly to the highest priority Ready state | ||||
|  * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is | ||||
|  * passed into the function.  See the code example below for an example. | ||||
|  * | ||||
|  * @return The length, in bytes, of the message read from the message buffer, if | ||||
|  * any. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| // A message buffer that has already been created. | ||||
| MessageBuffer_t xMessageBuffer; | ||||
|  | ||||
| void vAnInterruptServiceRoutine( void ) | ||||
| { | ||||
| uint8_t ucRxData[ 20 ]; | ||||
| size_t xReceivedBytes; | ||||
| BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE. | ||||
|  | ||||
|     // Receive the next message from the message buffer. | ||||
|     xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer, | ||||
|                                                   ( void * ) ucRxData, | ||||
|                                                   sizeof( ucRxData ), | ||||
|                                                   &xHigherPriorityTaskWoken ); | ||||
|  | ||||
|     if( xReceivedBytes > 0 ) | ||||
|     { | ||||
|         // A ucRxData contains a message that is xReceivedBytes long.  Process | ||||
|         // the message here.... | ||||
|     } | ||||
|  | ||||
|     // If xHigherPriorityTaskWoken was set to pdTRUE inside | ||||
|     // xMessageBufferReceiveFromISR() then a task that has a priority above the | ||||
|     // priority of the currently executing task was unblocked and a context | ||||
|     // switch should be performed to ensure the ISR returns to the unblocked | ||||
|     // task.  In most FreeRTOS ports this is done by simply passing | ||||
|     // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the | ||||
|     // variables value, and perform the context switch if necessary.  Check the | ||||
|     // documentation for the port in use for port specific instructions. | ||||
|     taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Deletes a message buffer that was previously created using a call to | ||||
|  * xMessageBufferCreate() or xMessageBufferCreateStatic().  If the message | ||||
|  * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), | ||||
|  * then the allocated memory is freed. | ||||
|  * | ||||
|  * A message buffer handle must not be used after the message buffer has been | ||||
|  * deleted. | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer to be deleted. | ||||
|  * | ||||
|  */ | ||||
| #define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
| <pre> | ||||
| BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); | ||||
| </pre> | ||||
|  * | ||||
|  * Tests to see if a message buffer is full.  A message buffer is full if it | ||||
|  * cannot accept any more messages, of any size, until space is made available | ||||
|  * by a message being removed from the message buffer. | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer being queried. | ||||
|  * | ||||
|  * @return If the message buffer referenced by xMessageBuffer is full then | ||||
|  * pdTRUE is returned.  Otherwise pdFALSE is returned. | ||||
|  */ | ||||
| #define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
| <pre> | ||||
| BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); | ||||
| </pre> | ||||
|  * | ||||
|  * Tests to see if a message buffer is empty (does not contain any messages). | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer being queried. | ||||
|  * | ||||
|  * @return If the message buffer referenced by xMessageBuffer is empty then | ||||
|  * pdTRUE is returned.  Otherwise pdFALSE is returned. | ||||
|  * | ||||
|  */ | ||||
| #define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
| <pre> | ||||
| BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Resets a message buffer to its initial empty state, discarding any message it | ||||
|  * contained. | ||||
|  * | ||||
|  * A message buffer can only be reset if there are no tasks blocked on it. | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer being reset. | ||||
|  * | ||||
|  * @return If the message buffer was reset then pdPASS is returned.  If the | ||||
|  * message buffer could not be reset because either there was a task blocked on | ||||
|  * the message queue to wait for space to become available, or to wait for a | ||||
|  * a message to be available, then pdFAIL is returned. | ||||
|  * | ||||
|  * \defgroup xMessageBufferReset xMessageBufferReset | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
| <pre> | ||||
| size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); | ||||
| </pre> | ||||
|  * Returns the number of bytes of free space in the message buffer. | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer being queried. | ||||
|  * | ||||
|  * @return The number of bytes that can be written to the message buffer before | ||||
|  * the message buffer would be full.  When a message is written to the message | ||||
|  * buffer an additional sizeof( size_t ) bytes are also written to store the | ||||
|  * message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit | ||||
|  * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size | ||||
|  * of the largest message that can be written to the message buffer is 6 bytes. | ||||
|  * | ||||
|  * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) | ||||
| #define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  <pre> | ||||
|  size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); | ||||
|  </pre> | ||||
|  * Returns the length (in bytes) of the next message in a message buffer. | ||||
|  * Useful if xMessageBufferReceive() returned 0 because the size of the buffer | ||||
|  * passed into xMessageBufferReceive() was too small to hold the next message. | ||||
|  * | ||||
|  * @param xMessageBuffer The handle of the message buffer being queried. | ||||
|  * | ||||
|  * @return The length (in bytes) of the next message in the message buffer, or 0 | ||||
|  * if the message buffer is empty. | ||||
|  * | ||||
|  * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes | ||||
|  * \ingroup MessageBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * For advanced users only. | ||||
|  * | ||||
|  * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when | ||||
|  * data is sent to a message buffer or stream buffer.  If there was a task that | ||||
|  * was blocked on the message or stream buffer waiting for data to arrive then | ||||
|  * the sbSEND_COMPLETED() macro sends a notification to the task to remove it | ||||
|  * from the Blocked state.  xMessageBufferSendCompletedFromISR() does the same | ||||
|  * thing.  It is provided to enable application writers to implement their own | ||||
|  * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. | ||||
|  * | ||||
|  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for | ||||
|  * additional information. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer to which data was | ||||
|  * written. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be | ||||
|  * initialised to pdFALSE before it is passed into | ||||
|  * xMessageBufferSendCompletedFromISR().  If calling | ||||
|  * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, | ||||
|  * and the task has a priority above the priority of the currently running task, | ||||
|  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a | ||||
|  * context switch should be performed before exiting the ISR. | ||||
|  * | ||||
|  * @return If a task was removed from the Blocked state then pdTRUE is returned. | ||||
|  * Otherwise pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * For advanced users only. | ||||
|  * | ||||
|  * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when | ||||
|  * data is read out of a message buffer or stream buffer.  If there was a task | ||||
|  * that was blocked on the message or stream buffer waiting for data to arrive | ||||
|  * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to | ||||
|  * remove it from the Blocked state.  xMessageBufferReceiveCompletedFromISR() | ||||
|  * does the same thing.  It is provided to enable application writers to | ||||
|  * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT | ||||
|  * ANY OTHER TIME. | ||||
|  * | ||||
|  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for | ||||
|  * additional information. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer from which data was | ||||
|  * read. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be | ||||
|  * initialised to pdFALSE before it is passed into | ||||
|  * xMessageBufferReceiveCompletedFromISR().  If calling | ||||
|  * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, | ||||
|  * and the task has a priority above the priority of the currently running task, | ||||
|  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a | ||||
|  * context switch should be performed before exiting the ISR. | ||||
|  * | ||||
|  * @return If a task was removed from the Blocked state then pdTRUE is returned. | ||||
|  * Otherwise pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| #define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) | ||||
|  | ||||
| #if defined( __cplusplus ) | ||||
| } /* extern "C" */ | ||||
| #endif | ||||
|  | ||||
| #endif	/* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ | ||||
							
								
								
									
										157
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * When the MPU is used the standard (non MPU) API functions are mapped to | ||||
|  * equivalents that start "MPU_", the prototypes for which are defined in this | ||||
|  * header files.  This will cause the application code to call the MPU_ version | ||||
|  * which wraps the non-MPU version with privilege promoting then demoting code, | ||||
|  * so the kernel code always runs will full privileges. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef MPU_PROTOTYPES_H | ||||
| #define MPU_PROTOTYPES_H | ||||
|  | ||||
| /* MPU versions of tasks.h API functions. */ | ||||
| BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; | ||||
| TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; | ||||
| char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; | ||||
| void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; | ||||
| TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; | ||||
|  | ||||
| /* MPU versions of queue.h API functions. */ | ||||
| BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; | ||||
| QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; | ||||
| QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; | ||||
| QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
| uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; | ||||
|  | ||||
| /* MPU versions of timers.h API functions. */ | ||||
| TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; | ||||
| TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; | ||||
| TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; | ||||
| TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; | ||||
| TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
|  | ||||
| /* MPU versions of event_group.h API functions. */ | ||||
| EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; | ||||
| EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; | ||||
| EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; | ||||
| EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; | ||||
| UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; | ||||
|  | ||||
| /* MPU versions of message/stream_buffer.h API functions. */ | ||||
| size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; | ||||
| size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; | ||||
| StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; | ||||
| StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* MPU_PROTOTYPES_H */ | ||||
|  | ||||
							
								
								
									
										186
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef MPU_WRAPPERS_H | ||||
| #define MPU_WRAPPERS_H | ||||
|  | ||||
| /* This file redefines API functions to be called through a wrapper macro, but | ||||
| only for ports that are using the MPU. */ | ||||
| #ifdef portUSING_MPU_WRAPPERS | ||||
|  | ||||
| 	/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is | ||||
| 	included from queue.c or task.c to prevent it from having an effect within | ||||
| 	those files. */ | ||||
| 	#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE | ||||
|  | ||||
| 		/* | ||||
| 		 * Map standard (non MPU) API functions to equivalents that start | ||||
| 		 * "MPU_".  This will cause the application code to call the MPU_ | ||||
| 		 * version, which wraps the non-MPU version with privilege promoting | ||||
| 		 * then demoting code, so the kernel code always runs will full | ||||
| 		 * privileges. | ||||
| 		 */ | ||||
|  | ||||
| 		/* Map standard tasks.h API functions to the MPU equivalents. */ | ||||
| 		#define xTaskCreate								MPU_xTaskCreate | ||||
| 		#define xTaskCreateStatic						MPU_xTaskCreateStatic | ||||
| 		#define xTaskCreateRestricted					MPU_xTaskCreateRestricted | ||||
| 		#define vTaskAllocateMPURegions					MPU_vTaskAllocateMPURegions | ||||
| 		#define vTaskDelete								MPU_vTaskDelete | ||||
| 		#define vTaskDelay								MPU_vTaskDelay | ||||
| 		#define vTaskDelayUntil							MPU_vTaskDelayUntil | ||||
| 		#define xTaskAbortDelay							MPU_xTaskAbortDelay | ||||
| 		#define uxTaskPriorityGet						MPU_uxTaskPriorityGet | ||||
| 		#define eTaskGetState							MPU_eTaskGetState | ||||
| 		#define vTaskGetInfo							MPU_vTaskGetInfo | ||||
| 		#define vTaskPrioritySet						MPU_vTaskPrioritySet | ||||
| 		#define vTaskSuspend							MPU_vTaskSuspend | ||||
| 		#define vTaskResume								MPU_vTaskResume | ||||
| 		#define vTaskSuspendAll							MPU_vTaskSuspendAll | ||||
| 		#define xTaskResumeAll							MPU_xTaskResumeAll | ||||
| 		#define xTaskGetTickCount						MPU_xTaskGetTickCount | ||||
| 		#define uxTaskGetNumberOfTasks					MPU_uxTaskGetNumberOfTasks | ||||
| 		#define pcTaskGetName							MPU_pcTaskGetName | ||||
| 		#define xTaskGetHandle							MPU_xTaskGetHandle | ||||
| 		#define uxTaskGetStackHighWaterMark				MPU_uxTaskGetStackHighWaterMark | ||||
| 		#define uxTaskGetStackHighWaterMark2			MPU_uxTaskGetStackHighWaterMark2 | ||||
| 		#define vTaskSetApplicationTaskTag				MPU_vTaskSetApplicationTaskTag | ||||
| 		#define xTaskGetApplicationTaskTag				MPU_xTaskGetApplicationTaskTag | ||||
| 		#define vTaskSetThreadLocalStoragePointer		MPU_vTaskSetThreadLocalStoragePointer | ||||
| 		#define pvTaskGetThreadLocalStoragePointer		MPU_pvTaskGetThreadLocalStoragePointer | ||||
| 		#define xTaskCallApplicationTaskHook			MPU_xTaskCallApplicationTaskHook | ||||
| 		#define xTaskGetIdleTaskHandle					MPU_xTaskGetIdleTaskHandle | ||||
| 		#define uxTaskGetSystemState					MPU_uxTaskGetSystemState | ||||
| 		#define vTaskList								MPU_vTaskList | ||||
| 		#define vTaskGetRunTimeStats					MPU_vTaskGetRunTimeStats | ||||
| 		#define xTaskGetIdleRunTimeCounter				MPU_xTaskGetIdleRunTimeCounter | ||||
| 		#define xTaskGenericNotify						MPU_xTaskGenericNotify | ||||
| 		#define xTaskNotifyWait							MPU_xTaskNotifyWait | ||||
| 		#define ulTaskNotifyTake						MPU_ulTaskNotifyTake | ||||
| 		#define xTaskNotifyStateClear					MPU_xTaskNotifyStateClear | ||||
|  | ||||
| 		#define xTaskGetCurrentTaskHandle				MPU_xTaskGetCurrentTaskHandle | ||||
| 		#define vTaskSetTimeOutState					MPU_vTaskSetTimeOutState | ||||
| 		#define xTaskCheckForTimeOut					MPU_xTaskCheckForTimeOut | ||||
| 		#define xTaskGetSchedulerState					MPU_xTaskGetSchedulerState | ||||
|  | ||||
| 		/* Map standard queue.h API functions to the MPU equivalents. */ | ||||
| 		#define xQueueGenericSend						MPU_xQueueGenericSend | ||||
| 		#define xQueueReceive							MPU_xQueueReceive | ||||
| 		#define xQueuePeek								MPU_xQueuePeek | ||||
| 		#define xQueueSemaphoreTake						MPU_xQueueSemaphoreTake | ||||
| 		#define uxQueueMessagesWaiting					MPU_uxQueueMessagesWaiting | ||||
| 		#define uxQueueSpacesAvailable					MPU_uxQueueSpacesAvailable | ||||
| 		#define vQueueDelete							MPU_vQueueDelete | ||||
| 		#define xQueueCreateMutex						MPU_xQueueCreateMutex | ||||
| 		#define xQueueCreateMutexStatic					MPU_xQueueCreateMutexStatic | ||||
| 		#define xQueueCreateCountingSemaphore			MPU_xQueueCreateCountingSemaphore | ||||
| 		#define xQueueCreateCountingSemaphoreStatic		MPU_xQueueCreateCountingSemaphoreStatic | ||||
| 		#define xQueueGetMutexHolder					MPU_xQueueGetMutexHolder | ||||
| 		#define xQueueTakeMutexRecursive				MPU_xQueueTakeMutexRecursive | ||||
| 		#define xQueueGiveMutexRecursive				MPU_xQueueGiveMutexRecursive | ||||
| 		#define xQueueGenericCreate						MPU_xQueueGenericCreate | ||||
| 		#define xQueueGenericCreateStatic				MPU_xQueueGenericCreateStatic | ||||
| 		#define xQueueCreateSet							MPU_xQueueCreateSet | ||||
| 		#define xQueueAddToSet							MPU_xQueueAddToSet | ||||
| 		#define xQueueRemoveFromSet						MPU_xQueueRemoveFromSet | ||||
| 		#define xQueueSelectFromSet						MPU_xQueueSelectFromSet | ||||
| 		#define xQueueGenericReset						MPU_xQueueGenericReset | ||||
|  | ||||
| 		#if( configQUEUE_REGISTRY_SIZE > 0 ) | ||||
| 			#define vQueueAddToRegistry						MPU_vQueueAddToRegistry | ||||
| 			#define vQueueUnregisterQueue					MPU_vQueueUnregisterQueue | ||||
| 			#define pcQueueGetName							MPU_pcQueueGetName | ||||
| 		#endif | ||||
|  | ||||
| 		/* Map standard timer.h API functions to the MPU equivalents. */ | ||||
| 		#define xTimerCreate							MPU_xTimerCreate | ||||
| 		#define xTimerCreateStatic						MPU_xTimerCreateStatic | ||||
| 		#define pvTimerGetTimerID						MPU_pvTimerGetTimerID | ||||
| 		#define vTimerSetTimerID						MPU_vTimerSetTimerID | ||||
| 		#define xTimerIsTimerActive						MPU_xTimerIsTimerActive | ||||
| 		#define xTimerGetTimerDaemonTaskHandle			MPU_xTimerGetTimerDaemonTaskHandle | ||||
| 		#define xTimerPendFunctionCall					MPU_xTimerPendFunctionCall | ||||
| 		#define pcTimerGetName							MPU_pcTimerGetName | ||||
| 		#define vTimerSetReloadMode						MPU_vTimerSetReloadMode | ||||
| 		#define xTimerGetPeriod							MPU_xTimerGetPeriod | ||||
| 		#define xTimerGetExpiryTime						MPU_xTimerGetExpiryTime | ||||
| 		#define xTimerGenericCommand					MPU_xTimerGenericCommand | ||||
|  | ||||
| 		/* Map standard event_group.h API functions to the MPU equivalents. */ | ||||
| 		#define xEventGroupCreate						MPU_xEventGroupCreate | ||||
| 		#define xEventGroupCreateStatic					MPU_xEventGroupCreateStatic | ||||
| 		#define xEventGroupWaitBits						MPU_xEventGroupWaitBits | ||||
| 		#define xEventGroupClearBits					MPU_xEventGroupClearBits | ||||
| 		#define xEventGroupSetBits						MPU_xEventGroupSetBits | ||||
| 		#define xEventGroupSync							MPU_xEventGroupSync | ||||
| 		#define vEventGroupDelete						MPU_vEventGroupDelete | ||||
|  | ||||
| 		/* Map standard message/stream_buffer.h API functions to the MPU | ||||
| 		equivalents. */ | ||||
| 		#define xStreamBufferSend						MPU_xStreamBufferSend | ||||
| 		#define xStreamBufferReceive					MPU_xStreamBufferReceive | ||||
| 		#define xStreamBufferNextMessageLengthBytes		MPU_xStreamBufferNextMessageLengthBytes | ||||
| 		#define vStreamBufferDelete						MPU_vStreamBufferDelete | ||||
| 		#define xStreamBufferIsFull						MPU_xStreamBufferIsFull | ||||
| 		#define xStreamBufferIsEmpty					MPU_xStreamBufferIsEmpty | ||||
| 		#define xStreamBufferReset						MPU_xStreamBufferReset | ||||
| 		#define xStreamBufferSpacesAvailable			MPU_xStreamBufferSpacesAvailable | ||||
| 		#define xStreamBufferBytesAvailable				MPU_xStreamBufferBytesAvailable | ||||
| 		#define xStreamBufferSetTriggerLevel			MPU_xStreamBufferSetTriggerLevel | ||||
| 		#define xStreamBufferGenericCreate				MPU_xStreamBufferGenericCreate | ||||
| 		#define xStreamBufferGenericCreateStatic		MPU_xStreamBufferGenericCreateStatic | ||||
|  | ||||
|  | ||||
| 		/* Remove the privileged function macro, but keep the PRIVILEGED_DATA | ||||
| 		macro so applications can place data in privileged access sections | ||||
| 		(useful when using statically allocated objects). */ | ||||
| 		#define PRIVILEGED_FUNCTION | ||||
| 		#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) | ||||
| 		#define FREERTOS_SYSTEM_CALL | ||||
|  | ||||
| 	#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ | ||||
|  | ||||
| 		/* Ensure API functions go in the privileged execution section. */ | ||||
| 		#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) | ||||
| 		#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) | ||||
| 		#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) | ||||
|  | ||||
| 	#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ | ||||
|  | ||||
| #else /* portUSING_MPU_WRAPPERS */ | ||||
|  | ||||
| 	#define PRIVILEGED_FUNCTION | ||||
| 	#define PRIVILEGED_DATA | ||||
| 	#define FREERTOS_SYSTEM_CALL | ||||
| 	#define portUSING_MPU_WRAPPERS 0 | ||||
|  | ||||
| #endif /* portUSING_MPU_WRAPPERS */ | ||||
|  | ||||
|  | ||||
| #endif /* MPU_WRAPPERS_H */ | ||||
|  | ||||
							
								
								
									
										181
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/portable.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/portable.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /*----------------------------------------------------------- | ||||
|  * Portable layer API.  Each function must be defined for each port. | ||||
|  *----------------------------------------------------------*/ | ||||
|  | ||||
| #ifndef PORTABLE_H | ||||
| #define PORTABLE_H | ||||
|  | ||||
| /* Each FreeRTOS port has a unique portmacro.h header file.  Originally a | ||||
| pre-processor definition was used to ensure the pre-processor found the correct | ||||
| portmacro.h file for the port being used.  That scheme was deprecated in favour | ||||
| of setting the compiler's include path such that it found the correct | ||||
| portmacro.h file - removing the need for the constant and allowing the | ||||
| portmacro.h file to be located anywhere in relation to the port being used. | ||||
| Purely for reasons of backward compatibility the old method is still valid, but | ||||
| to make it clear that new projects should not use it, support for the port | ||||
| specific constants has been moved into the deprecated_definitions.h header | ||||
| file. */ | ||||
| #include "deprecated_definitions.h" | ||||
|  | ||||
| /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h | ||||
| did not result in a portmacro.h header file being included - and it should be | ||||
| included here.  In this case the path to the correct portmacro.h header file | ||||
| must be set in the compiler's include path. */ | ||||
| #ifndef portENTER_CRITICAL | ||||
| 	#include "portmacro.h" | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 32 | ||||
| 	#define portBYTE_ALIGNMENT_MASK ( 0x001f ) | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 16 | ||||
| 	#define portBYTE_ALIGNMENT_MASK ( 0x000f ) | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 8 | ||||
| 	#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 4 | ||||
| 	#define portBYTE_ALIGNMENT_MASK	( 0x0003 ) | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 2 | ||||
| 	#define portBYTE_ALIGNMENT_MASK	( 0x0001 ) | ||||
| #endif | ||||
|  | ||||
| #if portBYTE_ALIGNMENT == 1 | ||||
| 	#define portBYTE_ALIGNMENT_MASK	( 0x0000 ) | ||||
| #endif | ||||
|  | ||||
| #ifndef portBYTE_ALIGNMENT_MASK | ||||
| 	#error "Invalid portBYTE_ALIGNMENT definition" | ||||
| #endif | ||||
|  | ||||
| #ifndef portNUM_CONFIGURABLE_REGIONS | ||||
| 	#define portNUM_CONFIGURABLE_REGIONS 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef portHAS_STACK_OVERFLOW_CHECKING | ||||
| 	#define portHAS_STACK_OVERFLOW_CHECKING 0 | ||||
| #endif | ||||
|  | ||||
| #ifndef portARCH_NAME | ||||
| 	#define portARCH_NAME NULL | ||||
| #endif | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #include "mpu_wrappers.h" | ||||
|  | ||||
| /* | ||||
|  * Setup the stack of a new task so it is ready to be placed under the | ||||
|  * scheduler control.  The registers have to be placed on the stack in | ||||
|  * the order that the port expects to find them. | ||||
|  * | ||||
|  */ | ||||
| #if( portUSING_MPU_WRAPPERS == 1 ) | ||||
| 	#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) | ||||
| 		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; | ||||
| 	#else | ||||
| 		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; | ||||
| 	#endif | ||||
| #else | ||||
| 	#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) | ||||
| 		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; | ||||
| 	#else | ||||
| 		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; | ||||
| 	#endif | ||||
| #endif | ||||
|  | ||||
| /* Used by heap_5.c. */ | ||||
| typedef struct HeapRegion | ||||
| { | ||||
| 	uint8_t *pucStartAddress; | ||||
| 	size_t xSizeInBytes; | ||||
| } HeapRegion_t; | ||||
|  | ||||
| /* | ||||
|  * Used to define multiple heap regions for use by heap_5.c.  This function | ||||
|  * must be called before any calls to pvPortMalloc() - not creating a task, | ||||
|  * queue, semaphore, mutex, software timer, event group, etc. will result in | ||||
|  * pvPortMalloc being called. | ||||
|  * | ||||
|  * pxHeapRegions passes in an array of HeapRegion_t structures - each of which | ||||
|  * defines a region of memory that can be used as the heap.  The array is | ||||
|  * terminated by a HeapRegions_t structure that has a size of 0.  The region | ||||
|  * with the lowest start address must appear first in the array. | ||||
|  */ | ||||
| void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Map to the memory management routines required for the port. | ||||
|  */ | ||||
| void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; | ||||
| void vPortFree( void *pv ) PRIVILEGED_FUNCTION; | ||||
| void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; | ||||
| size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; | ||||
| size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Setup the hardware ready for the scheduler to take control.  This generally | ||||
|  * sets up a tick interrupt and sets timers for the correct tick frequency. | ||||
|  */ | ||||
| BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so | ||||
|  * the hardware is left in its original condition after the scheduler stops | ||||
|  * executing. | ||||
|  */ | ||||
| void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* | ||||
|  * The structures and methods of manipulating the MPU are contained within the | ||||
|  * port layer. | ||||
|  * | ||||
|  * Fills the xMPUSettings structure with the memory region information | ||||
|  * contained in xRegions. | ||||
|  */ | ||||
| #if( portUSING_MPU_WRAPPERS == 1 ) | ||||
| 	struct xMEMORY_REGION; | ||||
| 	void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; | ||||
| #endif | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif /* PORTABLE_H */ | ||||
|  | ||||
							
								
								
									
										124
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef PROJDEFS_H | ||||
| #define PROJDEFS_H | ||||
|  | ||||
| /* | ||||
|  * Defines the prototype to which task functions must conform.  Defined in this | ||||
|  * file to ensure the type is known before portable.h is included. | ||||
|  */ | ||||
| typedef void (*TaskFunction_t)( void * ); | ||||
|  | ||||
| /* Converts a time in milliseconds to a time in ticks.  This macro can be | ||||
| overridden by a macro of the same name defined in FreeRTOSConfig.h in case the | ||||
| definition here is not suitable for your application. */ | ||||
| #ifndef pdMS_TO_TICKS | ||||
| 	#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) | ||||
| #endif | ||||
|  | ||||
| #define pdFALSE			( ( BaseType_t ) 0 ) | ||||
| #define pdTRUE			( ( BaseType_t ) 1 ) | ||||
|  | ||||
| #define pdPASS			( pdTRUE ) | ||||
| #define pdFAIL			( pdFALSE ) | ||||
| #define errQUEUE_EMPTY	( ( BaseType_t ) 0 ) | ||||
| #define errQUEUE_FULL	( ( BaseType_t ) 0 ) | ||||
|  | ||||
| /* FreeRTOS error definitions. */ | ||||
| #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY	( -1 ) | ||||
| #define errQUEUE_BLOCKED						( -4 ) | ||||
| #define errQUEUE_YIELD							( -5 ) | ||||
|  | ||||
| /* Macros used for basic data corruption checks. */ | ||||
| #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES | ||||
| 	#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 | ||||
| #endif | ||||
|  | ||||
| #if( configUSE_16_BIT_TICKS == 1 ) | ||||
| 	#define pdINTEGRITY_CHECK_VALUE 0x5a5a | ||||
| #else | ||||
| 	#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL | ||||
| #endif | ||||
|  | ||||
| /* The following errno values are used by FreeRTOS+ components, not FreeRTOS | ||||
| itself. */ | ||||
| #define pdFREERTOS_ERRNO_NONE			0	/* No errors */ | ||||
| #define	pdFREERTOS_ERRNO_ENOENT			2	/* No such file or directory */ | ||||
| #define	pdFREERTOS_ERRNO_EINTR			4	/* Interrupted system call */ | ||||
| #define	pdFREERTOS_ERRNO_EIO			5	/* I/O error */ | ||||
| #define	pdFREERTOS_ERRNO_ENXIO			6	/* No such device or address */ | ||||
| #define	pdFREERTOS_ERRNO_EBADF			9	/* Bad file number */ | ||||
| #define	pdFREERTOS_ERRNO_EAGAIN			11	/* No more processes */ | ||||
| #define	pdFREERTOS_ERRNO_EWOULDBLOCK	11	/* Operation would block */ | ||||
| #define	pdFREERTOS_ERRNO_ENOMEM			12	/* Not enough memory */ | ||||
| #define	pdFREERTOS_ERRNO_EACCES			13	/* Permission denied */ | ||||
| #define	pdFREERTOS_ERRNO_EFAULT			14	/* Bad address */ | ||||
| #define	pdFREERTOS_ERRNO_EBUSY			16	/* Mount device busy */ | ||||
| #define	pdFREERTOS_ERRNO_EEXIST			17	/* File exists */ | ||||
| #define	pdFREERTOS_ERRNO_EXDEV			18	/* Cross-device link */ | ||||
| #define	pdFREERTOS_ERRNO_ENODEV			19	/* No such device */ | ||||
| #define	pdFREERTOS_ERRNO_ENOTDIR		20	/* Not a directory */ | ||||
| #define	pdFREERTOS_ERRNO_EISDIR			21	/* Is a directory */ | ||||
| #define	pdFREERTOS_ERRNO_EINVAL			22	/* Invalid argument */ | ||||
| #define	pdFREERTOS_ERRNO_ENOSPC			28	/* No space left on device */ | ||||
| #define	pdFREERTOS_ERRNO_ESPIPE			29	/* Illegal seek */ | ||||
| #define	pdFREERTOS_ERRNO_EROFS			30	/* Read only file system */ | ||||
| #define	pdFREERTOS_ERRNO_EUNATCH		42	/* Protocol driver not attached */ | ||||
| #define	pdFREERTOS_ERRNO_EBADE			50	/* Invalid exchange */ | ||||
| #define	pdFREERTOS_ERRNO_EFTYPE			79	/* Inappropriate file type or format */ | ||||
| #define	pdFREERTOS_ERRNO_ENMFILE		89	/* No more files */ | ||||
| #define	pdFREERTOS_ERRNO_ENOTEMPTY		90	/* Directory not empty */ | ||||
| #define	pdFREERTOS_ERRNO_ENAMETOOLONG 	91	/* File or path name too long */ | ||||
| #define	pdFREERTOS_ERRNO_EOPNOTSUPP		95	/* Operation not supported on transport endpoint */ | ||||
| #define	pdFREERTOS_ERRNO_ENOBUFS		105	/* No buffer space available */ | ||||
| #define	pdFREERTOS_ERRNO_ENOPROTOOPT	109	/* Protocol not available */ | ||||
| #define	pdFREERTOS_ERRNO_EADDRINUSE		112	/* Address already in use */ | ||||
| #define	pdFREERTOS_ERRNO_ETIMEDOUT		116	/* Connection timed out */ | ||||
| #define	pdFREERTOS_ERRNO_EINPROGRESS	119	/* Connection already in progress */ | ||||
| #define	pdFREERTOS_ERRNO_EALREADY		120	/* Socket already connected */ | ||||
| #define	pdFREERTOS_ERRNO_EADDRNOTAVAIL 	125	/* Address not available */ | ||||
| #define	pdFREERTOS_ERRNO_EISCONN		127	/* Socket is already connected */ | ||||
| #define	pdFREERTOS_ERRNO_ENOTCONN		128	/* Socket is not connected */ | ||||
| #define	pdFREERTOS_ERRNO_ENOMEDIUM		135	/* No medium inserted */ | ||||
| #define	pdFREERTOS_ERRNO_EILSEQ			138	/* An invalid UTF-16 sequence was encountered. */ | ||||
| #define	pdFREERTOS_ERRNO_ECANCELED		140	/* Operation canceled. */ | ||||
|  | ||||
| /* The following endian values are used by FreeRTOS+ components, not FreeRTOS | ||||
| itself. */ | ||||
| #define pdFREERTOS_LITTLE_ENDIAN		0 | ||||
| #define pdFREERTOS_BIG_ENDIAN			1 | ||||
|  | ||||
| /* Re-defining endian values for generic naming. */ | ||||
| #define pdLITTLE_ENDIAN					pdFREERTOS_LITTLE_ENDIAN | ||||
| #define pdBIG_ENDIAN					pdFREERTOS_BIG_ENDIAN | ||||
|  | ||||
|  | ||||
| #endif /* PROJDEFS_H */ | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										1655
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/queue.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1655
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/queue.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1140
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1140
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										129
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| #ifndef STACK_MACROS_H | ||||
| #define STACK_MACROS_H | ||||
|  | ||||
| /* | ||||
|  * Call the stack overflow hook function if the stack of the task being swapped | ||||
|  * out is currently overflowed, or looks like it might have overflowed in the | ||||
|  * past. | ||||
|  * | ||||
|  * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check | ||||
|  * the current stack state only - comparing the current top of stack value to | ||||
|  * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 | ||||
|  * will also cause the last few stack bytes to be checked to ensure the value | ||||
|  * to which the bytes were set when the task was created have not been | ||||
|  * overwritten.  Note this second test does not guarantee that an overflowed | ||||
|  * stack will always be recognised. | ||||
|  */ | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) | ||||
|  | ||||
| 	/* Only the current stack state is to be checked. */ | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 		/* Is the currently saved stack pointer within the stack limit? */								\ | ||||
| 		if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )										\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) | ||||
|  | ||||
| 	/* Only the current stack state is to be checked. */ | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 																										\ | ||||
| 		/* Is the currently saved stack pointer within the stack limit? */								\ | ||||
| 		if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack )									\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) | ||||
|  | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																\ | ||||
| 	{																									\ | ||||
| 		const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack;							\ | ||||
| 		const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5;											\ | ||||
| 																										\ | ||||
| 		if( ( pulStack[ 0 ] != ulCheckValue ) ||														\ | ||||
| 			( pulStack[ 1 ] != ulCheckValue ) ||														\ | ||||
| 			( pulStack[ 2 ] != ulCheckValue ) ||														\ | ||||
| 			( pulStack[ 3 ] != ulCheckValue ) )															\ | ||||
| 		{																								\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\ | ||||
| 		}																								\ | ||||
| 	} | ||||
|  | ||||
| #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) | ||||
|  | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW()																								\ | ||||
| 	{																																	\ | ||||
| 	int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack;																		\ | ||||
| 	static const uint8_t ucExpectedStackBytes[] = {	tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\ | ||||
| 													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };	\ | ||||
| 																																		\ | ||||
| 																																		\ | ||||
| 		pcEndOfStack -= sizeof( ucExpectedStackBytes );																					\ | ||||
| 																																		\ | ||||
| 		/* Has the extremity of the task stack ever been written over? */																\ | ||||
| 		if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )					\ | ||||
| 		{																																\ | ||||
| 			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );									\ | ||||
| 		}																																\ | ||||
| 	} | ||||
|  | ||||
| #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Remove stack overflow macro if not being used. */ | ||||
| #ifndef taskCHECK_FOR_STACK_OVERFLOW | ||||
| 	#define taskCHECK_FOR_STACK_OVERFLOW() | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* STACK_MACROS_H */ | ||||
|  | ||||
							
								
								
									
										855
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										855
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,855 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Stream buffers are used to send a continuous stream of data from one task or | ||||
|  * interrupt to another.  Their implementation is light weight, making them | ||||
|  * particularly suited for interrupt to task and core to core communication | ||||
|  * scenarios. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xStreamBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xStreamBufferRead()) inside a critical section section and set the | ||||
|  * receive block time to 0. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef STREAM_BUFFER_H | ||||
| #define STREAM_BUFFER_H | ||||
|  | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Type by which stream buffers are referenced.  For example, a call to | ||||
|  * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can | ||||
|  * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), | ||||
|  * etc. | ||||
|  */ | ||||
| struct StreamBufferDef_t; | ||||
| typedef struct StreamBufferDef_t * StreamBufferHandle_t; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * message_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); | ||||
| </pre> | ||||
|  * | ||||
|  * Creates a new stream buffer using dynamically allocated memory.  See | ||||
|  * xStreamBufferCreateStatic() for a version that uses statically allocated | ||||
|  * memory (memory that is allocated at compile time). | ||||
|  * | ||||
|  * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in | ||||
|  * FreeRTOSConfig.h for xStreamBufferCreate() to be available. | ||||
|  * | ||||
|  * @param xBufferSizeBytes The total number of bytes the stream buffer will be | ||||
|  * able to hold at any one time. | ||||
|  * | ||||
|  * @param xTriggerLevelBytes The number of bytes that must be in the stream | ||||
|  * buffer before a task that is blocked on the stream buffer to wait for data is | ||||
|  * moved out of the blocked state.  For example, if a task is blocked on a read | ||||
|  * of an empty stream buffer that has a trigger level of 1 then the task will be | ||||
|  * unblocked when a single byte is written to the buffer or the task's block | ||||
|  * time expires.  As another example, if a task is blocked on a read of an empty | ||||
|  * stream buffer that has a trigger level of 10 then the task will not be | ||||
|  * unblocked until the stream buffer contains at least 10 bytes or the task's | ||||
|  * block time expires.  If a reading task's block time expires before the | ||||
|  * trigger level is reached then the task will still receive however many bytes | ||||
|  * are actually available.  Setting a trigger level of 0 will result in a | ||||
|  * trigger level of 1 being used.  It is not valid to specify a trigger level | ||||
|  * that is greater than the buffer size. | ||||
|  * | ||||
|  * @return If NULL is returned, then the stream buffer cannot be created | ||||
|  * because there is insufficient heap memory available for FreeRTOS to allocate | ||||
|  * the stream buffer data structures and storage area.  A non-NULL value being | ||||
|  * returned indicates that the stream buffer has been created successfully - | ||||
|  * the returned value should be stored as the handle to the created stream | ||||
|  * buffer. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
|  | ||||
| void vAFunction( void ) | ||||
| { | ||||
| StreamBufferHandle_t xStreamBuffer; | ||||
| const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; | ||||
|  | ||||
|     // Create a stream buffer that can hold 100 bytes.  The memory used to hold | ||||
|     // both the stream buffer structure and the data in the stream buffer is | ||||
|     // allocated dynamically. | ||||
|     xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); | ||||
|  | ||||
|     if( xStreamBuffer == NULL ) | ||||
|     { | ||||
|         // There was not enough heap memory space available to create the | ||||
|         // stream buffer. | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // The stream buffer was created successfully and can now be used. | ||||
|     } | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferCreate xStreamBufferCreate | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, | ||||
|                                                 size_t xTriggerLevelBytes, | ||||
|                                                 uint8_t *pucStreamBufferStorageArea, | ||||
|                                                 StaticStreamBuffer_t *pxStaticStreamBuffer ); | ||||
| </pre> | ||||
|  * Creates a new stream buffer using statically allocated memory.  See | ||||
|  * xStreamBufferCreate() for a version that uses dynamically allocated memory. | ||||
|  * | ||||
|  * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for | ||||
|  * xStreamBufferCreateStatic() to be available. | ||||
|  * | ||||
|  * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the | ||||
|  * pucStreamBufferStorageArea parameter. | ||||
|  * | ||||
|  * @param xTriggerLevelBytes The number of bytes that must be in the stream | ||||
|  * buffer before a task that is blocked on the stream buffer to wait for data is | ||||
|  * moved out of the blocked state.  For example, if a task is blocked on a read | ||||
|  * of an empty stream buffer that has a trigger level of 1 then the task will be | ||||
|  * unblocked when a single byte is written to the buffer or the task's block | ||||
|  * time expires.  As another example, if a task is blocked on a read of an empty | ||||
|  * stream buffer that has a trigger level of 10 then the task will not be | ||||
|  * unblocked until the stream buffer contains at least 10 bytes or the task's | ||||
|  * block time expires.  If a reading task's block time expires before the | ||||
|  * trigger level is reached then the task will still receive however many bytes | ||||
|  * are actually available.  Setting a trigger level of 0 will result in a | ||||
|  * trigger level of 1 being used.  It is not valid to specify a trigger level | ||||
|  * that is greater than the buffer size. | ||||
|  * | ||||
|  * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at | ||||
|  * least xBufferSizeBytes + 1 big.  This is the array to which streams are | ||||
|  * copied when they are written to the stream buffer. | ||||
|  * | ||||
|  * @param pxStaticStreamBuffer Must point to a variable of type | ||||
|  * StaticStreamBuffer_t, which will be used to hold the stream buffer's data | ||||
|  * structure. | ||||
|  * | ||||
|  * @return If the stream buffer is created successfully then a handle to the | ||||
|  * created stream buffer is returned. If either pucStreamBufferStorageArea or | ||||
|  * pxStaticstreamBuffer are NULL then NULL is returned. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
|  | ||||
| // Used to dimension the array used to hold the streams.  The available space | ||||
| // will actually be one less than this, so 999. | ||||
| #define STORAGE_SIZE_BYTES 1000 | ||||
|  | ||||
| // Defines the memory that will actually hold the streams within the stream | ||||
| // buffer. | ||||
| static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; | ||||
|  | ||||
| // The variable used to hold the stream buffer structure. | ||||
| StaticStreamBuffer_t xStreamBufferStruct; | ||||
|  | ||||
| void MyFunction( void ) | ||||
| { | ||||
| StreamBufferHandle_t xStreamBuffer; | ||||
| const size_t xTriggerLevel = 1; | ||||
|  | ||||
|     xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ), | ||||
|                                                xTriggerLevel, | ||||
|                                                ucBufferStorage, | ||||
|                                                &xStreamBufferStruct ); | ||||
|  | ||||
|     // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer | ||||
|     // parameters were NULL, xStreamBuffer will not be NULL, and can be used to | ||||
|     // reference the created stream buffer in other stream buffer API calls. | ||||
|  | ||||
|     // Other code that uses the stream buffer can go here. | ||||
| } | ||||
|  | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, | ||||
|                           const void *pvTxData, | ||||
|                           size_t xDataLengthBytes, | ||||
|                           TickType_t xTicksToWait ); | ||||
| </pre> | ||||
|  * | ||||
|  * Sends bytes to a stream buffer.  The bytes are copied into the stream buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xStreamBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xStreamBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xStreamBufferSend() to write to a stream buffer from a task.  Use | ||||
|  * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt | ||||
|  * service routine (ISR). | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer to which a stream is | ||||
|  * being sent. | ||||
|  * | ||||
|  * @param pvTxData A pointer to the buffer that holds the bytes to be copied | ||||
|  * into the stream buffer. | ||||
|  * | ||||
|  * @param xDataLengthBytes   The maximum number of bytes to copy from pvTxData | ||||
|  * into the stream buffer. | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time the task should remain in the | ||||
|  * Blocked state to wait for enough space to become available in the stream | ||||
|  * buffer, should the stream buffer contain too little space to hold the | ||||
|  * another xDataLengthBytes bytes.  The block time is specified in tick periods, | ||||
|  * so the absolute time it represents is dependent on the tick frequency.  The | ||||
|  * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds | ||||
|  * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will | ||||
|  * cause the task to wait indefinitely (without timing out), provided | ||||
|  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  If a task times out | ||||
|  * before it can write all xDataLengthBytes into the buffer it will still write | ||||
|  * as many bytes as possible.  A task does not use any CPU time when it is in | ||||
|  * the blocked state. | ||||
|  * | ||||
|  * @return The number of bytes written to the stream buffer.  If a task times | ||||
|  * out before it can write all xDataLengthBytes into the buffer it will still | ||||
|  * write as many bytes as possible. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| void vAFunction( StreamBufferHandle_t xStreamBuffer ) | ||||
| { | ||||
| size_t xBytesSent; | ||||
| uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; | ||||
| char *pcStringToSend = "String to send"; | ||||
| const TickType_t x100ms = pdMS_TO_TICKS( 100 ); | ||||
|  | ||||
|     // Send an array to the stream buffer, blocking for a maximum of 100ms to | ||||
|     // wait for enough space to be available in the stream buffer. | ||||
|     xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); | ||||
|  | ||||
|     if( xBytesSent != sizeof( ucArrayToSend ) ) | ||||
|     { | ||||
|         // The call to xStreamBufferSend() times out before there was enough | ||||
|         // space in the buffer for the data to be written, but it did | ||||
|         // successfully write xBytesSent bytes. | ||||
|     } | ||||
|  | ||||
|     // Send the string to the stream buffer.  Return immediately if there is not | ||||
|     // enough space in the buffer. | ||||
|     xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); | ||||
|  | ||||
|     if( xBytesSent != strlen( pcStringToSend ) ) | ||||
|     { | ||||
|         // The entire string could not be added to the stream buffer because | ||||
|         // there was not enough free space in the buffer, but xBytesSent bytes | ||||
|         // were sent.  Could try again to send the remaining bytes. | ||||
|     } | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferSend xStreamBufferSend | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, | ||||
| 						  const void *pvTxData, | ||||
| 						  size_t xDataLengthBytes, | ||||
| 						  TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, | ||||
|                                  const void *pvTxData, | ||||
|                                  size_t xDataLengthBytes, | ||||
|                                  BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * Interrupt safe version of the API function that sends a stream of bytes to | ||||
|  * the stream buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xStreamBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xStreamBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xStreamBufferSend() to write to a stream buffer from a task.  Use | ||||
|  * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt | ||||
|  * service routine (ISR). | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer to which a stream is | ||||
|  * being sent. | ||||
|  * | ||||
|  * @param pvTxData A pointer to the data that is to be copied into the stream | ||||
|  * buffer. | ||||
|  * | ||||
|  * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData | ||||
|  * into the stream buffer. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will | ||||
|  * have a task blocked on it waiting for data.  Calling | ||||
|  * xStreamBufferSendFromISR() can make data available, and so cause a task that | ||||
|  * was waiting for data to leave the Blocked state.  If calling | ||||
|  * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the | ||||
|  * unblocked task has a priority higher than the currently executing task (the | ||||
|  * task that was interrupted), then, internally, xStreamBufferSendFromISR() | ||||
|  * will set *pxHigherPriorityTaskWoken to pdTRUE.  If | ||||
|  * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a | ||||
|  * context switch should be performed before the interrupt is exited.  This will | ||||
|  * ensure that the interrupt returns directly to the highest priority Ready | ||||
|  * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it | ||||
|  * is passed into the function.  See the example code below for an example. | ||||
|  * | ||||
|  * @return The number of bytes actually written to the stream buffer, which will | ||||
|  * be less than xDataLengthBytes if the stream buffer didn't have enough free | ||||
|  * space for all the bytes to be written. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| // A stream buffer that has already been created. | ||||
| StreamBufferHandle_t xStreamBuffer; | ||||
|  | ||||
| void vAnInterruptServiceRoutine( void ) | ||||
| { | ||||
| size_t xBytesSent; | ||||
| char *pcStringToSend = "String to send"; | ||||
| BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. | ||||
|  | ||||
|     // Attempt to send the string to the stream buffer. | ||||
|     xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, | ||||
|                                            ( void * ) pcStringToSend, | ||||
|                                            strlen( pcStringToSend ), | ||||
|                                            &xHigherPriorityTaskWoken ); | ||||
|  | ||||
|     if( xBytesSent != strlen( pcStringToSend ) ) | ||||
|     { | ||||
|         // There was not enough free space in the stream buffer for the entire | ||||
|         // string to be written, ut xBytesSent bytes were written. | ||||
|     } | ||||
|  | ||||
|     // If xHigherPriorityTaskWoken was set to pdTRUE inside | ||||
|     // xStreamBufferSendFromISR() then a task that has a priority above the | ||||
|     // priority of the currently executing task was unblocked and a context | ||||
|     // switch should be performed to ensure the ISR returns to the unblocked | ||||
|     // task.  In most FreeRTOS ports this is done by simply passing | ||||
|     // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the | ||||
|     // variables value, and perform the context switch if necessary.  Check the | ||||
|     // documentation for the port in use for port specific instructions. | ||||
|     taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, | ||||
| 								 const void *pvTxData, | ||||
| 								 size_t xDataLengthBytes, | ||||
| 								 BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, | ||||
|                              void *pvRxData, | ||||
|                              size_t xBufferLengthBytes, | ||||
|                              TickType_t xTicksToWait ); | ||||
| </pre> | ||||
|  * | ||||
|  * Receives bytes from a stream buffer. | ||||
|  * | ||||
|  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer | ||||
|  * implementation (so also the message buffer implementation, as message buffers | ||||
|  * are built on top of stream buffers) assumes there is only one task or | ||||
|  * interrupt that will write to the buffer (the writer), and only one task or | ||||
|  * interrupt that will read from the buffer (the reader).  It is safe for the | ||||
|  * writer and reader to be different tasks or interrupts, but, unlike other | ||||
|  * FreeRTOS objects, it is not safe to have multiple different writers or | ||||
|  * multiple different readers.  If there are to be multiple different writers | ||||
|  * then the application writer must place each call to a writing API function | ||||
|  * (such as xStreamBufferSend()) inside a critical section and set the send | ||||
|  * block time to 0.  Likewise, if there are to be multiple different readers | ||||
|  * then the application writer must place each call to a reading API function | ||||
|  * (such as xStreamBufferRead()) inside a critical section and set the receive | ||||
|  * block time to 0. | ||||
|  * | ||||
|  * Use xStreamBufferReceive() to read from a stream buffer from a task.  Use | ||||
|  * xStreamBufferReceiveFromISR() to read from a stream buffer from an | ||||
|  * interrupt service routine (ISR). | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer from which bytes are to | ||||
|  * be received. | ||||
|  * | ||||
|  * @param pvRxData A pointer to the buffer into which the received bytes will be | ||||
|  * copied. | ||||
|  * | ||||
|  * @param xBufferLengthBytes The length of the buffer pointed to by the | ||||
|  * pvRxData parameter.  This sets the maximum number of bytes to receive in one | ||||
|  * call.  xStreamBufferReceive will return as many bytes as possible up to a | ||||
|  * maximum set by xBufferLengthBytes. | ||||
|  * | ||||
|  * @param xTicksToWait The maximum amount of time the task should remain in the | ||||
|  * Blocked state to wait for data to become available if the stream buffer is | ||||
|  * empty.  xStreamBufferReceive() will return immediately if xTicksToWait is | ||||
|  * zero.  The block time is specified in tick periods, so the absolute time it | ||||
|  * represents is dependent on the tick frequency.  The macro pdMS_TO_TICKS() can | ||||
|  * be used to convert a time specified in milliseconds into a time specified in | ||||
|  * ticks.  Setting xTicksToWait to portMAX_DELAY will cause the task to wait | ||||
|  * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 | ||||
|  * in FreeRTOSConfig.h.  A task does not use any CPU time when it is in the | ||||
|  * Blocked state. | ||||
|  * | ||||
|  * @return The number of bytes actually read from the stream buffer, which will | ||||
|  * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed | ||||
|  * out before xBufferLengthBytes were available. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| void vAFunction( StreamBuffer_t xStreamBuffer ) | ||||
| { | ||||
| uint8_t ucRxData[ 20 ]; | ||||
| size_t xReceivedBytes; | ||||
| const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); | ||||
|  | ||||
|     // Receive up to another sizeof( ucRxData ) bytes from the stream buffer. | ||||
|     // Wait in the Blocked state (so not using any CPU processing time) for a | ||||
|     // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be | ||||
|     // available. | ||||
|     xReceivedBytes = xStreamBufferReceive( xStreamBuffer, | ||||
|                                            ( void * ) ucRxData, | ||||
|                                            sizeof( ucRxData ), | ||||
|                                            xBlockTime ); | ||||
|  | ||||
|     if( xReceivedBytes > 0 ) | ||||
|     { | ||||
|         // A ucRxData contains another xRecievedBytes bytes of data, which can | ||||
|         // be processed here.... | ||||
|     } | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferReceive xStreamBufferReceive | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, | ||||
| 							 void *pvRxData, | ||||
| 							 size_t xBufferLengthBytes, | ||||
| 							 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, | ||||
|                                     void *pvRxData, | ||||
|                                     size_t xBufferLengthBytes, | ||||
|                                     BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * An interrupt safe version of the API function that receives bytes from a | ||||
|  * stream buffer. | ||||
|  * | ||||
|  * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. | ||||
|  * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an | ||||
|  * interrupt service routine (ISR). | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer from which a stream | ||||
|  * is being received. | ||||
|  * | ||||
|  * @param pvRxData A pointer to the buffer into which the received bytes are | ||||
|  * copied. | ||||
|  * | ||||
|  * @param xBufferLengthBytes The length of the buffer pointed to by the | ||||
|  * pvRxData parameter.  This sets the maximum number of bytes to receive in one | ||||
|  * call.  xStreamBufferReceive will return as many bytes as possible up to a | ||||
|  * maximum set by xBufferLengthBytes. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will | ||||
|  * have a task blocked on it waiting for space to become available.  Calling | ||||
|  * xStreamBufferReceiveFromISR() can make space available, and so cause a task | ||||
|  * that is waiting for space to leave the Blocked state.  If calling | ||||
|  * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and | ||||
|  * the unblocked task has a priority higher than the currently executing task | ||||
|  * (the task that was interrupted), then, internally, | ||||
|  * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. | ||||
|  * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a | ||||
|  * context switch should be performed before the interrupt is exited.  That will | ||||
|  * ensure the interrupt returns directly to the highest priority Ready state | ||||
|  * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is | ||||
|  * passed into the function.  See the code example below for an example. | ||||
|  * | ||||
|  * @return The number of bytes read from the stream buffer, if any. | ||||
|  * | ||||
|  * Example use: | ||||
| <pre> | ||||
| // A stream buffer that has already been created. | ||||
| StreamBuffer_t xStreamBuffer; | ||||
|  | ||||
| void vAnInterruptServiceRoutine( void ) | ||||
| { | ||||
| uint8_t ucRxData[ 20 ]; | ||||
| size_t xReceivedBytes; | ||||
| BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE. | ||||
|  | ||||
|     // Receive the next stream from the stream buffer. | ||||
|     xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, | ||||
|                                                   ( void * ) ucRxData, | ||||
|                                                   sizeof( ucRxData ), | ||||
|                                                   &xHigherPriorityTaskWoken ); | ||||
|  | ||||
|     if( xReceivedBytes > 0 ) | ||||
|     { | ||||
|         // ucRxData contains xReceivedBytes read from the stream buffer. | ||||
|         // Process the stream here.... | ||||
|     } | ||||
|  | ||||
|     // If xHigherPriorityTaskWoken was set to pdTRUE inside | ||||
|     // xStreamBufferReceiveFromISR() then a task that has a priority above the | ||||
|     // priority of the currently executing task was unblocked and a context | ||||
|     // switch should be performed to ensure the ISR returns to the unblocked | ||||
|     // task.  In most FreeRTOS ports this is done by simply passing | ||||
|     // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the | ||||
|     // variables value, and perform the context switch if necessary.  Check the | ||||
|     // documentation for the port in use for port specific instructions. | ||||
|     taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | ||||
| } | ||||
| </pre> | ||||
|  * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, | ||||
| 									void *pvRxData, | ||||
| 									size_t xBufferLengthBytes, | ||||
| 									BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Deletes a stream buffer that was previously created using a call to | ||||
|  * xStreamBufferCreate() or xStreamBufferCreateStatic().  If the stream | ||||
|  * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), | ||||
|  * then the allocated memory is freed. | ||||
|  * | ||||
|  * A stream buffer handle must not be used after the stream buffer has been | ||||
|  * deleted. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer to be deleted. | ||||
|  * | ||||
|  * \defgroup vStreamBufferDelete vStreamBufferDelete | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Queries a stream buffer to see if it is full.  A stream buffer is full if it | ||||
|  * does not have any free space, and therefore cannot accept any more data. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being queried. | ||||
|  * | ||||
|  * @return If the stream buffer is full then pdTRUE is returned.  Otherwise | ||||
|  * pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferIsFull xStreamBufferIsFull | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Queries a stream buffer to see if it is empty.  A stream buffer is empty if | ||||
|  * it does not contain any data. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being queried. | ||||
|  * | ||||
|  * @return If the stream buffer is empty then pdTRUE is returned.  Otherwise | ||||
|  * pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Resets a stream buffer to its initial, empty, state.  Any data that was in | ||||
|  * the stream buffer is discarded.  A stream buffer can only be reset if there | ||||
|  * are no tasks blocked waiting to either send to or receive from the stream | ||||
|  * buffer. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being reset. | ||||
|  * | ||||
|  * @return If the stream buffer is reset then pdPASS is returned.  If there was | ||||
|  * a task blocked waiting to send to or read from the stream buffer then the | ||||
|  * stream buffer is not reset and pdFAIL is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferReset xStreamBufferReset | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Queries a stream buffer to see how much free space it contains, which is | ||||
|  * equal to the amount of data that can be sent to the stream buffer before it | ||||
|  * is full. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being queried. | ||||
|  * | ||||
|  * @return The number of bytes that can be written to the stream buffer before | ||||
|  * the stream buffer would be full. | ||||
|  * | ||||
|  * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); | ||||
| </pre> | ||||
|  * | ||||
|  * Queries a stream buffer to see how much data it contains, which is equal to | ||||
|  * the number of bytes that can be read from the stream buffer before the stream | ||||
|  * buffer would be empty. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being queried. | ||||
|  * | ||||
|  * @return The number of bytes that can be read from the stream buffer before | ||||
|  * the stream buffer would be empty. | ||||
|  * | ||||
|  * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); | ||||
| </pre> | ||||
|  * | ||||
|  * A stream buffer's trigger level is the number of bytes that must be in the | ||||
|  * stream buffer before a task that is blocked on the stream buffer to | ||||
|  * wait for data is moved out of the blocked state.  For example, if a task is | ||||
|  * blocked on a read of an empty stream buffer that has a trigger level of 1 | ||||
|  * then the task will be unblocked when a single byte is written to the buffer | ||||
|  * or the task's block time expires.  As another example, if a task is blocked | ||||
|  * on a read of an empty stream buffer that has a trigger level of 10 then the | ||||
|  * task will not be unblocked until the stream buffer contains at least 10 bytes | ||||
|  * or the task's block time expires.  If a reading task's block time expires | ||||
|  * before the trigger level is reached then the task will still receive however | ||||
|  * many bytes are actually available.  Setting a trigger level of 0 will result | ||||
|  * in a trigger level of 1 being used.  It is not valid to specify a trigger | ||||
|  * level that is greater than the buffer size. | ||||
|  * | ||||
|  * A trigger level is set when the stream buffer is created, and can be modified | ||||
|  * using xStreamBufferSetTriggerLevel(). | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer being updated. | ||||
|  * | ||||
|  * @param xTriggerLevel The new trigger level for the stream buffer. | ||||
|  * | ||||
|  * @return If xTriggerLevel was less than or equal to the stream buffer's length | ||||
|  * then the trigger level will be updated and pdTRUE is returned.  Otherwise | ||||
|  * pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * For advanced users only. | ||||
|  * | ||||
|  * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when | ||||
|  * data is sent to a message buffer or stream buffer.  If there was a task that | ||||
|  * was blocked on the message or stream buffer waiting for data to arrive then | ||||
|  * the sbSEND_COMPLETED() macro sends a notification to the task to remove it | ||||
|  * from the Blocked state.  xStreamBufferSendCompletedFromISR() does the same | ||||
|  * thing.  It is provided to enable application writers to implement their own | ||||
|  * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. | ||||
|  * | ||||
|  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for | ||||
|  * additional information. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer to which data was | ||||
|  * written. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be | ||||
|  * initialised to pdFALSE before it is passed into | ||||
|  * xStreamBufferSendCompletedFromISR().  If calling | ||||
|  * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, | ||||
|  * and the task has a priority above the priority of the currently running task, | ||||
|  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a | ||||
|  * context switch should be performed before exiting the ISR. | ||||
|  * | ||||
|  * @return If a task was removed from the Blocked state then pdTRUE is returned. | ||||
|  * Otherwise pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /** | ||||
|  * stream_buffer.h | ||||
|  * | ||||
| <pre> | ||||
| BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); | ||||
| </pre> | ||||
|  * | ||||
|  * For advanced users only. | ||||
|  * | ||||
|  * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when | ||||
|  * data is read out of a message buffer or stream buffer.  If there was a task | ||||
|  * that was blocked on the message or stream buffer waiting for data to arrive | ||||
|  * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to | ||||
|  * remove it from the Blocked state.  xStreamBufferReceiveCompletedFromISR() | ||||
|  * does the same thing.  It is provided to enable application writers to | ||||
|  * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT | ||||
|  * ANY OTHER TIME. | ||||
|  * | ||||
|  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for | ||||
|  * additional information. | ||||
|  * | ||||
|  * @param xStreamBuffer The handle of the stream buffer from which data was | ||||
|  * read. | ||||
|  * | ||||
|  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be | ||||
|  * initialised to pdFALSE before it is passed into | ||||
|  * xStreamBufferReceiveCompletedFromISR().  If calling | ||||
|  * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, | ||||
|  * and the task has a priority above the priority of the currently running task, | ||||
|  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a | ||||
|  * context switch should be performed before exiting the ISR. | ||||
|  * | ||||
|  * @return If a task was removed from the Blocked state then pdTRUE is returned. | ||||
|  * Otherwise pdFALSE is returned. | ||||
|  * | ||||
|  * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR | ||||
|  * \ingroup StreamBufferManagement | ||||
|  */ | ||||
| BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| /* Functions below here are not part of the public API. */ | ||||
| StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, | ||||
| 												 size_t xTriggerLevelBytes, | ||||
| 												 BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, | ||||
| 													   size_t xTriggerLevelBytes, | ||||
| 													   BaseType_t xIsMessageBuffer, | ||||
| 													   uint8_t * const pucStreamBufferStorageArea, | ||||
| 													   StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
|  | ||||
| #if( configUSE_TRACE_FACILITY == 1 ) | ||||
| 	void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; | ||||
| 	UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
| 	uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; | ||||
| #endif | ||||
|  | ||||
| #if defined( __cplusplus ) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif	/* !defined( STREAM_BUFFER_H ) */ | ||||
							
								
								
									
										2421
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/task.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2421
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/task.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1295
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/timers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1295
									
								
								Middlewares/Third_Party/FreeRTOS/Source/include/timers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										198
									
								
								Middlewares/Third_Party/FreeRTOS/Source/list.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								Middlewares/Third_Party/FreeRTOS/Source/list.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include "FreeRTOS.h" | ||||
| #include "list.h" | ||||
|  | ||||
| /*----------------------------------------------------------- | ||||
|  * PUBLIC LIST API documented in list.h | ||||
|  *----------------------------------------------------------*/ | ||||
|  | ||||
| void vListInitialise( List_t * const pxList ) | ||||
| { | ||||
| 	/* The list structure contains a list item which is used to mark the | ||||
| 	end of the list.  To initialise the list the list end is inserted | ||||
| 	as the only list entry. */ | ||||
| 	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */ | ||||
|  | ||||
| 	/* The list end value is the highest possible value in the list to | ||||
| 	ensure it remains at the end of the list. */ | ||||
| 	pxList->xListEnd.xItemValue = portMAX_DELAY; | ||||
|  | ||||
| 	/* The list end next and previous pointers point to itself so we know | ||||
| 	when the list is empty. */ | ||||
| 	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */ | ||||
| 	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */ | ||||
|  | ||||
| 	pxList->uxNumberOfItems = ( UBaseType_t ) 0U; | ||||
|  | ||||
| 	/* Write known values into the list if | ||||
| 	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| 	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); | ||||
| 	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vListInitialiseItem( ListItem_t * const pxItem ) | ||||
| { | ||||
| 	/* Make sure the list item is not recorded as being on a list. */ | ||||
| 	pxItem->pxContainer = NULL; | ||||
|  | ||||
| 	/* Write known values into the list item if | ||||
| 	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ | ||||
| 	listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); | ||||
| 	listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) | ||||
| { | ||||
| ListItem_t * const pxIndex = pxList->pxIndex; | ||||
|  | ||||
| 	/* Only effective when configASSERT() is also defined, these tests may catch | ||||
| 	the list data structures being overwritten in memory.  They will not catch | ||||
| 	data errors caused by incorrect configuration or use of FreeRTOS. */ | ||||
| 	listTEST_LIST_INTEGRITY( pxList ); | ||||
| 	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); | ||||
|  | ||||
| 	/* Insert a new list item into pxList, but rather than sort the list, | ||||
| 	makes the new list item the last item to be removed by a call to | ||||
| 	listGET_OWNER_OF_NEXT_ENTRY(). */ | ||||
| 	pxNewListItem->pxNext = pxIndex; | ||||
| 	pxNewListItem->pxPrevious = pxIndex->pxPrevious; | ||||
|  | ||||
| 	/* Only used during decision coverage testing. */ | ||||
| 	mtCOVERAGE_TEST_DELAY(); | ||||
|  | ||||
| 	pxIndex->pxPrevious->pxNext = pxNewListItem; | ||||
| 	pxIndex->pxPrevious = pxNewListItem; | ||||
|  | ||||
| 	/* Remember which list the item is in. */ | ||||
| 	pxNewListItem->pxContainer = pxList; | ||||
|  | ||||
| 	( pxList->uxNumberOfItems )++; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) | ||||
| { | ||||
| ListItem_t *pxIterator; | ||||
| const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; | ||||
|  | ||||
| 	/* Only effective when configASSERT() is also defined, these tests may catch | ||||
| 	the list data structures being overwritten in memory.  They will not catch | ||||
| 	data errors caused by incorrect configuration or use of FreeRTOS. */ | ||||
| 	listTEST_LIST_INTEGRITY( pxList ); | ||||
| 	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); | ||||
|  | ||||
| 	/* Insert the new list item into the list, sorted in xItemValue order. | ||||
|  | ||||
| 	If the list already contains a list item with the same item value then the | ||||
| 	new list item should be placed after it.  This ensures that TCBs which are | ||||
| 	stored in ready lists (all of which have the same xItemValue value) get a | ||||
| 	share of the CPU.  However, if the xItemValue is the same as the back marker | ||||
| 	the iteration loop below will not end.  Therefore the value is checked | ||||
| 	first, and the algorithm slightly modified if necessary. */ | ||||
| 	if( xValueOfInsertion == portMAX_DELAY ) | ||||
| 	{ | ||||
| 		pxIterator = pxList->xListEnd.pxPrevious; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* *** NOTE *********************************************************** | ||||
| 		If you find your application is crashing here then likely causes are | ||||
| 		listed below.  In addition see https://www.freertos.org/FAQHelp.html for | ||||
| 		more tips, and ensure configASSERT() is defined! | ||||
| 		https://www.freertos.org/a00110.html#configASSERT | ||||
|  | ||||
| 			1) Stack overflow - | ||||
| 			   see https://www.freertos.org/Stacks-and-stack-overflow-checking.html | ||||
| 			2) Incorrect interrupt priority assignment, especially on Cortex-M | ||||
| 			   parts where numerically high priority values denote low actual | ||||
| 			   interrupt priorities, which can seem counter intuitive.  See | ||||
| 			   https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition | ||||
| 			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on | ||||
| 			   https://www.freertos.org/a00110.html | ||||
| 			3) Calling an API function from within a critical section or when | ||||
| 			   the scheduler is suspended, or calling an API function that does | ||||
| 			   not end in "FromISR" from an interrupt. | ||||
| 			4) Using a queue or semaphore before it has been initialised or | ||||
| 			   before the scheduler has been started (are interrupts firing | ||||
| 			   before vTaskStartScheduler() has been called?). | ||||
| 		**********************************************************************/ | ||||
|  | ||||
| 		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ | ||||
| 		{ | ||||
| 			/* There is nothing to do here, just iterating to the wanted | ||||
| 			insertion position. */ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	pxNewListItem->pxNext = pxIterator->pxNext; | ||||
| 	pxNewListItem->pxNext->pxPrevious = pxNewListItem; | ||||
| 	pxNewListItem->pxPrevious = pxIterator; | ||||
| 	pxIterator->pxNext = pxNewListItem; | ||||
|  | ||||
| 	/* Remember which list the item is in.  This allows fast removal of the | ||||
| 	item later. */ | ||||
| 	pxNewListItem->pxContainer = pxList; | ||||
|  | ||||
| 	( pxList->uxNumberOfItems )++; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) | ||||
| { | ||||
| /* The list item knows which list it is in.  Obtain the list from the list | ||||
| item. */ | ||||
| List_t * const pxList = pxItemToRemove->pxContainer; | ||||
|  | ||||
| 	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; | ||||
| 	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; | ||||
|  | ||||
| 	/* Only used during decision coverage testing. */ | ||||
| 	mtCOVERAGE_TEST_DELAY(); | ||||
|  | ||||
| 	/* Make sure the index is left pointing to a valid item. */ | ||||
| 	if( pxList->pxIndex == pxItemToRemove ) | ||||
| 	{ | ||||
| 		pxList->pxIndex = pxItemToRemove->pxPrevious; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		mtCOVERAGE_TEST_MARKER(); | ||||
| 	} | ||||
|  | ||||
| 	pxItemToRemove->pxContainer = NULL; | ||||
| 	( pxList->uxNumberOfItems )--; | ||||
|  | ||||
| 	return pxList->uxNumberOfItems; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
							
								
								
									
										765
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										765
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,765 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /*----------------------------------------------------------- | ||||
|  * Implementation of functions defined in portable.h for the ARM CM4F port. | ||||
|  *----------------------------------------------------------*/ | ||||
|  | ||||
| /* Scheduler includes. */ | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
|  | ||||
| #ifndef __VFP_FP__ | ||||
| 	#error This port can only be used when the project options are configured to enable hardware floating point support. | ||||
| #endif | ||||
|  | ||||
| #ifndef configSYSTICK_CLOCK_HZ | ||||
| 	#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ | ||||
| 	/* Ensure the SysTick is clocked at the same frequency as the core. */ | ||||
| 	#define portNVIC_SYSTICK_CLK_BIT	( 1UL << 2UL ) | ||||
| #else | ||||
| 	/* The way the SysTick is clocked is not modified in case it is not the same | ||||
| 	as the core. */ | ||||
| 	#define portNVIC_SYSTICK_CLK_BIT	( 0 ) | ||||
| #endif | ||||
|  | ||||
| /* Constants required to manipulate the core.  Registers first... */ | ||||
| #define portNVIC_SYSTICK_CTRL_REG			( * ( ( volatile uint32_t * ) 0xe000e010 ) ) | ||||
| #define portNVIC_SYSTICK_LOAD_REG			( * ( ( volatile uint32_t * ) 0xe000e014 ) ) | ||||
| #define portNVIC_SYSTICK_CURRENT_VALUE_REG	( * ( ( volatile uint32_t * ) 0xe000e018 ) ) | ||||
| #define portNVIC_SYSPRI2_REG				( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) | ||||
| /* ...then bits in the registers. */ | ||||
| #define portNVIC_SYSTICK_INT_BIT			( 1UL << 1UL ) | ||||
| #define portNVIC_SYSTICK_ENABLE_BIT			( 1UL << 0UL ) | ||||
| #define portNVIC_SYSTICK_COUNT_FLAG_BIT		( 1UL << 16UL ) | ||||
| #define portNVIC_PENDSVCLEAR_BIT 			( 1UL << 27UL ) | ||||
| #define portNVIC_PEND_SYSTICK_CLEAR_BIT		( 1UL << 25UL ) | ||||
|  | ||||
| #define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) | ||||
| #define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) | ||||
|  | ||||
| /* Constants required to check the validity of an interrupt priority. */ | ||||
| #define portFIRST_USER_INTERRUPT_NUMBER		( 16 ) | ||||
| #define portNVIC_IP_REGISTERS_OFFSET_16 	( 0xE000E3F0 ) | ||||
| #define portAIRCR_REG						( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) | ||||
| #define portMAX_8_BIT_VALUE					( ( uint8_t ) 0xff ) | ||||
| #define portTOP_BIT_OF_BYTE					( ( uint8_t ) 0x80 ) | ||||
| #define portMAX_PRIGROUP_BITS				( ( uint8_t ) 7 ) | ||||
| #define portPRIORITY_GROUP_MASK				( 0x07UL << 8UL ) | ||||
| #define portPRIGROUP_SHIFT					( 8UL ) | ||||
|  | ||||
| /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ | ||||
| #define portVECTACTIVE_MASK					( 0xFFUL ) | ||||
|  | ||||
| /* Constants required to manipulate the VFP. */ | ||||
| #define portFPCCR							( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ | ||||
| #define portASPEN_AND_LSPEN_BITS			( 0x3UL << 30UL ) | ||||
|  | ||||
| /* Constants required to set up the initial stack. */ | ||||
| #define portINITIAL_XPSR					( 0x01000000 ) | ||||
| #define portINITIAL_EXC_RETURN				( 0xfffffffd ) | ||||
|  | ||||
| /* The systick is a 24-bit counter. */ | ||||
| #define portMAX_24_BIT_NUMBER				( 0xffffffUL ) | ||||
|  | ||||
| /* For strict compliance with the Cortex-M spec the task start address should | ||||
| have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ | ||||
| #define portSTART_ADDRESS_MASK		( ( StackType_t ) 0xfffffffeUL ) | ||||
|  | ||||
| /* A fiddle factor to estimate the number of SysTick counts that would have | ||||
| occurred while the SysTick counter is stopped during tickless idle | ||||
| calculations. */ | ||||
| #define portMISSED_COUNTS_FACTOR			( 45UL ) | ||||
|  | ||||
| /* Let the user override the pre-loading of the initial LR with the address of | ||||
| prvTaskExitError() in case it messes up unwinding of the stack in the | ||||
| debugger. */ | ||||
| #ifdef configTASK_RETURN_ADDRESS | ||||
| 	#define portTASK_RETURN_ADDRESS	configTASK_RETURN_ADDRESS | ||||
| #else | ||||
| 	#define portTASK_RETURN_ADDRESS	prvTaskExitError | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Setup the timer to generate the tick interrupts.  The implementation in this | ||||
|  * file is weak to allow application writers to change the timer used to | ||||
|  * generate the tick interrupt. | ||||
|  */ | ||||
| void vPortSetupTimerInterrupt( void ); | ||||
|  | ||||
| /* | ||||
|  * Exception handlers. | ||||
|  */ | ||||
| void xPortPendSVHandler( void ) __attribute__ (( naked )); | ||||
| void xPortSysTickHandler( void ); | ||||
| void vPortSVCHandler( void ) __attribute__ (( naked )); | ||||
|  | ||||
| /* | ||||
|  * Start first task is a separate function so it can be tested in isolation. | ||||
|  */ | ||||
| static void prvPortStartFirstTask( void ) __attribute__ (( naked )); | ||||
|  | ||||
| /* | ||||
|  * Function to enable the VFP. | ||||
|  */ | ||||
| static void vPortEnableVFP( void ) __attribute__ (( naked )); | ||||
|  | ||||
| /* | ||||
|  * Used to catch tasks that attempt to return from their implementing function. | ||||
|  */ | ||||
| static void prvTaskExitError( void ); | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Each task maintains its own interrupt status in the critical nesting | ||||
| variable. */ | ||||
| static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; | ||||
|  | ||||
| /* | ||||
|  * The number of SysTick increments that make up one tick period. | ||||
|  */ | ||||
| #if( configUSE_TICKLESS_IDLE == 1 ) | ||||
| 	static uint32_t ulTimerCountsForOneTick = 0; | ||||
| #endif /* configUSE_TICKLESS_IDLE */ | ||||
|  | ||||
| /* | ||||
|  * The maximum number of tick periods that can be suppressed is limited by the | ||||
|  * 24 bit resolution of the SysTick timer. | ||||
|  */ | ||||
| #if( configUSE_TICKLESS_IDLE == 1 ) | ||||
| 	static uint32_t xMaximumPossibleSuppressedTicks = 0; | ||||
| #endif /* configUSE_TICKLESS_IDLE */ | ||||
|  | ||||
| /* | ||||
|  * Compensate for the CPU cycles that pass while the SysTick is stopped (low | ||||
|  * power functionality only. | ||||
|  */ | ||||
| #if( configUSE_TICKLESS_IDLE == 1 ) | ||||
| 	static uint32_t ulStoppedTimerCompensation = 0; | ||||
| #endif /* configUSE_TICKLESS_IDLE */ | ||||
|  | ||||
| /* | ||||
|  * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure | ||||
|  * FreeRTOS API functions are not called from interrupts that have been assigned | ||||
|  * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. | ||||
|  */ | ||||
| #if( configASSERT_DEFINED == 1 ) | ||||
| 	 static uint8_t ucMaxSysCallPriority = 0; | ||||
| 	 static uint32_t ulMaxPRIGROUPValue = 0; | ||||
| 	 static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; | ||||
| #endif /* configASSERT_DEFINED */ | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * See header file for description. | ||||
|  */ | ||||
| StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) | ||||
| { | ||||
| 	/* Simulate the stack frame as it would be created by a context switch | ||||
| 	interrupt. */ | ||||
|  | ||||
| 	/* Offset added to account for the way the MCU uses the stack on entry/exit | ||||
| 	of interrupts, and to ensure alignment. */ | ||||
| 	pxTopOfStack--; | ||||
|  | ||||
| 	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */ | ||||
| 	pxTopOfStack--; | ||||
| 	*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK;	/* PC */ | ||||
| 	pxTopOfStack--; | ||||
| 	*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS;	/* LR */ | ||||
|  | ||||
| 	/* Save code space by skipping register initialisation. */ | ||||
| 	pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */ | ||||
| 	*pxTopOfStack = ( StackType_t ) pvParameters;	/* R0 */ | ||||
|  | ||||
| 	/* A save method is being used that requires each task to maintain its | ||||
| 	own exec return value. */ | ||||
| 	pxTopOfStack--; | ||||
| 	*pxTopOfStack = portINITIAL_EXC_RETURN; | ||||
|  | ||||
| 	pxTopOfStack -= 8;	/* R11, R10, R9, R8, R7, R6, R5 and R4. */ | ||||
|  | ||||
| 	return pxTopOfStack; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvTaskExitError( void ) | ||||
| { | ||||
| volatile uint32_t ulDummy = 0; | ||||
|  | ||||
| 	/* A function that implements a task must not exit or attempt to return to | ||||
| 	its caller as there is nothing to return to.  If a task wants to exit it | ||||
| 	should instead call vTaskDelete( NULL ). | ||||
|  | ||||
| 	Artificially force an assert() to be triggered if configASSERT() is | ||||
| 	defined, then stop here so application writers can catch the error. */ | ||||
| 	configASSERT( uxCriticalNesting == ~0UL ); | ||||
| 	portDISABLE_INTERRUPTS(); | ||||
| 	while( ulDummy == 0 ) | ||||
| 	{ | ||||
| 		/* This file calls prvTaskExitError() after the scheduler has been | ||||
| 		started to remove a compiler warning about the function being defined | ||||
| 		but never called.  ulDummy is used purely to quieten other warnings | ||||
| 		about code appearing after this function is called - making ulDummy | ||||
| 		volatile makes the compiler think the function could return and | ||||
| 		therefore not output an 'unreachable code' warning for code that appears | ||||
| 		after it. */ | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortSVCHandler( void ) | ||||
| { | ||||
| 	__asm volatile ( | ||||
| 					"	ldr	r3, pxCurrentTCBConst2		\n" /* Restore the context. */ | ||||
| 					"	ldr r1, [r3]					\n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ | ||||
| 					"	ldr r0, [r1]					\n" /* The first item in pxCurrentTCB is the task top of stack. */ | ||||
| 					"	ldmia r0!, {r4-r11, r14}		\n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ | ||||
| 					"	msr psp, r0						\n" /* Restore the task stack pointer. */ | ||||
| 					"	isb								\n" | ||||
| 					"	mov r0, #0 						\n" | ||||
| 					"	msr	basepri, r0					\n" | ||||
| 					"	bx r14							\n" | ||||
| 					"									\n" | ||||
| 					"	.align 4						\n" | ||||
| 					"pxCurrentTCBConst2: .word pxCurrentTCB				\n" | ||||
| 				); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvPortStartFirstTask( void ) | ||||
| { | ||||
| 	/* Start the first task.  This also clears the bit that indicates the FPU is | ||||
| 	in use in case the FPU was used before the scheduler was started - which | ||||
| 	would otherwise result in the unnecessary leaving of space in the SVC stack | ||||
| 	for lazy saving of FPU registers. */ | ||||
| 	__asm volatile( | ||||
| 					" ldr r0, =0xE000ED08 	\n" /* Use the NVIC offset register to locate the stack. */ | ||||
| 					" ldr r0, [r0] 			\n" | ||||
| 					" ldr r0, [r0] 			\n" | ||||
| 					" msr msp, r0			\n" /* Set the msp back to the start of the stack. */ | ||||
| 					" mov r0, #0			\n" /* Clear the bit that indicates the FPU is in use, see comment above. */ | ||||
| 					" msr control, r0		\n" | ||||
| 					" cpsie i				\n" /* Globally enable interrupts. */ | ||||
| 					" cpsie f				\n" | ||||
| 					" dsb					\n" | ||||
| 					" isb					\n" | ||||
| 					" svc 0					\n" /* System call to start first task. */ | ||||
| 					" nop					\n" | ||||
| 				); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * See header file for description. | ||||
|  */ | ||||
| BaseType_t xPortStartScheduler( void ) | ||||
| { | ||||
| 	/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. | ||||
| 	See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ | ||||
| 	configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); | ||||
|  | ||||
| 	#if( configASSERT_DEFINED == 1 ) | ||||
| 	{ | ||||
| 		volatile uint32_t ulOriginalPriority; | ||||
| 		volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); | ||||
| 		volatile uint8_t ucMaxPriorityValue; | ||||
|  | ||||
| 		/* Determine the maximum priority from which ISR safe FreeRTOS API | ||||
| 		functions can be called.  ISR safe functions are those that end in | ||||
| 		"FromISR".  FreeRTOS maintains separate thread and ISR API functions to | ||||
| 		ensure interrupt entry is as fast and simple as possible. | ||||
|  | ||||
| 		Save the interrupt priority value that is about to be clobbered. */ | ||||
| 		ulOriginalPriority = *pucFirstUserPriorityRegister; | ||||
|  | ||||
| 		/* Determine the number of priority bits available.  First write to all | ||||
| 		possible bits. */ | ||||
| 		*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; | ||||
|  | ||||
| 		/* Read the value back to see how many bits stuck. */ | ||||
| 		ucMaxPriorityValue = *pucFirstUserPriorityRegister; | ||||
|  | ||||
| 		/* Use the same mask on the maximum system call priority. */ | ||||
| 		ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; | ||||
|  | ||||
| 		/* Calculate the maximum acceptable priority group value for the number | ||||
| 		of bits read back. */ | ||||
| 		ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; | ||||
| 		while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) | ||||
| 		{ | ||||
| 			ulMaxPRIGROUPValue--; | ||||
| 			ucMaxPriorityValue <<= ( uint8_t ) 0x01; | ||||
| 		} | ||||
|  | ||||
| 		#ifdef __NVIC_PRIO_BITS | ||||
| 		{ | ||||
| 			/* Check the CMSIS configuration that defines the number of | ||||
| 			priority bits matches the number of priority bits actually queried | ||||
| 			from the hardware. */ | ||||
| 			configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); | ||||
| 		} | ||||
| 		#endif | ||||
|  | ||||
| 		#ifdef configPRIO_BITS | ||||
| 		{ | ||||
| 			/* Check the FreeRTOS configuration that defines the number of | ||||
| 			priority bits matches the number of priority bits actually queried | ||||
| 			from the hardware. */ | ||||
| 			configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); | ||||
| 		} | ||||
| 		#endif | ||||
|  | ||||
| 		/* Shift the priority group value back to its position within the AIRCR | ||||
| 		register. */ | ||||
| 		ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; | ||||
| 		ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; | ||||
|  | ||||
| 		/* Restore the clobbered interrupt priority register to its original | ||||
| 		value. */ | ||||
| 		*pucFirstUserPriorityRegister = ulOriginalPriority; | ||||
| 	} | ||||
| 	#endif /* conifgASSERT_DEFINED */ | ||||
|  | ||||
| 	/* Make PendSV and SysTick the lowest priority interrupts. */ | ||||
| 	portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; | ||||
| 	portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; | ||||
|  | ||||
| 	/* Start the timer that generates the tick ISR.  Interrupts are disabled | ||||
| 	here already. */ | ||||
| 	vPortSetupTimerInterrupt(); | ||||
|  | ||||
| 	/* Initialise the critical nesting count ready for the first task. */ | ||||
| 	uxCriticalNesting = 0; | ||||
|  | ||||
| 	/* Ensure the VFP is enabled - it should be anyway. */ | ||||
| 	vPortEnableVFP(); | ||||
|  | ||||
| 	/* Lazy save always. */ | ||||
| 	*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; | ||||
|  | ||||
| 	/* Start the first task. */ | ||||
| 	prvPortStartFirstTask(); | ||||
|  | ||||
| 	/* Should never get here as the tasks will now be executing!  Call the task | ||||
| 	exit error function to prevent compiler warnings about a static function | ||||
| 	not being called in the case that the application writer overrides this | ||||
| 	functionality by defining configTASK_RETURN_ADDRESS.  Call | ||||
| 	vTaskSwitchContext() so link time optimisation does not remove the | ||||
| 	symbol. */ | ||||
| 	vTaskSwitchContext(); | ||||
| 	prvTaskExitError(); | ||||
|  | ||||
| 	/* Should not get here! */ | ||||
| 	return 0; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortEndScheduler( void ) | ||||
| { | ||||
| 	/* Not implemented in ports where there is nothing to return to. | ||||
| 	Artificially force an assert. */ | ||||
| 	configASSERT( uxCriticalNesting == 1000UL ); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortEnterCritical( void ) | ||||
| { | ||||
| 	portDISABLE_INTERRUPTS(); | ||||
| 	uxCriticalNesting++; | ||||
|  | ||||
| 	/* This is not the interrupt safe version of the enter critical function so | ||||
| 	assert() if it is being called from an interrupt context.  Only API | ||||
| 	functions that end in "FromISR" can be used in an interrupt.  Only assert if | ||||
| 	the critical nesting count is 1 to protect against recursive calls if the | ||||
| 	assert function also uses a critical section. */ | ||||
| 	if( uxCriticalNesting == 1 ) | ||||
| 	{ | ||||
| 		configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortExitCritical( void ) | ||||
| { | ||||
| 	configASSERT( uxCriticalNesting ); | ||||
| 	uxCriticalNesting--; | ||||
| 	if( uxCriticalNesting == 0 ) | ||||
| 	{ | ||||
| 		portENABLE_INTERRUPTS(); | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void xPortPendSVHandler( void ) | ||||
| { | ||||
| 	/* This is a naked function. */ | ||||
|  | ||||
| 	__asm volatile | ||||
| 	( | ||||
| 	"	mrs r0, psp							\n" | ||||
| 	"	isb									\n" | ||||
| 	"										\n" | ||||
| 	"	ldr	r3, pxCurrentTCBConst			\n" /* Get the location of the current TCB. */ | ||||
| 	"	ldr	r2, [r3]						\n" | ||||
| 	"										\n" | ||||
| 	"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, push high vfp registers. */ | ||||
| 	"	it eq								\n" | ||||
| 	"	vstmdbeq r0!, {s16-s31}				\n" | ||||
| 	"										\n" | ||||
| 	"	stmdb r0!, {r4-r11, r14}			\n" /* Save the core registers. */ | ||||
| 	"	str r0, [r2]						\n" /* Save the new top of stack into the first member of the TCB. */ | ||||
| 	"										\n" | ||||
| 	"	stmdb sp!, {r0, r3}					\n" | ||||
| 	"	mov r0, %0 							\n" | ||||
| 	"	cpsid i								\n" /* Errata workaround. */ | ||||
| 	"	msr basepri, r0						\n" | ||||
| 	"	dsb									\n" | ||||
| 	"	isb									\n" | ||||
| 	"	cpsie i								\n" /* Errata workaround. */ | ||||
| 	"	bl vTaskSwitchContext				\n" | ||||
| 	"	mov r0, #0							\n" | ||||
| 	"	msr basepri, r0						\n" | ||||
| 	"	ldmia sp!, {r0, r3}					\n" | ||||
| 	"										\n" | ||||
| 	"	ldr r1, [r3]						\n" /* The first item in pxCurrentTCB is the task top of stack. */ | ||||
| 	"	ldr r0, [r1]						\n" | ||||
| 	"										\n" | ||||
| 	"	ldmia r0!, {r4-r11, r14}			\n" /* Pop the core registers. */ | ||||
| 	"										\n" | ||||
| 	"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, pop the high vfp registers too. */ | ||||
| 	"	it eq								\n" | ||||
| 	"	vldmiaeq r0!, {s16-s31}				\n" | ||||
| 	"										\n" | ||||
| 	"	msr psp, r0							\n" | ||||
| 	"	isb									\n" | ||||
| 	"										\n" | ||||
| 	#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ | ||||
| 		#if WORKAROUND_PMU_CM001 == 1 | ||||
| 	"			push { r14 }				\n" | ||||
| 	"			pop { pc }					\n" | ||||
| 		#endif | ||||
| 	#endif | ||||
| 	"										\n" | ||||
| 	"	bx r14								\n" | ||||
| 	"										\n" | ||||
| 	"	.align 4							\n" | ||||
| 	"pxCurrentTCBConst: .word pxCurrentTCB	\n" | ||||
| 	::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) | ||||
| 	); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void xPortSysTickHandler( void ) | ||||
| { | ||||
| 	/* The SysTick runs at the lowest interrupt priority, so when this interrupt | ||||
| 	executes all interrupts must be unmasked.  There is therefore no need to | ||||
| 	save and then restore the interrupt mask value as its value is already | ||||
| 	known. */ | ||||
| 	portDISABLE_INTERRUPTS(); | ||||
| 	{ | ||||
| 		/* Increment the RTOS tick. */ | ||||
| 		if( xTaskIncrementTick() != pdFALSE ) | ||||
| 		{ | ||||
| 			/* A context switch is required.  Context switching is performed in | ||||
| 			the PendSV interrupt.  Pend the PendSV interrupt. */ | ||||
| 			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; | ||||
| 		} | ||||
| 	} | ||||
| 	portENABLE_INTERRUPTS(); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( configUSE_TICKLESS_IDLE == 1 ) | ||||
|  | ||||
| 	__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) | ||||
| 	{ | ||||
| 	uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements; | ||||
| 	TickType_t xModifiableIdleTime; | ||||
|  | ||||
| 		/* Make sure the SysTick reload value does not overflow the counter. */ | ||||
| 		if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) | ||||
| 		{ | ||||
| 			xExpectedIdleTime = xMaximumPossibleSuppressedTicks; | ||||
| 		} | ||||
|  | ||||
| 		/* Stop the SysTick momentarily.  The time the SysTick is stopped for | ||||
| 		is accounted for as best it can be, but using the tickless mode will | ||||
| 		inevitably result in some tiny drift of the time maintained by the | ||||
| 		kernel with respect to calendar time. */ | ||||
| 		portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; | ||||
|  | ||||
| 		/* Calculate the reload value required to wait xExpectedIdleTime | ||||
| 		tick periods.  -1 is used because this code will execute part way | ||||
| 		through one of the tick periods. */ | ||||
| 		ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); | ||||
| 		if( ulReloadValue > ulStoppedTimerCompensation ) | ||||
| 		{ | ||||
| 			ulReloadValue -= ulStoppedTimerCompensation; | ||||
| 		} | ||||
|  | ||||
| 		/* Enter a critical section but don't use the taskENTER_CRITICAL() | ||||
| 		method as that will mask interrupts that should exit sleep mode. */ | ||||
| 		__asm volatile( "cpsid i" ::: "memory" ); | ||||
| 		__asm volatile( "dsb" ); | ||||
| 		__asm volatile( "isb" ); | ||||
|  | ||||
| 		/* If a context switch is pending or a task is waiting for the scheduler | ||||
| 		to be unsuspended then abandon the low power entry. */ | ||||
| 		if( eTaskConfirmSleepModeStatus() == eAbortSleep ) | ||||
| 		{ | ||||
| 			/* Restart from whatever is left in the count register to complete | ||||
| 			this tick period. */ | ||||
| 			portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; | ||||
|  | ||||
| 			/* Restart SysTick. */ | ||||
| 			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; | ||||
|  | ||||
| 			/* Reset the reload register to the value required for normal tick | ||||
| 			periods. */ | ||||
| 			portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; | ||||
|  | ||||
| 			/* Re-enable interrupts - see comments above the cpsid instruction() | ||||
| 			above. */ | ||||
| 			__asm volatile( "cpsie i" ::: "memory" ); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* Set the new reload value. */ | ||||
| 			portNVIC_SYSTICK_LOAD_REG = ulReloadValue; | ||||
|  | ||||
| 			/* Clear the SysTick count flag and set the count value back to | ||||
| 			zero. */ | ||||
| 			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; | ||||
|  | ||||
| 			/* Restart SysTick. */ | ||||
| 			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; | ||||
|  | ||||
| 			/* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can | ||||
| 			set its parameter to 0 to indicate that its implementation contains | ||||
| 			its own wait for interrupt or wait for event instruction, and so wfi | ||||
| 			should not be executed again.  However, the original expected idle | ||||
| 			time variable must remain unmodified, so a copy is taken. */ | ||||
| 			xModifiableIdleTime = xExpectedIdleTime; | ||||
| 			configPRE_SLEEP_PROCESSING( &xModifiableIdleTime ); | ||||
| 			if( xModifiableIdleTime > 0 ) | ||||
| 			{ | ||||
| 				__asm volatile( "dsb" ::: "memory" ); | ||||
| 				__asm volatile( "wfi" ); | ||||
| 				__asm volatile( "isb" ); | ||||
| 			} | ||||
| 			configPOST_SLEEP_PROCESSING( &xExpectedIdleTime ); | ||||
|  | ||||
| 			/* Re-enable interrupts to allow the interrupt that brought the MCU | ||||
| 			out of sleep mode to execute immediately.  see comments above | ||||
| 			__disable_interrupt() call above. */ | ||||
| 			__asm volatile( "cpsie i" ::: "memory" ); | ||||
| 			__asm volatile( "dsb" ); | ||||
| 			__asm volatile( "isb" ); | ||||
|  | ||||
| 			/* Disable interrupts again because the clock is about to be stopped | ||||
| 			and interrupts that execute while the clock is stopped will increase | ||||
| 			any slippage between the time maintained by the RTOS and calendar | ||||
| 			time. */ | ||||
| 			__asm volatile( "cpsid i" ::: "memory" ); | ||||
| 			__asm volatile( "dsb" ); | ||||
| 			__asm volatile( "isb" ); | ||||
|  | ||||
| 			/* Disable the SysTick clock without reading the | ||||
| 			portNVIC_SYSTICK_CTRL_REG register to ensure the | ||||
| 			portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set.  Again, | ||||
| 			the time the SysTick is stopped for is accounted for as best it can | ||||
| 			be, but using the tickless mode will inevitably result in some tiny | ||||
| 			drift of the time maintained by the kernel with respect to calendar | ||||
| 			time*/ | ||||
| 			portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); | ||||
|  | ||||
| 			/* Determine if the SysTick clock has already counted to zero and | ||||
| 			been set back to the current reload value (the reload back being | ||||
| 			correct for the entire expected idle time) or if the SysTick is yet | ||||
| 			to count to zero (in which case an interrupt other than the SysTick | ||||
| 			must have brought the system out of sleep mode). */ | ||||
| 			if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) | ||||
| 			{ | ||||
| 				uint32_t ulCalculatedLoadValue; | ||||
|  | ||||
| 				/* The tick interrupt is already pending, and the SysTick count | ||||
| 				reloaded with ulReloadValue.  Reset the | ||||
| 				portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick | ||||
| 				period. */ | ||||
| 				ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); | ||||
|  | ||||
| 				/* Don't allow a tiny value, or values that have somehow | ||||
| 				underflowed because the post sleep hook did something | ||||
| 				that took too long. */ | ||||
| 				if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) | ||||
| 				{ | ||||
| 					ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); | ||||
| 				} | ||||
|  | ||||
| 				portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; | ||||
|  | ||||
| 				/* As the pending tick will be processed as soon as this | ||||
| 				function exits, the tick value maintained by the tick is stepped | ||||
| 				forward by one less than the time spent waiting. */ | ||||
| 				ulCompleteTickPeriods = xExpectedIdleTime - 1UL; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* Something other than the tick interrupt ended the sleep. | ||||
| 				Work out how long the sleep lasted rounded to complete tick | ||||
| 				periods (not the ulReload value which accounted for part | ||||
| 				ticks). */ | ||||
| 				ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; | ||||
|  | ||||
| 				/* How many complete tick periods passed while the processor | ||||
| 				was waiting? */ | ||||
| 				ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; | ||||
|  | ||||
| 				/* The reload value is set to whatever fraction of a single tick | ||||
| 				period remains. */ | ||||
| 				portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; | ||||
| 			} | ||||
|  | ||||
| 			/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG | ||||
| 			again, then set portNVIC_SYSTICK_LOAD_REG back to its standard | ||||
| 			value. */ | ||||
| 			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; | ||||
| 			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; | ||||
| 			vTaskStepTick( ulCompleteTickPeriods ); | ||||
| 			portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; | ||||
|  | ||||
| 			/* Exit with interrpts enabled. */ | ||||
| 			__asm volatile( "cpsie i" ::: "memory" ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| #endif /* #if configUSE_TICKLESS_IDLE */ | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * Setup the systick timer to generate the tick interrupts at the required | ||||
|  * frequency. | ||||
|  */ | ||||
| __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) | ||||
| { | ||||
| 	/* Calculate the constants required to configure the tick interrupt. */ | ||||
| 	#if( configUSE_TICKLESS_IDLE == 1 ) | ||||
| 	{ | ||||
| 		ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); | ||||
| 		xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; | ||||
| 		ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); | ||||
| 	} | ||||
| 	#endif /* configUSE_TICKLESS_IDLE */ | ||||
|  | ||||
| 	/* Stop and clear the SysTick. */ | ||||
| 	portNVIC_SYSTICK_CTRL_REG = 0UL; | ||||
| 	portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; | ||||
|  | ||||
| 	/* Configure SysTick to interrupt at the requested rate. */ | ||||
| 	portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; | ||||
| 	portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* This is a naked function. */ | ||||
| static void vPortEnableVFP( void ) | ||||
| { | ||||
| 	__asm volatile | ||||
| 	( | ||||
| 		"	ldr.w r0, =0xE000ED88		\n" /* The FPU enable bits are in the CPACR. */ | ||||
| 		"	ldr r1, [r0]				\n" | ||||
| 		"								\n" | ||||
| 		"	orr r1, r1, #( 0xf << 20 )	\n" /* Enable CP10 and CP11 coprocessors, then save back. */ | ||||
| 		"	str r1, [r0]				\n" | ||||
| 		"	bx r14						" | ||||
| 	); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #if( configASSERT_DEFINED == 1 ) | ||||
|  | ||||
| 	void vPortValidateInterruptPriority( void ) | ||||
| 	{ | ||||
| 	uint32_t ulCurrentInterrupt; | ||||
| 	uint8_t ucCurrentPriority; | ||||
|  | ||||
| 		/* Obtain the number of the currently executing interrupt. */ | ||||
| 		__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); | ||||
|  | ||||
| 		/* Is the interrupt number a user defined interrupt? */ | ||||
| 		if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) | ||||
| 		{ | ||||
| 			/* Look up the interrupt's priority. */ | ||||
| 			ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; | ||||
|  | ||||
| 			/* The following assertion will fail if a service routine (ISR) for | ||||
| 			an interrupt that has been assigned a priority above | ||||
| 			configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API | ||||
| 			function.  ISR safe FreeRTOS API functions must *only* be called | ||||
| 			from interrupts that have been assigned a priority at or below | ||||
| 			configMAX_SYSCALL_INTERRUPT_PRIORITY. | ||||
|  | ||||
| 			Numerically low interrupt priority numbers represent logically high | ||||
| 			interrupt priorities, therefore the priority of the interrupt must | ||||
| 			be set to a value equal to or numerically *higher* than | ||||
| 			configMAX_SYSCALL_INTERRUPT_PRIORITY. | ||||
|  | ||||
| 			Interrupts that	use the FreeRTOS API must not be left at their | ||||
| 			default priority of	zero as that is the highest possible priority, | ||||
| 			which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, | ||||
| 			and	therefore also guaranteed to be invalid. | ||||
|  | ||||
| 			FreeRTOS maintains separate thread and ISR API functions to ensure | ||||
| 			interrupt entry is as fast and simple as possible. | ||||
|  | ||||
| 			The following links provide detailed information: | ||||
| 			http://www.freertos.org/RTOS-Cortex-M3-M4.html | ||||
| 			http://www.freertos.org/FAQHelp.html */ | ||||
| 			configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); | ||||
| 		} | ||||
|  | ||||
| 		/* Priority grouping:  The interrupt controller (NVIC) allows the bits | ||||
| 		that define each interrupt's priority to be split between bits that | ||||
| 		define the interrupt's pre-emption priority bits and bits that define | ||||
| 		the interrupt's sub-priority.  For simplicity all bits must be defined | ||||
| 		to be pre-emption priority bits.  The following assertion will fail if | ||||
| 		this is not the case (if some bits represent a sub-priority). | ||||
|  | ||||
| 		If the application only uses CMSIS libraries for interrupt | ||||
| 		configuration then the correct setting can be achieved on all Cortex-M | ||||
| 		devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the | ||||
| 		scheduler.  Note however that some vendor specific peripheral libraries | ||||
| 		assume a non-zero priority group setting, in which cases using a value | ||||
| 		of zero will result in unpredictable behaviour. */ | ||||
| 		configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); | ||||
| 	} | ||||
|  | ||||
| #endif /* configASSERT_DEFINED */ | ||||
|  | ||||
|  | ||||
							
								
								
									
										247
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef PORTMACRO_H | ||||
| #define PORTMACRO_H | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /*----------------------------------------------------------- | ||||
|  * Port specific definitions. | ||||
|  * | ||||
|  * The settings in this file configure FreeRTOS correctly for the | ||||
|  * given hardware and compiler. | ||||
|  * | ||||
|  * These settings should not be altered. | ||||
|  *----------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| /* Type definitions. */ | ||||
| #define portCHAR		char | ||||
| #define portFLOAT		float | ||||
| #define portDOUBLE		double | ||||
| #define portLONG		long | ||||
| #define portSHORT		short | ||||
| #define portSTACK_TYPE	uint32_t | ||||
| #define portBASE_TYPE	long | ||||
|  | ||||
| typedef portSTACK_TYPE StackType_t; | ||||
| typedef long BaseType_t; | ||||
| typedef unsigned long UBaseType_t; | ||||
|  | ||||
| #if( configUSE_16_BIT_TICKS == 1 ) | ||||
| 	typedef uint16_t TickType_t; | ||||
| 	#define portMAX_DELAY ( TickType_t ) 0xffff | ||||
| #else | ||||
| 	typedef uint32_t TickType_t; | ||||
| 	#define portMAX_DELAY ( TickType_t ) 0xffffffffUL | ||||
|  | ||||
| 	/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do | ||||
| 	not need to be guarded with a critical section. */ | ||||
| 	#define portTICK_TYPE_IS_ATOMIC 1 | ||||
| #endif | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Architecture specifics. */ | ||||
| #define portSTACK_GROWTH			( -1 ) | ||||
| #define portTICK_PERIOD_MS			( ( TickType_t ) 1000 / configTICK_RATE_HZ ) | ||||
| #define portBYTE_ALIGNMENT			8 | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Scheduler utilities. */ | ||||
| #define portYIELD() 															\ | ||||
| {																				\ | ||||
| 	/* Set a PendSV to request a context switch. */								\ | ||||
| 	portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;								\ | ||||
| 																				\ | ||||
| 	/* Barriers are normally not required but do ensure the code is completely	\ | ||||
| 	within the specified behaviour for the architecture. */						\ | ||||
| 	__asm volatile( "dsb" ::: "memory" );										\ | ||||
| 	__asm volatile( "isb" );													\ | ||||
| } | ||||
|  | ||||
| #define portNVIC_INT_CTRL_REG		( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) | ||||
| #define portNVIC_PENDSVSET_BIT		( 1UL << 28UL ) | ||||
| #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() | ||||
| #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Critical section management. */ | ||||
| extern void vPortEnterCritical( void ); | ||||
| extern void vPortExitCritical( void ); | ||||
| #define portSET_INTERRUPT_MASK_FROM_ISR()		ulPortRaiseBASEPRI() | ||||
| #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)	vPortSetBASEPRI(x) | ||||
| #define portDISABLE_INTERRUPTS()				vPortRaiseBASEPRI() | ||||
| #define portENABLE_INTERRUPTS()					vPortSetBASEPRI(0) | ||||
| #define portENTER_CRITICAL()					vPortEnterCritical() | ||||
| #define portEXIT_CRITICAL()						vPortExitCritical() | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Task function macros as described on the FreeRTOS.org WEB site.  These are | ||||
| not necessary for to use this port.  They are defined so the common demo files | ||||
| (which build with all the ports) will build. */ | ||||
| #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) | ||||
| #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Tickless idle/low power functionality. */ | ||||
| #ifndef portSUPPRESS_TICKS_AND_SLEEP | ||||
| 	extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); | ||||
| 	#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) | ||||
| #endif | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* Architecture specific optimisations. */ | ||||
| #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION | ||||
| 	#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 | ||||
| #endif | ||||
|  | ||||
| #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 | ||||
|  | ||||
| 	/* Generic helper function. */ | ||||
| 	__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) | ||||
| 	{ | ||||
| 	uint8_t ucReturn; | ||||
|  | ||||
| 		__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); | ||||
| 		return ucReturn; | ||||
| 	} | ||||
|  | ||||
| 	/* Check the configuration. */ | ||||
| 	#if( configMAX_PRIORITIES > 32 ) | ||||
| 		#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32.  It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. | ||||
| 	#endif | ||||
|  | ||||
| 	/* Store/clear the ready priorities in a bit map. */ | ||||
| 	#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) | ||||
| 	#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) | ||||
|  | ||||
| 	/*-----------------------------------------------------------*/ | ||||
|  | ||||
| 	#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) | ||||
|  | ||||
| #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #ifdef configASSERT | ||||
| 	void vPortValidateInterruptPriority( void ); | ||||
| 	#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() 	vPortValidateInterruptPriority() | ||||
| #endif | ||||
|  | ||||
| /* portNOP() is not required by this port. */ | ||||
| #define portNOP() | ||||
|  | ||||
| #define portINLINE	__inline | ||||
|  | ||||
| #ifndef portFORCE_INLINE | ||||
| 	#define portFORCE_INLINE inline __attribute__(( always_inline)) | ||||
| #endif | ||||
|  | ||||
| portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) | ||||
| { | ||||
| uint32_t ulCurrentInterrupt; | ||||
| BaseType_t xReturn; | ||||
|  | ||||
| 	/* Obtain the number of the currently executing interrupt. */ | ||||
| 	__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); | ||||
|  | ||||
| 	if( ulCurrentInterrupt == 0 ) | ||||
| 	{ | ||||
| 		xReturn = pdFALSE; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		xReturn = pdTRUE; | ||||
| 	} | ||||
|  | ||||
| 	return xReturn; | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| portFORCE_INLINE static void vPortRaiseBASEPRI( void ) | ||||
| { | ||||
| uint32_t ulNewBASEPRI; | ||||
|  | ||||
| 	__asm volatile | ||||
| 	( | ||||
| 		"	mov %0, %1												\n"	\ | ||||
| 		"	cpsid i													\n" \ | ||||
| 		"	msr basepri, %0											\n" \ | ||||
| 		"	isb														\n" \ | ||||
| 		"	dsb														\n" \ | ||||
| 		"	cpsie i													\n" \ | ||||
| 		:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" | ||||
| 	); | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) | ||||
| { | ||||
| uint32_t ulOriginalBASEPRI, ulNewBASEPRI; | ||||
|  | ||||
| 	__asm volatile | ||||
| 	( | ||||
| 		"	mrs %0, basepri											\n" \ | ||||
| 		"	mov %1, %2												\n"	\ | ||||
| 		"	cpsid i													\n" \ | ||||
| 		"	msr basepri, %1											\n" \ | ||||
| 		"	isb														\n" \ | ||||
| 		"	dsb														\n" \ | ||||
| 		"	cpsie i													\n" \ | ||||
| 		:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" | ||||
| 	); | ||||
|  | ||||
| 	/* This return will not be reached but is necessary to prevent compiler | ||||
| 	warnings. */ | ||||
| 	return ulOriginalBASEPRI; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) | ||||
| { | ||||
| 	__asm volatile | ||||
| 	( | ||||
| 		"	msr basepri, %0	" :: "r" ( ulNewMaskValue ) : "memory" | ||||
| 	); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif /* PORTMACRO_H */ | ||||
|  | ||||
							
								
								
									
										436
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										436
									
								
								Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,436 @@ | ||||
| /* | ||||
|  * FreeRTOS Kernel V10.2.1 | ||||
|  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * http://www.FreeRTOS.org | ||||
|  * http://aws.amazon.com/freertos | ||||
|  * | ||||
|  * 1 tab == 4 spaces! | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * A sample implementation of pvPortMalloc() and vPortFree() that combines | ||||
|  * (coalescences) adjacent memory blocks as they are freed, and in so doing | ||||
|  * limits memory fragmentation. | ||||
|  * | ||||
|  * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the | ||||
|  * memory management pages of http://www.FreeRTOS.org for more information. | ||||
|  */ | ||||
| #include <stdlib.h> | ||||
|  | ||||
| /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining | ||||
| all the API functions to use the MPU wrappers.  That should only be done when | ||||
| task.h is included from an application file. */ | ||||
| #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE | ||||
|  | ||||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
|  | ||||
| #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE | ||||
|  | ||||
| #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) | ||||
| 	#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 | ||||
| #endif | ||||
|  | ||||
| /* Block sizes must not get too small. */ | ||||
| #define heapMINIMUM_BLOCK_SIZE	( ( size_t ) ( xHeapStructSize << 1 ) ) | ||||
|  | ||||
| /* Assumes 8bit bytes! */ | ||||
| #define heapBITS_PER_BYTE		( ( size_t ) 8 ) | ||||
|  | ||||
| /* Allocate the memory for the heap. */ | ||||
| #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) | ||||
| 	/* The application writer has already defined the array used for the RTOS | ||||
| 	heap - probably so it can be placed in a special segment or address. */ | ||||
| 	extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; | ||||
| #else | ||||
| 	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; | ||||
| #endif /* configAPPLICATION_ALLOCATED_HEAP */ | ||||
|  | ||||
| /* Define the linked list structure.  This is used to link free blocks in order | ||||
| of their memory address. */ | ||||
| typedef struct A_BLOCK_LINK | ||||
| { | ||||
| 	struct A_BLOCK_LINK *pxNextFreeBlock;	/*<< The next free block in the list. */ | ||||
| 	size_t xBlockSize;						/*<< The size of the free block. */ | ||||
| } BlockLink_t; | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * Inserts a block of memory that is being freed into the correct position in | ||||
|  * the list of free memory blocks.  The block being freed will be merged with | ||||
|  * the block in front it and/or the block behind it if the memory blocks are | ||||
|  * adjacent to each other. | ||||
|  */ | ||||
| static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); | ||||
|  | ||||
| /* | ||||
|  * Called automatically to setup the required heap structures the first time | ||||
|  * pvPortMalloc() is called. | ||||
|  */ | ||||
| static void prvHeapInit( void ); | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| /* The size of the structure placed at the beginning of each allocated memory | ||||
| block must by correctly byte aligned. */ | ||||
| static const size_t xHeapStructSize	= ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); | ||||
|  | ||||
| /* Create a couple of list links to mark the start and end of the list. */ | ||||
| static BlockLink_t xStart, *pxEnd = NULL; | ||||
|  | ||||
| /* Keeps track of the number of free bytes remaining, but says nothing about | ||||
| fragmentation. */ | ||||
| static size_t xFreeBytesRemaining = 0U; | ||||
| static size_t xMinimumEverFreeBytesRemaining = 0U; | ||||
|  | ||||
| /* Gets set to the top bit of an size_t type.  When this bit in the xBlockSize | ||||
| member of an BlockLink_t structure is set then the block belongs to the | ||||
| application.  When the bit is free the block is still part of the free heap | ||||
| space. */ | ||||
| static size_t xBlockAllocatedBit = 0; | ||||
|  | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void *pvPortMalloc( size_t xWantedSize ) | ||||
| { | ||||
| BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; | ||||
| void *pvReturn = NULL; | ||||
|  | ||||
| 	vTaskSuspendAll(); | ||||
| 	{ | ||||
| 		/* If this is the first call to malloc then the heap will require | ||||
| 		initialisation to setup the list of free blocks. */ | ||||
| 		if( pxEnd == NULL ) | ||||
| 		{ | ||||
| 			prvHeapInit(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
|  | ||||
| 		/* Check the requested block size is not so large that the top bit is | ||||
| 		set.  The top bit of the block size member of the BlockLink_t structure | ||||
| 		is used to determine who owns the block - the application or the | ||||
| 		kernel, so it must be free. */ | ||||
| 		if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) | ||||
| 		{ | ||||
| 			/* The wanted size is increased so it can contain a BlockLink_t | ||||
| 			structure in addition to the requested amount of bytes. */ | ||||
| 			if( xWantedSize > 0 ) | ||||
| 			{ | ||||
| 				xWantedSize += xHeapStructSize; | ||||
|  | ||||
| 				/* Ensure that blocks are always aligned to the required number | ||||
| 				of bytes. */ | ||||
| 				if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) | ||||
| 				{ | ||||
| 					/* Byte alignment required. */ | ||||
| 					xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); | ||||
| 					configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
|  | ||||
| 			if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) | ||||
| 			{ | ||||
| 				/* Traverse the list from the start	(lowest address) block until | ||||
| 				one	of adequate size is found. */ | ||||
| 				pxPreviousBlock = &xStart; | ||||
| 				pxBlock = xStart.pxNextFreeBlock; | ||||
| 				while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) | ||||
| 				{ | ||||
| 					pxPreviousBlock = pxBlock; | ||||
| 					pxBlock = pxBlock->pxNextFreeBlock; | ||||
| 				} | ||||
|  | ||||
| 				/* If the end marker was reached then a block of adequate size | ||||
| 				was	not found. */ | ||||
| 				if( pxBlock != pxEnd ) | ||||
| 				{ | ||||
| 					/* Return the memory space pointed to - jumping over the | ||||
| 					BlockLink_t structure at its start. */ | ||||
| 					pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); | ||||
|  | ||||
| 					/* This block is being returned for use so must be taken out | ||||
| 					of the list of free blocks. */ | ||||
| 					pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; | ||||
|  | ||||
| 					/* If the block is larger than required it can be split into | ||||
| 					two. */ | ||||
| 					if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) | ||||
| 					{ | ||||
| 						/* This block is to be split into two.  Create a new | ||||
| 						block following the number of bytes requested. The void | ||||
| 						cast is used to prevent byte alignment warnings from the | ||||
| 						compiler. */ | ||||
| 						pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); | ||||
| 						configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); | ||||
|  | ||||
| 						/* Calculate the sizes of two blocks split from the | ||||
| 						single block. */ | ||||
| 						pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; | ||||
| 						pxBlock->xBlockSize = xWantedSize; | ||||
|  | ||||
| 						/* Insert the new block into the list of free blocks. */ | ||||
| 						prvInsertBlockIntoFreeList( pxNewBlockLink ); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						mtCOVERAGE_TEST_MARKER(); | ||||
| 					} | ||||
|  | ||||
| 					xFreeBytesRemaining -= pxBlock->xBlockSize; | ||||
|  | ||||
| 					if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) | ||||
| 					{ | ||||
| 						xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						mtCOVERAGE_TEST_MARKER(); | ||||
| 					} | ||||
|  | ||||
| 					/* The block is being returned - it is allocated and owned | ||||
| 					by the application and has no "next" block. */ | ||||
| 					pxBlock->xBlockSize |= xBlockAllocatedBit; | ||||
| 					pxBlock->pxNextFreeBlock = NULL; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					mtCOVERAGE_TEST_MARKER(); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
|  | ||||
| 		traceMALLOC( pvReturn, xWantedSize ); | ||||
| 	} | ||||
| 	( void ) xTaskResumeAll(); | ||||
|  | ||||
| 	#if( configUSE_MALLOC_FAILED_HOOK == 1 ) | ||||
| 	{ | ||||
| 		if( pvReturn == NULL ) | ||||
| 		{ | ||||
| 			extern void vApplicationMallocFailedHook( void ); | ||||
| 			vApplicationMallocFailedHook(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); | ||||
| 	return pvReturn; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortFree( void *pv ) | ||||
| { | ||||
| uint8_t *puc = ( uint8_t * ) pv; | ||||
| BlockLink_t *pxLink; | ||||
|  | ||||
| 	if( pv != NULL ) | ||||
| 	{ | ||||
| 		/* The memory being freed will have an BlockLink_t structure immediately | ||||
| 		before it. */ | ||||
| 		puc -= xHeapStructSize; | ||||
|  | ||||
| 		/* This casting is to keep the compiler from issuing warnings. */ | ||||
| 		pxLink = ( void * ) puc; | ||||
|  | ||||
| 		/* Check the block is actually allocated. */ | ||||
| 		configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); | ||||
| 		configASSERT( pxLink->pxNextFreeBlock == NULL ); | ||||
|  | ||||
| 		if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) | ||||
| 		{ | ||||
| 			if( pxLink->pxNextFreeBlock == NULL ) | ||||
| 			{ | ||||
| 				/* The block is being returned to the heap - it is no longer | ||||
| 				allocated. */ | ||||
| 				pxLink->xBlockSize &= ~xBlockAllocatedBit; | ||||
|  | ||||
| 				vTaskSuspendAll(); | ||||
| 				{ | ||||
| 					/* Add this block to the list of free blocks. */ | ||||
| 					xFreeBytesRemaining += pxLink->xBlockSize; | ||||
| 					traceFREE( pv, pxLink->xBlockSize ); | ||||
| 					prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); | ||||
| 				} | ||||
| 				( void ) xTaskResumeAll(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				mtCOVERAGE_TEST_MARKER(); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			mtCOVERAGE_TEST_MARKER(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| size_t xPortGetFreeHeapSize( void ) | ||||
| { | ||||
| 	return xFreeBytesRemaining; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| size_t xPortGetMinimumEverFreeHeapSize( void ) | ||||
| { | ||||
| 	return xMinimumEverFreeBytesRemaining; | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| void vPortInitialiseBlocks( void ) | ||||
| { | ||||
| 	/* This just exists to keep the linker quiet. */ | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvHeapInit( void ) | ||||
| { | ||||
| BlockLink_t *pxFirstFreeBlock; | ||||
| uint8_t *pucAlignedHeap; | ||||
| size_t uxAddress; | ||||
| size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; | ||||
|  | ||||
| 	/* Ensure the heap starts on a correctly aligned boundary. */ | ||||
| 	uxAddress = ( size_t ) ucHeap; | ||||
|  | ||||
| 	if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) | ||||
| 	{ | ||||
| 		uxAddress += ( portBYTE_ALIGNMENT - 1 ); | ||||
| 		uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); | ||||
| 		xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; | ||||
| 	} | ||||
|  | ||||
| 	pucAlignedHeap = ( uint8_t * ) uxAddress; | ||||
|  | ||||
| 	/* xStart is used to hold a pointer to the first item in the list of free | ||||
| 	blocks.  The void cast is used to prevent compiler warnings. */ | ||||
| 	xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; | ||||
| 	xStart.xBlockSize = ( size_t ) 0; | ||||
|  | ||||
| 	/* pxEnd is used to mark the end of the list of free blocks and is inserted | ||||
| 	at the end of the heap space. */ | ||||
| 	uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; | ||||
| 	uxAddress -= xHeapStructSize; | ||||
| 	uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); | ||||
| 	pxEnd = ( void * ) uxAddress; | ||||
| 	pxEnd->xBlockSize = 0; | ||||
| 	pxEnd->pxNextFreeBlock = NULL; | ||||
|  | ||||
| 	/* To start with there is a single free block that is sized to take up the | ||||
| 	entire heap space, minus the space taken by pxEnd. */ | ||||
| 	pxFirstFreeBlock = ( void * ) pucAlignedHeap; | ||||
| 	pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; | ||||
| 	pxFirstFreeBlock->pxNextFreeBlock = pxEnd; | ||||
|  | ||||
| 	/* Only one block exists - and it covers the entire usable heap space. */ | ||||
| 	xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; | ||||
| 	xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; | ||||
|  | ||||
| 	/* Work out the position of the top bit in a size_t variable. */ | ||||
| 	xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); | ||||
| } | ||||
| /*-----------------------------------------------------------*/ | ||||
|  | ||||
| static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) | ||||
| { | ||||
| BlockLink_t *pxIterator; | ||||
| uint8_t *puc; | ||||
|  | ||||
| 	/* Iterate through the list until a block is found that has a higher address | ||||
| 	than the block being inserted. */ | ||||
| 	for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) | ||||
| 	{ | ||||
| 		/* Nothing to do here, just iterate to the right position. */ | ||||
| 	} | ||||
|  | ||||
| 	/* Do the block being inserted, and the block it is being inserted after | ||||
| 	make a contiguous block of memory? */ | ||||
| 	puc = ( uint8_t * ) pxIterator; | ||||
| 	if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) | ||||
| 	{ | ||||
| 		pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; | ||||
| 		pxBlockToInsert = pxIterator; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		mtCOVERAGE_TEST_MARKER(); | ||||
| 	} | ||||
|  | ||||
| 	/* Do the block being inserted, and the block it is being inserted before | ||||
| 	make a contiguous block of memory? */ | ||||
| 	puc = ( uint8_t * ) pxBlockToInsert; | ||||
| 	if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) | ||||
| 	{ | ||||
| 		if( pxIterator->pxNextFreeBlock != pxEnd ) | ||||
| 		{ | ||||
| 			/* Form one big block from the two blocks. */ | ||||
| 			pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; | ||||
| 			pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			pxBlockToInsert->pxNextFreeBlock = pxEnd; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; | ||||
| 	} | ||||
|  | ||||
| 	/* If the block being inserted plugged a gab, so was merged with the block | ||||
| 	before and the block after, then it's pxNextFreeBlock pointer will have | ||||
| 	already been set, and should not be set here as that would make it point | ||||
| 	to itself. */ | ||||
| 	if( pxIterator != pxBlockToInsert ) | ||||
| 	{ | ||||
| 		pxIterator->pxNextFreeBlock = pxBlockToInsert; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		mtCOVERAGE_TEST_MARKER(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										2941
									
								
								Middlewares/Third_Party/FreeRTOS/Source/queue.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2941
									
								
								Middlewares/Third_Party/FreeRTOS/Source/queue.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1263
									
								
								Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1263
									
								
								Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5214
									
								
								Middlewares/Third_Party/FreeRTOS/Source/tasks.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5214
									
								
								Middlewares/Third_Party/FreeRTOS/Source/tasks.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1102
									
								
								Middlewares/Third_Party/FreeRTOS/Source/timers.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1102
									
								
								Middlewares/Third_Party/FreeRTOS/Source/timers.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -4,6 +4,9 @@ ADC3.Channel-IN0=ADC_CHANNEL_0 | ||||
| ADC3.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1 | ||||
| ADC3.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING | ||||
| ADC3.IPParameters=Channel-IN0,Channel-0\#ChannelRegularConversion,ExternalTrigConv,ExternalTrigConvEdge | ||||
| CORTEX_M7.CPU_DCache=Enabled | ||||
| CORTEX_M7.CPU_ICache=Enabled | ||||
| CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache | ||||
| FMC.CASLatency1=FMC_SDRAM_CAS_LATENCY_3 | ||||
| FMC.ExitSelfRefreshDelay1=7 | ||||
| FMC.IPParameters=CASLatency1,SDClockPeriod1,SDClockPeriod2,ReadBurst1,ReadBurst2,LoadToActiveDelay1,ExitSelfRefreshDelay1,SelfRefreshTime1,RowCycleDelay1,RowCycleDelay2,WriteRecoveryTime1,RPDelay1,RPDelay2,RCDDelay1 | ||||
| @@ -19,6 +22,11 @@ FMC.SDClockPeriod1=FMC_SDRAM_CLOCK_PERIOD_2 | ||||
| FMC.SDClockPeriod2=FMC_SDRAM_CLOCK_PERIOD_2 | ||||
| FMC.SelfRefreshTime1=4 | ||||
| FMC.WriteRecoveryTime1=3 | ||||
| FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,configMINIMAL_STACK_SIZE,configUSE_NEWLIB_REENTRANT | ||||
| FREERTOS.Tasks01=defaultTask,24,2048,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL | ||||
| FREERTOS.configMINIMAL_STACK_SIZE=2048 | ||||
| FREERTOS.configTOTAL_HEAP_SIZE=65536 | ||||
| FREERTOS.configUSE_NEWLIB_REENTRANT=1 | ||||
| File.Version=6 | ||||
| GPIO.groupedBy=Group By Peripherals | ||||
| I2C3.IPParameters=Timing | ||||
| @@ -45,23 +53,24 @@ Mcu.CPN=STM32F746NGH6 | ||||
| Mcu.Family=STM32F7 | ||||
| Mcu.IP0=ADC3 | ||||
| Mcu.IP1=CORTEX_M7 | ||||
| Mcu.IP10=SPI2 | ||||
| Mcu.IP11=SYS | ||||
| Mcu.IP12=TIM1 | ||||
| Mcu.IP13=TIM2 | ||||
| Mcu.IP14=TIM3 | ||||
| Mcu.IP15=TIM5 | ||||
| Mcu.IP16=TIM8 | ||||
| Mcu.IP17=USART1 | ||||
| Mcu.IP10=RTC | ||||
| Mcu.IP11=SPI2 | ||||
| Mcu.IP12=SYS | ||||
| Mcu.IP13=TIM1 | ||||
| Mcu.IP14=TIM2 | ||||
| Mcu.IP15=TIM3 | ||||
| Mcu.IP16=TIM5 | ||||
| Mcu.IP17=TIM8 | ||||
| Mcu.IP18=USART1 | ||||
| Mcu.IP2=CRC | ||||
| Mcu.IP3=DMA2D | ||||
| Mcu.IP4=FMC | ||||
| Mcu.IP5=I2C3 | ||||
| Mcu.IP6=LTDC | ||||
| Mcu.IP7=NVIC | ||||
| Mcu.IP8=RCC | ||||
| Mcu.IP9=RTC | ||||
| Mcu.IPNb=18 | ||||
| Mcu.IP5=FREERTOS | ||||
| Mcu.IP6=I2C3 | ||||
| Mcu.IP7=LTDC | ||||
| Mcu.IP8=NVIC | ||||
| Mcu.IP9=RCC | ||||
| Mcu.IPNb=19 | ||||
| Mcu.Name=STM32F746NGHx | ||||
| Mcu.Package=TFBGA216 | ||||
| Mcu.Pin0=PE4 | ||||
| @@ -141,18 +150,19 @@ Mcu.Pin164=PB14 | ||||
| Mcu.Pin165=PB15 | ||||
| Mcu.Pin166=VP_CRC_VS_CRC | ||||
| Mcu.Pin167=VP_DMA2D_VS_DMA2D | ||||
| Mcu.Pin168=VP_RTC_VS_RTC_Activate | ||||
| Mcu.Pin169=VP_RTC_VS_RTC_Calendar | ||||
| Mcu.Pin168=VP_FREERTOS_VS_CMSIS_V2 | ||||
| Mcu.Pin169=VP_RTC_VS_RTC_Activate | ||||
| Mcu.Pin17=PG13 | ||||
| Mcu.Pin170=VP_RTC_VS_RTC_Alarm_B_Intern | ||||
| Mcu.Pin171=VP_RTC_VS_RTC_Alarm_A_Intern | ||||
| Mcu.Pin172=VP_SYS_VS_tim6 | ||||
| Mcu.Pin173=VP_TIM1_VS_ClockSourceINT | ||||
| Mcu.Pin174=VP_TIM1_VS_no_output1 | ||||
| Mcu.Pin175=VP_TIM2_VS_ClockSourceINT | ||||
| Mcu.Pin176=VP_TIM3_VS_ClockSourceINT | ||||
| Mcu.Pin177=VP_TIM5_VS_ClockSourceINT | ||||
| Mcu.Pin178=VP_TIM8_VS_ClockSourceINT | ||||
| Mcu.Pin170=VP_RTC_VS_RTC_Calendar | ||||
| Mcu.Pin171=VP_RTC_VS_RTC_Alarm_B_Intern | ||||
| Mcu.Pin172=VP_RTC_VS_RTC_Alarm_A_Intern | ||||
| Mcu.Pin173=VP_SYS_VS_tim6 | ||||
| Mcu.Pin174=VP_TIM1_VS_ClockSourceINT | ||||
| Mcu.Pin175=VP_TIM1_VS_no_output1 | ||||
| Mcu.Pin176=VP_TIM2_VS_ClockSourceINT | ||||
| Mcu.Pin177=VP_TIM3_VS_ClockSourceINT | ||||
| Mcu.Pin178=VP_TIM5_VS_ClockSourceINT | ||||
| Mcu.Pin179=VP_TIM8_VS_ClockSourceINT | ||||
| Mcu.Pin18=PB9 | ||||
| Mcu.Pin19=PB7 | ||||
| Mcu.Pin2=PE2 | ||||
| @@ -243,32 +253,35 @@ Mcu.Pin96=PF5 | ||||
| Mcu.Pin97=PH2 | ||||
| Mcu.Pin98=PJ6 | ||||
| Mcu.Pin99=PD15 | ||||
| Mcu.PinsNb=179 | ||||
| Mcu.PinsNb=180 | ||||
| Mcu.ThirdPartyNb=0 | ||||
| Mcu.UserConstants= | ||||
| Mcu.UserName=STM32F746NGHx | ||||
| MxCube.Version=6.5.0 | ||||
| MxDb.Version=DB.6.0.50 | ||||
| NVIC.ADC_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.DMA2D_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.EXTI2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.EXTI3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.EXTI9_5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.ADC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| NVIC.DMA2D_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| NVIC.EXTI2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.EXTI3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.EXTI9_5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.ForceEnableDMAVector=true | ||||
| NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.LTDC_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true | ||||
| NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| NVIC.LTDC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true | ||||
| NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:true | ||||
| NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 | ||||
| NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true | ||||
| NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true | ||||
| NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:true | ||||
| NVIC.SavedPendsvIrqHandlerGenerated=true | ||||
| NVIC.SavedSvcallIrqHandlerGenerated=true | ||||
| NVIC.SavedSystickIrqHandlerGenerated=true | ||||
| NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:true | ||||
| NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true | ||||
| NVIC.TimeBase=TIM6_DAC_IRQn | ||||
| NVIC.TimeBaseIP=TIM6 | ||||
| NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | ||||
| NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true | ||||
| PA0/WKUP.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_Mode | ||||
| PA0/WKUP.GPIO_Label=ARDUINO A0 | ||||
| PA0/WKUP.GPIO_Mode=GPIO_MODE_ANALOG | ||||
| @@ -1220,7 +1233,7 @@ TIM1.Channel-Output\ Compare1\ No\ Output=TIM_CHANNEL_1 | ||||
| TIM1.IPParameters=Prescaler,Period,Channel-Output Compare1 No Output,OCMode_1 | ||||
| TIM1.OCMode_1=TIM_OCMODE_TOGGLE | ||||
| TIM1.Period=99 | ||||
| TIM1.Prescaler=199 | ||||
| TIM1.Prescaler=19 | ||||
| TIM5.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 | ||||
| TIM5.IPParameters=Channel-PWM Generation4 CH4 | ||||
| USART1.IPParameters=VirtualMode-Asynchronous | ||||
| @@ -1229,6 +1242,8 @@ VP_CRC_VS_CRC.Mode=CRC_Activate | ||||
| VP_CRC_VS_CRC.Signal=CRC_VS_CRC | ||||
| VP_DMA2D_VS_DMA2D.Mode=DMA2D_Activate | ||||
| VP_DMA2D_VS_DMA2D.Signal=DMA2D_VS_DMA2D | ||||
| VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 | ||||
| VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 | ||||
| VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled | ||||
| VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate | ||||
| VP_RTC_VS_RTC_Alarm_A_Intern.Mode=Alarm A | ||||
|   | ||||
| @@ -119,7 +119,7 @@ void Controller::doShowAnalogSignal() { | ||||
| 	 * 5	ms/div => 4000 samples => scale = 4000/460 =  8,696 | ||||
| 	 * 10	ms/div => 8000 samples => scale = 8000/460 = 17,391 | ||||
| 	 */ | ||||
| 	static float scales[7] = {0.87,0.87,1.739,3.478,8.696,17.391,17.391}; | ||||
| 	static float scales[7] = {0.870, 0.870, 1.739, 3.478, 8.696, 17.391, 17.391}; // tab for 100kHz | ||||
| 	float scale = scales[this->_tdivValue]; | ||||
| 	gui().drawGraphPoints(_adcValuesBuffer, _adcValuesBufferSize, scale); | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
| 													//	HZ_1000 = 1000, | ||||
| 													//	HZ_5000 = 5000, | ||||
| 													//	HZ_10000 = 10000 | ||||
| #define EXTFREQGEN_START_WAVEFORM       TRIANGLE	//  one of these: | ||||
| #define EXTFREQGEN_START_WAVEFORM       SINUS	//  one of these: | ||||
| 													//  SINUS | ||||
| 													//  TRIANGLE | ||||
| 													//  SQUARE | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| /** | ||||
|  * Waring: Only one PORT define should be enabled at a time! | ||||
|  */ | ||||
| #define TOUCHGFX_BAREMETAL		1 | ||||
| #define TOUCHGFX_FREERTOS		0 | ||||
| #define TOUCHGFX_BAREMETAL		0 | ||||
| #define TOUCHGFX_FREERTOS		1 | ||||
|  | ||||
| #endif // TOUCHGFX_CONFIG_H | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| /** | ||||
|  * Waring: Only one PORT define should be enabled at a time! | ||||
|  */ | ||||
| #define PORT_IDF_STM32CUBE                  1 | ||||
| #define PORT_STM32CUBE_CMSIS_FREERTOS       0 | ||||
| #define PORT_IDF_STM32CUBE                  0 | ||||
| #define PORT_STM32CUBE_CMSIS_FREERTOS       1 | ||||
|  | ||||
| #endif // XF_PORT_CONFIG_H | ||||
|   | ||||
		Reference in New Issue
	
	Block a user