Added LVGL, added FatFS, added FreeRTOS
Added LVGL source code, fixed 24bit image, added test image, added FatFs, disabled Unicode support for FatFs(bug).
This commit is contained in:
parent
9488499f5d
commit
69329efb44
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "Middlewares/Third_Party/LittleVGL"]
|
||||||
|
path = Middlewares/Third_Party/LittleVGL
|
||||||
|
url = https://github.com/lvgl/lvgl.git
|
158
Core/Inc/FreeRTOSConfig.h
Normal file
158
Core/Inc/FreeRTOSConfig.h
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/* 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)128)
|
||||||
|
#define configTOTAL_HEAP_SIZE ((size_t)81920)
|
||||||
|
#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 256
|
||||||
|
|
||||||
|
/* 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 */
|
762
Core/Inc/lv_conf.h
Normal file
762
Core/Inc/lv_conf.h
Normal file
|
@ -0,0 +1,762 @@
|
||||||
|
/**
|
||||||
|
* @file lv_conf.h
|
||||||
|
* Configuration file for v7.10.0-dev
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1 /*Set it to "1" to enable content*/
|
||||||
|
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_H
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*====================
|
||||||
|
Graphical settings
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||||
|
#define LV_HOR_RES_MAX (800)
|
||||||
|
#define LV_VER_RES_MAX (480)
|
||||||
|
|
||||||
|
/* Color depth:
|
||||||
|
* - 1: 1 byte per pixel
|
||||||
|
* - 8: RGB332
|
||||||
|
* - 16: RGB565
|
||||||
|
* - 32: ARGB8888
|
||||||
|
*/
|
||||||
|
#define LV_COLOR_DEPTH 32
|
||||||
|
|
||||||
|
/* Swap the 2 bytes of RGB565 color.
|
||||||
|
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||||
|
#define LV_COLOR_16_SWAP 0
|
||||||
|
|
||||||
|
/* 1: Enable screen transparency.
|
||||||
|
* Useful for OSD or other overlapping GUIs.
|
||||||
|
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||||
|
#define LV_COLOR_SCREEN_TRANSP 0
|
||||||
|
|
||||||
|
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||||
|
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||||
|
|
||||||
|
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||||
|
#define LV_ANTIALIAS 1
|
||||||
|
|
||||||
|
/* Default display refresh period.
|
||||||
|
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||||
|
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||||
|
|
||||||
|
/* Dot Per Inch: used to initialize default sizes.
|
||||||
|
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||||
|
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||||
|
#define LV_DPI 130 /*[px]*/
|
||||||
|
|
||||||
|
/* The the real width of the display changes some default values:
|
||||||
|
* default object sizes, layout of examples, etc.
|
||||||
|
* According to the width of the display (hor. res. / dpi)
|
||||||
|
* the displays fall in 4 categories.
|
||||||
|
* The 4th is extra large which has no upper limit so not listed here
|
||||||
|
* The upper limit of the categories are set below in 0.1 inch unit.
|
||||||
|
*/
|
||||||
|
#define LV_DISP_SMALL_LIMIT 30
|
||||||
|
#define LV_DISP_MEDIUM_LIMIT 50
|
||||||
|
#define LV_DISP_LARGE_LIMIT 70
|
||||||
|
|
||||||
|
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||||
|
typedef int16_t lv_coord_t;
|
||||||
|
|
||||||
|
/*=========================
|
||||||
|
Memory manager settings
|
||||||
|
*=========================*/
|
||||||
|
|
||||||
|
/* LittelvGL's internal memory manager's settings.
|
||||||
|
* The graphical objects and other related data are stored here. */
|
||||||
|
|
||||||
|
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
|
||||||
|
#define LV_MEM_CUSTOM 0
|
||||||
|
#if LV_MEM_CUSTOM == 0
|
||||||
|
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||||
|
# define LV_MEM_SIZE (128U * 1024U)
|
||||||
|
|
||||||
|
/* Compiler prefix for a big array declaration */
|
||||||
|
# define LV_MEM_ATTR
|
||||||
|
|
||||||
|
/* Set an address for the memory pool instead of allocating it as an array.
|
||||||
|
* Can be in external SRAM too. */
|
||||||
|
# define LV_MEM_ADR 0
|
||||||
|
|
||||||
|
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||||
|
# define LV_MEM_AUTO_DEFRAG 1
|
||||||
|
#else /*LV_MEM_CUSTOM*/
|
||||||
|
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||||
|
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||||
|
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||||
|
#endif /*LV_MEM_CUSTOM*/
|
||||||
|
|
||||||
|
/* Use the standard memcpy and memset instead of LVGL's own functions.
|
||||||
|
* The standard functions might or might not be faster depending on their implementation. */
|
||||||
|
#define LV_MEMCPY_MEMSET_STD 0
|
||||||
|
|
||||||
|
/* Garbage Collector settings
|
||||||
|
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||||
|
#define LV_ENABLE_GC 0
|
||||||
|
#if LV_ENABLE_GC != 0
|
||||||
|
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||||
|
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||||
|
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||||
|
#endif /* LV_ENABLE_GC */
|
||||||
|
|
||||||
|
/*=======================
|
||||||
|
Input device settings
|
||||||
|
*=======================*/
|
||||||
|
|
||||||
|
/* Input device default settings.
|
||||||
|
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||||
|
|
||||||
|
/* Input device read period in milliseconds */
|
||||||
|
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||||
|
|
||||||
|
/* Drag threshold in pixels */
|
||||||
|
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||||
|
|
||||||
|
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||||
|
#define LV_INDEV_DEF_DRAG_THROW 10
|
||||||
|
|
||||||
|
/* Long press time in milliseconds.
|
||||||
|
* Time to send `LV_EVENT_LONG_PRESSED`) */
|
||||||
|
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||||
|
|
||||||
|
/* Repeated trigger period in long press [ms]
|
||||||
|
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||||
|
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||||
|
|
||||||
|
/* Gesture threshold in pixels */
|
||||||
|
#define LV_INDEV_DEF_GESTURE_LIMIT 50
|
||||||
|
|
||||||
|
/* Gesture min velocity at release before swipe (pixels)*/
|
||||||
|
#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3
|
||||||
|
|
||||||
|
/*==================
|
||||||
|
* Feature usage
|
||||||
|
*==================*/
|
||||||
|
|
||||||
|
/*1: Enable the Animations */
|
||||||
|
#define LV_USE_ANIMATION 1
|
||||||
|
#if LV_USE_ANIMATION
|
||||||
|
|
||||||
|
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
|
typedef void * lv_anim_user_data_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 1: Enable shadow drawing on rectangles*/
|
||||||
|
#define LV_USE_SHADOW 1
|
||||||
|
#if LV_USE_SHADOW
|
||||||
|
/* Allow buffering some shadow calculation
|
||||||
|
* LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer,
|
||||||
|
* where shadow size is `shadow_width + radius`
|
||||||
|
* Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
||||||
|
#define LV_SHADOW_CACHE_SIZE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*1: enable outline drawing on rectangles*/
|
||||||
|
#define LV_USE_OUTLINE 1
|
||||||
|
|
||||||
|
/*1: enable pattern drawing on rectangles*/
|
||||||
|
#define LV_USE_PATTERN 1
|
||||||
|
|
||||||
|
/*1: enable value string drawing on rectangles*/
|
||||||
|
#define LV_USE_VALUE_STR 1
|
||||||
|
|
||||||
|
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
|
||||||
|
#define LV_USE_BLEND_MODES 1
|
||||||
|
|
||||||
|
/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/
|
||||||
|
#define LV_USE_OPA_SCALE 1
|
||||||
|
|
||||||
|
/* 1: Use image zoom and rotation*/
|
||||||
|
#define LV_USE_IMG_TRANSFORM 1
|
||||||
|
|
||||||
|
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||||
|
#define LV_USE_GROUP 1
|
||||||
|
#if LV_USE_GROUP
|
||||||
|
typedef void * lv_group_user_data_t;
|
||||||
|
#endif /*LV_USE_GROUP*/
|
||||||
|
|
||||||
|
/* 1: Enable GPU interface*/
|
||||||
|
#define LV_USE_GPU 1 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
|
||||||
|
#define LV_USE_GPU_STM32_DMA2D 0
|
||||||
|
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
|
||||||
|
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||||
|
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||||
|
|
||||||
|
/*1: Use PXP for CPU off-load on NXP RTxxx platforms */
|
||||||
|
#define LV_USE_GPU_NXP_PXP 0
|
||||||
|
|
||||||
|
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
||||||
|
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
|
||||||
|
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||||
|
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||||
|
* */
|
||||||
|
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
||||||
|
|
||||||
|
/*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */
|
||||||
|
#define LV_USE_GPU_NXP_VG_LITE 0
|
||||||
|
|
||||||
|
/* 1: Enable file system (might be required for images */
|
||||||
|
#define LV_USE_FILESYSTEM 1
|
||||||
|
#if LV_USE_FILESYSTEM
|
||||||
|
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
|
typedef void * lv_fs_drv_user_data_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*1: Add a `user_data` to drivers and objects*/
|
||||||
|
#define LV_USE_USER_DATA 1
|
||||||
|
|
||||||
|
/*1: Show CPU usage and FPS count in the right bottom corner*/
|
||||||
|
#define LV_USE_PERF_MONITOR 0
|
||||||
|
|
||||||
|
/*1: Use the functions and types from the older API if possible */
|
||||||
|
#define LV_USE_API_EXTENSION_V6 1
|
||||||
|
#define LV_USE_API_EXTENSION_V7 1
|
||||||
|
|
||||||
|
/*========================
|
||||||
|
* Image decoder and cache
|
||||||
|
*========================*/
|
||||||
|
|
||||||
|
/* 1: Enable indexed (palette) images */
|
||||||
|
#define LV_IMG_CF_INDEXED 1
|
||||||
|
|
||||||
|
/* 1: Enable alpha indexed images */
|
||||||
|
#define LV_IMG_CF_ALPHA 1
|
||||||
|
|
||||||
|
/* Default image cache size. Image caching keeps the images opened.
|
||||||
|
* If only the built-in image formats are used there is no real advantage of caching.
|
||||||
|
* (I.e. no new image decoder is added)
|
||||||
|
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||||
|
* However the opened images might consume additional RAM.
|
||||||
|
* Set it to 0 to disable caching */
|
||||||
|
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||||
|
|
||||||
|
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
|
typedef void * lv_img_decoder_user_data_t;
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Compiler settings
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/* For big endian systems set to 1 */
|
||||||
|
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||||
|
|
||||||
|
/* Define a custom attribute to `lv_tick_inc` function */
|
||||||
|
#define LV_ATTRIBUTE_TICK_INC
|
||||||
|
|
||||||
|
/* Define a custom attribute to `lv_task_handler` function */
|
||||||
|
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||||
|
|
||||||
|
/* Define a custom attribute to `lv_disp_flush_ready` function */
|
||||||
|
#define LV_ATTRIBUTE_FLUSH_READY
|
||||||
|
|
||||||
|
/* Required alignment size for buffers */
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE
|
||||||
|
|
||||||
|
/* With size optimization (-Os) the compiler might not align data to
|
||||||
|
* 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes.
|
||||||
|
* This alignment will be explicitly applied where needed.
|
||||||
|
* LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size.
|
||||||
|
* E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
|
||||||
|
/* Attribute to mark large constant arrays for example
|
||||||
|
* font's bitmaps */
|
||||||
|
#define LV_ATTRIBUTE_LARGE_CONST
|
||||||
|
|
||||||
|
/* Prefix performance critical functions to place them into a faster memory (e.g RAM)
|
||||||
|
* Uses 15-20 kB extra memory */
|
||||||
|
#define LV_ATTRIBUTE_FAST_MEM
|
||||||
|
|
||||||
|
/* Export integer constant to binding.
|
||||||
|
* This macro is used with constants in the form of LV_<CONST> that
|
||||||
|
* should also appear on lvgl binding API such as Micropython
|
||||||
|
*
|
||||||
|
* The default value just prevents a GCC warning.
|
||||||
|
*/
|
||||||
|
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||||
|
|
||||||
|
/* Prefix variables that are used in GPU accelerated operations, often these need to be
|
||||||
|
* placed in RAM sections that are DMA accessible */
|
||||||
|
#define LV_ATTRIBUTE_DMA
|
||||||
|
|
||||||
|
/*===================
|
||||||
|
* HAL settings
|
||||||
|
*==================*/
|
||||||
|
|
||||||
|
/* 1: use a custom tick source.
|
||||||
|
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||||
|
#define LV_TICK_CUSTOM 0
|
||||||
|
#if LV_TICK_CUSTOM == 1
|
||||||
|
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||||
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||||
|
#endif /*LV_TICK_CUSTOM*/
|
||||||
|
|
||||||
|
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||||
|
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||||
|
|
||||||
|
/*================
|
||||||
|
* Log settings
|
||||||
|
*===============*/
|
||||||
|
|
||||||
|
/*1: Enable the log module*/
|
||||||
|
#define LV_USE_LOG 0
|
||||||
|
#if LV_USE_LOG
|
||||||
|
/* How important log should be added:
|
||||||
|
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||||
|
* LV_LOG_LEVEL_INFO Log important events
|
||||||
|
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||||
|
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||||
|
* LV_LOG_LEVEL_NONE Do not log anything
|
||||||
|
*/
|
||||||
|
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||||
|
|
||||||
|
/* 1: Print the log with 'printf';
|
||||||
|
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||||
|
# define LV_LOG_PRINTF 0
|
||||||
|
#endif /*LV_USE_LOG*/
|
||||||
|
|
||||||
|
/*=================
|
||||||
|
* Debug settings
|
||||||
|
*================*/
|
||||||
|
|
||||||
|
/* If Debug is enabled LittelvGL validates the parameters of the functions.
|
||||||
|
* If an invalid parameter is found an error log message is printed and
|
||||||
|
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
|
||||||
|
* If you are debugging the MCU you can pause
|
||||||
|
* the debugger to see exactly where the issue is.
|
||||||
|
*
|
||||||
|
* The behavior of asserts can be overwritten by redefining them here.
|
||||||
|
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
|
||||||
|
*/
|
||||||
|
#define LV_USE_DEBUG 1
|
||||||
|
#if LV_USE_DEBUG
|
||||||
|
|
||||||
|
/*Check if the parameter is NULL. (Quite fast) */
|
||||||
|
#define LV_USE_ASSERT_NULL 1
|
||||||
|
|
||||||
|
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||||
|
#define LV_USE_ASSERT_MEM 1
|
||||||
|
|
||||||
|
/*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
||||||
|
#define LV_USE_ASSERT_MEM_INTEGRITY 0
|
||||||
|
|
||||||
|
/* Check the strings.
|
||||||
|
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||||
|
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||||
|
#define LV_USE_ASSERT_STR 0
|
||||||
|
|
||||||
|
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
|
||||||
|
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||||
|
#define LV_USE_ASSERT_OBJ 0
|
||||||
|
|
||||||
|
/*Check if the styles are properly initialized. (Fast)*/
|
||||||
|
#define LV_USE_ASSERT_STYLE 0
|
||||||
|
|
||||||
|
#endif /*LV_USE_DEBUG*/
|
||||||
|
|
||||||
|
/*==================
|
||||||
|
* FONT USAGE
|
||||||
|
*===================*/
|
||||||
|
|
||||||
|
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||||
|
* The symbols are available via `LV_SYMBOL_...` defines
|
||||||
|
* More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html
|
||||||
|
* To create a new font go to: https://lvgl.com/ttf-font-to-c-array
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Montserrat fonts with bpp = 4
|
||||||
|
* https://fonts.google.com/specimen/Montserrat */
|
||||||
|
#define LV_FONT_MONTSERRAT_8 0
|
||||||
|
#define LV_FONT_MONTSERRAT_10 0
|
||||||
|
#define LV_FONT_MONTSERRAT_12 0
|
||||||
|
#define LV_FONT_MONTSERRAT_14 1
|
||||||
|
#define LV_FONT_MONTSERRAT_16 0
|
||||||
|
#define LV_FONT_MONTSERRAT_18 0
|
||||||
|
#define LV_FONT_MONTSERRAT_20 0
|
||||||
|
#define LV_FONT_MONTSERRAT_22 0
|
||||||
|
#define LV_FONT_MONTSERRAT_24 0
|
||||||
|
#define LV_FONT_MONTSERRAT_26 0
|
||||||
|
#define LV_FONT_MONTSERRAT_28 0
|
||||||
|
#define LV_FONT_MONTSERRAT_30 0
|
||||||
|
#define LV_FONT_MONTSERRAT_32 1
|
||||||
|
#define LV_FONT_MONTSERRAT_34 0
|
||||||
|
#define LV_FONT_MONTSERRAT_36 0
|
||||||
|
#define LV_FONT_MONTSERRAT_38 0
|
||||||
|
#define LV_FONT_MONTSERRAT_40 0
|
||||||
|
#define LV_FONT_MONTSERRAT_42 0
|
||||||
|
#define LV_FONT_MONTSERRAT_44 0
|
||||||
|
#define LV_FONT_MONTSERRAT_46 0
|
||||||
|
#define LV_FONT_MONTSERRAT_48 0
|
||||||
|
|
||||||
|
/* Demonstrate special features */
|
||||||
|
#define LV_FONT_MONTSERRAT_12_SUBPX 0
|
||||||
|
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
|
||||||
|
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/
|
||||||
|
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
|
||||||
|
|
||||||
|
/*Pixel perfect monospace font
|
||||||
|
* http://pelulamu.net/unscii/ */
|
||||||
|
#define LV_FONT_UNSCII_8 0
|
||||||
|
#define LV_FONT_UNSCII_16 0
|
||||||
|
|
||||||
|
/* Optionally declare your custom fonts here.
|
||||||
|
* You can use these fonts as default font too
|
||||||
|
* and they will be available globally. E.g.
|
||||||
|
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
|
||||||
|
* LV_FONT_DECLARE(my_font_2)
|
||||||
|
*/
|
||||||
|
#define LV_FONT_CUSTOM_DECLARE
|
||||||
|
|
||||||
|
/* Enable it if you have fonts with a lot of characters.
|
||||||
|
* The limit depends on the font size, font face and bpp
|
||||||
|
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||||
|
#define LV_FONT_FMT_TXT_LARGE 0
|
||||||
|
|
||||||
|
/* Enables/disables support for compressed fonts. If it's disabled, compressed
|
||||||
|
* glyphs cannot be processed by the library and won't be rendered.
|
||||||
|
*/
|
||||||
|
#define LV_USE_FONT_COMPRESSED 1
|
||||||
|
|
||||||
|
/* Enable subpixel rendering */
|
||||||
|
#define LV_USE_FONT_SUBPX 1
|
||||||
|
#if LV_USE_FONT_SUBPX
|
||||||
|
/* Set the pixel order of the display.
|
||||||
|
* Important only if "subpx fonts" are used.
|
||||||
|
* With "normal" font it doesn't matter.
|
||||||
|
*/
|
||||||
|
#define LV_FONT_SUBPX_BGR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
|
typedef void * lv_font_user_data_t;
|
||||||
|
|
||||||
|
/*================
|
||||||
|
* THEME USAGE
|
||||||
|
*================*/
|
||||||
|
|
||||||
|
/*Always enable at least on theme*/
|
||||||
|
|
||||||
|
/* No theme, you can apply your styles as you need
|
||||||
|
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||||
|
#define LV_USE_THEME_EMPTY 1
|
||||||
|
|
||||||
|
/*Simple to the create your theme based on it
|
||||||
|
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||||
|
#define LV_USE_THEME_TEMPLATE 1
|
||||||
|
|
||||||
|
/* A fast and impressive theme.
|
||||||
|
* Flags:
|
||||||
|
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme
|
||||||
|
* LV_THEME_MATERIAL_FLAG_DARK: dark theme
|
||||||
|
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
|
||||||
|
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
|
||||||
|
* */
|
||||||
|
#define LV_USE_THEME_MATERIAL 1
|
||||||
|
|
||||||
|
/* Mono-color theme for monochrome displays.
|
||||||
|
* If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the
|
||||||
|
* texts and borders will be black and the background will be
|
||||||
|
* white. Else the colors are inverted.
|
||||||
|
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||||
|
#define LV_USE_THEME_MONO 1
|
||||||
|
|
||||||
|
#define LV_THEME_DEFAULT_INCLUDE <stdint.h> /*Include a header for the init. function*/
|
||||||
|
#define LV_THEME_DEFAULT_INIT lv_theme_material_init
|
||||||
|
#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1)
|
||||||
|
#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6)
|
||||||
|
#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_LIGHT
|
||||||
|
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_32
|
||||||
|
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_32
|
||||||
|
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_32
|
||||||
|
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_32
|
||||||
|
|
||||||
|
/*=================
|
||||||
|
* Text settings
|
||||||
|
*=================*/
|
||||||
|
|
||||||
|
/* Select a character encoding for strings.
|
||||||
|
* Your IDE or editor should have the same character encoding
|
||||||
|
* - LV_TXT_ENC_UTF8
|
||||||
|
* - LV_TXT_ENC_ASCII
|
||||||
|
* */
|
||||||
|
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||||
|
|
||||||
|
/*Can break (wrap) texts on these chars*/
|
||||||
|
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||||
|
|
||||||
|
/* If a word is at least this long, will break wherever "prettiest"
|
||||||
|
* To disable, set to a value <= 0 */
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
||||||
|
|
||||||
|
/* Minimum number of characters in a long word to put on a line before a break.
|
||||||
|
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
|
|
||||||
|
/* Minimum number of characters in a long word to put on a line after a break.
|
||||||
|
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
|
||||||
|
/* The control character to use for signalling text recoloring. */
|
||||||
|
#define LV_TXT_COLOR_CMD "#"
|
||||||
|
|
||||||
|
/* Support bidirectional texts.
|
||||||
|
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||||
|
* The direction will be processed according to the Unicode Bidirectional Algorithm:
|
||||||
|
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||||
|
#define LV_USE_BIDI 0
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
/* Set the default direction. Supported values:
|
||||||
|
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||||
|
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||||
|
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||||
|
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable Arabic/Persian processing
|
||||||
|
* In these languages characters should be replaced with
|
||||||
|
* an other form based on their position in the text */
|
||||||
|
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
||||||
|
|
||||||
|
/*Change the built in (v)snprintf functions*/
|
||||||
|
#define LV_SPRINTF_CUSTOM 0
|
||||||
|
#if LV_SPRINTF_CUSTOM
|
||||||
|
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||||
|
# define lv_snprintf snprintf
|
||||||
|
# define lv_vsnprintf vsnprintf
|
||||||
|
#else /*!LV_SPRINTF_CUSTOM*/
|
||||||
|
# define LV_SPRINTF_DISABLE_FLOAT 1
|
||||||
|
#endif /*LV_SPRINTF_CUSTOM*/
|
||||||
|
|
||||||
|
/*===================
|
||||||
|
* LV_OBJ SETTINGS
|
||||||
|
*==================*/
|
||||||
|
|
||||||
|
#if LV_USE_USER_DATA
|
||||||
|
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
|
typedef void * lv_obj_user_data_t;
|
||||||
|
/*Provide a function to free user data*/
|
||||||
|
#define LV_USE_USER_DATA_FREE 0
|
||||||
|
#if LV_USE_USER_DATA_FREE
|
||||||
|
# define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/
|
||||||
|
/* Function prototype : void user_data_free(lv_obj_t * obj); */
|
||||||
|
# define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/
|
||||||
|
#define LV_USE_OBJ_REALIGN 1
|
||||||
|
|
||||||
|
/* Enable to make the object clickable on a larger area.
|
||||||
|
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||||
|
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||||
|
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||||
|
*/
|
||||||
|
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY
|
||||||
|
|
||||||
|
/*==================
|
||||||
|
* LV OBJ X USAGE
|
||||||
|
*================*/
|
||||||
|
/*
|
||||||
|
* Documentation of the object types: https://docs.lvgl.com/#Object-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*Arc (dependencies: -)*/
|
||||||
|
#define LV_USE_ARC 1
|
||||||
|
|
||||||
|
/*Bar (dependencies: -)*/
|
||||||
|
#define LV_USE_BAR 1
|
||||||
|
|
||||||
|
/*Button (dependencies: lv_cont*/
|
||||||
|
#define LV_USE_BTN 1
|
||||||
|
|
||||||
|
/*Button matrix (dependencies: -)*/
|
||||||
|
#define LV_USE_BTNMATRIX 1
|
||||||
|
|
||||||
|
/*Calendar (dependencies: -)*/
|
||||||
|
#define LV_USE_CALENDAR 1
|
||||||
|
#if LV_USE_CALENDAR
|
||||||
|
# define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Canvas (dependencies: lv_img)*/
|
||||||
|
#define LV_USE_CANVAS 1
|
||||||
|
|
||||||
|
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||||
|
#define LV_USE_CHECKBOX 1
|
||||||
|
|
||||||
|
/*Chart (dependencies: -)*/
|
||||||
|
#define LV_USE_CHART 1
|
||||||
|
#if LV_USE_CHART
|
||||||
|
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Container (dependencies: -*/
|
||||||
|
#define LV_USE_CONT 1
|
||||||
|
|
||||||
|
/*Color picker (dependencies: -*/
|
||||||
|
#define LV_USE_CPICKER 1
|
||||||
|
|
||||||
|
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||||
|
#define LV_USE_DROPDOWN 1
|
||||||
|
#if LV_USE_DROPDOWN != 0
|
||||||
|
/*Open and close default animation time [ms] (0: no animation)*/
|
||||||
|
# define LV_DROPDOWN_DEF_ANIM_TIME 200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Gauge (dependencies:lv_bar, lv_linemeter)*/
|
||||||
|
#define LV_USE_GAUGE 1
|
||||||
|
|
||||||
|
/*Image (dependencies: lv_label*/
|
||||||
|
#define LV_USE_IMG 1
|
||||||
|
|
||||||
|
/*Image Button (dependencies: lv_btn*/
|
||||||
|
#define LV_USE_IMGBTN 1
|
||||||
|
#if LV_USE_IMGBTN
|
||||||
|
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||||
|
# define LV_IMGBTN_TILED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Keyboard (dependencies: lv_btnm)*/
|
||||||
|
#define LV_USE_KEYBOARD 1
|
||||||
|
|
||||||
|
/*Label (dependencies: -*/
|
||||||
|
#define LV_USE_LABEL 1
|
||||||
|
#if LV_USE_LABEL != 0
|
||||||
|
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||||
|
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||||
|
|
||||||
|
/* Waiting period at beginning/end of animation cycle */
|
||||||
|
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||||
|
|
||||||
|
/*Enable selecting text of the label */
|
||||||
|
# define LV_LABEL_TEXT_SEL 0
|
||||||
|
|
||||||
|
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||||
|
# define LV_LABEL_LONG_TXT_HINT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*LED (dependencies: -)*/
|
||||||
|
#define LV_USE_LED 1
|
||||||
|
#if LV_USE_LED
|
||||||
|
# define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/
|
||||||
|
# define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Line (dependencies: -*/
|
||||||
|
#define LV_USE_LINE 1
|
||||||
|
|
||||||
|
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||||
|
#define LV_USE_LIST 1
|
||||||
|
#if LV_USE_LIST != 0
|
||||||
|
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||||
|
# define LV_LIST_DEF_ANIM_TIME 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Line meter (dependencies: *;)*/
|
||||||
|
#define LV_USE_LINEMETER 1
|
||||||
|
#if LV_USE_LINEMETER
|
||||||
|
/* Draw line more precisely at cost of performance.
|
||||||
|
* Useful if there are lot of lines any minor are visible
|
||||||
|
* 0: No extra precision
|
||||||
|
* 1: Some extra precision
|
||||||
|
* 2: Best precision
|
||||||
|
*/
|
||||||
|
# define LV_LINEMETER_PRECISE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Mask (dependencies: -)*/
|
||||||
|
#define LV_USE_OBJMASK 1
|
||||||
|
|
||||||
|
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||||
|
#define LV_USE_MSGBOX 1
|
||||||
|
|
||||||
|
/*Page (dependencies: lv_cont)*/
|
||||||
|
#define LV_USE_PAGE 1
|
||||||
|
#if LV_USE_PAGE != 0
|
||||||
|
/*Focus default animation time [ms] (0: no animation)*/
|
||||||
|
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||||
|
#define LV_USE_SPINNER 1
|
||||||
|
#if LV_USE_SPINNER != 0
|
||||||
|
# define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||||
|
# define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||||
|
# define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Roller (dependencies: lv_ddlist)*/
|
||||||
|
#define LV_USE_ROLLER 1
|
||||||
|
#if LV_USE_ROLLER != 0
|
||||||
|
/*Focus animation time [ms] (0: no animation)*/
|
||||||
|
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||||
|
|
||||||
|
/*Number of extra "pages" when the roller is infinite*/
|
||||||
|
# define LV_ROLLER_INF_PAGES 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Slider (dependencies: lv_bar)*/
|
||||||
|
#define LV_USE_SLIDER 1
|
||||||
|
|
||||||
|
/*Spinbox (dependencies: lv_ta)*/
|
||||||
|
#define LV_USE_SPINBOX 1
|
||||||
|
|
||||||
|
/*Switch (dependencies: lv_slider)*/
|
||||||
|
#define LV_USE_SWITCH 1
|
||||||
|
|
||||||
|
/*Text area (dependencies: lv_label, lv_page)*/
|
||||||
|
#define LV_USE_TEXTAREA 1
|
||||||
|
#if LV_USE_TEXTAREA != 0
|
||||||
|
# define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||||
|
# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Table (dependencies: lv_label)*/
|
||||||
|
#define LV_USE_TABLE 1
|
||||||
|
#if LV_USE_TABLE
|
||||||
|
# define LV_TABLE_COL_MAX 12
|
||||||
|
# define LV_TABLE_CELL_STYLE_CNT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||||
|
#define LV_USE_TABVIEW 1
|
||||||
|
# if LV_USE_TABVIEW != 0
|
||||||
|
/*Time of slide animation [ms] (0: no animation)*/
|
||||||
|
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Tileview (dependencies: lv_page) */
|
||||||
|
#define LV_USE_TILEVIEW 1
|
||||||
|
#if LV_USE_TILEVIEW
|
||||||
|
/*Time of slide animation [ms] (0: no animation)*/
|
||||||
|
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||||
|
#define LV_USE_WIN 1
|
||||||
|
|
||||||
|
/*==================
|
||||||
|
* Non-user section
|
||||||
|
*==================*/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||||
|
# define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*--END OF LV_CONF_H--*/
|
||||||
|
|
||||||
|
#endif /*LV_CONF_H*/
|
||||||
|
|
||||||
|
#endif /*End of "Content enable"*/
|
|
@ -60,6 +60,10 @@ void Error_Handler(void);
|
||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
#define LCD_BL_Pin GPIO_PIN_1
|
#define LCD_BL_Pin GPIO_PIN_1
|
||||||
#define LCD_BL_GPIO_Port GPIOB
|
#define LCD_BL_GPIO_Port GPIOB
|
||||||
|
#define LED2_Pin GPIO_PIN_15
|
||||||
|
#define LED2_GPIO_Port GPIOA
|
||||||
|
#define LED1_Pin GPIO_PIN_11
|
||||||
|
#define LED1_GPIO_Port GPIOC
|
||||||
/* USER CODE BEGIN Private defines */
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
/* USER CODE END Private defines */
|
/* USER CODE END Private defines */
|
||||||
|
|
|
@ -31,14 +31,21 @@ typedef enum {
|
||||||
OTM_VERTICAL_INV
|
OTM_VERTICAL_INV
|
||||||
} otm_direction_t;
|
} otm_direction_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OTM_RGB888,
|
||||||
|
OTM_RGB565
|
||||||
|
} otm_color_format_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
otm_ret_t (*write_reg_cb)(void *handle, otm_data_t *reg, uint8_t len);
|
otm_ret_t (*write_reg_cb)(void *handle, otm_data_t *reg, uint8_t len);
|
||||||
otm_ret_t (*write_data_cb)(void *handle, otm_data_t *data, uint32_t len);
|
otm_ret_t (*write_data_cb)(void *handle, otm_data_t *data, uint32_t len);
|
||||||
otm_ret_t (*delay_cb)(void *handle, uint32_t usec);
|
otm_ret_t (*delay_cb)(void *handle, uint32_t usec);
|
||||||
|
otm_ret_t (*backlight_cb)(void *handle, uint8_t on);
|
||||||
} otm_cb_t;
|
} otm_cb_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
otm_direction_t direction;
|
otm_direction_t direction;
|
||||||
|
otm_color_format_t color_format;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
otm_cb_t cb;
|
otm_cb_t cb;
|
||||||
} otm_t;
|
} otm_t;
|
||||||
|
@ -49,5 +56,6 @@ otm_ret_t otm_lcd_init(otm_t *lcd);
|
||||||
otm_ret_t otm_lcd_display(otm_t *lcd, uint8_t on);
|
otm_ret_t otm_lcd_display(otm_t *lcd, uint8_t on);
|
||||||
otm_ret_t otm_lcd_upload(otm_t *lcd, uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, uint16_t *data);
|
otm_ret_t otm_lcd_upload(otm_t *lcd, uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, uint16_t *data);
|
||||||
otm_ret_t otm_lcd_direction(otm_t *lcd, otm_direction_t direction);
|
otm_ret_t otm_lcd_direction(otm_t *lcd, otm_direction_t direction);
|
||||||
|
otm_ret_t otm_lcd_color_format(otm_t *lcd, otm_color_format_t format);
|
||||||
|
|
||||||
#endif
|
#endif
|
7
Core/Inc/otm8009a_lcd_lvgl_impl.h
Normal file
7
Core/Inc/otm8009a_lcd_lvgl_impl.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
void _otm_lcd_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||||
|
void _otm_lcd_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w,
|
||||||
|
lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||||
|
void _otm_lcd_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area);
|
|
@ -6,5 +6,6 @@
|
||||||
otm_ret_t _otm_impl_write_reg(void *handle, otm_data_t *reg, uint8_t len);
|
otm_ret_t _otm_impl_write_reg(void *handle, otm_data_t *reg, uint8_t len);
|
||||||
otm_ret_t _otm_impl_write_data(void *handle, otm_data_t *data, uint32_t len);
|
otm_ret_t _otm_impl_write_data(void *handle, otm_data_t *data, uint32_t len);
|
||||||
otm_ret_t _otm_impl_delay(void *handle, uint32_t usec);
|
otm_ret_t _otm_impl_delay(void *handle, uint32_t usec);
|
||||||
|
otm_ret_t _otm_impl_backlight(void *handle, uint8_t on);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -68,12 +68,12 @@
|
||||||
/* #define HAL_RNG_MODULE_ENABLED */
|
/* #define HAL_RNG_MODULE_ENABLED */
|
||||||
#define HAL_RTC_MODULE_ENABLED
|
#define HAL_RTC_MODULE_ENABLED
|
||||||
/* #define HAL_SAI_MODULE_ENABLED */
|
/* #define HAL_SAI_MODULE_ENABLED */
|
||||||
/* #define HAL_SD_MODULE_ENABLED */
|
#define HAL_SD_MODULE_ENABLED
|
||||||
/* #define HAL_MMC_MODULE_ENABLED */
|
/* #define HAL_MMC_MODULE_ENABLED */
|
||||||
/* #define HAL_SPDIFRX_MODULE_ENABLED */
|
/* #define HAL_SPDIFRX_MODULE_ENABLED */
|
||||||
/* #define HAL_SPI_MODULE_ENABLED */
|
/* #define HAL_SPI_MODULE_ENABLED */
|
||||||
/* #define HAL_SWPMI_MODULE_ENABLED */
|
/* #define HAL_SWPMI_MODULE_ENABLED */
|
||||||
/* #define HAL_TIM_MODULE_ENABLED */
|
#define HAL_TIM_MODULE_ENABLED
|
||||||
/* #define HAL_UART_MODULE_ENABLED */
|
/* #define HAL_UART_MODULE_ENABLED */
|
||||||
/* #define HAL_USART_MODULE_ENABLED */
|
/* #define HAL_USART_MODULE_ENABLED */
|
||||||
/* #define HAL_IRDA_MODULE_ENABLED */
|
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||||
|
@ -166,7 +166,7 @@
|
||||||
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
|
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
|
||||||
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
|
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
|
||||||
#define USE_RTOS 0U
|
#define USE_RTOS 0U
|
||||||
#define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */
|
#define USE_SD_TRANSCEIVER 1U /*!< use uSD Transceiver */
|
||||||
#define USE_SPI_CRC 0U /*!< use CRC in SPI */
|
#define USE_SPI_CRC 0U /*!< use CRC in SPI */
|
||||||
|
|
||||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||||
|
|
|
@ -52,15 +52,14 @@ void HardFault_Handler(void);
|
||||||
void MemManage_Handler(void);
|
void MemManage_Handler(void);
|
||||||
void BusFault_Handler(void);
|
void BusFault_Handler(void);
|
||||||
void UsageFault_Handler(void);
|
void UsageFault_Handler(void);
|
||||||
void SVC_Handler(void);
|
|
||||||
void DebugMon_Handler(void);
|
void DebugMon_Handler(void);
|
||||||
void PendSV_Handler(void);
|
|
||||||
void SysTick_Handler(void);
|
|
||||||
void PVD_AVD_IRQHandler(void);
|
void PVD_AVD_IRQHandler(void);
|
||||||
void FLASH_IRQHandler(void);
|
void FLASH_IRQHandler(void);
|
||||||
void RCC_IRQHandler(void);
|
void RCC_IRQHandler(void);
|
||||||
|
void TIM6_DAC_IRQHandler(void);
|
||||||
void FPU_IRQHandler(void);
|
void FPU_IRQHandler(void);
|
||||||
void QUADSPI_IRQHandler(void);
|
void QUADSPI_IRQHandler(void);
|
||||||
|
void SDMMC2_IRQHandler(void);
|
||||||
void HSEM1_IRQHandler(void);
|
void HSEM1_IRQHandler(void);
|
||||||
/* USER CODE BEGIN EFP */
|
/* USER CODE BEGIN EFP */
|
||||||
|
|
||||||
|
|
5
Core/Inc/user_tasks.h
Normal file
5
Core/Inc/user_tasks.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void user_tasks_init(void);
|
||||||
|
void user_task_lvgl_init(void);
|
||||||
|
void user_task_hello_init(void);
|
61
Core/Src/freertos.c
Normal file
61
Core/Src/freertos.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* File Name : freertos.c
|
||||||
|
* Description : Code for freertos applications
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
1959
Core/Src/kururin_pa.c
Normal file
1959
Core/Src/kururin_pa.c
Normal file
File diff suppressed because one or more lines are too long
172
Core/Src/main.c
172
Core/Src/main.c
|
@ -19,13 +19,13 @@
|
||||||
/* USER CODE END Header */
|
/* USER CODE END Header */
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#include "fatfs.h"
|
||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
#include <string.h>
|
#include "user_tasks.h"
|
||||||
#include "otm8009a_lcd.h"
|
|
||||||
#include "otm_lcd_impl.h"
|
|
||||||
|
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
@ -49,18 +49,18 @@ QSPI_HandleTypeDef hqspi;
|
||||||
|
|
||||||
RTC_HandleTypeDef hrtc;
|
RTC_HandleTypeDef hrtc;
|
||||||
|
|
||||||
|
SD_HandleTypeDef hsd2;
|
||||||
|
|
||||||
SRAM_HandleTypeDef hsram1;
|
SRAM_HandleTypeDef hsram1;
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* Definitions for defaultTask */
|
||||||
|
osThreadId_t defaultTaskHandle;
|
||||||
otm_t g_lcd = {
|
const osThreadAttr_t defaultTask_attributes = {
|
||||||
.cb = {
|
.name = "defaultTask",
|
||||||
.delay_cb = _otm_impl_delay,
|
.priority = (osPriority_t) osPriorityNormal,
|
||||||
.write_data_cb = _otm_impl_write_data,
|
.stack_size = 128 * 4
|
||||||
.write_reg_cb = _otm_impl_write_reg
|
|
||||||
},
|
|
||||||
.user_data = NULL
|
|
||||||
};
|
};
|
||||||
|
/* USER CODE BEGIN PV */
|
||||||
|
|
||||||
/* USER CODE END PV */
|
/* USER CODE END PV */
|
||||||
|
|
||||||
|
@ -71,6 +71,9 @@ static void MX_GPIO_Init(void);
|
||||||
static void MX_FMC_Init(void);
|
static void MX_FMC_Init(void);
|
||||||
static void MX_QUADSPI_Init(void);
|
static void MX_QUADSPI_Init(void);
|
||||||
static void MX_RTC_Init(void);
|
static void MX_RTC_Init(void);
|
||||||
|
static void MX_SDMMC2_SD_Init(void);
|
||||||
|
void StartDefaultTask(void *argument);
|
||||||
|
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
/* USER CODE END PFP */
|
/* USER CODE END PFP */
|
||||||
|
@ -123,16 +126,47 @@ int main(void)
|
||||||
MX_FMC_Init();
|
MX_FMC_Init();
|
||||||
MX_QUADSPI_Init();
|
MX_QUADSPI_Init();
|
||||||
MX_RTC_Init();
|
MX_RTC_Init();
|
||||||
|
MX_SDMMC2_SD_Init();
|
||||||
|
MX_FATFS_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
otm_lcd_init(&g_lcd);
|
|
||||||
otm_lcd_direction(&g_lcd, OTM_HORIZONTAL_INV);
|
|
||||||
uint32_t color[1024];
|
|
||||||
memset(color, 0xFF, 1024 * 4);
|
|
||||||
otm_lcd_upload(&g_lcd, 0, 99, 0, 9, (uint16_t *)color);
|
|
||||||
|
|
||||||
/* USER CODE END 2 */
|
/* 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 */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -202,10 +236,12 @@ void SystemClock_Config(void)
|
||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_QSPI
|
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_SDMMC
|
||||||
|RCC_PERIPHCLK_FMC|RCC_PERIPHCLK_CKPER;
|
|RCC_PERIPHCLK_QSPI|RCC_PERIPHCLK_FMC
|
||||||
|
|RCC_PERIPHCLK_CKPER;
|
||||||
PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL;
|
PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL;
|
||||||
PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_CLKP;
|
PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_CLKP;
|
||||||
|
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
|
||||||
PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSI;
|
PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSI;
|
||||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
|
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
|
||||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||||
|
@ -317,6 +353,34 @@ static void MX_RTC_Init(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SDMMC2 Initialization Function
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void MX_SDMMC2_SD_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN SDMMC2_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN SDMMC2_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_Init 1 */
|
||||||
|
hsd2.Instance = SDMMC2;
|
||||||
|
hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
|
||||||
|
hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
|
||||||
|
hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
|
||||||
|
hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||||
|
hsd2.Init.ClockDiv = 0;
|
||||||
|
hsd2.Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
|
||||||
|
/* USER CODE BEGIN SDMMC2_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* FMC initialization function */
|
/* FMC initialization function */
|
||||||
static void MX_FMC_Init(void)
|
static void MX_FMC_Init(void)
|
||||||
{
|
{
|
||||||
|
@ -352,10 +416,10 @@ static void MX_FMC_Init(void)
|
||||||
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
|
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
|
||||||
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
|
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
|
||||||
/* Timing */
|
/* Timing */
|
||||||
Timing.AddressSetupTime = 15;
|
Timing.AddressSetupTime = 5;
|
||||||
Timing.AddressHoldTime = 15;
|
Timing.AddressHoldTime = 15;
|
||||||
Timing.DataSetupTime = 255;
|
Timing.DataSetupTime = 5;
|
||||||
Timing.BusTurnAroundDuration = 15;
|
Timing.BusTurnAroundDuration = 5;
|
||||||
Timing.CLKDivision = 16;
|
Timing.CLKDivision = 16;
|
||||||
Timing.DataLatency = 17;
|
Timing.DataLatency = 17;
|
||||||
Timing.AccessMode = FMC_ACCESS_MODE_A;
|
Timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||||
|
@ -389,7 +453,13 @@ static void MX_GPIO_Init(void)
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
|
/*Configure GPIO pin Output Level */
|
||||||
|
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
|
/*Configure GPIO pin Output Level */
|
||||||
|
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
/*Configure GPIO pin : LCD_BL_Pin */
|
/*Configure GPIO pin : LCD_BL_Pin */
|
||||||
GPIO_InitStruct.Pin = LCD_BL_Pin;
|
GPIO_InitStruct.Pin = LCD_BL_Pin;
|
||||||
|
@ -398,12 +468,46 @@ static void MX_GPIO_Init(void)
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
HAL_GPIO_Init(LCD_BL_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(LCD_BL_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/*Configure GPIO pin : LED2_Pin */
|
||||||
|
GPIO_InitStruct.Pin = LED2_Pin;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
|
HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/*Configure GPIO pin : LED1_Pin */
|
||||||
|
GPIO_InitStruct.Pin = LED1_Pin;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
|
HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
/* USER CODE END 4 */
|
/* 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 */
|
||||||
|
user_tasks_init();
|
||||||
|
osThreadExit();
|
||||||
|
/* Infinite loop */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
osDelay(1);
|
||||||
|
}
|
||||||
|
/* USER CODE END 5 */
|
||||||
|
}
|
||||||
|
|
||||||
/* MPU Configuration */
|
/* MPU Configuration */
|
||||||
|
|
||||||
void MPU_Config(void)
|
void MPU_Config(void)
|
||||||
|
@ -491,6 +595,26 @@ void MPU_Config(void)
|
||||||
HAL_MPU_Enable(MPU_HFNMI_PRIVDEF_NONE);
|
HAL_MPU_Enable(MPU_HFNMI_PRIVDEF_NONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Period elapsed callback in non blocking mode
|
||||||
|
* @note This function is called when TIM6 interrupt took place, inside
|
||||||
|
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
|
||||||
|
* a global variable "uwTick" used as application time base.
|
||||||
|
* @param htim : TIM handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN Callback 0 */
|
||||||
|
|
||||||
|
/* USER CODE END Callback 0 */
|
||||||
|
if (htim->Instance == TIM6) {
|
||||||
|
HAL_IncTick();
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN Callback 1 */
|
||||||
|
|
||||||
|
/* USER CODE END Callback 1 */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is executed in case of error occurrence.
|
* @brief This function is executed in case of error occurrence.
|
||||||
|
|
|
@ -50,7 +50,6 @@ uint16_t otm8009a_800480_16b_init_sequence[] = {
|
||||||
0x0001, 0xcca1, 0x0000, 0x0001, 0xcca2, 0x0000, 0x0001, 0xcca3, 0x0000,
|
0x0001, 0xcca1, 0x0000, 0x0001, 0xcca2, 0x0000, 0x0001, 0xcca3, 0x0000,
|
||||||
0x0001, 0xcca4, 0x0000, 0x0001, 0xcca5, 0x0000, 0x0001, 0xcca6, 0x0000,
|
0x0001, 0xcca4, 0x0000, 0x0001, 0xcca5, 0x0000, 0x0001, 0xcca6, 0x0000,
|
||||||
0x0001, 0xcca7, 0x0000, 0x0001, 0xcca8, 0x0000, 0x0001, 0xcca9, 0x0000,
|
0x0001, 0xcca7, 0x0000, 0x0001, 0xcca8, 0x0000, 0x0001, 0xcca9, 0x0000,
|
||||||
0x0001, 0x3a00, 0x0057
|
|
||||||
};
|
};
|
||||||
|
|
||||||
otm_ret_t _otm_lcd_init_seq(otm_t *lcd) {
|
otm_ret_t _otm_lcd_init_seq(otm_t *lcd) {
|
||||||
|
@ -65,7 +64,7 @@ otm_ret_t _otm_lcd_init_seq(otm_t *lcd) {
|
||||||
otm_ret_t _otm_lcd_sleep(otm_t *lcd, uint8_t sleep) {
|
otm_ret_t _otm_lcd_sleep(otm_t *lcd, uint8_t sleep) {
|
||||||
uint16_t reg = sleep ? 0x1000 : 0x1100; // SLPIN : SLPOUT
|
uint16_t reg = sleep ? 0x1000 : 0x1100; // SLPIN : SLPOUT
|
||||||
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, ®, 0x01));
|
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, ®, 0x01));
|
||||||
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd->user_data, 10000)); // 5ms delay.
|
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd->user_data, 5000)); // 5ms delay.
|
||||||
|
|
||||||
return OTM_OK;
|
return OTM_OK;
|
||||||
}
|
}
|
||||||
|
@ -92,10 +91,12 @@ otm_ret_t _otm_lcd_window(otm_t *lcd, uint16_t x_start, uint16_t x_end, uint16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
otm_ret_t otm_lcd_init(otm_t *lcd) {
|
otm_ret_t otm_lcd_init(otm_t *lcd) {
|
||||||
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd, 100000)); //50ms
|
OTM_ERROR_CHECK(lcd->cb.backlight_cb(lcd, 1));
|
||||||
|
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd, 50000)); //50ms
|
||||||
OTM_ERROR_CHECK(_otm_lcd_init_seq(lcd));
|
OTM_ERROR_CHECK(_otm_lcd_init_seq(lcd));
|
||||||
OTM_ERROR_CHECK(_otm_lcd_sleep(lcd, 0));
|
OTM_ERROR_CHECK(_otm_lcd_sleep(lcd, 0));
|
||||||
OTM_ERROR_CHECK(otm_lcd_display(lcd, 1));
|
OTM_ERROR_CHECK(otm_lcd_display(lcd, 1));
|
||||||
|
OTM_ERROR_CHECK(otm_lcd_color_format(lcd, OTM_RGB888));
|
||||||
|
|
||||||
return OTM_OK;
|
return OTM_OK;
|
||||||
}
|
}
|
||||||
|
@ -111,10 +112,11 @@ otm_ret_t otm_lcd_upload(otm_t *lcd, uint16_t x1, uint16_t x2, uint16_t y1, uint
|
||||||
OTM_ERROR_CHECK(_otm_lcd_window(lcd, x1, x2, y1, y2));
|
OTM_ERROR_CHECK(_otm_lcd_window(lcd, x1, x2, y1, y2));
|
||||||
|
|
||||||
uint32_t pixels = (y2 - y1 + 1) * (x2 - x1 + 1);
|
uint32_t pixels = (y2 - y1 + 1) * (x2 - x1 + 1);
|
||||||
|
uint32_t transfer_count = (lcd->color_format == OTM_RGB888) ? (pixels * 3 / 2) : (pixels);
|
||||||
|
|
||||||
uint16_t reg = 0x2C00;
|
uint16_t reg = 0x2C00;
|
||||||
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, ®, 0x01));
|
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, ®, 0x01));
|
||||||
OTM_ERROR_CHECK(lcd->cb.write_data_cb(lcd->user_data, data, pixels * 2));
|
OTM_ERROR_CHECK(lcd->cb.write_data_cb(lcd->user_data, data, transfer_count));
|
||||||
|
|
||||||
return OTM_OK;
|
return OTM_OK;
|
||||||
}
|
}
|
||||||
|
@ -133,4 +135,21 @@ otm_ret_t otm_lcd_direction(otm_t *lcd, otm_direction_t direction) {
|
||||||
lcd->direction = direction;
|
lcd->direction = direction;
|
||||||
|
|
||||||
return OTM_OK;
|
return OTM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otm_ret_t otm_lcd_color_format(otm_t *lcd, otm_color_format_t format) {
|
||||||
|
uint16_t reg[] = { 0x3a00, 0x0057 };
|
||||||
|
switch(format) {
|
||||||
|
case OTM_RGB565:
|
||||||
|
reg[1] = 0x0055;
|
||||||
|
break;
|
||||||
|
case OTM_RGB888:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
|
||||||
|
|
||||||
|
lcd->color_format = format;
|
||||||
|
|
||||||
|
return OTM_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "stm32h7xx_hal.h"
|
#include "stm32h7xx_hal.h"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include "otm_lcd_impl.h"
|
#include "otm_lcd_impl.h"
|
||||||
|
|
||||||
#define LCD_REGISTER_ADDR 0x60000000
|
#define LCD_REGISTER_ADDR 0x60000000
|
||||||
|
@ -25,5 +26,10 @@ otm_ret_t _otm_impl_write_data(void *handle, otm_data_t *data, uint32_t len) {
|
||||||
otm_ret_t _otm_impl_delay(void *handle, uint32_t usec) {
|
otm_ret_t _otm_impl_delay(void *handle, uint32_t usec) {
|
||||||
HAL_Delay(usec / 1000);
|
HAL_Delay(usec / 1000);
|
||||||
|
|
||||||
|
return OTM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
otm_ret_t _otm_impl_backlight(void *handle, uint8_t on) {
|
||||||
|
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, on ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||||
return OTM_OK;
|
return OTM_OK;
|
||||||
}
|
}
|
36
Core/Src/otm_lcd_lvgl_impl.c
Normal file
36
Core/Src/otm_lcd_lvgl_impl.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "otm8009a_lcd.h"
|
||||||
|
|
||||||
|
#include "otm8009a_lcd_lvgl_impl.h"
|
||||||
|
|
||||||
|
void _otm_lcd_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
|
||||||
|
otm_t *lcd = disp_drv->user_data;
|
||||||
|
otm_lcd_upload(lcd, area->x1, area->x2, area->y1, area->y2, (uint16_t *)color_p);
|
||||||
|
lv_disp_flush_ready(disp_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _otm_lcd_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w,
|
||||||
|
lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
|
||||||
|
otm_t *lcd = disp_drv->user_data;
|
||||||
|
uint8_t * pixel_ptr;
|
||||||
|
if(lcd->color_format == OTM_RGB888) {
|
||||||
|
pixel_ptr = buf + (buf_w * y + x) * 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel_ptr = buf + (buf_w * y + x) * 2;
|
||||||
|
}
|
||||||
|
if(x % 2 == 0) {
|
||||||
|
*(pixel_ptr) = color.ch.green;
|
||||||
|
*(pixel_ptr + 1) =color.ch.red;
|
||||||
|
*(pixel_ptr + 3) = color.ch.blue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*(pixel_ptr - 1) = color.ch.red;
|
||||||
|
*(pixel_ptr + 1) = color.ch.blue;
|
||||||
|
*(pixel_ptr + 2) = color.ch.green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _otm_lcd_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) {
|
||||||
|
area->x1 &= ~0x01;
|
||||||
|
area->x2 |= 0x01;
|
||||||
|
}
|
|
@ -70,22 +70,24 @@ void HAL_MspInit(void)
|
||||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||||
|
|
||||||
/* System interrupt init*/
|
/* System interrupt init*/
|
||||||
|
/* PendSV_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
||||||
|
|
||||||
/* Peripheral interrupt init */
|
/* Peripheral interrupt init */
|
||||||
/* PVD_AVD_IRQn interrupt configuration */
|
/* PVD_AVD_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(PVD_AVD_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(PVD_AVD_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(PVD_AVD_IRQn);
|
HAL_NVIC_EnableIRQ(PVD_AVD_IRQn);
|
||||||
/* FLASH_IRQn interrupt configuration */
|
/* FLASH_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(FLASH_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(FLASH_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(FLASH_IRQn);
|
HAL_NVIC_EnableIRQ(FLASH_IRQn);
|
||||||
/* RCC_IRQn interrupt configuration */
|
/* RCC_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(RCC_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(RCC_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(RCC_IRQn);
|
HAL_NVIC_EnableIRQ(RCC_IRQn);
|
||||||
/* FPU_IRQn interrupt configuration */
|
/* FPU_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(FPU_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(FPU_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(FPU_IRQn);
|
HAL_NVIC_EnableIRQ(FPU_IRQn);
|
||||||
/* HSEM1_IRQn interrupt configuration */
|
/* HSEM1_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(HSEM1_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(HSEM1_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(HSEM1_IRQn);
|
HAL_NVIC_EnableIRQ(HSEM1_IRQn);
|
||||||
|
|
||||||
/* USER CODE BEGIN MspInit 1 */
|
/* USER CODE BEGIN MspInit 1 */
|
||||||
|
@ -151,7 +153,7 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
|
||||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||||
|
|
||||||
/* QUADSPI interrupt Init */
|
/* QUADSPI interrupt Init */
|
||||||
HAL_NVIC_SetPriority(QUADSPI_IRQn, 0, 0);
|
HAL_NVIC_SetPriority(QUADSPI_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
|
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
|
||||||
/* USER CODE BEGIN QUADSPI_MspInit 1 */
|
/* USER CODE BEGIN QUADSPI_MspInit 1 */
|
||||||
|
|
||||||
|
@ -245,6 +247,94 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SD MSP Initialization
|
||||||
|
* This function configures the hardware resources used in this example
|
||||||
|
* @param hsd: SD handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
|
if(hsd->Instance==SDMMC2)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN SDMMC2_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_MspInit 0 */
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_SDMMC2_CLK_ENABLE();
|
||||||
|
|
||||||
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
/**SDMMC2 GPIO Configuration
|
||||||
|
PB14 ------> SDMMC2_D0
|
||||||
|
PB15 ------> SDMMC2_D1
|
||||||
|
PD6 ------> SDMMC2_CK
|
||||||
|
PD7 ------> SDMMC2_CMD
|
||||||
|
PB3 (JTDO/TRACESWO) ------> SDMMC2_D2
|
||||||
|
PB4 (NJTRST) ------> SDMMC2_D3
|
||||||
|
*/
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF9_SDIO2;
|
||||||
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF11_SDIO2;
|
||||||
|
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* SDMMC2 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(SDMMC2_IRQn, 5, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(SDMMC2_IRQn);
|
||||||
|
/* USER CODE BEGIN SDMMC2_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_MspInit 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SD MSP De-Initialization
|
||||||
|
* This function freeze the hardware resources used in this example
|
||||||
|
* @param hsd: SD handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
|
||||||
|
{
|
||||||
|
if(hsd->Instance==SDMMC2)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN SDMMC2_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_SDMMC2_CLK_DISABLE();
|
||||||
|
|
||||||
|
/**SDMMC2 GPIO Configuration
|
||||||
|
PB14 ------> SDMMC2_D0
|
||||||
|
PB15 ------> SDMMC2_D1
|
||||||
|
PD6 ------> SDMMC2_CK
|
||||||
|
PD7 ------> SDMMC2_CMD
|
||||||
|
PB3 (JTDO/TRACESWO) ------> SDMMC2_D2
|
||||||
|
PB4 (NJTRST) ------> SDMMC2_D3
|
||||||
|
*/
|
||||||
|
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4);
|
||||||
|
|
||||||
|
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_6|GPIO_PIN_7);
|
||||||
|
|
||||||
|
/* SDMMC2 interrupt DeInit */
|
||||||
|
HAL_NVIC_DisableIRQ(SDMMC2_IRQn);
|
||||||
|
/* USER CODE BEGIN SDMMC2_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t FMC_Initialized = 0;
|
static uint32_t FMC_Initialized = 0;
|
||||||
|
|
||||||
static void HAL_FMC_MspInit(void){
|
static void HAL_FMC_MspInit(void){
|
||||||
|
|
130
Core/Src/stm32h7xx_hal_timebase_tim.c
Normal file
130
Core/Src/stm32h7xx_hal_timebase_tim.c
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32h7xx_hal_timebase_TIM.c
|
||||||
|
* @brief HAL time base based on the hardware TIM.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32h7xx_hal.h"
|
||||||
|
#include "stm32h7xx_hal_tim.h"
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
TIM_HandleTypeDef htim6;
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function configures the TIM6 as a time base source.
|
||||||
|
* The time source is configured to have 1ms time base with a dedicated
|
||||||
|
* Tick interrupt priority.
|
||||||
|
* @note This function is called automatically at the beginning of program after
|
||||||
|
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
|
||||||
|
* @param TickPriority: Tick interrupt priority.
|
||||||
|
* @retval HAL status
|
||||||
|
*/
|
||||||
|
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||||
|
{
|
||||||
|
RCC_ClkInitTypeDef clkconfig;
|
||||||
|
uint32_t uwTimclock, uwAPB1Prescaler;
|
||||||
|
|
||||||
|
uint32_t uwPrescalerValue;
|
||||||
|
uint32_t pFLatency;
|
||||||
|
/*Configure the TIM6 IRQ priority */
|
||||||
|
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||||
|
{
|
||||||
|
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);
|
||||||
|
|
||||||
|
/* Enable the TIM6 global Interrupt */
|
||||||
|
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
|
||||||
|
uwTickPrio = TickPriority;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HAL_ERROR;
|
||||||
|
}
|
||||||
|
/* Enable TIM6 clock */
|
||||||
|
__HAL_RCC_TIM6_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Get clock configuration */
|
||||||
|
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||||
|
|
||||||
|
/* Get APB1 prescaler */
|
||||||
|
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
|
||||||
|
/* Compute TIM6 clock */
|
||||||
|
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
|
||||||
|
{
|
||||||
|
uwTimclock = HAL_RCC_GetPCLK1Freq();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */
|
||||||
|
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
|
||||||
|
|
||||||
|
/* Initialize TIM6 */
|
||||||
|
htim6.Instance = TIM6;
|
||||||
|
|
||||||
|
/* Initialize TIMx peripheral as follow:
|
||||||
|
+ Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||||
|
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||||
|
+ ClockDivision = 0
|
||||||
|
+ Counter direction = Up
|
||||||
|
*/
|
||||||
|
htim6.Init.Period = (1000000U / 1000U) - 1U;
|
||||||
|
htim6.Init.Prescaler = uwPrescalerValue;
|
||||||
|
htim6.Init.ClockDivision = 0;
|
||||||
|
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
if(HAL_TIM_Base_Init(&htim6) == HAL_OK)
|
||||||
|
{
|
||||||
|
/* Start the TIM time Base generation in interrupt mode */
|
||||||
|
return HAL_TIM_Base_Start_IT(&htim6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return HAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend Tick increment.
|
||||||
|
* @note Disable the tick increment by disabling TIM6 update interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SuspendTick(void)
|
||||||
|
{
|
||||||
|
/* Disable TIM6 update Interrupt */
|
||||||
|
__HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume Tick increment.
|
||||||
|
* @note Enable the tick increment by Enabling TIM6 update interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_ResumeTick(void)
|
||||||
|
{
|
||||||
|
/* Enable TIM6 Update interrupt */
|
||||||
|
__HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -57,6 +57,9 @@
|
||||||
|
|
||||||
/* External variables --------------------------------------------------------*/
|
/* External variables --------------------------------------------------------*/
|
||||||
extern QSPI_HandleTypeDef hqspi;
|
extern QSPI_HandleTypeDef hqspi;
|
||||||
|
extern SD_HandleTypeDef hsd2;
|
||||||
|
extern TIM_HandleTypeDef htim6;
|
||||||
|
|
||||||
/* USER CODE BEGIN EV */
|
/* USER CODE BEGIN EV */
|
||||||
|
|
||||||
/* USER CODE END EV */
|
/* USER CODE END EV */
|
||||||
|
@ -140,19 +143,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.
|
* @brief This function handles Debug monitor.
|
||||||
*/
|
*/
|
||||||
|
@ -166,33 +156,6 @@ void DebugMon_Handler(void)
|
||||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
/* 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 */
|
|
||||||
HAL_IncTick();
|
|
||||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* STM32H7xx Peripheral Interrupt Handlers */
|
/* STM32H7xx Peripheral Interrupt Handlers */
|
||||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||||
|
@ -241,6 +204,20 @@ void RCC_IRQHandler(void)
|
||||||
/* USER CODE END RCC_IRQn 1 */
|
/* USER CODE END RCC_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles TIM6 global interrupt, DAC1_CH1 and DAC1_CH2 underrun error interrupts.
|
||||||
|
*/
|
||||||
|
void TIM6_DAC_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM6_DAC_IRQn 0 */
|
||||||
|
HAL_TIM_IRQHandler(&htim6);
|
||||||
|
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM6_DAC_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles FPU global interrupt.
|
* @brief This function handles FPU global interrupt.
|
||||||
*/
|
*/
|
||||||
|
@ -268,6 +245,20 @@ void QUADSPI_IRQHandler(void)
|
||||||
/* USER CODE END QUADSPI_IRQn 1 */
|
/* USER CODE END QUADSPI_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles SDMMC2 global interrupt.
|
||||||
|
*/
|
||||||
|
void SDMMC2_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN SDMMC2_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_IRQn 0 */
|
||||||
|
HAL_SD_IRQHandler(&hsd2);
|
||||||
|
/* USER CODE BEGIN SDMMC2_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SDMMC2_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles HSEM1 global interrupt.
|
* @brief This function handles HSEM1 global interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
30
Core/Src/user_task_hello.c
Normal file
30
Core/Src/user_task_hello.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
#include "fatfs.h"
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
osThreadId_t hello_thread_handle;
|
||||||
|
const osThreadAttr_t hello_thread_attributes = {
|
||||||
|
.name = "HELLO",
|
||||||
|
.priority = (osPriority_t) osPriorityNormal,
|
||||||
|
.stack_size = 1024 * 4
|
||||||
|
};
|
||||||
|
|
||||||
|
extern osSemaphoreId_t g_lvgl_semaphore;
|
||||||
|
|
||||||
|
void hello_thread(void *parameters);
|
||||||
|
|
||||||
|
void user_task_hello_init(void) {
|
||||||
|
hello_thread_handle = osThreadNew(hello_thread, NULL, &hello_thread_attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hello_thread(void *parameters) {
|
||||||
|
osSemaphoreAcquire(g_lvgl_semaphore, osWaitForever);
|
||||||
|
|
||||||
|
osSemaphoreRelease(g_lvgl_semaphore);
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
osDelay(1000);
|
||||||
|
}
|
||||||
|
}
|
92
Core/Src/user_task_lvgl.c
Normal file
92
Core/Src/user_task_lvgl.c
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "fatfs.h"
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
#include "otm8009a_lcd.h"
|
||||||
|
#include "otm_lcd_impl.h"
|
||||||
|
#include "otm8009a_lcd_lvgl_impl.h"
|
||||||
|
|
||||||
|
#include "user_tasks.h"
|
||||||
|
|
||||||
|
#define DISP_BUF_SIZE (800 * 10)
|
||||||
|
|
||||||
|
osThreadId_t lvgl_tick_thread_handle;
|
||||||
|
const osThreadAttr_t lvgl_tick_thread_attributes = {
|
||||||
|
.name = "LVTICK",
|
||||||
|
.priority = (osPriority_t) osPriorityNormal,
|
||||||
|
.stack_size = 128 * 4
|
||||||
|
};
|
||||||
|
|
||||||
|
osThreadId_t lvgl_task_thread_handle;
|
||||||
|
const osThreadAttr_t lvgl_task_thread_attributes = {
|
||||||
|
.name = "LVTASK",
|
||||||
|
.priority = (osPriority_t) osPriorityBelowNormal,
|
||||||
|
.stack_size = 512 * 4
|
||||||
|
};
|
||||||
|
|
||||||
|
osSemaphoreId_t g_lvgl_semaphore;
|
||||||
|
|
||||||
|
lv_disp_buf_t g_disp_buf;
|
||||||
|
lv_color_t g_disp_buf_array[DISP_BUF_SIZE];
|
||||||
|
|
||||||
|
otm_t g_lcd = {
|
||||||
|
.cb = {
|
||||||
|
.delay_cb = _otm_impl_delay,
|
||||||
|
.write_data_cb = _otm_impl_write_data,
|
||||||
|
.write_reg_cb = _otm_impl_write_reg,
|
||||||
|
.backlight_cb = _otm_impl_backlight
|
||||||
|
},
|
||||||
|
.user_data = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
void lvgl_tick_thread(void *parameters);
|
||||||
|
void lvgl_task_thread(void *parameters);
|
||||||
|
|
||||||
|
void user_task_lvgl_init(void) {
|
||||||
|
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
|
lv_init();
|
||||||
|
|
||||||
|
otm_lcd_init(&g_lcd);
|
||||||
|
otm_lcd_color_format(&g_lcd, OTM_RGB888);
|
||||||
|
otm_lcd_direction(&g_lcd, OTM_HORIZONTAL_INV);
|
||||||
|
|
||||||
|
lv_disp_buf_init(&g_disp_buf, &g_disp_buf_array, NULL, DISP_BUF_SIZE);
|
||||||
|
|
||||||
|
lv_disp_drv_t disp_drv;
|
||||||
|
lv_disp_drv_init(&disp_drv);
|
||||||
|
disp_drv.buffer = &g_disp_buf;
|
||||||
|
disp_drv.flush_cb = _otm_lcd_flush_cb;
|
||||||
|
disp_drv.rounder_cb = _otm_lcd_rounder_cb;
|
||||||
|
if(g_lcd.color_format == OTM_RGB888) {
|
||||||
|
disp_drv.set_px_cb = _otm_lcd_set_px_cb;
|
||||||
|
}
|
||||||
|
disp_drv.user_data = &g_lcd;
|
||||||
|
|
||||||
|
lv_disp_drv_register(&disp_drv);
|
||||||
|
|
||||||
|
g_lvgl_semaphore = osSemaphoreNew(1, 1, NULL);
|
||||||
|
|
||||||
|
lvgl_tick_thread_handle = osThreadNew(lvgl_tick_thread, NULL, &lvgl_tick_thread_attributes);
|
||||||
|
lvgl_task_thread_handle = osThreadNew(lvgl_task_thread, NULL, &lvgl_task_thread_attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvgl_tick_thread(void *parameters) {
|
||||||
|
for(;;) {
|
||||||
|
osSemaphoreAcquire(g_lvgl_semaphore, osWaitForever);
|
||||||
|
lv_tick_inc(30);
|
||||||
|
osSemaphoreRelease(g_lvgl_semaphore);
|
||||||
|
osDelay(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvgl_task_thread(void *parameters) {
|
||||||
|
for(;;) {
|
||||||
|
osSemaphoreAcquire(g_lvgl_semaphore, osWaitForever);
|
||||||
|
lv_task_handler();
|
||||||
|
osSemaphoreRelease(g_lvgl_semaphore);
|
||||||
|
osDelay(31);
|
||||||
|
}
|
||||||
|
}
|
6
Core/Src/user_tasks.c
Normal file
6
Core/Src/user_tasks.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "user_tasks.h"
|
||||||
|
|
||||||
|
void user_tasks_init(void) {
|
||||||
|
user_task_lvgl_init();
|
||||||
|
user_task_hello_init();
|
||||||
|
}
|
56
FATFS/App/fatfs.c
Normal file
56
FATFS/App/fatfs.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file fatfs.c
|
||||||
|
* @brief Code for fatfs applications
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fatfs.h"
|
||||||
|
|
||||||
|
uint8_t retSD; /* Return value for SD */
|
||||||
|
char SDPath[4]; /* SD logical drive path */
|
||||||
|
FATFS SDFatFS; /* File system object for SD logical drive */
|
||||||
|
FIL SDFile; /* File object for SD */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Variables */
|
||||||
|
|
||||||
|
/* USER CODE END Variables */
|
||||||
|
|
||||||
|
void MX_FATFS_Init(void)
|
||||||
|
{
|
||||||
|
/*## FatFS: Link the SD driver ###########################*/
|
||||||
|
retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Init */
|
||||||
|
/* additional user code for init */
|
||||||
|
/* USER CODE END Init */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets Time from RTC
|
||||||
|
* @param None
|
||||||
|
* @retval Time in DWORD
|
||||||
|
*/
|
||||||
|
DWORD get_fattime(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN get_fattime */
|
||||||
|
return 0;
|
||||||
|
/* USER CODE END get_fattime */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Application */
|
||||||
|
|
||||||
|
/* USER CODE END Application */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
49
FATFS/App/fatfs.h
Normal file
49
FATFS/App/fatfs.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file fatfs.h
|
||||||
|
* @brief Header for fatfs applications
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __fatfs_H
|
||||||
|
#define __fatfs_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ff.h"
|
||||||
|
#include "ff_gen_drv.h"
|
||||||
|
#include "sd_diskio.h" /* defines SD_Driver as external */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
extern uint8_t retSD; /* Return value for SD */
|
||||||
|
extern char SDPath[4]; /* SD logical drive path */
|
||||||
|
extern FATFS SDFatFS; /* File system object for SD logical drive */
|
||||||
|
extern FIL SDFile; /* File object for SD */
|
||||||
|
|
||||||
|
void MX_FATFS_Init(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Prototypes */
|
||||||
|
|
||||||
|
/* USER CODE END Prototypes */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /*__fatfs_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
309
FATFS/Target/bsp_driver_sd.c
Normal file
309
FATFS/Target/bsp_driver_sd.c
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file bsp_driver_sd.c for H7 (based on stm32h743i_eval_sd.c)
|
||||||
|
* @brief This file includes a generic uSD card driver.
|
||||||
|
* To be completed by the user according to the board used for the project.
|
||||||
|
* @note Some functions generated as weak: they can be overriden by
|
||||||
|
* - code in user files
|
||||||
|
* - or BSP code from the FW pack files
|
||||||
|
* if such files are added to the generated project (by the user).
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN FirstSection */
|
||||||
|
/* can be used to modify / undefine following code or add new definitions */
|
||||||
|
/* USER CODE END FirstSection */
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "bsp_driver_sd.h"
|
||||||
|
|
||||||
|
/* Extern variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern SD_HandleTypeDef hsd2;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeInitSection */
|
||||||
|
/* can be used to modify / undefine following code or add code */
|
||||||
|
/* USER CODE END BeforeInitSection */
|
||||||
|
/**
|
||||||
|
* @brief Initializes the SD card device.
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_Init(void)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
/* Check if the SD card is plugged in the slot */
|
||||||
|
if (BSP_SD_IsDetected() != SD_PRESENT)
|
||||||
|
{
|
||||||
|
return MSD_ERROR_SD_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
/* HAL SD initialization */
|
||||||
|
sd_state = HAL_SD_Init(&hsd2);
|
||||||
|
/* Configure SD Bus width (4 bits mode selected) */
|
||||||
|
if (sd_state == MSD_OK)
|
||||||
|
{
|
||||||
|
/* Enable wide operation */
|
||||||
|
if (HAL_SD_ConfigWideBusOperation(&hsd2, SDMMC_BUS_WIDE_4B) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN AfterInitSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END AfterInitSection */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN InterruptMode */
|
||||||
|
/**
|
||||||
|
* @brief Configures Interrupt mode for SD detection pin.
|
||||||
|
* @retval Returns 0
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_ITConfig(void)
|
||||||
|
{
|
||||||
|
/* Code to be updated by the user or replaced by one from the FW pack (in a stmxxxx_sd.c file) */
|
||||||
|
|
||||||
|
return (uint8_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE END InterruptMode */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeReadBlocksSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeReadBlocksSection */
|
||||||
|
/**
|
||||||
|
* @brief Reads block(s) from a specified address in an SD card, in polling mode.
|
||||||
|
* @param pData: Pointer to the buffer that will contain the data to transmit
|
||||||
|
* @param ReadAddr: Address from where data is to be read
|
||||||
|
* @param NumOfBlocks: Number of SD blocks to read
|
||||||
|
* @param Timeout: Timeout for read operation
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
|
||||||
|
if (HAL_SD_ReadBlocks(&hsd2, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeWriteBlocksSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeWriteBlocksSection */
|
||||||
|
/**
|
||||||
|
* @brief Writes block(s) to a specified address in an SD card, in polling mode.
|
||||||
|
* @param pData: Pointer to the buffer that will contain the data to transmit
|
||||||
|
* @param WriteAddr: Address from where data is to be written
|
||||||
|
* @param NumOfBlocks: Number of SD blocks to write
|
||||||
|
* @param Timeout: Timeout for write operation
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
|
||||||
|
if (HAL_SD_WriteBlocks(&hsd2, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeReadDMABlocksSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeReadDMABlocksSection */
|
||||||
|
/**
|
||||||
|
* @brief Reads block(s) from a specified address in an SD card, in DMA mode.
|
||||||
|
* @param pData: Pointer to the buffer that will contain the data to transmit
|
||||||
|
* @param ReadAddr: Address from where data is to be read
|
||||||
|
* @param NumOfBlocks: Number of SD blocks to read
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
|
||||||
|
/* Read block(s) in DMA transfer mode */
|
||||||
|
if (HAL_SD_ReadBlocks_DMA(&hsd2, (uint8_t *)pData, ReadAddr, NumOfBlocks) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeWriteDMABlocksSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeWriteDMABlocksSection */
|
||||||
|
/**
|
||||||
|
* @brief Writes block(s) to a specified address in an SD card, in DMA mode.
|
||||||
|
* @param pData: Pointer to the buffer that will contain the data to transmit
|
||||||
|
* @param WriteAddr: Address from where data is to be written
|
||||||
|
* @param NumOfBlocks: Number of SD blocks to write
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
|
||||||
|
/* Write block(s) in DMA transfer mode */
|
||||||
|
if (HAL_SD_WriteBlocks_DMA(&hsd2, (uint8_t *)pData, WriteAddr, NumOfBlocks) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeEraseSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeEraseSection */
|
||||||
|
/**
|
||||||
|
* @brief Erases the specified memory area of the given SD card.
|
||||||
|
* @param StartAddr: Start byte address
|
||||||
|
* @param EndAddr: End byte address
|
||||||
|
* @retval SD status
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
|
||||||
|
{
|
||||||
|
uint8_t sd_state = MSD_OK;
|
||||||
|
|
||||||
|
if (HAL_SD_Erase(&hsd2, StartAddr, EndAddr) != HAL_OK)
|
||||||
|
{
|
||||||
|
sd_state = MSD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeGetCardStateSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeGetCardStateSection */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the current SD card data status.
|
||||||
|
* @param None
|
||||||
|
* @retval Data transfer state.
|
||||||
|
* This value can be one of the following values:
|
||||||
|
* @arg SD_TRANSFER_OK: No data transfer is acting
|
||||||
|
* @arg SD_TRANSFER_BUSY: Data transfer is acting
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_GetCardState(void)
|
||||||
|
{
|
||||||
|
return ((HAL_SD_GetCardState(&hsd2) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get SD information about specific SD card.
|
||||||
|
* @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo)
|
||||||
|
{
|
||||||
|
/* Get SD card Information */
|
||||||
|
HAL_SD_GetCardInfo(&hsd2, CardInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BeforeCallBacksSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add code */
|
||||||
|
/* USER CODE END BeforeCallBacksSection */
|
||||||
|
/**
|
||||||
|
* @brief SD Abort callbacks
|
||||||
|
* @param hsd: SD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
|
||||||
|
{
|
||||||
|
BSP_SD_AbortCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tx Transfer completed callback
|
||||||
|
* @param hsd: SD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
|
||||||
|
{
|
||||||
|
BSP_SD_WriteCpltCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rx Transfer completed callback
|
||||||
|
* @param hsd: SD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
|
||||||
|
{
|
||||||
|
BSP_SD_ReadCpltCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN CallBacksSection_C */
|
||||||
|
/**
|
||||||
|
* @brief BSP SD Abort callback
|
||||||
|
* @retval None
|
||||||
|
* @note empty (up to the user to fill it in or to remove it if useless)
|
||||||
|
*/
|
||||||
|
__weak void BSP_SD_AbortCallback(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BSP Tx Transfer completed callback
|
||||||
|
* @retval None
|
||||||
|
* @note empty (up to the user to fill it in or to remove it if useless)
|
||||||
|
*/
|
||||||
|
__weak void BSP_SD_WriteCpltCallback(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BSP Rx Transfer completed callback
|
||||||
|
* @retval None
|
||||||
|
* @note empty (up to the user to fill it in or to remove it if useless)
|
||||||
|
*/
|
||||||
|
__weak void BSP_SD_ReadCpltCallback(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/* USER CODE END CallBacksSection_C */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detects if SD card is correctly plugged in the memory slot or not.
|
||||||
|
* @param None
|
||||||
|
* @retval Returns if SD is detected or not
|
||||||
|
*/
|
||||||
|
__weak uint8_t BSP_SD_IsDetected(void)
|
||||||
|
{
|
||||||
|
__IO uint8_t status = SD_PRESENT;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN IsDetectedSection */
|
||||||
|
/* user code can be inserted here */
|
||||||
|
/* USER CODE END IsDetectedSection */
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN AdditionalCode */
|
||||||
|
/* user code can be inserted here */
|
||||||
|
/* USER CODE END AdditionalCode */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
83
FATFS/Target/bsp_driver_sd.h
Normal file
83
FATFS/Target/bsp_driver_sd.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file bsp_driver_sd.h (based on stm32h743i_eval_sd.h)
|
||||||
|
* @brief This file contains the common defines and functions prototypes for
|
||||||
|
* the bsp_driver_sd.c driver.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32H7_SD_H
|
||||||
|
#define __STM32H7_SD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32h7xx_hal.h"
|
||||||
|
|
||||||
|
/* Exported types --------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief SD Card information structure
|
||||||
|
*/
|
||||||
|
#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief SD status structure definition
|
||||||
|
*/
|
||||||
|
#define MSD_OK ((uint8_t)0x00)
|
||||||
|
#define MSD_ERROR ((uint8_t)0x01)
|
||||||
|
#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SD transfer state definition
|
||||||
|
*/
|
||||||
|
#define SD_TRANSFER_OK ((uint8_t)0x00)
|
||||||
|
#define SD_TRANSFER_BUSY ((uint8_t)0x01)
|
||||||
|
|
||||||
|
#define SD_PRESENT ((uint8_t)0x01)
|
||||||
|
#define SD_NOT_PRESENT ((uint8_t)0x00)
|
||||||
|
#define SD_DATATIMEOUT ((uint32_t)100000000)
|
||||||
|
|
||||||
|
/* USER CODE BEGIN BSP_H_CODE */
|
||||||
|
#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8)
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
uint8_t BSP_SD_Init(void);
|
||||||
|
uint8_t BSP_SD_ITConfig(void);
|
||||||
|
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
|
||||||
|
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
|
||||||
|
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
|
||||||
|
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
|
||||||
|
uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
|
||||||
|
uint8_t BSP_SD_GetCardState(void);
|
||||||
|
void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo);
|
||||||
|
uint8_t BSP_SD_IsDetected(void);
|
||||||
|
|
||||||
|
/* These functions can be modified in case the current settings (e.g. DMA stream)
|
||||||
|
need to be changed for specific application needs */
|
||||||
|
void BSP_SD_AbortCallback(void);
|
||||||
|
void BSP_SD_WriteCpltCallback(void);
|
||||||
|
void BSP_SD_ReadCpltCallback(void);
|
||||||
|
/* USER CODE END BSP_H_CODE */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32H7_SD_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
271
FATFS/Target/ffconf.h
Normal file
271
FATFS/Target/ffconf.h
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
#ifndef _FFCONF
|
||||||
|
#define _FFCONF 68300 /* Revision ID */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------/
|
||||||
|
/ Additional user header to be used
|
||||||
|
/-----------------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "stm32h7xx_hal.h"
|
||||||
|
#include "bsp_driver_sd.h"
|
||||||
|
#include "cmsis_os.h" /* _FS_REENTRANT set to 1 and CMSIS API chosen */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------/
|
||||||
|
/ Function Configurations
|
||||||
|
/-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||||
|
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||||
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||||
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
|
/
|
||||||
|
/ 0: All basic functions are enabled.
|
||||||
|
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||||
|
/ 3: f_lseek() function is removed in addition to 2. */
|
||||||
|
|
||||||
|
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */
|
||||||
|
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||||
|
/ f_printf().
|
||||||
|
/
|
||||||
|
/ 0: Disable string functions.
|
||||||
|
/ 1: Enable without LF-CRLF conversion.
|
||||||
|
/ 2: Enable with LF-CRLF conversion. */
|
||||||
|
|
||||||
|
#define _USE_FIND 1
|
||||||
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
#define _USE_MKFS 1
|
||||||
|
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
#define _USE_FASTSEEK 1
|
||||||
|
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
#define _USE_EXPAND 0
|
||||||
|
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
#define _USE_CHMOD 0
|
||||||
|
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||||
|
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
#define _USE_LABEL 0
|
||||||
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
#define _USE_FORWARD 0
|
||||||
|
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------/
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _CODE_PAGE 932
|
||||||
|
/* This option specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect setting of the code page can cause a file open failure.
|
||||||
|
/
|
||||||
|
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||||
|
/ 437 - U.S.
|
||||||
|
/ 720 - Arabic
|
||||||
|
/ 737 - Greek
|
||||||
|
/ 771 - KBL
|
||||||
|
/ 775 - Baltic
|
||||||
|
/ 850 - Latin 1
|
||||||
|
/ 852 - Latin 2
|
||||||
|
/ 855 - Cyrillic
|
||||||
|
/ 857 - Turkish
|
||||||
|
/ 860 - Portuguese
|
||||||
|
/ 861 - Icelandic
|
||||||
|
/ 862 - Hebrew
|
||||||
|
/ 863 - Canadian French
|
||||||
|
/ 864 - Arabic
|
||||||
|
/ 865 - Nordic
|
||||||
|
/ 866 - Russian
|
||||||
|
/ 869 - Greek 2
|
||||||
|
/ 932 - Japanese (DBCS)
|
||||||
|
/ 936 - Simplified Chinese (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese (DBCS)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _USE_LFN 3 /* 0 to 3 */
|
||||||
|
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||||
|
/* The _USE_LFN switches the support of long file name (LFN).
|
||||||
|
/
|
||||||
|
/ 0: Disable support of LFN. _MAX_LFN has no effect.
|
||||||
|
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||||
|
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||||
|
/
|
||||||
|
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||||
|
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
||||||
|
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
||||||
|
/ It should be set 255 to support full featured LFN operations.
|
||||||
|
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||||
|
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||||
|
/ ff_memfree(), must be added to the project. */
|
||||||
|
|
||||||
|
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||||
|
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
|
||||||
|
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
||||||
|
/ This option also affects behavior of string I/O functions. */
|
||||||
|
|
||||||
|
#define _STRF_ENCODE 0
|
||||||
|
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
|
||||||
|
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM
|
||||||
|
/ 1: UTF-16LE
|
||||||
|
/ 2: UTF-16BE
|
||||||
|
/ 3: UTF-8
|
||||||
|
/
|
||||||
|
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||||
|
|
||||||
|
#define _FS_RPATH 0 /* 0 to 2 */
|
||||||
|
/* This option configures support of relative path.
|
||||||
|
/
|
||||||
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||||
|
/ 2: f_getcwd() function is available in addition to 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Drive/Volume Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _VOLUMES 1
|
||||||
|
/* Number of volumes (logical drives) to be used. */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Volumes */
|
||||||
|
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
|
||||||
|
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||||
|
/* _STR_VOLUME_ID switches string support of volume ID.
|
||||||
|
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||||
|
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||||
|
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||||
|
/ the drive ID strings are: A-Z and 0-9. */
|
||||||
|
/* USER CODE END Volumes */
|
||||||
|
|
||||||
|
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Multiple partition */
|
||||||
|
/* This option switches support of multi-partition on a physical drive.
|
||||||
|
/ By default (0), each logical drive number is bound to the same physical drive
|
||||||
|
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||||
|
/ When multi-partition is enabled (1), each logical drive number can be bound to
|
||||||
|
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||||
|
/ funciton will be available. */
|
||||||
|
#define _MIN_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||||
|
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||||
|
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||||
|
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||||
|
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||||
|
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||||
|
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
#define _USE_TRIM 0
|
||||||
|
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
||||||
|
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
#define _FS_NOFSINFO 0 /* 0,1,2 or 3 */
|
||||||
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
|
/ option, and f_getfree() function at first time after volume mount will force
|
||||||
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
|
/
|
||||||
|
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||||
|
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||||
|
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||||
|
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ System Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||||
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
|
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
|
||||||
|
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||||
|
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||||
|
|
||||||
|
#define _FS_EXFAT 1
|
||||||
|
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
||||||
|
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
||||||
|
/ Note that enabling exFAT discards C89 compatibility. */
|
||||||
|
|
||||||
|
#define _FS_NORTC 0
|
||||||
|
#define _NORTC_MON 6
|
||||||
|
#define _NORTC_MDAY 4
|
||||||
|
#define _NORTC_YEAR 2015
|
||||||
|
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||||
|
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||||
|
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||||
|
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||||
|
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||||
|
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||||
|
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||||
|
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||||
|
|
||||||
|
#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */
|
||||||
|
/* The option _FS_LOCK switches file lock function to control duplicated file open
|
||||||
|
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||||
|
/ is 1.
|
||||||
|
/
|
||||||
|
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||||
|
/ should avoid illegal open, remove and rename to the open objects.
|
||||||
|
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||||
|
/ can be opened simultaneously under file lock control. Note that the file
|
||||||
|
/ lock control is independent of re-entrancy. */
|
||||||
|
|
||||||
|
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */
|
||||||
|
|
||||||
|
#define _USE_MUTEX 1 /* 0:Disable or 1:Enable */
|
||||||
|
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||||
|
#define _SYNC_t osMutexId_t
|
||||||
|
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||||
|
/ module itself. Note that regardless of this option, file access to different
|
||||||
|
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||||
|
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||||
|
/ to the same volume is under control of this function.
|
||||||
|
/
|
||||||
|
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||||
|
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||||
|
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||||
|
/ function, must be added to the project. Samples are available in
|
||||||
|
/ option/syscall.c.
|
||||||
|
/
|
||||||
|
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||||
|
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||||
|
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||||
|
/ included somewhere in the scope of ff.h. */
|
||||||
|
|
||||||
|
/* define the ff_malloc ff_free macros as FreeRTOS pvPortMalloc and vPortFree macros */
|
||||||
|
#if !defined(ff_malloc) && !defined(ff_free)
|
||||||
|
#define ff_malloc pvPortMalloc
|
||||||
|
#define ff_free vPortFree
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FFCONF */
|
686
FATFS/Target/sd_diskio.c
Normal file
686
FATFS/Target/sd_diskio.c
Normal file
|
@ -0,0 +1,686 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file sd_diskio.c
|
||||||
|
* @brief SD Disk I/O driver
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Note: code generation based on sd_diskio_dma_rtos_template_bspv1.c v2.1.4
|
||||||
|
as FreeRTOS is enabled. */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN firstSection */
|
||||||
|
/* can be used to modify / undefine following code or add new definitions */
|
||||||
|
/* USER CODE END firstSection*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "ff_gen_drv.h"
|
||||||
|
#include "sd_diskio.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define QUEUE_SIZE (uint32_t) 10
|
||||||
|
#define READ_CPLT_MSG (uint32_t) 1
|
||||||
|
#define WRITE_CPLT_MSG (uint32_t) 2
|
||||||
|
/*
|
||||||
|
==================================================================
|
||||||
|
enable the defines below to send custom rtos messages
|
||||||
|
when an error or an abort occurs.
|
||||||
|
Notice: depending on the HAL/SD driver the HAL_SD_ErrorCallback()
|
||||||
|
may not be available.
|
||||||
|
See BSP_SD_ErrorCallback() and BSP_SD_AbortCallback() below
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
#define RW_ERROR_MSG (uint32_t) 3
|
||||||
|
#define RW_ABORT_MSG (uint32_t) 4
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* the following Timeout is useful to give the control back to the applications
|
||||||
|
* in case of errors in either BSP_SD_ReadCpltCallback() or BSP_SD_WriteCpltCallback()
|
||||||
|
* the value by default is as defined in the BSP platform driver otherwise 30 secs
|
||||||
|
*/
|
||||||
|
#define SD_TIMEOUT 30 * 1000
|
||||||
|
|
||||||
|
#define SD_DEFAULT_BLOCK_SIZE 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depending on the use case, the SD card initialization could be done at the
|
||||||
|
* application level: if it is the case define the flag below to disable
|
||||||
|
* the BSP_SD_Init() call in the SD_Initialize() and add a call to
|
||||||
|
* BSP_SD_Init() elsewhere in the application.
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN disableSDInit */
|
||||||
|
/* #define DISABLE_SD_INIT */
|
||||||
|
/* USER CODE END disableSDInit */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* when using cachable memory region, it may be needed to maintain the cache
|
||||||
|
* validity. Enable the define below to activate a cache maintenance at each
|
||||||
|
* read and write operation.
|
||||||
|
* Notice: This is applicable only for cortex M7 based platform.
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN enableSDDmaCacheMaintenance */
|
||||||
|
/* #define ENABLE_SD_DMA_CACHE_MAINTENANCE 1 */
|
||||||
|
/* USER CODE END enableSDDmaCacheMaintenance */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some DMA requires 4-Byte aligned address buffer to correctly read/wite data,
|
||||||
|
* in FatFs some accesses aren't thus we need a 4-byte aligned scratch buffer to correctly
|
||||||
|
* transfer data
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN enableScratchBuffer */
|
||||||
|
/* #define ENABLE_SCRATCH_BUFFER */
|
||||||
|
/* USER CODE END enableScratchBuffer */
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
#if defined (ENABLE_SD_DMA_CACHE_MAINTENANCE)
|
||||||
|
ALIGN_32BYTES(static uint8_t scratch[BLOCKSIZE]); // 32-Byte aligned for cache maintenance
|
||||||
|
#else
|
||||||
|
__ALIGN_BEGIN static uint8_t scratch[BLOCKSIZE] __ALIGN_END;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/* Disk status */
|
||||||
|
static volatile DSTATUS Stat = STA_NOINIT;
|
||||||
|
|
||||||
|
#if (osCMSIS <= 0x20000U)
|
||||||
|
static osMessageQId SDQueueID = NULL;
|
||||||
|
#else
|
||||||
|
static osMessageQueueId_t SDQueueID = NULL;
|
||||||
|
#endif
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
static DSTATUS SD_CheckStatus(BYTE lun);
|
||||||
|
DSTATUS SD_initialize (BYTE);
|
||||||
|
DSTATUS SD_status (BYTE);
|
||||||
|
DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
|
||||||
|
#if _USE_WRITE == 1
|
||||||
|
DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
|
||||||
|
#endif /* _USE_WRITE == 1 */
|
||||||
|
#if _USE_IOCTL == 1
|
||||||
|
DRESULT SD_ioctl (BYTE, BYTE, void*);
|
||||||
|
#endif /* _USE_IOCTL == 1 */
|
||||||
|
|
||||||
|
const Diskio_drvTypeDef SD_Driver =
|
||||||
|
{
|
||||||
|
SD_initialize,
|
||||||
|
SD_status,
|
||||||
|
SD_read,
|
||||||
|
#if _USE_WRITE == 1
|
||||||
|
SD_write,
|
||||||
|
#endif /* _USE_WRITE == 1 */
|
||||||
|
|
||||||
|
#if _USE_IOCTL == 1
|
||||||
|
SD_ioctl,
|
||||||
|
#endif /* _USE_IOCTL == 1 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* USER CODE BEGIN beforeFunctionSection */
|
||||||
|
/* can be used to modify / undefine following code or add new code */
|
||||||
|
/* USER CODE END beforeFunctionSection */
|
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int SD_CheckStatusWithTimeout(uint32_t timeout)
|
||||||
|
{
|
||||||
|
uint32_t timer;
|
||||||
|
/* block until SDIO peripherial is ready again or a timeout occur */
|
||||||
|
#if (osCMSIS <= 0x20000U)
|
||||||
|
timer = osKernelSysTick();
|
||||||
|
while( osKernelSysTick() - timer < timeout)
|
||||||
|
#else
|
||||||
|
timer = osKernelGetTickCount();
|
||||||
|
while( osKernelGetTickCount() - timer < timeout)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DSTATUS SD_CheckStatus(BYTE lun)
|
||||||
|
{
|
||||||
|
Stat = STA_NOINIT;
|
||||||
|
|
||||||
|
if(BSP_SD_GetCardState() == SD_TRANSFER_OK)
|
||||||
|
{
|
||||||
|
Stat &= ~STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes a Drive
|
||||||
|
* @param lun : not used
|
||||||
|
* @retval DSTATUS: Operation status
|
||||||
|
*/
|
||||||
|
DSTATUS SD_initialize(BYTE lun)
|
||||||
|
{
|
||||||
|
Stat = STA_NOINIT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check that the kernel has been started before continuing
|
||||||
|
* as the osMessage API will fail otherwise
|
||||||
|
*/
|
||||||
|
#if (osCMSIS <= 0x20000U)
|
||||||
|
if(osKernelRunning())
|
||||||
|
#else
|
||||||
|
if(osKernelGetState() == osKernelRunning)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if !defined(DISABLE_SD_INIT)
|
||||||
|
|
||||||
|
if(BSP_SD_Init() == MSD_OK)
|
||||||
|
{
|
||||||
|
Stat = SD_CheckStatus(lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
Stat = SD_CheckStatus(lun);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the SD is correctly initialized, create the operation queue
|
||||||
|
* if not already created
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Stat != STA_NOINIT)
|
||||||
|
{
|
||||||
|
if (SDQueueID == NULL)
|
||||||
|
{
|
||||||
|
#if (osCMSIS <= 0x20000U)
|
||||||
|
osMessageQDef(SD_Queue, QUEUE_SIZE, uint16_t);
|
||||||
|
SDQueueID = osMessageCreate (osMessageQ(SD_Queue), NULL);
|
||||||
|
#else
|
||||||
|
SDQueueID = osMessageQueueNew(QUEUE_SIZE, 2, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDQueueID == NULL)
|
||||||
|
{
|
||||||
|
Stat |= STA_NOINIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets Disk Status
|
||||||
|
* @param lun : not used
|
||||||
|
* @retval DSTATUS: Operation status
|
||||||
|
*/
|
||||||
|
DSTATUS SD_status(BYTE lun)
|
||||||
|
{
|
||||||
|
return SD_CheckStatus(lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN beforeReadSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add new code */
|
||||||
|
/* USER CODE END beforeReadSection */
|
||||||
|
/**
|
||||||
|
* @brief Reads Sector(s)
|
||||||
|
* @param lun : not used
|
||||||
|
* @param *buff: Data buffer to store read data
|
||||||
|
* @param sector: Sector address (LBA)
|
||||||
|
* @param count: Number of sectors to read (1..128)
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
|
||||||
|
DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
DRESULT res = RES_ERROR;
|
||||||
|
uint32_t timer;
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osEvent event;
|
||||||
|
#else
|
||||||
|
uint16_t event;
|
||||||
|
osStatus_t status;
|
||||||
|
#endif
|
||||||
|
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
|
||||||
|
uint32_t alignedAddr;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* ensure the SDCard is ready for a new operation
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
if (!((uint32_t)buff & 0x3))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
/* Fast path cause destination buffer is correctly aligned */
|
||||||
|
uint8_t ret = BSP_SD_ReadBlocks_DMA((uint32_t*)buff, (uint32_t)(sector), count);
|
||||||
|
|
||||||
|
if (ret == MSD_OK) {
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
/* wait for a message from the queue or a timeout */
|
||||||
|
event = osMessageGet(SDQueueID, SD_TIMEOUT);
|
||||||
|
|
||||||
|
if (event.status == osEventMessage)
|
||||||
|
{
|
||||||
|
if (event.value.v == READ_CPLT_MSG)
|
||||||
|
{
|
||||||
|
timer = osKernelSysTick();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelSysTick() - timer <SD_TIMEOUT)
|
||||||
|
#else
|
||||||
|
status = osMessageQueueGet(SDQueueID, (void *)&event, NULL, SD_TIMEOUT);
|
||||||
|
if ((status == osOK) && (event == READ_CPLT_MSG))
|
||||||
|
{
|
||||||
|
timer = osKernelGetTickCount();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelGetTickCount() - timer <SD_TIMEOUT)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
|
||||||
|
{
|
||||||
|
res = RES_OK;
|
||||||
|
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
|
||||||
|
/*
|
||||||
|
the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
|
||||||
|
adjust the address and the D-Cache size to invalidate accordingly.
|
||||||
|
*/
|
||||||
|
alignedAddr = (uint32_t)buff & ~0x1F;
|
||||||
|
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Slow path, fetch each sector a part and memcpy to destination buffer */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
ret = BSP_SD_ReadBlocks_DMA((uint32_t*)scratch, (uint32_t)sector++, 1);
|
||||||
|
if (ret == MSD_OK )
|
||||||
|
{
|
||||||
|
/* wait until the read is successful or a timeout occurs */
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
/* wait for a message from the queue or a timeout */
|
||||||
|
event = osMessageGet(SDQueueID, SD_TIMEOUT);
|
||||||
|
|
||||||
|
if (event.status == osEventMessage)
|
||||||
|
{
|
||||||
|
if (event.value.v == READ_CPLT_MSG)
|
||||||
|
{
|
||||||
|
timer = osKernelSysTick();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelSysTick() - timer <SD_TIMEOUT)
|
||||||
|
#else
|
||||||
|
status = osMessageQueueGet(SDQueueID, (void *)&event, NULL, SD_TIMEOUT);
|
||||||
|
if ((status == osOK) && (event == READ_CPLT_MSG))
|
||||||
|
{
|
||||||
|
timer = osKernelGetTickCount();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
ret = MSD_ERROR;
|
||||||
|
while(osKernelGetTickCount() - timer < SD_TIMEOUT)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ret = BSP_SD_GetCardState();
|
||||||
|
|
||||||
|
if (ret == MSD_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != MSD_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* invalidate the scratch buffer before the next read to get the actual data instead of the cached one
|
||||||
|
*/
|
||||||
|
SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, BLOCKSIZE);
|
||||||
|
#endif
|
||||||
|
memcpy(buff, scratch, BLOCKSIZE);
|
||||||
|
buff += BLOCKSIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i == count) && (ret == MSD_OK ))
|
||||||
|
res = RES_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN beforeWriteSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add new code */
|
||||||
|
/* USER CODE END beforeWriteSection */
|
||||||
|
/**
|
||||||
|
* @brief Writes Sector(s)
|
||||||
|
* @param lun : not used
|
||||||
|
* @param *buff: Data to be written
|
||||||
|
* @param sector: Sector address (LBA)
|
||||||
|
* @param count: Number of sectors to write (1..128)
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
#if _USE_WRITE == 1
|
||||||
|
|
||||||
|
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
DRESULT res = RES_ERROR;
|
||||||
|
uint32_t timer;
|
||||||
|
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osEvent event;
|
||||||
|
#else
|
||||||
|
uint16_t event;
|
||||||
|
osStatus_t status;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
int32_t ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ensure the SDCard is ready for a new operation
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
if (!((uint32_t)buff & 0x3))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
|
||||||
|
uint32_t alignedAddr;
|
||||||
|
/*
|
||||||
|
the SCB_CleanDCache_by_Addr() requires a 32-Byte aligned address
|
||||||
|
adjust the address and the D-Cache size to clean accordingly.
|
||||||
|
*/
|
||||||
|
alignedAddr = (uint32_t)buff & ~0x1F;
|
||||||
|
SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
|
||||||
|
(uint32_t) (sector),
|
||||||
|
count) == MSD_OK)
|
||||||
|
{
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
/* Get the message from the queue */
|
||||||
|
event = osMessageGet(SDQueueID, SD_TIMEOUT);
|
||||||
|
|
||||||
|
if (event.status == osEventMessage)
|
||||||
|
{
|
||||||
|
if (event.value.v == WRITE_CPLT_MSG)
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
status = osMessageQueueGet(SDQueueID, (void *)&event, NULL, SD_TIMEOUT);
|
||||||
|
if ((status == osOK) && (event == WRITE_CPLT_MSG))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
timer = osKernelSysTick();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelSysTick() - timer < SD_TIMEOUT)
|
||||||
|
#else
|
||||||
|
timer = osKernelGetTickCount();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelGetTickCount() - timer < SD_TIMEOUT)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
|
||||||
|
{
|
||||||
|
res = RES_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if defined(ENABLE_SCRATCH_BUFFER)
|
||||||
|
else {
|
||||||
|
/* Slow path, fetch each sector a part and memcpy to destination buffer */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
|
||||||
|
/*
|
||||||
|
* invalidate the scratch buffer before the next write to get the actual data instead of the cached one
|
||||||
|
*/
|
||||||
|
SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, BLOCKSIZE);
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
memcpy((void *)scratch, buff, BLOCKSIZE);
|
||||||
|
buff += BLOCKSIZE;
|
||||||
|
|
||||||
|
ret = BSP_SD_WriteBlocks_DMA((uint32_t*)scratch, (uint32_t)sector++, 1);
|
||||||
|
if (ret == MSD_OK )
|
||||||
|
{
|
||||||
|
/* wait until the read is successful or a timeout occurs */
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
/* wait for a message from the queue or a timeout */
|
||||||
|
event = osMessageGet(SDQueueID, SD_TIMEOUT);
|
||||||
|
|
||||||
|
if (event.status == osEventMessage)
|
||||||
|
{
|
||||||
|
if (event.value.v == READ_CPLT_MSG)
|
||||||
|
{
|
||||||
|
timer = osKernelSysTick();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
while(osKernelSysTick() - timer <SD_TIMEOUT)
|
||||||
|
#else
|
||||||
|
status = osMessageQueueGet(SDQueueID, (void *)&event, NULL, SD_TIMEOUT);
|
||||||
|
if ((status == osOK) && (event == READ_CPLT_MSG))
|
||||||
|
{
|
||||||
|
timer = osKernelGetTickCount();
|
||||||
|
/* block until SDIO IP is ready or a timeout occur */
|
||||||
|
ret = MSD_ERROR;
|
||||||
|
while(osKernelGetTickCount() - timer < SD_TIMEOUT)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ret = BSP_SD_GetCardState();
|
||||||
|
|
||||||
|
if (ret == MSD_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != MSD_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i == count) && (ret == MSD_OK ))
|
||||||
|
res = RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* _USE_WRITE == 1 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN beforeIoctlSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add new code */
|
||||||
|
/* USER CODE END beforeIoctlSection */
|
||||||
|
/**
|
||||||
|
* @brief I/O control operation
|
||||||
|
* @param lun : not used
|
||||||
|
* @param cmd: Control code
|
||||||
|
* @param *buff: Buffer to send/receive control data
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
#if _USE_IOCTL == 1
|
||||||
|
DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
|
||||||
|
{
|
||||||
|
DRESULT res = RES_ERROR;
|
||||||
|
BSP_SD_CardInfo CardInfo;
|
||||||
|
|
||||||
|
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
/* Make sure that no pending write process */
|
||||||
|
case CTRL_SYNC :
|
||||||
|
res = RES_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get number of sectors on the disk (DWORD) */
|
||||||
|
case GET_SECTOR_COUNT :
|
||||||
|
BSP_SD_GetCardInfo(&CardInfo);
|
||||||
|
*(DWORD*)buff = CardInfo.LogBlockNbr;
|
||||||
|
res = RES_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get R/W sector size (WORD) */
|
||||||
|
case GET_SECTOR_SIZE :
|
||||||
|
BSP_SD_GetCardInfo(&CardInfo);
|
||||||
|
*(WORD*)buff = CardInfo.LogBlockSize;
|
||||||
|
res = RES_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get erase block size in unit of sector (DWORD) */
|
||||||
|
case GET_BLOCK_SIZE :
|
||||||
|
BSP_SD_GetCardInfo(&CardInfo);
|
||||||
|
*(DWORD*)buff = CardInfo.LogBlockSize / SD_DEFAULT_BLOCK_SIZE;
|
||||||
|
res = RES_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
res = RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* _USE_IOCTL == 1 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN afterIoctlSection */
|
||||||
|
/* can be used to modify previous code / undefine following code / add new code */
|
||||||
|
/* USER CODE END afterIoctlSection */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN callbackSection */
|
||||||
|
/* can be used to modify / following code or add new code */
|
||||||
|
/* USER CODE END callbackSection */
|
||||||
|
/**
|
||||||
|
* @brief Tx Transfer completed callbacks
|
||||||
|
* @param hsd: SD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void BSP_SD_WriteCpltCallback(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to add an "osKernelRunning()" check here, as the SD_initialize()
|
||||||
|
* is always called before any SD_Read()/SD_Write() call
|
||||||
|
*/
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osMessagePut(SDQueueID, WRITE_CPLT_MSG, 0);
|
||||||
|
#else
|
||||||
|
const uint16_t msg = WRITE_CPLT_MSG;
|
||||||
|
osMessageQueuePut(SDQueueID, (const void *)&msg, NULL, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rx Transfer completed callbacks
|
||||||
|
* @param hsd: SD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void BSP_SD_ReadCpltCallback(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No need to add an "osKernelRunning()" check here, as the SD_initialize()
|
||||||
|
* is always called before any SD_Read()/SD_Write() call
|
||||||
|
*/
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osMessagePut(SDQueueID, READ_CPLT_MSG, 0);
|
||||||
|
#else
|
||||||
|
const uint16_t msg = READ_CPLT_MSG;
|
||||||
|
osMessageQueuePut(SDQueueID, (const void *)&msg, NULL, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN ErrorAbortCallbacks */
|
||||||
|
/*
|
||||||
|
void BSP_SD_AbortCallback(void)
|
||||||
|
{
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osMessagePut(SDQueueID, RW_ABORT_MSG, 0);
|
||||||
|
#else
|
||||||
|
const uint16_t msg = RW_ABORT_MSG;
|
||||||
|
osMessageQueuePut(SDQueueID, (const void *)&msg, NULL, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* USER CODE END ErrorAbortCallbacks */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN lastSection */
|
||||||
|
/* can be used to modify / undefine previous code or add new code */
|
||||||
|
/* USER CODE END lastSection */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
45
FATFS/Target/sd_diskio.h
Normal file
45
FATFS/Target/sd_diskio.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file sd_diskio.h
|
||||||
|
* @brief Header for sd_diskio.c module
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Ultimate Liberty license
|
||||||
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at:
|
||||||
|
* www.st.com/SLA0044
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Note: code generation based on sd_diskio_dma_rtos_template.h */
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __SD_DISKIO_H
|
||||||
|
#define __SD_DISKIO_H
|
||||||
|
|
||||||
|
/* USER CODE BEGIN firstSection */
|
||||||
|
/* can be used to modify / undefine following code or add new definitions */
|
||||||
|
/* USER CODE END firstSection */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "bsp_driver_sd.h"
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
extern const Diskio_drvTypeDef SD_Driver;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN lastSection */
|
||||||
|
/* can be used to modify / undefine previous code or add new definitions */
|
||||||
|
/* USER CODE END lastSection */
|
||||||
|
|
||||||
|
#endif /* __SD_DISKIO_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
157
Makefile
157
Makefile
|
@ -1,5 +1,5 @@
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
# File automatically-generated by tool: [projectgenerator] version: [3.11.2] date: [Thu Jan 28 22:34:22 CST 2021]
|
# File automatically-generated by tool: [projectgenerator] version: [3.11.2] date: [Sat Jan 30 23:19:48 CST 2021]
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
|
@ -41,6 +41,11 @@ Core/Src/stm32h7xx_it.c \
|
||||||
Core/Src/stm32h7xx_hal_msp.c \
|
Core/Src/stm32h7xx_hal_msp.c \
|
||||||
Core/Src/otm8009a_lcd.c \
|
Core/Src/otm8009a_lcd.c \
|
||||||
Core/Src/otm_lcd_impl.c \
|
Core/Src/otm_lcd_impl.c \
|
||||||
|
Core/Src/user_tasks.c \
|
||||||
|
Core/Src/user_task_lvgl.c \
|
||||||
|
Core/Src/user_task_hello.c \
|
||||||
|
Core/Src/otm_lcd_lvgl_impl.c \
|
||||||
|
Core/Src/kururin_pa.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c \
|
||||||
|
@ -64,7 +69,142 @@ Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c \
|
||||||
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c \
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c \
|
||||||
Core/Src/system_stm32h7xx.c
|
Core/Src/system_stm32h7xx.c \
|
||||||
|
Core/Src/freertos.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/croutine.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/list.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/queue.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/tasks.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/timers.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \
|
||||||
|
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \
|
||||||
|
Core/Src/stm32h7xx_hal_timebase_tim.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_14.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_12_subpx.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_dejavu_16_persian_hebrew.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_42.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_simsun_16_cjk.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_16.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_fmt_txt.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_28_compressed.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_20.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_28.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_48.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_18.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_loader.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_44.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_46.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_38.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_34.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_26.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_36.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_unscii_8.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_40.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_12.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_10.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_8.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_30.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_32.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_unscii_16.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_24.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_font/lv_font_montserrat_22.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_img_decoder.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_img.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_img_cache.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_mask.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_blend.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_label.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_arc.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_rect.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_line.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_img_buf.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_draw/lv_draw_triangle.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_hal/lv_hal_indev.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_hal/lv_hal_disp.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_hal/lv_hal_tick.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_gpu/lv_gpu_nxp_pxp_osa.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_gpu/lv_gpu_nxp_vglite.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_gpu/lv_gpu_nxp_pxp.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_gpu/lv_gpu_stm32_dma2d.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_debug.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_mem.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_log.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_async.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_math.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_gc.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_printf.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_color.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_txt_ap.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_task.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_anim.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_ll.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_bidi.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_area.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_fs.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_utils.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_txt.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_misc/lv_templ.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_style.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_refr.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_obj.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_disp.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_indev.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_core/lv_group.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_themes/lv_theme_empty.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_themes/lv_theme_material.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_themes/lv_theme_template.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_themes/lv_theme_mono.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_themes/lv_theme.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_dropdown.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_cpicker.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_objmask.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_label.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_gauge.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_bar.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_spinner.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_keyboard.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_msgbox.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_win.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_arc.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_led.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_switch.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_btn.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_textarea.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_cont.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_objx_templ.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_table.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_checkbox.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_calendar.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_imgbtn.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_btnmatrix.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_tabview.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_spinbox.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_tileview.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_canvas.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_page.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_list.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_line.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_slider.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_roller.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_img.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_chart.c \
|
||||||
|
Middlewares/Third_Party/LittleVGL/src/lv_widgets/lv_linemeter.c \
|
||||||
|
FATFS/App/fatfs.c \
|
||||||
|
FATFS/Target/bsp_driver_sd.c \
|
||||||
|
FATFS/Target/sd_diskio.c \
|
||||||
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_sdmmc.c \
|
||||||
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_delayblock.c \
|
||||||
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sd.c \
|
||||||
|
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sd_ex.c \
|
||||||
|
Middlewares/Third_Party/FatFs/src/diskio.c \
|
||||||
|
Middlewares/Third_Party/FatFs/src/ff.c \
|
||||||
|
Middlewares/Third_Party/FatFs/src/ff_gen_drv.c \
|
||||||
|
Middlewares/Third_Party/FatFs/src/option/syscall.c \
|
||||||
|
Middlewares/Third_Party/FatFs/src/option/cc932.c
|
||||||
|
|
||||||
# ASM sources
|
# ASM sources
|
||||||
ASM_SOURCES = \
|
ASM_SOURCES = \
|
||||||
|
@ -113,7 +253,9 @@ AS_DEFS =
|
||||||
# C defines
|
# C defines
|
||||||
C_DEFS = \
|
C_DEFS = \
|
||||||
-DUSE_HAL_DRIVER \
|
-DUSE_HAL_DRIVER \
|
||||||
-DSTM32H750xx
|
-DSTM32H750xx \
|
||||||
|
-DLV_CONF_INCLUDE_SIMPLE \
|
||||||
|
-DLV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
|
||||||
|
|
||||||
# AS includes
|
# AS includes
|
||||||
|
@ -125,7 +267,14 @@ C_INCLUDES = \
|
||||||
-IDrivers/STM32H7xx_HAL_Driver/Inc \
|
-IDrivers/STM32H7xx_HAL_Driver/Inc \
|
||||||
-IDrivers/STM32H7xx_HAL_Driver/Inc/Legacy \
|
-IDrivers/STM32H7xx_HAL_Driver/Inc/Legacy \
|
||||||
-IDrivers/CMSIS/Device/ST/STM32H7xx/Include \
|
-IDrivers/CMSIS/Device/ST/STM32H7xx/Include \
|
||||||
-IDrivers/CMSIS/Include
|
-IDrivers/CMSIS/Include \
|
||||||
|
-IMiddlewares/Third_Party/FreeRTOS/Source/include \
|
||||||
|
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
|
||||||
|
-IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \
|
||||||
|
-IMiddlewares/Third_Party/LittleVGL \
|
||||||
|
-IFATFS/Target \
|
||||||
|
-IFATFS/App \
|
||||||
|
-IMiddlewares/Third_Party/FatFs/src
|
||||||
|
|
||||||
|
|
||||||
# compile gcc flags
|
# compile gcc flags
|
||||||
|
|
288
Middlewares/Third_Party/FatFs/src/00history.txt
vendored
Normal file
288
Middlewares/Third_Party/FatFs/src/00history.txt
vendored
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
Revision history of FatFs module
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
R0.00 (February 26, 2006)
|
||||||
|
|
||||||
|
Prototype.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.01 (April 29, 2006)
|
||||||
|
|
||||||
|
The first release.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02 (June 01, 2006)
|
||||||
|
|
||||||
|
Added FAT12 support.
|
||||||
|
Removed unbuffered mode.
|
||||||
|
Fixed a problem on small (<32M) partition.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02a (June 10, 2006)
|
||||||
|
|
||||||
|
Added a configuration option (_FS_MINIMUM).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03 (September 22, 2006)
|
||||||
|
|
||||||
|
Added f_rename().
|
||||||
|
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03a (December 11, 2006)
|
||||||
|
|
||||||
|
Improved cluster scan algorithm to write files fast.
|
||||||
|
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04 (February 04, 2007)
|
||||||
|
|
||||||
|
Added f_mkfs().
|
||||||
|
Supported multiple drive system.
|
||||||
|
Changed some interfaces for multiple drive system.
|
||||||
|
Changed f_mountdrv() to f_mount().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04a (April 01, 2007)
|
||||||
|
|
||||||
|
Supported multiple partitions on a physical drive.
|
||||||
|
Added a capability of extending file size to f_lseek().
|
||||||
|
Added minimization level 3.
|
||||||
|
Fixed an endian sensitive code in f_mkfs().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04b (May 05, 2007)
|
||||||
|
|
||||||
|
Added a configuration option _USE_NTFLAG.
|
||||||
|
Added FSINFO support.
|
||||||
|
Fixed DBCS name can result FR_INVALID_NAME.
|
||||||
|
Fixed short seek (<= csize) collapses the file object.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05 (August 25, 2007)
|
||||||
|
|
||||||
|
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||||
|
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||||
|
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05a (February 03, 2008)
|
||||||
|
|
||||||
|
Added f_truncate() and f_utime().
|
||||||
|
Fixed off by one error at FAT sub-type determination.
|
||||||
|
Fixed btr in f_read() can be mistruncated.
|
||||||
|
Fixed cached sector is not flushed when create and close without write.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.06 (April 01, 2008)
|
||||||
|
|
||||||
|
Added fputc(), fputs(), fprintf() and fgets().
|
||||||
|
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07 (April 01, 2009)
|
||||||
|
|
||||||
|
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||||
|
Added long file name feature. (_USE_LFN)
|
||||||
|
Added multiple code page feature. (_CODE_PAGE)
|
||||||
|
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||||
|
Added auto cluster size selection to f_mkfs().
|
||||||
|
Added rewind option to f_readdir().
|
||||||
|
Changed result code of critical errors.
|
||||||
|
Renamed string functions to avoid name collision.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07a (April 14, 2009)
|
||||||
|
|
||||||
|
Septemberarated out OS dependent code on reentrant cfg.
|
||||||
|
Added multiple sector size feature.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07c (June 21, 2009)
|
||||||
|
|
||||||
|
Fixed f_unlink() can return FR_OK on error.
|
||||||
|
Fixed wrong cache control in f_lseek().
|
||||||
|
Added relative path feature.
|
||||||
|
Added f_chdir() and f_chdrive().
|
||||||
|
Added proper case conversion to extended character.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07e (November 03, 2009)
|
||||||
|
|
||||||
|
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||||
|
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||||
|
Fixed name matching error on the 13 character boundary.
|
||||||
|
Added a configuration option, _LFN_UNICODE.
|
||||||
|
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08 (May 15, 2010)
|
||||||
|
|
||||||
|
Added a memory configuration option. (_USE_LFN = 3)
|
||||||
|
Added file lock feature. (_FS_SHARE)
|
||||||
|
Added fast seek feature. (_USE_FASTSEEK)
|
||||||
|
Changed some types on the API, XCHAR->TCHAR.
|
||||||
|
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||||
|
String functions support UTF-8 encoding files on Unicode cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08a (August 16, 2010)
|
||||||
|
|
||||||
|
Added f_getcwd(). (_FS_RPATH = 2)
|
||||||
|
Added sector erase feature. (_USE_ERASE)
|
||||||
|
Moved file lock semaphore table from fs object to the bss.
|
||||||
|
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08b (January 15, 2011)
|
||||||
|
|
||||||
|
Fast seek feature is also applied to f_read() and f_write().
|
||||||
|
f_lseek() reports required table size on creating CLMP.
|
||||||
|
Extended format syntax of f_printf().
|
||||||
|
Ignores duplicated directory separators in given path name.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09 (September 06, 2011)
|
||||||
|
|
||||||
|
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||||
|
Added f_fdisk().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09a (August 27, 2012)
|
||||||
|
|
||||||
|
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||||
|
Changed option name _FS_SHARE to _FS_LOCK.
|
||||||
|
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09b (January 24, 2013)
|
||||||
|
|
||||||
|
Added f_setlabel() and f_getlabel().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10 (October 02, 2013)
|
||||||
|
|
||||||
|
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||||
|
Added f_closedir().
|
||||||
|
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||||
|
Added forced mount feature with changes of f_mount().
|
||||||
|
Improved behavior of volume auto detection.
|
||||||
|
Improved write throughput of f_puts() and f_printf().
|
||||||
|
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||||
|
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||||
|
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10a (January 15, 2014)
|
||||||
|
|
||||||
|
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||||
|
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||||
|
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||||
|
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||||
|
Fixed f_close() invalidates the file object without volume lock.
|
||||||
|
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||||
|
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10b (May 19, 2014)
|
||||||
|
|
||||||
|
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||||
|
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10c (November 09, 2014)
|
||||||
|
|
||||||
|
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||||
|
Changed option name _USE_ERASE to _USE_TRIM.
|
||||||
|
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||||
|
Fixed a potential problem of FAT access that can appear on disk error.
|
||||||
|
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11 (February 09, 2015)
|
||||||
|
|
||||||
|
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||||
|
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||||
|
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11a (September 05, 2015)
|
||||||
|
|
||||||
|
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||||
|
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||||
|
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||||
|
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||||
|
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12 (April 12, 2016)
|
||||||
|
|
||||||
|
Added support for exFAT file system. (_FS_EXFAT)
|
||||||
|
Added f_expand(). (_USE_EXPAND)
|
||||||
|
Changed some members in FINFO structure and behavior of f_readdir().
|
||||||
|
Added an option _USE_CHMOD.
|
||||||
|
Removed an option _WORD_ACCESS.
|
||||||
|
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12a (July 10, 2016)
|
||||||
|
|
||||||
|
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||||
|
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||||
|
f_forward() is available regardless of _FS_TINY.
|
||||||
|
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||||
|
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||||
|
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12b (September 04, 2016)
|
||||||
|
|
||||||
|
Made f_rename() be able to rename objects with the same name but case.
|
||||||
|
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||||
|
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||||
|
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||||
|
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||||
|
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||||
|
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12c (March 04, 2017)
|
||||||
|
|
||||||
|
Improved write throughput at the fragmented file on the exFAT volume.
|
||||||
|
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||||
|
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||||
|
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||||
|
|
21
Middlewares/Third_Party/FatFs/src/00readme.txt
vendored
Normal file
21
Middlewares/Third_Party/FatFs/src/00readme.txt
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FatFs Module Source Files R0.12c
|
||||||
|
|
||||||
|
|
||||||
|
FILES
|
||||||
|
|
||||||
|
00readme.txt This file.
|
||||||
|
00history.txt Revision history.
|
||||||
|
ff.c FatFs module.
|
||||||
|
ffconf.h Configuration file of FatFs module.
|
||||||
|
ff.h Common include file for FatFs and application module.
|
||||||
|
diskio.h Common include file for FatFs and disk I/O module.
|
||||||
|
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||||
|
integer.h Integer type definitions for FatFs.
|
||||||
|
option Optional external modules.
|
||||||
|
|
||||||
|
|
||||||
|
Low level disk I/O module is not included in this archive because the FatFs
|
||||||
|
module is only a generic file system layer and it does not depend on any specific
|
||||||
|
storage device. You have to provide a low level disk I/O module written to
|
||||||
|
control the storage device that attached to the target system.
|
||||||
|
|
141
Middlewares/Third_Party/FatFs/src/diskio.c
vendored
Normal file
141
Middlewares/Third_Party/FatFs/src/diskio.c
vendored
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2017 */
|
||||||
|
/* */
|
||||||
|
/* Portions COPYRIGHT 2017 STMicroelectronics */
|
||||||
|
/* Portions Copyright (C) 2017, ChaN, all right reserved */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* If a working storage control module is available, it should be */
|
||||||
|
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||||
|
/* This is an example of glue functions to attach various existing */
|
||||||
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "diskio.h"
|
||||||
|
#include "ff_gen_drv.h"
|
||||||
|
|
||||||
|
#if defined ( __GNUC__ )
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
extern Disk_drvTypeDef disk;
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets Disk Status
|
||||||
|
* @param pdrv: Physical drive number (0..)
|
||||||
|
* @retval DSTATUS: Operation status
|
||||||
|
*/
|
||||||
|
DSTATUS disk_status (
|
||||||
|
BYTE pdrv /* Physical drive number to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DSTATUS stat;
|
||||||
|
|
||||||
|
stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes a Drive
|
||||||
|
* @param pdrv: Physical drive number (0..)
|
||||||
|
* @retval DSTATUS: Operation status
|
||||||
|
*/
|
||||||
|
DSTATUS disk_initialize (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DSTATUS stat = RES_OK;
|
||||||
|
|
||||||
|
if(disk.is_initialized[pdrv] == 0)
|
||||||
|
{
|
||||||
|
disk.is_initialized[pdrv] = 1;
|
||||||
|
stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads Sector(s)
|
||||||
|
* @param pdrv: Physical drive number (0..)
|
||||||
|
* @param *buff: Data buffer to store read data
|
||||||
|
* @param sector: Sector address (LBA)
|
||||||
|
* @param count: Number of sectors to read (1..128)
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
DRESULT disk_read (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
BYTE *buff, /* Data buffer to store read data */
|
||||||
|
DWORD sector, /* Sector address in LBA */
|
||||||
|
UINT count /* Number of sectors to read */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
|
||||||
|
res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes Sector(s)
|
||||||
|
* @param pdrv: Physical drive number (0..)
|
||||||
|
* @param *buff: Data to be written
|
||||||
|
* @param sector: Sector address (LBA)
|
||||||
|
* @param count: Number of sectors to write (1..128)
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
#if _USE_WRITE == 1
|
||||||
|
DRESULT disk_write (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
const BYTE *buff, /* Data to be written */
|
||||||
|
DWORD sector, /* Sector address in LBA */
|
||||||
|
UINT count /* Number of sectors to write */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
|
||||||
|
res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* _USE_WRITE == 1 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I/O control operation
|
||||||
|
* @param pdrv: Physical drive number (0..)
|
||||||
|
* @param cmd: Control code
|
||||||
|
* @param *buff: Buffer to send/receive control data
|
||||||
|
* @retval DRESULT: Operation result
|
||||||
|
*/
|
||||||
|
#if _USE_IOCTL == 1
|
||||||
|
DRESULT disk_ioctl (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||||
|
BYTE cmd, /* Control code */
|
||||||
|
void *buff /* Buffer to send/receive control data */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
|
||||||
|
res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* _USE_IOCTL == 1 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets Time from RTC
|
||||||
|
* @param None
|
||||||
|
* @retval Time in DWORD
|
||||||
|
*/
|
||||||
|
__weak DWORD get_fattime (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
80
Middlewares/Third_Party/FatFs/src/diskio.h
vendored
Normal file
80
Middlewares/Third_Party/FatFs/src/diskio.h
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*-----------------------------------------------------------------------/
|
||||||
|
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||||
|
/-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _DISKIO_DEFINED
|
||||||
|
#define _DISKIO_DEFINED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
||||||
|
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */
|
||||||
|
|
||||||
|
#include "integer.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Status of Disk Functions */
|
||||||
|
typedef BYTE DSTATUS;
|
||||||
|
|
||||||
|
/* Results of Disk Functions */
|
||||||
|
typedef enum {
|
||||||
|
RES_OK = 0, /* 0: Successful */
|
||||||
|
RES_ERROR, /* 1: R/W Error */
|
||||||
|
RES_WRPRT, /* 2: Write Protected */
|
||||||
|
RES_NOTRDY, /* 3: Not Ready */
|
||||||
|
RES_PARERR /* 4: Invalid Parameter */
|
||||||
|
} DRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
/* Prototypes for disk control functions */
|
||||||
|
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (BYTE pdrv);
|
||||||
|
DSTATUS disk_status (BYTE pdrv);
|
||||||
|
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||||
|
DWORD get_fattime (void);
|
||||||
|
|
||||||
|
/* Disk Status Bits (DSTATUS) */
|
||||||
|
|
||||||
|
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||||
|
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||||
|
#define STA_PROTECT 0x04 /* Write protected */
|
||||||
|
|
||||||
|
|
||||||
|
/* Command code for disk_ioctrl fucntion */
|
||||||
|
|
||||||
|
/* Generic command (Used by FatFs) */
|
||||||
|
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||||
|
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||||
|
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||||
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||||
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||||
|
|
||||||
|
/* Generic command (Not used by FatFs) */
|
||||||
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||||
|
#define CTRL_EJECT 7 /* Eject media */
|
||||||
|
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||||
|
|
||||||
|
/* MMC/SDC specific ioctl command */
|
||||||
|
#define MMC_GET_TYPE 10 /* Get card type */
|
||||||
|
#define MMC_GET_CSD 11 /* Get CSD */
|
||||||
|
#define MMC_GET_CID 12 /* Get CID */
|
||||||
|
#define MMC_GET_OCR 13 /* Get OCR */
|
||||||
|
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||||
|
|
||||||
|
/* ATA/CF specific ioctl command */
|
||||||
|
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||||
|
#define ATA_GET_MODEL 21 /* Get model name */
|
||||||
|
#define ATA_GET_SN 22 /* Get serial number */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
6140
Middlewares/Third_Party/FatFs/src/ff.c
vendored
Normal file
6140
Middlewares/Third_Party/FatFs/src/ff.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
361
Middlewares/Third_Party/FatFs/src/ff.h
vendored
Normal file
361
Middlewares/Third_Party/FatFs/src/ff.h
vendored
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
/*----------------------------------------------------------------------------/
|
||||||
|
/ FatFs - Generic FAT file system module R0.12c /
|
||||||
|
/-----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
/ that the following condition is met:
|
||||||
|
|
||||||
|
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
/ this condition and the following disclaimer.
|
||||||
|
/
|
||||||
|
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||||
|
/ and any warranties related to this software are DISCLAIMED.
|
||||||
|
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||||
|
/ by use of this software.
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _FATFS
|
||||||
|
#define _FATFS 68300 /* Revision ID */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "integer.h" /* Basic integer types */
|
||||||
|
#include "ffconf.h" /* FatFs configuration options */
|
||||||
|
|
||||||
|
#if _FATFS != _FFCONF
|
||||||
|
#error Wrong configuration file (ffconf.h).
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions of volume management */
|
||||||
|
|
||||||
|
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
typedef struct {
|
||||||
|
BYTE pd; /* Physical drive number */
|
||||||
|
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||||
|
} PARTITION;
|
||||||
|
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of path name strings on FatFs API */
|
||||||
|
|
||||||
|
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
||||||
|
#if _USE_LFN == 0
|
||||||
|
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||||
|
#endif
|
||||||
|
#ifndef _INC_TCHAR
|
||||||
|
typedef WCHAR TCHAR;
|
||||||
|
#define _T(x) L ## x
|
||||||
|
#define _TEXT(x) L ## x
|
||||||
|
#endif
|
||||||
|
#else /* ANSI/OEM string */
|
||||||
|
#ifndef _INC_TCHAR
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) x
|
||||||
|
#define _TEXT(x) x
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of file size variables */
|
||||||
|
|
||||||
|
#if _FS_EXFAT
|
||||||
|
#if _USE_LFN == 0
|
||||||
|
#error LFN must be enabled when enable exFAT
|
||||||
|
#endif
|
||||||
|
typedef QWORD FSIZE_t;
|
||||||
|
#else
|
||||||
|
typedef DWORD FSIZE_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File system object structure (FATFS) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE fs_type; /* File system type (0:N/A) */
|
||||||
|
BYTE drv; /* Physical drive number */
|
||||||
|
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||||
|
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||||
|
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||||
|
WORD id; /* File system mount ID */
|
||||||
|
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||||
|
WORD csize; /* Cluster size [sectors] */
|
||||||
|
#if _MAX_SS != _MIN_SS
|
||||||
|
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||||
|
#endif
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
WCHAR* lfnbuf; /* LFN working buffer */
|
||||||
|
#endif
|
||||||
|
#if _FS_EXFAT
|
||||||
|
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
||||||
|
#endif
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
_SYNC_t sobj; /* Identifier of sync object */
|
||||||
|
#endif
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD last_clst; /* Last allocated cluster */
|
||||||
|
DWORD free_clst; /* Number of free clusters */
|
||||||
|
#endif
|
||||||
|
#if _FS_RPATH != 0
|
||||||
|
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||||
|
#if _FS_EXFAT
|
||||||
|
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||||
|
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||||
|
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||||
|
DWORD fsize; /* Size of an FAT [sectors] */
|
||||||
|
DWORD volbase; /* Volume base sector */
|
||||||
|
DWORD fatbase; /* FAT base sector */
|
||||||
|
DWORD dirbase; /* Root directory base sector/cluster */
|
||||||
|
DWORD database; /* Data base sector */
|
||||||
|
DWORD winsect; /* Current sector appearing in the win[] */
|
||||||
|
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Object ID and allocation information (_FDID) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FATFS* fs; /* Pointer to the owner file system object */
|
||||||
|
WORD id; /* Owner file system mount ID */
|
||||||
|
BYTE attr; /* Object attribute */
|
||||||
|
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
|
||||||
|
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
||||||
|
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||||
|
#if _FS_EXFAT
|
||||||
|
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
|
||||||
|
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
|
||||||
|
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||||
|
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||||
|
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
|
||||||
|
#endif
|
||||||
|
#if _FS_LOCK != 0
|
||||||
|
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||||
|
#endif
|
||||||
|
} _FDID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File object structure (FIL) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||||
|
BYTE flag; /* File status flags */
|
||||||
|
BYTE err; /* Abort flag (error code) */
|
||||||
|
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||||
|
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||||
|
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||||
|
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||||
|
#endif
|
||||||
|
#if _USE_FASTSEEK
|
||||||
|
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||||
|
#endif
|
||||||
|
#if !_FS_TINY
|
||||||
|
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||||
|
#endif
|
||||||
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Directory object structure (DIR) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
_FDID obj; /* Object identifier */
|
||||||
|
DWORD dptr; /* Current read/write offset */
|
||||||
|
DWORD clust; /* Current cluster */
|
||||||
|
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||||
|
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||||
|
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||||
|
#endif
|
||||||
|
#if _USE_FIND
|
||||||
|
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||||
|
#endif
|
||||||
|
} DIR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File information structure (FILINFO) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FSIZE_t fsize; /* File size */
|
||||||
|
WORD fdate; /* Modified date */
|
||||||
|
WORD ftime; /* Modified time */
|
||||||
|
BYTE fattrib; /* File attribute */
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
TCHAR altname[13]; /* Alternative file name */
|
||||||
|
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
||||||
|
#else
|
||||||
|
TCHAR fname[13]; /* File name */
|
||||||
|
#endif
|
||||||
|
} FILINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File function return code (FRESULT) */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FR_OK = 0, /* (0) Succeeded */
|
||||||
|
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||||
|
FR_INT_ERR, /* (2) Assertion failed */
|
||||||
|
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||||
|
FR_NO_FILE, /* (4) Could not find the file */
|
||||||
|
FR_NO_PATH, /* (5) Could not find the path */
|
||||||
|
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||||
|
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||||
|
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||||
|
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||||
|
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||||
|
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||||
|
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||||
|
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||||
|
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||||
|
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||||
|
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||||
|
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||||
|
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
|
||||||
|
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||||
|
} FRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* FatFs module application interface */
|
||||||
|
|
||||||
|
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||||
|
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||||
|
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||||
|
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||||
|
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||||
|
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||||
|
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||||
|
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||||
|
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||||
|
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||||
|
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||||
|
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||||
|
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||||
|
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||||
|
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||||
|
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||||
|
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||||
|
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||||
|
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||||
|
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||||
|
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||||
|
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||||
|
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||||
|
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||||
|
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||||
|
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||||
|
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||||
|
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||||
|
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||||
|
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||||
|
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||||
|
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||||
|
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||||
|
|
||||||
|
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||||
|
#define f_error(fp) ((fp)->err)
|
||||||
|
#define f_tell(fp) ((fp)->fptr)
|
||||||
|
#define f_size(fp) ((fp)->obj.objsize)
|
||||||
|
#define f_rewind(fp) f_lseek((fp), 0)
|
||||||
|
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||||
|
#define f_rmdir(path) f_unlink(path)
|
||||||
|
|
||||||
|
#ifndef EOF
|
||||||
|
#define EOF (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Additional user defined functions */
|
||||||
|
|
||||||
|
/* RTC function */
|
||||||
|
#if !_FS_READONLY && !_FS_NORTC
|
||||||
|
DWORD get_fattime (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Unicode support functions */
|
||||||
|
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
|
||||||
|
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||||
|
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||||
|
#if _USE_LFN == 3 /* Memory functions */
|
||||||
|
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||||
|
void ff_memfree (void* mblock); /* Free memory block */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sync functions */
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
||||||
|
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||||
|
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||||
|
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Flags and offset address */
|
||||||
|
|
||||||
|
|
||||||
|
/* File access mode and open method flags (3rd argument of f_open) */
|
||||||
|
#define FA_READ 0x01
|
||||||
|
#define FA_WRITE 0x02
|
||||||
|
#define FA_OPEN_EXISTING 0x00
|
||||||
|
#define FA_CREATE_NEW 0x04
|
||||||
|
#define FA_CREATE_ALWAYS 0x08
|
||||||
|
#define FA_OPEN_ALWAYS 0x10
|
||||||
|
#define FA_OPEN_APPEND 0x30
|
||||||
|
|
||||||
|
/* Fast seek controls (2nd argument of f_lseek) */
|
||||||
|
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||||
|
|
||||||
|
/* Format options (2nd argument of f_mkfs) */
|
||||||
|
#define FM_FAT 0x01
|
||||||
|
#define FM_FAT32 0x02
|
||||||
|
#define FM_EXFAT 0x04
|
||||||
|
#define FM_ANY 0x07
|
||||||
|
#define FM_SFD 0x08
|
||||||
|
|
||||||
|
/* Filesystem type (FATFS.fs_type) */
|
||||||
|
#define FS_FAT12 1
|
||||||
|
#define FS_FAT16 2
|
||||||
|
#define FS_FAT32 3
|
||||||
|
#define FS_EXFAT 4
|
||||||
|
|
||||||
|
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||||
|
#define AM_RDO 0x01 /* Read only */
|
||||||
|
#define AM_HID 0x02 /* Hidden */
|
||||||
|
#define AM_SYS 0x04 /* System */
|
||||||
|
#define AM_DIR 0x10 /* Directory */
|
||||||
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FATFS */
|
122
Middlewares/Third_Party/FatFs/src/ff_gen_drv.c
vendored
Normal file
122
Middlewares/Third_Party/FatFs/src/ff_gen_drv.c
vendored
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file ff_gen_drv.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief FatFs generic low level driver.
|
||||||
|
*****************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
**/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "ff_gen_drv.h"
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
Disk_drvTypeDef disk = {{0},{0},{0},0};
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Links a compatible diskio driver/lun id and increments the number of active
|
||||||
|
* linked drivers.
|
||||||
|
* @note The number of linked drivers (volumes) is up to 10 due to FatFs limits.
|
||||||
|
* @param drv: pointer to the disk IO Driver structure
|
||||||
|
* @param path: pointer to the logical drive path
|
||||||
|
* @param lun : only used for USB Key Disk to add multi-lun management
|
||||||
|
else the parameter must be equal to 0
|
||||||
|
* @retval Returns 0 in case of success, otherwise 1.
|
||||||
|
*/
|
||||||
|
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, uint8_t lun)
|
||||||
|
{
|
||||||
|
uint8_t ret = 1;
|
||||||
|
uint8_t DiskNum = 0;
|
||||||
|
|
||||||
|
if(disk.nbr < _VOLUMES)
|
||||||
|
{
|
||||||
|
disk.is_initialized[disk.nbr] = 0;
|
||||||
|
disk.drv[disk.nbr] = drv;
|
||||||
|
disk.lun[disk.nbr] = lun;
|
||||||
|
DiskNum = disk.nbr++;
|
||||||
|
path[0] = DiskNum + '0';
|
||||||
|
path[1] = ':';
|
||||||
|
path[2] = '/';
|
||||||
|
path[3] = 0;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Links a compatible diskio driver and increments the number of active
|
||||||
|
* linked drivers.
|
||||||
|
* @note The number of linked drivers (volumes) is up to 10 due to FatFs limits
|
||||||
|
* @param drv: pointer to the disk IO Driver structure
|
||||||
|
* @param path: pointer to the logical drive path
|
||||||
|
* @retval Returns 0 in case of success, otherwise 1.
|
||||||
|
*/
|
||||||
|
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path)
|
||||||
|
{
|
||||||
|
return FATFS_LinkDriverEx(drv, path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unlinks a diskio driver and decrements the number of active linked
|
||||||
|
* drivers.
|
||||||
|
* @param path: pointer to the logical drive path
|
||||||
|
* @param lun : not used
|
||||||
|
* @retval Returns 0 in case of success, otherwise 1.
|
||||||
|
*/
|
||||||
|
uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun)
|
||||||
|
{
|
||||||
|
uint8_t DiskNum = 0;
|
||||||
|
uint8_t ret = 1;
|
||||||
|
|
||||||
|
if(disk.nbr >= 1)
|
||||||
|
{
|
||||||
|
DiskNum = path[0] - '0';
|
||||||
|
if(disk.drv[DiskNum] != 0)
|
||||||
|
{
|
||||||
|
disk.drv[DiskNum] = 0;
|
||||||
|
disk.lun[DiskNum] = 0;
|
||||||
|
disk.nbr--;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unlinks a diskio driver and decrements the number of active linked
|
||||||
|
* drivers.
|
||||||
|
* @param path: pointer to the logical drive path
|
||||||
|
* @retval Returns 0 in case of success, otherwise 1.
|
||||||
|
*/
|
||||||
|
uint8_t FATFS_UnLinkDriver(char *path)
|
||||||
|
{
|
||||||
|
return FATFS_UnLinkDriverEx(path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets number of linked drivers to the FatFs module.
|
||||||
|
* @param None
|
||||||
|
* @retval Number of attached drivers.
|
||||||
|
*/
|
||||||
|
uint8_t FATFS_GetAttachedDriversNbr(void)
|
||||||
|
{
|
||||||
|
return disk.nbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
80
Middlewares/Third_Party/FatFs/src/ff_gen_drv.h
vendored
Normal file
80
Middlewares/Third_Party/FatFs/src/ff_gen_drv.h
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file ff_gen_drv.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief Header for ff_gen_drv.c module.
|
||||||
|
*****************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __FF_GEN_DRV_H
|
||||||
|
#define __FF_GEN_DRV_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "diskio.h"
|
||||||
|
#include "ff.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disk IO Driver structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
|
||||||
|
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
|
||||||
|
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
|
||||||
|
#if _USE_WRITE == 1
|
||||||
|
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
|
||||||
|
#endif /* _USE_WRITE == 1 */
|
||||||
|
#if _USE_IOCTL == 1
|
||||||
|
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
|
||||||
|
#endif /* _USE_IOCTL == 1 */
|
||||||
|
|
||||||
|
}Diskio_drvTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Global Disk IO Drivers structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t is_initialized[_VOLUMES];
|
||||||
|
const Diskio_drvTypeDef *drv[_VOLUMES];
|
||||||
|
uint8_t lun[_VOLUMES];
|
||||||
|
volatile uint8_t nbr;
|
||||||
|
|
||||||
|
}Disk_drvTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path);
|
||||||
|
uint8_t FATFS_UnLinkDriver(char *path);
|
||||||
|
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun);
|
||||||
|
uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun);
|
||||||
|
uint8_t FATFS_GetAttachedDriversNbr(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __FF_GEN_DRV_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
341
Middlewares/Third_Party/FatFs/src/ffconf_template.h
vendored
Normal file
341
Middlewares/Third_Party/FatFs/src/ffconf_template.h
vendored
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
/*----------------------------------------------------------------------------/
|
||||||
|
/ FatFs - Generic FAT file system module R0.12c /
|
||||||
|
/-----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||||
|
/ Portions Copyright (C) STMicroelectronics, all right reserved.
|
||||||
|
/
|
||||||
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
/ that the following condition is met:
|
||||||
|
|
||||||
|
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
/ this condition and the following disclaimer.
|
||||||
|
/
|
||||||
|
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||||
|
/ and any warranties related to this software are DISCLAIMED.
|
||||||
|
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||||
|
/ by use of this software.
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ FatFs - FAT file system module configuration file
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FFCONF 68300 /* Revision ID */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Function Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FS_READONLY 0
|
||||||
|
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||||
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_MINIMIZE 0
|
||||||
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
|
/
|
||||||
|
/ 0: All basic functions are enabled.
|
||||||
|
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||||
|
/ 3: f_lseek() function is removed in addition to 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_STRFUNC 0
|
||||||
|
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||||
|
/ f_printf().
|
||||||
|
/
|
||||||
|
/ 0: Disable string functions.
|
||||||
|
/ 1: Enable without LF-CRLF conversion.
|
||||||
|
/ 2: Enable with LF-CRLF conversion. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_FIND 0
|
||||||
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_MKFS 1
|
||||||
|
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_FASTSEEK 1
|
||||||
|
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_EXPAND 0
|
||||||
|
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_CHMOD 0
|
||||||
|
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||||
|
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_LABEL 0
|
||||||
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_FORWARD 0
|
||||||
|
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _CODE_PAGE 850
|
||||||
|
/* This option specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect setting of the code page can cause a file open failure.
|
||||||
|
/
|
||||||
|
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||||
|
/ 437 - U.S.
|
||||||
|
/ 720 - Arabic
|
||||||
|
/ 737 - Greek
|
||||||
|
/ 771 - KBL
|
||||||
|
/ 775 - Baltic
|
||||||
|
/ 850 - Latin 1
|
||||||
|
/ 852 - Latin 2
|
||||||
|
/ 855 - Cyrillic
|
||||||
|
/ 857 - Turkish
|
||||||
|
/ 860 - Portuguese
|
||||||
|
/ 861 - Icelandic
|
||||||
|
/ 862 - Hebrew
|
||||||
|
/ 863 - Canadian French
|
||||||
|
/ 864 - Arabic
|
||||||
|
/ 865 - Nordic
|
||||||
|
/ 866 - Russian
|
||||||
|
/ 869 - Greek 2
|
||||||
|
/ 932 - Japanese (DBCS)
|
||||||
|
/ 936 - Simplified Chinese (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese (DBCS)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_LFN 3
|
||||||
|
#define _MAX_LFN 255
|
||||||
|
/* The _USE_LFN switches the support of long file name (LFN).
|
||||||
|
/
|
||||||
|
/ 0: Disable support of LFN. _MAX_LFN has no effect.
|
||||||
|
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||||
|
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||||
|
/
|
||||||
|
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||||
|
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
||||||
|
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
||||||
|
/ It should be set 255 to support full featured LFN operations.
|
||||||
|
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||||
|
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||||
|
/ ff_memfree(), must be added to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _LFN_UNICODE 0
|
||||||
|
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
|
||||||
|
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
||||||
|
/ This option also affects behavior of string I/O functions. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _STRF_ENCODE 3
|
||||||
|
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
|
||||||
|
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM
|
||||||
|
/ 1: UTF-16LE
|
||||||
|
/ 2: UTF-16BE
|
||||||
|
/ 3: UTF-8
|
||||||
|
/
|
||||||
|
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_RPATH 0
|
||||||
|
/* This option configures support of relative path.
|
||||||
|
/
|
||||||
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||||
|
/ 2: f_getcwd() function is available in addition to 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Drive/Volume Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _VOLUMES 2
|
||||||
|
/* Number of volumes (logical drives) to be used. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _STR_VOLUME_ID 0
|
||||||
|
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||||
|
/* _STR_VOLUME_ID switches string support of volume ID.
|
||||||
|
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||||
|
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||||
|
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||||
|
/ the drive ID strings are: A-Z and 0-9. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MULTI_PARTITION 0
|
||||||
|
/* This option switches support of multi-partition on a physical drive.
|
||||||
|
/ By default (0), each logical drive number is bound to the same physical drive
|
||||||
|
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||||
|
/ When multi-partition is enabled (1), each logical drive number can be bound to
|
||||||
|
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||||
|
/ funciton will be available. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MIN_SS 512
|
||||||
|
#define _MAX_SS 512
|
||||||
|
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||||
|
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||||
|
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||||
|
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||||
|
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_TRIM 0
|
||||||
|
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
||||||
|
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_NOFSINFO 0
|
||||||
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
|
/ option, and f_getfree() function at first time after volume mount will force
|
||||||
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
|
/
|
||||||
|
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||||
|
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||||
|
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||||
|
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ System Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FS_TINY 0
|
||||||
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
|
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
|
||||||
|
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||||
|
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_EXFAT 0
|
||||||
|
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
||||||
|
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
||||||
|
/ Note that enabling exFAT discards C89 compatibility. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_NORTC 0
|
||||||
|
#define _NORTC_MON 1
|
||||||
|
#define _NORTC_MDAY 1
|
||||||
|
#define _NORTC_YEAR 2016
|
||||||
|
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||||
|
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||||
|
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||||
|
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||||
|
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||||
|
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||||
|
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||||
|
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_LOCK 2
|
||||||
|
/* The option _FS_LOCK switches file lock function to control duplicated file open
|
||||||
|
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||||
|
/ is 1.
|
||||||
|
/
|
||||||
|
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||||
|
/ should avoid illegal open, remove and rename to the open objects.
|
||||||
|
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||||
|
/ can be opened simultaneously under file lock control. Note that the file
|
||||||
|
/ lock control is independent of re-entrancy. */
|
||||||
|
|
||||||
|
#define _FS_REENTRANT 0
|
||||||
|
#define _USE_MUTEX 0
|
||||||
|
/* Use CMSIS-OS mutexes as _SYNC_t object instead of Semaphores */
|
||||||
|
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#define _FS_TIMEOUT 1000
|
||||||
|
|
||||||
|
#if _USE_MUTEX
|
||||||
|
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
#define _SYNC_t osMutexId
|
||||||
|
#else
|
||||||
|
#define _SYNC_t osMutexId_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
#define _SYNC_t osSemaphoreId
|
||||||
|
#else
|
||||||
|
#define _SYNC_t osSemaphoreId_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif //_FS_REENTRANT
|
||||||
|
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||||
|
/ module itself. Note that regardless of this option, file access to different
|
||||||
|
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||||
|
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||||
|
/ to the same volume is under control of this function.
|
||||||
|
/
|
||||||
|
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||||
|
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||||
|
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||||
|
/ function, must be added to the project. Samples are available in
|
||||||
|
/ option/syscall.c.
|
||||||
|
/
|
||||||
|
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||||
|
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||||
|
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||||
|
/ included somewhere in the scope of ff.h. */
|
||||||
|
|
||||||
|
/* #include <windows.h> // O/S definitions */
|
||||||
|
|
||||||
|
#if _USE_LFN == 3
|
||||||
|
|
||||||
|
#if !defined(ff_malloc) || !defined(ff_free)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ff_malloc)
|
||||||
|
#define ff_malloc malloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ff_free)
|
||||||
|
#define ff_free free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* by default the system malloc/free are used, but when the FreeRTOS is enabled
|
||||||
|
/ the macros pvPortMalloc()/vportFree() to be used thus uncomment the code below
|
||||||
|
/
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#if !defined(ff_malloc) || !defined(ff_free)
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ff_malloc)
|
||||||
|
#define ff_malloc pvPortMalloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ff_free)
|
||||||
|
#define ff_free vPortFree
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
/*--- End of configuration options ---*/
|
38
Middlewares/Third_Party/FatFs/src/integer.h
vendored
Normal file
38
Middlewares/Third_Party/FatFs/src/integer.h
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*-------------------------------------------*/
|
||||||
|
/* Integer type definitions for FatFs module */
|
||||||
|
/*-------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _FF_INTEGER
|
||||||
|
#define _FF_INTEGER
|
||||||
|
|
||||||
|
#ifdef _WIN32 /* FatFs development platform */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
typedef unsigned __int64 QWORD;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* Embedded platform */
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit or 32-bit */
|
||||||
|
typedef int INT;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
|
||||||
|
/* This type MUST be 8-bit */
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit */
|
||||||
|
typedef short SHORT;
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned short WCHAR;
|
||||||
|
|
||||||
|
/* These types MUST be 32-bit */
|
||||||
|
typedef long LONG;
|
||||||
|
typedef unsigned long DWORD;
|
||||||
|
|
||||||
|
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||||
|
typedef unsigned long long QWORD;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
3870
Middlewares/Third_Party/FatFs/src/option/cc932.c
vendored
Normal file
3870
Middlewares/Third_Party/FatFs/src/option/cc932.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11045
Middlewares/Third_Party/FatFs/src/option/cc936.c
vendored
Normal file
11045
Middlewares/Third_Party/FatFs/src/option/cc936.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8674
Middlewares/Third_Party/FatFs/src/option/cc949.c
vendored
Normal file
8674
Middlewares/Third_Party/FatFs/src/option/cc949.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6900
Middlewares/Third_Party/FatFs/src/option/cc950.c
vendored
Normal file
6900
Middlewares/Third_Party/FatFs/src/option/cc950.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
388
Middlewares/Third_Party/FatFs/src/option/ccsbcs.c
vendored
Normal file
388
Middlewares/Third_Party/FatFs/src/option/ccsbcs.c
vendored
Normal file
|
@ -0,0 +1,388 @@
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
|
||||||
|
/* (SBCS code pages) */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* 437 U.S.
|
||||||
|
/ 720 Arabic
|
||||||
|
/ 737 Greek
|
||||||
|
/ 771 KBL
|
||||||
|
/ 775 Baltic
|
||||||
|
/ 850 Latin 1
|
||||||
|
/ 852 Latin 2
|
||||||
|
/ 855 Cyrillic
|
||||||
|
/ 857 Turkish
|
||||||
|
/ 860 Portuguese
|
||||||
|
/ 861 Icelandic
|
||||||
|
/ 862 Hebrew
|
||||||
|
/ 863 Canadian French
|
||||||
|
/ 864 Arabic
|
||||||
|
/ 865 Nordic
|
||||||
|
/ 866 Russian
|
||||||
|
/ 869 Greek 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if _CODE_PAGE == 437
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 720
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||||
|
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||||
|
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 737
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||||
|
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||||
|
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||||
|
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 771
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||||
|
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||||
|
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
|
||||||
|
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||||
|
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 775
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||||
|
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||||
|
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||||
|
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 850
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||||
|
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 852
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||||
|
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||||
|
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 855
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||||
|
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||||
|
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||||
|
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||||
|
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 857
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||||
|
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 860
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||||
|
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 861
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 862
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||||
|
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 863
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||||
|
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||||
|
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 864
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||||
|
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||||
|
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||||
|
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
|
||||||
|
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
|
||||||
|
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
|
||||||
|
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
||||||
|
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 865
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 866
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||||
|
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||||
|
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||||
|
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 869
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||||
|
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||||
|
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
|
||||||
|
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
|
||||||
|
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
||||||
|
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !_TBLDEF || !_USE_LFN
|
||||||
|
#error This file is not needed at current configuration. Remove from the project.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||||
|
WCHAR chr, /* Character code to be converted */
|
||||||
|
UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WCHAR c;
|
||||||
|
|
||||||
|
|
||||||
|
if (chr < 0x80) { /* ASCII */
|
||||||
|
c = chr;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (dir) { /* OEM code to Unicode */
|
||||||
|
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||||
|
|
||||||
|
} else { /* Unicode to OEM code */
|
||||||
|
for (c = 0; c < 0x80; c++) {
|
||||||
|
if (chr == Tbl[c]) break;
|
||||||
|
}
|
||||||
|
c = (c + 0x80) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WCHAR ff_wtoupper ( /* Returns upper converted character */
|
||||||
|
WCHAR chr /* Unicode character to be upper converted (BMP only) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Compressed upper conversion table */
|
||||||
|
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
||||||
|
/* Basic Latin */
|
||||||
|
0x0061,0x031A,
|
||||||
|
/* Latin-1 Supplement */
|
||||||
|
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||||
|
/* Latin Extended-A */
|
||||||
|
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||||
|
/* Latin Extended-B */
|
||||||
|
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||||
|
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
||||||
|
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
||||||
|
/* IPA Extensions */
|
||||||
|
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||||
|
/* Greek, Coptic */
|
||||||
|
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
||||||
|
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
||||||
|
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||||
|
/* Cyrillic */
|
||||||
|
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
||||||
|
/* Armenian */
|
||||||
|
0x0561,0x0426,
|
||||||
|
|
||||||
|
0x0000
|
||||||
|
};
|
||||||
|
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
||||||
|
/* Phonetic Extensions */
|
||||||
|
0x1D7D,0x0001,0x2C63,
|
||||||
|
/* Latin Extended Additional */
|
||||||
|
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||||
|
/* Greek Extended */
|
||||||
|
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
||||||
|
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
||||||
|
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||||
|
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||||
|
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
|
||||||
|
/* Letterlike Symbols */
|
||||||
|
0x214E,0x0001,0x2132,
|
||||||
|
/* Number forms */
|
||||||
|
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||||
|
/* Enclosed Alphanumerics */
|
||||||
|
0x24D0,0x051A, 0x2C30,0x042F,
|
||||||
|
/* Latin Extended-C */
|
||||||
|
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||||
|
/* Coptic */
|
||||||
|
0x2C80,0x0164,
|
||||||
|
/* Georgian Supplement */
|
||||||
|
0x2D00,0x0826,
|
||||||
|
/* Full-width */
|
||||||
|
0xFF41,0x031A,
|
||||||
|
|
||||||
|
0x0000
|
||||||
|
};
|
||||||
|
const WCHAR *p;
|
||||||
|
WCHAR bc, nc, cmd;
|
||||||
|
|
||||||
|
|
||||||
|
p = chr < 0x1000 ? cvt1 : cvt2;
|
||||||
|
for (;;) {
|
||||||
|
bc = *p++; /* Get block base */
|
||||||
|
if (!bc || chr < bc) break;
|
||||||
|
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||||
|
if (chr < bc + nc) { /* In the block? */
|
||||||
|
switch (cmd) {
|
||||||
|
case 0: chr = p[chr - bc]; break; /* Table conversion */
|
||||||
|
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
|
||||||
|
case 2: chr -= 16; break; /* Shift -16 */
|
||||||
|
case 3: chr -= 32; break; /* Shift -32 */
|
||||||
|
case 4: chr -= 48; break; /* Shift -48 */
|
||||||
|
case 5: chr -= 26; break; /* Shift -26 */
|
||||||
|
case 6: chr += 8; break; /* Shift +8 */
|
||||||
|
case 7: chr -= 80; break; /* Shift -80 */
|
||||||
|
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cmd) p += nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chr;
|
||||||
|
}
|
||||||
|
|
177
Middlewares/Third_Party/FatFs/src/option/syscall.c
vendored
Normal file
177
Middlewares/Third_Party/FatFs/src/option/syscall.c
vendored
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Sample code of OS dependent controls for FatFs */
|
||||||
|
/* (C)ChaN, 2014 */
|
||||||
|
/* Portions COPYRIGHT 2017 STMicroelectronics */
|
||||||
|
/* Portions Copyright (C) 2014, ChaN, all right reserved */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "../ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Create a Synchronization Object */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount() function to create a new
|
||||||
|
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||||
|
/ the f_mount() function fails with FR_INT_ERR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||||
|
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||||
|
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
#if _USE_MUTEX
|
||||||
|
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osMutexDef(MTX);
|
||||||
|
*sobj = osMutexCreate(osMutex(MTX));
|
||||||
|
#else
|
||||||
|
*sobj = osMutexNew(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
osSemaphoreDef(SEM);
|
||||||
|
*sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
|
||||||
|
#else
|
||||||
|
*sobj = osSemaphoreNew(1, 1, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
ret = (*sobj != NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Delete a Synchronization Object */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount() function to delete a synchronization
|
||||||
|
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
||||||
|
/ the f_mount() function fails with FR_INT_ERR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
|
||||||
|
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if _USE_MUTEX
|
||||||
|
osMutexDelete (sobj);
|
||||||
|
#else
|
||||||
|
osSemaphoreDelete (sobj);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Request Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on entering file functions to lock the volume.
|
||||||
|
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||||
|
_SYNC_t sobj /* Sync object to wait */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#if (osCMSIS < 0x20000U)
|
||||||
|
|
||||||
|
#if _USE_MUTEX
|
||||||
|
if(osMutexWait(sobj, _FS_TIMEOUT) == osOK)
|
||||||
|
#else
|
||||||
|
if(osSemaphoreWait(sobj, _FS_TIMEOUT) == osOK)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if _USE_MUTEX
|
||||||
|
if(osMutexAcquire(sobj, _FS_TIMEOUT) == osOK)
|
||||||
|
#else
|
||||||
|
if(osSemaphoreAcquire(sobj, _FS_TIMEOUT) == osOK)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Release Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on leaving file functions to unlock the volume.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ff_rel_grant (
|
||||||
|
_SYNC_t sobj /* Sync object to be signaled */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if _USE_MUTEX
|
||||||
|
osMutexRelease(sobj);
|
||||||
|
#else
|
||||||
|
osSemaphoreRelease(sobj);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Allocate a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||||
|
UINT msize /* Number of bytes to allocate */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ff_malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Free a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void ff_memfree (
|
||||||
|
void* mblock /* Pointer to the memory block to free */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ff_free(mblock); /* Discard the memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
17
Middlewares/Third_Party/FatFs/src/option/unicode.c
vendored
Normal file
17
Middlewares/Third_Party/FatFs/src/option/unicode.c
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "../ff.h"
|
||||||
|
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
|
||||||
|
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
|
||||||
|
#include "cc932.c"
|
||||||
|
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||||
|
#include "cc936.c"
|
||||||
|
#elif _CODE_PAGE == 949 /* Korean */
|
||||||
|
#include "cc949.c"
|
||||||
|
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||||
|
#include "cc950.c"
|
||||||
|
#else /* Single Byte Character-Set */
|
||||||
|
#include "ccsbcs.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
221
Middlewares/Third_Party/FatFs/src/st_readme.txt
vendored
Normal file
221
Middlewares/Third_Party/FatFs/src/st_readme.txt
vendored
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
@verbatim
|
||||||
|
******************************************************************************
|
||||||
|
* @file st_readme.txt
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief This file lists the main modification done by STMicroelectronics on
|
||||||
|
* FatFs for integration with STM32Cube solution.
|
||||||
|
* For more details on FatFs implementation on STM32Cube, please refer
|
||||||
|
* to UM1721 "Developing Applications on STM32Cube with FatFs"
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
### V2.1.4/18-10-2019 ###
|
||||||
|
============================
|
||||||
|
+ Fix wrong usage of the "memcpy" in the SD_Write() function
|
||||||
|
- drivers/sd_diskio_dma_template_bspv1.c
|
||||||
|
- drivers/sd_diskio_dma_template_bspv2.c
|
||||||
|
- drivers/sd_diskio_dma_rtos_template_bspv1.c
|
||||||
|
- drivers/sd_diskio_dma_rtos_template_bspv2.c
|
||||||
|
|
||||||
|
+ correct the usage of the "_USE_MUTEX" config flag
|
||||||
|
- syscall.c
|
||||||
|
|
||||||
|
### V2.1.3/26-07-2019 ###
|
||||||
|
============================
|
||||||
|
+ add new BSPv2 templates:
|
||||||
|
- drivers/sd_diskio_dma_rtos_template_bspv2.c
|
||||||
|
- drivers/sd_diskio_dma_template_bspv2.c
|
||||||
|
- drivers/sd_diskio_template_bspv2.c
|
||||||
|
- drivers/sdram_diskio_template_bspv2.c
|
||||||
|
|
||||||
|
+ rename old template to "xxxx_diskio_template_bspv1.c":
|
||||||
|
- drivers/sd_diskio_dma_rtos_template_bspv1.c
|
||||||
|
- drivers/sd_diskio_dma_template_bspv1.c
|
||||||
|
- drivers/sd_diskio_template_bspv1.c
|
||||||
|
- drivers/sdram_diskio_template_bspv1.c
|
||||||
|
|
||||||
|
+ Add CMSIS-OSv2 support in templates, syscall.c and ff_conf_template.h
|
||||||
|
- syscall.c
|
||||||
|
- ff_conf_template.h
|
||||||
|
- drivers/sd_diskio_dma_rtos_template_bspv2.c
|
||||||
|
|
||||||
|
+ support usage of "osMutex" alongside "osSemaphore" as _SYNC_t type in fatfs
|
||||||
|
- syscall.c
|
||||||
|
- ff_conf_template.h
|
||||||
|
|
||||||
|
|
||||||
|
### V2.1.2/29-03-2019 ###
|
||||||
|
============================
|
||||||
|
+ add st_license.txt in the root directory
|
||||||
|
+ src/drivers/xxx_diskio_template.[c/h], src/ff_gen_drv.[c/h], src/option/syscall.c: update the license terms to BSD-3-Clause
|
||||||
|
|
||||||
|
### V2.1.1/25-01-2019 ###
|
||||||
|
============================
|
||||||
|
+ sd_diskio_dma_rtos_template.c
|
||||||
|
- Fix memory leak in the SD_Initialize()
|
||||||
|
- Disable the ENABLE_SD_DMA_CACHE_MAINTENANCE flag by default to fix a build error for CM4
|
||||||
|
- include correct diskio header file
|
||||||
|
|
||||||
|
+ sd_diskio_dma_template.c
|
||||||
|
- Correct the SD_read() function when enabling the ENABLE_SCRATCH_BUFFER flag
|
||||||
|
|
||||||
|
+ sd_diskio_dma_rtos_template.c sd_diskio_dma_template.c
|
||||||
|
- fix potential overflow when using SysTick.
|
||||||
|
|
||||||
|
|
||||||
|
### V2.1.0/21-09-2018 ###
|
||||||
|
============================
|
||||||
|
+ ff.c
|
||||||
|
- back-port a fix from 0.13, to correct an issue when using multi-threading
|
||||||
|
access in the same device due to a missing semaphore lock when calling
|
||||||
|
disk_status() API.
|
||||||
|
|
||||||
|
+ sd_diskio_dma_rtos_template.c
|
||||||
|
- Add support to CMSIS-RTOS V2 API
|
||||||
|
|
||||||
|
+ sd_diskio_dma_rtos_template.c sd_diskio_dma_template.c
|
||||||
|
- Add a compile flag "ENABLE_SCRATCH_BUFFER" to avoid misaligned access
|
||||||
|
caused buffer alignment constraint in some DMA versions.
|
||||||
|
- Add BSP_SD_ErrorCallback() and BSP_SD_AbortCallback() template functions.
|
||||||
|
|
||||||
|
### V2.0.2/17-November-2017 ###
|
||||||
|
============================
|
||||||
|
+ sdram_diskio_template.c sram_diskio_template.c
|
||||||
|
Fix wrong buffer size in the (SRAM/SDRAM)DISK_read(), (SRAM/SDRAM)DISK_write()
|
||||||
|
|
||||||
|
+ sd_diskio_template.c
|
||||||
|
- define a generic 'SD_TIMEOUT' based on the BSP drivers defines. This fixes
|
||||||
|
a build issue when using this driver with the Adafruit shield.
|
||||||
|
|
||||||
|
+ sd_diskio_dma_rtos_template.c
|
||||||
|
- add a check via osKernelRunning(), to avoid runtime errors due to
|
||||||
|
osMessageXXX calls that needs the "osKernelStart()" call done first.
|
||||||
|
|
||||||
|
+ sd_diskio_dma_template.c, sd_diskio_dma_rtos_template.c
|
||||||
|
- fix wrong address alignment when calling SCB_InvalidateDCache_by_Addr() and
|
||||||
|
SCB_CleanDCache_by_Addr(), the address has to be 32-Byte and not
|
||||||
|
32-bit aligned.
|
||||||
|
|
||||||
|
- fix BSP_SD_ReadCpltCallback() and BSP_SD_WriteCpltCallback() prototypes by
|
||||||
|
adding 'void' as argument to avoid IAR compiler errors
|
||||||
|
|
||||||
|
|
||||||
|
+ sd_diskio_template.c sd_diskio_dma_template.c, sd_diskio_dma_rtos_template.c
|
||||||
|
- add the flag "DISABLE_SD_INIT" to give the user the choice to initialize the SD
|
||||||
|
either in the application or in the FatFs diskio driver.
|
||||||
|
|
||||||
|
+ all xxx_diskio_template.c
|
||||||
|
- fix GET_BLOCK_SIZE ioctl call; the return value is in unit of sectors.
|
||||||
|
|
||||||
|
|
||||||
|
### V2.0.1/10-July-2017 ###
|
||||||
|
============================
|
||||||
|
+ sd_diskio_dma_template.c, sd_diskio_dma_rtos_template.c
|
||||||
|
- add the flag "ENABLE_SD_DMA_CACHE_MAINTENANCE", to enable cache maintenance at each read write operation.
|
||||||
|
This is useful for STM32F7/STM32H7 based platforms when using a cachable memory region.
|
||||||
|
- add timeout checks in SD_Read() and SD_Write() to give the control back to the application to decide in case of errors.
|
||||||
|
|
||||||
|
+ ff_gen_drv.c: fix a wrong check that causes an out of bound array access.
|
||||||
|
|
||||||
|
|
||||||
|
### V2.0.0/07-March-2017 ###
|
||||||
|
============================
|
||||||
|
+ Upgrade to use FatFS R0.12c. The R0.12c breaks the API compatibility with R0.11b.
|
||||||
|
- f_mkfs() API has a new signature.
|
||||||
|
- The _CODE_PAGE got new values.
|
||||||
|
- For more details check the files (doc/updates.txt) and the following urls:
|
||||||
|
http://elm-chan.org/fsw/ff/en/mkfs.html
|
||||||
|
http://elm-chan.org/fsw/ff/en/config.html
|
||||||
|
|
||||||
|
+ Add USB, RAMDISK and uSD template drivers under src/drivers.
|
||||||
|
- The diskio drivers aren't part of fatfs anymore, they are just templates instead.
|
||||||
|
- User has to copy the suitable template .c/.h file under the project, rename them by
|
||||||
|
removing the "_template" suffix then link them into the final application.
|
||||||
|
- The diskio driver .c/.h files have to be edited according to the used platform.
|
||||||
|
|
||||||
|
+ Define the macros "ff_malloc" and "ff_free" in the ff_conf_template.h and use
|
||||||
|
them in the syscall.c instead of direct calls to stdlib malloc and free functions.
|
||||||
|
+ Define the "__weak" attribute in diskio.c for the GNU GCC compiler
|
||||||
|
|
||||||
|
|
||||||
|
### V1.4.0/09-September-2016 ###
|
||||||
|
================================
|
||||||
|
+ Upgrade to use FatFs R0.12b.
|
||||||
|
+ ff_conf.h: remove the use of define "_USE_BUFF_WO_ALIGNMENT".
|
||||||
|
|
||||||
|
|
||||||
|
### V1.3.0/08-May-2015 ###
|
||||||
|
==========================
|
||||||
|
+ Upgrade to use FatFs R0.11.
|
||||||
|
+ Add new APIs FATFS_LinkDriverEx() and FATFS_UnLinkDriverEx() to manage USB Key Disk having
|
||||||
|
multi-lun capability. These APIs are equivalent to FATFS_LinkDriver() and FATFS_UnLinkDriver()
|
||||||
|
with "lun" parameter set to 0.
|
||||||
|
+ ff_conf.h: add new define "_USE_BUFF_WO_ALIGNMENT".
|
||||||
|
This option is available only for usbh diskio interface and allow to disable
|
||||||
|
the management of the unaligned buffer.
|
||||||
|
When STM32 USB OTG HS or FS IP is used with internal DMA enabled, this define
|
||||||
|
must be set to 0 to align data into 32bits through an internal scratch buffer
|
||||||
|
before being processed by the DMA . Otherwise (DMA not used), this define must
|
||||||
|
be set to 1 to avoid Data alignment and improve the performance.
|
||||||
|
Please note that if _USE_BUFF_WO_ALIGNMENT is set to 1 and an unaligned 32bits
|
||||||
|
buffer is forwarded to the FatFs Write/Read functions, an error will be returned.
|
||||||
|
(0: default value or 1: unaligned buffer return an error).
|
||||||
|
|
||||||
|
|
||||||
|
+ Important note:
|
||||||
|
For application code based on previous FatFs version; when moving to R0.11
|
||||||
|
the changes that need to be done is to update ffconf.h file, taking
|
||||||
|
ffconf_template.h file as reference.
|
||||||
|
|
||||||
|
|
||||||
|
### V1.2.1/20-November-2014 ###
|
||||||
|
===============================
|
||||||
|
+ Disk I/O drivers; change count argument type from BYTE to UINT
|
||||||
|
|
||||||
|
+ Important note:
|
||||||
|
For application code based on previous FatFs version; when moving to R0.10b
|
||||||
|
the only change that need to be done is to update ffconf.h file, taking
|
||||||
|
ffconf_template.h file as reference.
|
||||||
|
|
||||||
|
|
||||||
|
### V1.2.0/04-November-2014 ###
|
||||||
|
===============================
|
||||||
|
+ Upgrade to use FatFs R0.10b.
|
||||||
|
+ diskio.c: update disk_read() and disk_write() argument's type.
|
||||||
|
|
||||||
|
+ Important note:
|
||||||
|
For application code based on previous FatFs version; when moving to R0.10b
|
||||||
|
the only change that need to be done is to update ffconf.h file, taking
|
||||||
|
ffconf_template.h file as reference.
|
||||||
|
|
||||||
|
|
||||||
|
### V1.1.1/12-September-2014 ###
|
||||||
|
================================
|
||||||
|
+ ff_gen_drv.c: Update the Disk_drvTypeDef disk variable initialization to avoid
|
||||||
|
warnings detected with Atollic TrueSTUDIO Complier.
|
||||||
|
|
||||||
|
|
||||||
|
### V1.1.0/22-April-2014 ###
|
||||||
|
============================
|
||||||
|
+ Update sd_diskio to use SD BSP in polling mode instead of DMA mode (the scratch
|
||||||
|
buffer needed for DMA alignment is removed as well).
|
||||||
|
+ diskio.c and ff_gen_drv.c/.h: update to prevent multiple initialization.
|
||||||
|
|
||||||
|
|
||||||
|
### V1.0.0/18-February-2014 ###
|
||||||
|
===============================
|
||||||
|
+ First R0.10 customized version for STM32Cube solution.
|
||||||
|
|
||||||
|
|
||||||
|
* <h3><center>© COPYRIGHT STMicroelectronics</center></h3>
|
||||||
|
*/
|
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
162
Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h
vendored
Normal file
162
Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* 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 FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* this is a template configuration files
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Ensure stdint is only used by the compiler, and not the assembler. */
|
||||||
|
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t SystemCoreClock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CMSIS-RTOSv2 defines 56 levels of priorities. To be able to use them
|
||||||
|
* all and avoid application misbehavior, configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* must be set to 0 and configMAX_PRIORITIES to 56
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0*/
|
||||||
|
/* #define configMAX_PRIORITIES ( 56 ) */
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configMAX_PRIORITIES (7)
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
#define configCPU_CLOCK_HZ (SystemCoreClock)
|
||||||
|
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||||
|
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
|
||||||
|
#define configTOTAL_HEAP_SIZE ((size_t)(15 * 1024))
|
||||||
|
#define configMAX_TASK_NAME_LEN (16)
|
||||||
|
#define configUSE_TRACE_FACILITY 1
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES (2)
|
||||||
|
|
||||||
|
/* Software timer definitions. */
|
||||||
|
#define configUSE_TIMERS 0
|
||||||
|
#define configTIMER_TASK_PRIORITY (2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 10
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)
|
||||||
|
|
||||||
|
/* 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 0
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 1
|
||||||
|
|
||||||
|
/*------------- CMSIS-RTOS V2 specific defines -----------*/
|
||||||
|
/* When using CMSIS-RTOSv2 set configSUPPORT_STATIC_ALLOCATION to 1
|
||||||
|
* is mandatory to avoid compile errors.
|
||||||
|
* CMSIS-RTOS V2 implmentation requires the following defines
|
||||||
|
*
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1 <-- cmsis_os threads are created using xTaskCreateStatic() API
|
||||||
|
#define configMAX_PRIORITIES (56) <-- Priority range in CMSIS-RTOS V2 is [0 .. 56]
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 <-- when set to 1, configMAX_PRIORITIES can't be more than 32 which is not suitable for the new CMSIS-RTOS v2 priority range
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* the CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
|
||||||
|
* by the application thus the correct define need to be enabled from the list
|
||||||
|
* below
|
||||||
|
*
|
||||||
|
//define USE_FreeRTOS_HEAP_1
|
||||||
|
//define USE_FreeRTOS_HEAP_2
|
||||||
|
//define USE_FreeRTOS_HEAP_3
|
||||||
|
//define USE_FreeRTOS_HEAP_4
|
||||||
|
//define USE_FreeRTOS_HEAP_5
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 /* 15 priority levels */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||||
|
function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
|
||||||
|
|
||||||
|
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||||
|
standard names. */
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
|
||||||
|
/* IMPORTANT: FreeRTOS is using the SysTick as internal time base, thus make sure the system and peripherials are
|
||||||
|
using a different time base (TIM based for example).
|
||||||
|
*/
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
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;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
775
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
vendored
Normal file
775
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
vendored
Normal file
|
@ -0,0 +1,775 @@
|
||||||
|
/*
|
||||||
|
* 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 )
|
||||||
|
|
||||||
|
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
|
||||||
|
r0p1 port. */
|
||||||
|
#define portCPUID ( * ( ( volatile uint32_t * ) 0xE000ed00 ) )
|
||||||
|
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
|
||||||
|
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
|
||||||
|
|
||||||
|
#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 );
|
||||||
|
|
||||||
|
/* This port can be used on all revisions of the Cortex-M7 core other than
|
||||||
|
the r0p1 parts. r0p1 parts should use the port from the
|
||||||
|
/source/portable/GCC/ARM_CM7/r0p1 directory. */
|
||||||
|
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||||
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
|
|
||||||
|
#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"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" 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 */
|
||||||
|
|
||||||
|
|
243
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
vendored
Normal file
243
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* 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" \
|
||||||
|
" msr basepri, %0 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \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" \
|
||||||
|
" msr basepri, %1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \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 */
|
||||||
|
|
146
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_1.c
vendored
Normal file
146
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_1.c
vendored
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* 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!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The simplest possible implementation of pvPortMalloc(). Note that this
|
||||||
|
* implementation does NOT allow allocated memory to be freed again.
|
||||||
|
*
|
||||||
|
* See heap_2.c, heap_3.c and heap_4.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
|
||||||
|
|
||||||
|
/* A few bytes might be lost to byte aligning the heap start address. */
|
||||||
|
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
/* Index into the ucHeap array. */
|
||||||
|
static size_t xNextFreeByte = ( size_t ) 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
void *pvReturn = NULL;
|
||||||
|
static uint8_t *pucAlignedHeap = NULL;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number of bytes. */
|
||||||
|
#if( portBYTE_ALIGNMENT != 1 )
|
||||||
|
{
|
||||||
|
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
if( pucAlignedHeap == NULL )
|
||||||
|
{
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check there is enough room left for the allocation. */
|
||||||
|
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
|
||||||
|
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
|
||||||
|
{
|
||||||
|
/* Return the next free byte then increment the index past this
|
||||||
|
block. */
|
||||||
|
pvReturn = pucAlignedHeap + xNextFreeByte;
|
||||||
|
xNextFreeByte += xWantedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void *pv )
|
||||||
|
{
|
||||||
|
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
|
||||||
|
heap_4.c for alternative implementations, and the memory management pages of
|
||||||
|
http://www.FreeRTOS.org for more information. */
|
||||||
|
( void ) pv;
|
||||||
|
|
||||||
|
/* Force an assert as it is invalid to call this function. */
|
||||||
|
configASSERT( pv == NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortInitialiseBlocks( void )
|
||||||
|
{
|
||||||
|
/* Only required when static memory is not cleared. */
|
||||||
|
xNextFreeByte = ( size_t ) 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
272
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_2.c
vendored
Normal file
272
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_2.c
vendored
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
* 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 permits
|
||||||
|
* allocated blocks to be freed, but does not combine adjacent free blocks
|
||||||
|
* into a single larger block (and so will fragment memory). See heap_4.c for
|
||||||
|
* an equivalent that does combine adjacent blocks into single larger blocks.
|
||||||
|
*
|
||||||
|
* See heap_1.c, heap_3.c and heap_4.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
|
||||||
|
|
||||||
|
/* A few bytes might be lost to byte aligning the heap start address. */
|
||||||
|
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialises the heap structures before their first use.
|
||||||
|
*/
|
||||||
|
static void prvHeapInit( void );
|
||||||
|
|
||||||
|
/* 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 size. */
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
|
||||||
|
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
|
||||||
|
|
||||||
|
/* Create a couple of list links to mark the start and end of the list. */
|
||||||
|
static BlockLink_t xStart, xEnd;
|
||||||
|
|
||||||
|
/* Keeps track of the number of free bytes remaining, but says nothing about
|
||||||
|
fragmentation. */
|
||||||
|
static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
|
||||||
|
|
||||||
|
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a block into the list of free blocks - which is ordered by size of
|
||||||
|
* the block. Small blocks at the start of the list and large blocks at the end
|
||||||
|
* of the list.
|
||||||
|
*/
|
||||||
|
#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
|
||||||
|
{ \
|
||||||
|
BlockLink_t *pxIterator; \
|
||||||
|
size_t xBlockSize; \
|
||||||
|
\
|
||||||
|
xBlockSize = pxBlockToInsert->xBlockSize; \
|
||||||
|
\
|
||||||
|
/* Iterate through the list until a block is found that has a larger size */ \
|
||||||
|
/* than the block we are inserting. */ \
|
||||||
|
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
|
||||||
|
{ \
|
||||||
|
/* There is nothing to do here - just iterate to the correct position. */ \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Update the list to include the block being inserted in the correct */ \
|
||||||
|
/* position. */ \
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
|
||||||
|
pxIterator->pxNextFreeBlock = pxBlockToInsert; \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
||||||
|
static BaseType_t xHeapHasBeenInitialised = pdFALSE;
|
||||||
|
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( xHeapHasBeenInitialised == pdFALSE )
|
||||||
|
{
|
||||||
|
prvHeapInit();
|
||||||
|
xHeapHasBeenInitialised = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 += heapSTRUCT_SIZE;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number of bytes. */
|
||||||
|
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
|
||||||
|
{
|
||||||
|
/* Blocks are stored in byte order - traverse the list from the start
|
||||||
|
(smallest) 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 we found the end marker then a block of adequate size was not found. */
|
||||||
|
if( pxBlock != &xEnd )
|
||||||
|
{
|
||||||
|
/* Return the memory space - jumping over the BlockLink_t structure
|
||||||
|
at its start. */
|
||||||
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
|
||||||
|
/* 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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 -= heapSTRUCT_SIZE;
|
||||||
|
|
||||||
|
/* This unexpected casting is to keep some compilers from issuing
|
||||||
|
byte alignment warnings. */
|
||||||
|
pxLink = ( void * ) puc;
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
/* Add this block to the list of free blocks. */
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortInitialiseBlocks( void )
|
||||||
|
{
|
||||||
|
/* This just exists to keep the linker quiet. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHeapInit( void )
|
||||||
|
{
|
||||||
|
BlockLink_t *pxFirstFreeBlock;
|
||||||
|
uint8_t *pucAlignedHeap;
|
||||||
|
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* xEnd is used to mark the end of the list of free blocks. */
|
||||||
|
xEnd.xBlockSize = configADJUSTED_HEAP_SIZE;
|
||||||
|
xEnd.pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block that is sized to take up the
|
||||||
|
entire heap space. */
|
||||||
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE;
|
||||||
|
pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
97
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_3.c
vendored
Normal file
97
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_3.c
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* 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 pvPortMalloc() and vPortFree() that relies on the
|
||||||
|
* compilers own malloc() and free() implementations.
|
||||||
|
*
|
||||||
|
* This file can only be used if the linker is configured to to generate
|
||||||
|
* a heap memory area.
|
||||||
|
*
|
||||||
|
* See heap_1.c, heap_2.c and heap_4.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
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
void *pvReturn;
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
pvReturn = malloc( xWantedSize );
|
||||||
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void *pv )
|
||||||
|
{
|
||||||
|
if( pv )
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
free( pv );
|
||||||
|
traceFREE( pv, 0 );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
485
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_5.c
vendored
Normal file
485
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_5.c
vendored
Normal file
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* 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() that allows the heap to be defined
|
||||||
|
* across multiple non-contigous blocks and combines (coalescences) adjacent
|
||||||
|
* memory blocks as they are freed.
|
||||||
|
*
|
||||||
|
* See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative
|
||||||
|
* implementations, and the memory management pages of http://www.FreeRTOS.org
|
||||||
|
* for more information.
|
||||||
|
*
|
||||||
|
* Usage notes:
|
||||||
|
*
|
||||||
|
* vPortDefineHeapRegions() ***must*** be called before pvPortMalloc().
|
||||||
|
* pvPortMalloc() will be called if any task objects (tasks, queues, event
|
||||||
|
* groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be
|
||||||
|
* called before any other objects are defined.
|
||||||
|
*
|
||||||
|
* vPortDefineHeapRegions() takes a single parameter. The parameter is an array
|
||||||
|
* of HeapRegion_t structures. HeapRegion_t is defined in portable.h as
|
||||||
|
*
|
||||||
|
* typedef struct HeapRegion
|
||||||
|
* {
|
||||||
|
* uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap.
|
||||||
|
* size_t xSizeInBytes; << Size of the block of memory.
|
||||||
|
* } HeapRegion_t;
|
||||||
|
*
|
||||||
|
* The array is terminated using a NULL zero sized region definition, and the
|
||||||
|
* memory regions defined in the array ***must*** appear in address order from
|
||||||
|
* low address to high address. So the following is a valid example of how
|
||||||
|
* to use the function.
|
||||||
|
*
|
||||||
|
* HeapRegion_t xHeapRegions[] =
|
||||||
|
* {
|
||||||
|
* { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000
|
||||||
|
* { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000
|
||||||
|
* { NULL, 0 } << Terminates the array.
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions().
|
||||||
|
*
|
||||||
|
* Note 0x80000000 is the lower address so appears in the array first.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#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 )
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* The heap must be initialised before the first call to
|
||||||
|
prvPortMalloc(). */
|
||||||
|
configASSERT( pxEnd );
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
/* 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 ) );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )
|
||||||
|
{
|
||||||
|
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
|
||||||
|
size_t xAlignedHeap;
|
||||||
|
size_t xTotalRegionSize, xTotalHeapSize = 0;
|
||||||
|
BaseType_t xDefinedRegions = 0;
|
||||||
|
size_t xAddress;
|
||||||
|
const HeapRegion_t *pxHeapRegion;
|
||||||
|
|
||||||
|
/* Can only call once! */
|
||||||
|
configASSERT( pxEnd == NULL );
|
||||||
|
|
||||||
|
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
|
||||||
|
|
||||||
|
while( pxHeapRegion->xSizeInBytes > 0 )
|
||||||
|
{
|
||||||
|
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
|
||||||
|
|
||||||
|
/* Ensure the heap region starts on a correctly aligned boundary. */
|
||||||
|
xAddress = ( size_t ) pxHeapRegion->pucStartAddress;
|
||||||
|
if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
xAddress += ( portBYTE_ALIGNMENT - 1 );
|
||||||
|
xAddress &= ~portBYTE_ALIGNMENT_MASK;
|
||||||
|
|
||||||
|
/* Adjust the size for the bytes lost to alignment. */
|
||||||
|
xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
xAlignedHeap = xAddress;
|
||||||
|
|
||||||
|
/* Set xStart if it has not already been set. */
|
||||||
|
if( xDefinedRegions == 0 )
|
||||||
|
{
|
||||||
|
/* 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 = ( BlockLink_t * ) xAlignedHeap;
|
||||||
|
xStart.xBlockSize = ( size_t ) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Should only get here if one region has already been added to the
|
||||||
|
heap. */
|
||||||
|
configASSERT( pxEnd != NULL );
|
||||||
|
|
||||||
|
/* Check blocks are passed in with increasing start addresses. */
|
||||||
|
configASSERT( xAddress > ( size_t ) pxEnd );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember the location of the end marker in the previous region, if
|
||||||
|
any. */
|
||||||
|
pxPreviousFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* pxEnd is used to mark the end of the list of free blocks and is
|
||||||
|
inserted at the end of the region space. */
|
||||||
|
xAddress = xAlignedHeap + xTotalRegionSize;
|
||||||
|
xAddress -= xHeapStructSize;
|
||||||
|
xAddress &= ~portBYTE_ALIGNMENT_MASK;
|
||||||
|
pxEnd = ( BlockLink_t * ) xAddress;
|
||||||
|
pxEnd->xBlockSize = 0;
|
||||||
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block in this region that is
|
||||||
|
sized to take up the entire heap region minus the space taken by the
|
||||||
|
free block structure. */
|
||||||
|
pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;
|
||||||
|
pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion;
|
||||||
|
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* If this is not the first region that makes up the entire heap space
|
||||||
|
then link the previous region to this region. */
|
||||||
|
if( pxPreviousFreeBlock != NULL )
|
||||||
|
{
|
||||||
|
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
|
||||||
|
|
||||||
|
/* Move onto the next HeapRegion_t structure. */
|
||||||
|
xDefinedRegions++;
|
||||||
|
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
|
||||||
|
xFreeBytesRemaining = xTotalHeapSize;
|
||||||
|
|
||||||
|
/* Check something was actually defined before it is accessed. */
|
||||||
|
configASSERT( xTotalHeapSize );
|
||||||
|
|
||||||
|
/* Work out the position of the top bit in a size_t variable. */
|
||||||
|
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
|
||||||
|
}
|
||||||
|
|
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
17
Middlewares/Third_Party/FreeRTOS/Source/readme.txt
vendored
Normal file
17
Middlewares/Third_Party/FreeRTOS/Source/readme.txt
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
Each real time kernel port consists of three files that contain the core kernel
|
||||||
|
components and are common to every port, and one or more files that are
|
||||||
|
specific to a particular microcontroller and or compiler.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source directory contains the three files that are common to
|
||||||
|
every port - list.c, queue.c and tasks.c. The kernel is contained within these
|
||||||
|
three files. croutine.c implements the optional co-routine functionality - which
|
||||||
|
is normally only used on very memory limited systems.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source/Portable directory contains the files that are specific to
|
||||||
|
a particular microcontroller and or compiler.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source/include directory contains the real time kernel header
|
||||||
|
files.
|
||||||
|
|
||||||
|
See the readme file in the FreeRTOS/Source/Portable directory for more
|
||||||
|
information.
|
368
Middlewares/Third_Party/FreeRTOS/Source/st_readme.txt
vendored
Normal file
368
Middlewares/Third_Party/FreeRTOS/Source/st_readme.txt
vendored
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Portions Copyright © 2019 STMicroelectronics International N.V. All rights reserved.
|
||||||
|
* Portions Copyright (C) 2016 Real Time Engineers Ltd, All rights reserved
|
||||||
|
*
|
||||||
|
* @file st_readme.txt
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief This file lists the main modification done by STMicroelectronics on
|
||||||
|
* FreeRTOS for integration with STM32Cube solution.
|
||||||
|
* For more details on FreeRTOS implementation on STM32Cube, please refer
|
||||||
|
* to UM1722 "Developing Applications on STM32Cube with FreeRTOS"
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
=======
|
||||||
|
|
||||||
|
### 17-January-2020 ###
|
||||||
|
=========================
|
||||||
|
+ Fix compile error in the GCC CM7_MPU port caused by a duplicated variable declaration
|
||||||
|
- Source/portable/GCC/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
|
||||||
|
### 13-December-2019 ###
|
||||||
|
=========================
|
||||||
|
+ Remove warnings thrown by EWARM for CM33/CM23 ports
|
||||||
|
- IAR/ARM_CM23/non_secure/portmacro.h
|
||||||
|
- IAR/ARM_CM23_NTZ/non_secure/portmacro.h
|
||||||
|
- IAR/ARM_CM33/non_secure/portmacro.h
|
||||||
|
- IAR/ARM_CM33_NTZ/non_secure/portmacro.h
|
||||||
|
|
||||||
|
### 19-July-2019 ###
|
||||||
|
=========================
|
||||||
|
+ Fix runtime error in the IAR/CM4_MPU port
|
||||||
|
- IAR/ARM_CM4_MPU/port.c
|
||||||
|
|
||||||
|
### 12-July-2019 ###
|
||||||
|
=========================
|
||||||
|
+ FreeRTOS: Update against the FreeRTOS v10.2.1 release
|
||||||
|
- support for the CM33 and CM23 cores
|
||||||
|
|
||||||
|
+ CMSIS_RTOS_V2: update against the latest CMSIS-FreeRTOS v10.2.0 release
|
||||||
|
|
||||||
|
+ Add MPU support for the CM7/r0p1:
|
||||||
|
- GCC/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- GCC/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/portasm.s
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
- RVDS/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- RVDS/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
|
||||||
|
+ cmsis_os.c: Fix compile errors by using the correct TimerCallbackFunction_t type for timer creation
|
||||||
|
|
||||||
|
### 29-Mars-2019 ###
|
||||||
|
=========================
|
||||||
|
+ cmsis_os.c : Fix bug in osPoolAlloc(): memory blocks can't be reused after being free'd
|
||||||
|
+ Source/CMSIS_RTOS_V2/cmsis_os, Source/CMSIS_RTOS_V2/cmsis_os1.c, Source/CMSIS_RTOS_V2/cmsis_os2.c, Source/CMSIS_RTOS_V2/cmsis_os2.h: restore original Apache license terms
|
||||||
|
+ st_readme.txt: update license terms to BSD-3-Clause
|
||||||
|
|
||||||
|
|
||||||
|
### 13-August-2018 ###
|
||||||
|
=========================
|
||||||
|
+ Add empty implementation for the missing function osThreadGetStackSize()
|
||||||
|
to avoid link errors when using CMSIS-RTOS V2.
|
||||||
|
|
||||||
|
+ Update the FreeRTOSConfig_template.h with specific defines for the
|
||||||
|
CMSIS-RTOS V2.
|
||||||
|
|
||||||
|
+ Rename the "RTE_RTOS_FreeRTOS_XXXX" macros to "USE_FreeRTOS_XXXX" in
|
||||||
|
cmsis_os2.c.
|
||||||
|
|
||||||
|
### 30-July-2018 ###
|
||||||
|
=========================
|
||||||
|
+ Update License.txt file to MIT license instead of GPLv2
|
||||||
|
|
||||||
|
### 23-July-2018 ###
|
||||||
|
=========================
|
||||||
|
+ Fix compiler warnings thrown by IAR compiler 8.20
|
||||||
|
|
||||||
|
+ Add MPU support for the CM7/r0p1:
|
||||||
|
- GCC/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- GCC/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/portasm.s
|
||||||
|
- IAR/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
- RVDS/ARM_CM7_MPU/r0p1/port.c
|
||||||
|
- RVDS/ARM_CM7_MPU/r0p1/portmacro.h
|
||||||
|
|
||||||
|
### 09-April-2018 ###
|
||||||
|
=========================
|
||||||
|
Update the FreeRTOS against the latest release 10.0.1
|
||||||
|
more details are available in: https://www.freertos.org/History.txt
|
||||||
|
|
||||||
|
+ Integrate support for tickless mode for ARM_CM0 core:
|
||||||
|
- GCC/ARM_CM0/port.c
|
||||||
|
- GCC/ARM_CM0/portmacro.h
|
||||||
|
- IAR/ARM_CM0/port.c
|
||||||
|
- IAR/ARM_CM0/portmacro.h
|
||||||
|
- RVDS/ARM_CM0/port.c
|
||||||
|
|
||||||
|
Integrate CMSIS-RTOSv2 wrapper based on: https://github.com/ARM-software/CMSIS-FreeRTOS/releases/tag/10.0.1
|
||||||
|
+ Add new files:
|
||||||
|
- CMSIS_RTOS_V2/cmsis_os.h
|
||||||
|
- CMSIS_RTOS_V2/cmsis_os1.c
|
||||||
|
- CMSIS_RTOS_V2/cmsis_os2.c
|
||||||
|
- CMSIS_RTOS_V2/cmsis_os2.h
|
||||||
|
"cmsis_os1.c" and "cmsis_os1.h" contains the reference implementation of
|
||||||
|
CMSIS-RTOSv1,i.e as released by ARM, using the CMSIS-RTOSV2 API.
|
||||||
|
|
||||||
|
+ The ST customized CMSIS-RTOSv1 is maintained under:
|
||||||
|
- CMSIS_RTOS/cmsis_os.c
|
||||||
|
- CMSIS_RTOS/cmsis_os.h
|
||||||
|
|
||||||
|
+ When using CMSIS-RTOSv2 APIs, the following FreeRTOS defines are required:
|
||||||
|
- #define configMAX_PRIORITIES 56
|
||||||
|
- #define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
- #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
|
||||||
|
|
||||||
|
### 10-August-2017 ###
|
||||||
|
=========================
|
||||||
|
Update FreeRTOS to support MPU feature with IAR compiler.
|
||||||
|
|
||||||
|
+ Add the following ports:
|
||||||
|
- IAR/ARM_CM4_MPU
|
||||||
|
- IAR/ARM_CM7_MPU
|
||||||
|
- RVDS/ARM_CM7_MPU
|
||||||
|
|
||||||
|
|
||||||
|
### 03-March-2017 ###
|
||||||
|
=========================
|
||||||
|
Update CMSIS-RTOS drivers to support both CMSIS Core V4.x and V5.x
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
+ CMSIS-RTOS: Wrong return value for osSignalWait()
|
||||||
|
+ CMSIS-RTOS: Not all queue size is 0 initialized with osMailCAlloc()
|
||||||
|
|
||||||
|
Limitation:
|
||||||
|
+ CMSIS-RTOS: osSignalWAit() function is not fully compliant with the specification
|
||||||
|
|
||||||
|
|
||||||
|
### 30-September-2016 ###
|
||||||
|
=========================
|
||||||
|
The purpose of this release is to Upgrade to use FreeRTOS V9.0.0, this version
|
||||||
|
is a drop-in compatible replacement for FreeRTOS V8.2.3.
|
||||||
|
For more details please refer to http://www.freertos.org/History.txt
|
||||||
|
|
||||||
|
+ Add support to tickless mode for MPU ports:
|
||||||
|
- GCC/ARM_CM3_MPU/port.c
|
||||||
|
- GCC/ARM_CM4_MPU/port.c
|
||||||
|
- RVDS/ARM_CM4_MPU/port.c
|
||||||
|
|
||||||
|
+ Update CM0 ports, add possibility to use a timebase different than Systick:
|
||||||
|
- IAR/ARM_CM0/port.c
|
||||||
|
- RVDS/ARM_CM0/port.c
|
||||||
|
- GCC/ARM_CM0/port.c
|
||||||
|
|
||||||
|
+ Fix compilation error in CM3_MPU and CM4_MPU ports:
|
||||||
|
- GCC/ARM_CM3_MPU/portmacro.h
|
||||||
|
- GCC/ARM_CM4_MPU/portmacro.h
|
||||||
|
- RVDS/ARM_CM4_MPU/portmacro.h
|
||||||
|
- Add "Source\portable\Common\" directory
|
||||||
|
|
||||||
|
+ cmsis_os.c
|
||||||
|
- Add support of Statically Allocated Systems introduced with FreeRTOS V9.0.0
|
||||||
|
- Add new wrappers CMSIS-RTOS APIs
|
||||||
|
|
||||||
|
FreeRTOS APIs | CMSIS-RTOS APIs | Description
|
||||||
|
==================================================================================================================
|
||||||
|
uxQueueMessagesWaiting() | osMessageWaiting() | Return the number of messages stored in a queue
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
xTaskAbortDelay() | osAbortDelay() | Force a thread to get out the blocked state immediately
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
uxSemaphoreGetCount() | osSemaphoreGetCount() | Return the current count of a semaphore
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
uxQueueSpacesAvailable() | osMessageAvailableSpace() | Return the available space in a message queue
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
vQueueDelete() | osMessageDelete() | Delete a message Queue
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
### 22-January-2016 ###
|
||||||
|
=======================
|
||||||
|
The purpose of this release is to Upgrade to use FreeRTOS V8.2.3.
|
||||||
|
It also provides fixes for minor issues.
|
||||||
|
|
||||||
|
+ cmsis_os.c
|
||||||
|
- Implementation of functions "osSignalSet" and "osSignalWait" are now delimited by
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS.
|
||||||
|
- Function "osTimerStart" : fix for an assert issue when called from an ISR.
|
||||||
|
- Function "osMailCreate" : internal variables initialization.
|
||||||
|
- Function "osSignalWait" : signals value is now compared versus integer zero for error checking.
|
||||||
|
|
||||||
|
+ freeRTOS sources
|
||||||
|
- FreeRTOS.h file : Add configuration sanity check in case of configUSE_RECURSIVE_MUTEXES set
|
||||||
|
and configUSE_MUTEXES not set.
|
||||||
|
|
||||||
|
+ STMicroelectronics license simplifications, see license disclaimer within this file's header
|
||||||
|
|
||||||
|
|
||||||
|
### 27-March-2015 ###
|
||||||
|
=====================
|
||||||
|
The purpose of this release is to Upgrade to use FreeRTOS V8.2.1.
|
||||||
|
|
||||||
|
+ Major change of the version 8.2.1 is the support of CM7 core.
|
||||||
|
For STM32F746xx/STM32F756xx devices, need to use port files under Source/Portable/XXX/ARM_CM7/r0p1,
|
||||||
|
where XXX refers to the compiler used.
|
||||||
|
|
||||||
|
+ It also provides implementation of osSignal management APIs, osSignalSet() and osSignalWait(),
|
||||||
|
fixes osMassage queue size, osMailQDef macro and osDelayUntil parameters.
|
||||||
|
|
||||||
|
+ In this release an alignment has been done in ARM_CM4 and ARM_CM3 port.c versus ARM_CM0 port.c
|
||||||
|
regarding the use of macros configPRE_SLEEP_PROCESSING and configPOST_SLEEP_PROCESSING, these tow macros
|
||||||
|
are now taking as parameter as pointer to TickType_t.
|
||||||
|
|
||||||
|
+ cmsis_os.c
|
||||||
|
- Add implementation of osSignalSet() and osSignalWait() APIs
|
||||||
|
- Fix massage queue size in osMessageCreate API
|
||||||
|
- osDelayUntil: parameter PreviousWakeTime is now passed as a pointer.
|
||||||
|
- Enabling Mail queue management APIs (temporary removed in previous version).
|
||||||
|
- Function "osThreadGetPriority" uses now uxTaskPriorityGetFromISR if called from an interrupt handler, if not use uxTaskPriorityGet.
|
||||||
|
|
||||||
|
+ cmsis_os.h
|
||||||
|
- osFeature_Wait is defined to 0 to indicate that osWait function is not available (as specified by cmsis_os template by ARM)
|
||||||
|
- Fix compilation issue with osMailQDef macro.
|
||||||
|
- Enabling Mail queue management APIs (temporary removed in previous version)
|
||||||
|
|
||||||
|
+ freeRTOS sources
|
||||||
|
- ARM_CM3 port.c and ARM_CM4 port.c:
|
||||||
|
function vPortSuppressTicksAndSleep : configPRE_SLEEP_PROCESSING and configPOST_SLEEP_PROCESSING are now taking
|
||||||
|
as parameter as pointer to TickType_t.
|
||||||
|
The purpose of this change is to align the CM3 and CM4 implementation with CM0 one.
|
||||||
|
|
||||||
|
+ Note
|
||||||
|
- osSignalSet returns an int32_t value which is a a status (osOK or osError)
|
||||||
|
instead of the previous signal value as specified in cmsis_os template by ARM.
|
||||||
|
This is mainly due to freeRTOS implementation, the return value will be aligned (with the cmsis os template by ARM) as soon as the freeRTOS next version will allow it.
|
||||||
|
|
||||||
|
- osThreadDef() macro is defined in the freeRTOS cmsis_os.h wrapper as follow :
|
||||||
|
osThreadDef(name, thread, priority, instances, stacksz)
|
||||||
|
the macro osThreadDef() as defined in ARM cmsis_os.h is defined with 4 parameters :
|
||||||
|
name : name of the thread function.
|
||||||
|
priority : initial priority of the thread function.
|
||||||
|
instances : number of possible thread instances.
|
||||||
|
stacksz : stack size (in bytes) requirements for the thread function.
|
||||||
|
|
||||||
|
- osThreadDef as defined in the ARM template file cmsis_os.h assumes that the thread name is the same as the thread function name.
|
||||||
|
where the freeRTOS implementation gives separate parameters for the thread name and the thread function name.
|
||||||
|
|
||||||
|
care must be taken when porting an application from/to another OS to/from freeRTOS cmsis_os regarding this macro.
|
||||||
|
|
||||||
|
the macro osThreadDef() as defined in ARM cmsis_os.h template is defined with 4 parameters :
|
||||||
|
name : name of the thread function.
|
||||||
|
priority : initial priority of the thread function.
|
||||||
|
instances : number of possible thread instances.
|
||||||
|
stacksz : stack size (in bytes) requirements for the thread function.
|
||||||
|
|
||||||
|
the macro osThreadDef() as defined in freeRTOS cmsis_os.h is defined with 5 parameters :
|
||||||
|
name : name of the thread (used for debugging and trace).
|
||||||
|
thread : name of the thread function
|
||||||
|
priority : initial priority of the thread function.
|
||||||
|
instances : number of possible thread instances.
|
||||||
|
stacksz : stack size (in bytes) requirements for the thread function.
|
||||||
|
|
||||||
|
|
||||||
|
### 25-December-2014 ###
|
||||||
|
========================
|
||||||
|
The purpose of this release is to remove compilation errors and warning. It also reintroduces
|
||||||
|
the function osThreadIsSuspended() which has been removed in the version V1.2.0.
|
||||||
|
|
||||||
|
+ cmsis_os.c
|
||||||
|
- osThreadGetPriority() and makeCmsisPriority(): replace INCLUDE_vTaskPriorityGet by the correct
|
||||||
|
freeRTOS constant uxTaskPriorityGet.
|
||||||
|
The version 1.2.2 is using a wrong constant INCLUDE_vTaskPriorityGet, while the correct freeRTOS
|
||||||
|
constant is uxTaskPriorityGet.
|
||||||
|
This fix ensure a safe use of osThreadGetPriority() function.
|
||||||
|
|
||||||
|
- osThreadIsSuspended(): this function has been removed in version V1.2.0, it is now available gain.
|
||||||
|
User can either use this function to check if a Thread is suspended either use function osThreadGetState,
|
||||||
|
which is more generic, to check the exact state of a thread.
|
||||||
|
|
||||||
|
- osThreadList(): this function is now taking as argument a pointer to uint8_t instead of a pointer to int8_t.
|
||||||
|
The change is made to remove a compilation warning.
|
||||||
|
|
||||||
|
- osRecursiveMutexCreate(): the prototype has been changed to osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def)
|
||||||
|
This change is made to make osRecursiveMutexCreate() compatible with function MutexCreate().
|
||||||
|
It also allow the better use of the function in conjunction with the macro osMutex, note that osMutex return a
|
||||||
|
"const osMutexDef_t *mutex_def".
|
||||||
|
example : osMutex1Id = osRecursiveMutexCreate (osMutex(Mutex1));
|
||||||
|
|
||||||
|
- Fix implementation of functions osSemaphoreWait(), osMutexRelease() and osMutexWait() by using the appropriate
|
||||||
|
freeRTOS “FromISR” APIs when called from an interrupt.
|
||||||
|
|
||||||
|
- Fix compilation warning when the constant INCLUDE_eTaskGetState is not defined
|
||||||
|
|
||||||
|
+ cmsis_os.h
|
||||||
|
- osThreadIsSuspended(): add function prototype.
|
||||||
|
- osThreadList(): function prototype modified as described in cmsis_os.c section.
|
||||||
|
- osRecursiveMutexCreate(): function modified as described in cmsis_os.c section.
|
||||||
|
|
||||||
|
+ Important note:
|
||||||
|
Mail Queue Management Functions are not supported in this cmsis_os version, will be added in the next release.
|
||||||
|
|
||||||
|
|
||||||
|
### 04-December-2014 ###
|
||||||
|
========================
|
||||||
|
+ cmsis_os.c, osSemaphoreCreate(): use vSemaphoreCreateBinary() instead of xSemaphoreCreateBinary(),
|
||||||
|
to keep compatibility with application code developed on FreeRTOS V7.6.0.
|
||||||
|
|
||||||
|
|
||||||
|
### 07-November-2014 ###
|
||||||
|
========================
|
||||||
|
+ cmsis_os.h: modify the osThreadState enum to fix warning generated by ARMCC compiler
|
||||||
|
+ task.c: add preprocessor compilation condition for prvTaskIsTaskSuspended() function
|
||||||
|
(it's build only when INCLUDE_vTaskSuspend option is enabled in FreeRTOSConfig.h file)
|
||||||
|
|
||||||
|
|
||||||
|
### 04-November-2014 ###
|
||||||
|
========================
|
||||||
|
+ Upgrade to use FreeRTOS V8.1.2 and CMSIS-RTOS V1.02.
|
||||||
|
+ cmsis_os.c
|
||||||
|
- Almost of CMSIS-RTOS APIs are implemented for FreeRTOS
|
||||||
|
- Additional wrapper APIs created for FreeRTOS
|
||||||
|
|
||||||
|
+ Important note:
|
||||||
|
When upgrading existing application code to use this last version, the following
|
||||||
|
update should be considered:
|
||||||
|
- osThreadIsSuspended() is no longer public API in FreeRTOS and it should
|
||||||
|
be replaced by the wrapping of eTaskGetState()
|
||||||
|
- osKernelStart() API changed, must be updated
|
||||||
|
- update FreeRTOSConfig.h file, taking FreeRTOSConfig_template.h file as reference
|
||||||
|
|
||||||
|
|
||||||
|
### 13-June-2014 ###
|
||||||
|
====================
|
||||||
|
+ FreeRTOSConfig_template.h: add this definition #define INCLUDE_xTaskGetSchedulerState 1
|
||||||
|
to enable the use of xTaskGetSchedulerState() API in the
|
||||||
|
application code.
|
||||||
|
|
||||||
|
|
||||||
|
### 30-April-2014 ###
|
||||||
|
=====================
|
||||||
|
+ cmsis_os.c: add preprocessor compilation condition when calling some FreeRTOS APIs, to avoid link
|
||||||
|
errors with MDK-ARM when some FreeRTOS features are not enabled in FreeRTOSConfig.h
|
||||||
|
|
||||||
|
|
||||||
|
### 22-April-2014 ###
|
||||||
|
=====================
|
||||||
|
+ Add Tickles mode for CM0 port (IAR, GCC, RVDS).
|
||||||
|
|
||||||
|
|
||||||
|
### 18-February-2014 ###
|
||||||
|
========================
|
||||||
|
+ FreeRTOS V7.6.0 customized version for STM32Cube solution.
|
||||||
|
|
||||||
|
|
||||||
|
* <h3><center>© COPYRIGHT STMicroelectronics</center></h3>
|
||||||
|
*/
|
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
1
Middlewares/Third_Party/LittleVGL
vendored
Submodule
1
Middlewares/Third_Party/LittleVGL
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 0aefab358b1c43f1dbb03cb65160f395032dc00d
|
|
@ -66,7 +66,8 @@ RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
|
||||||
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
|
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
|
||||||
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
|
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
|
||||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||||
FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 16M
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
QSPI_FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 16M
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define output sections */
|
/* Define output sections */
|
||||||
|
@ -78,7 +79,7 @@ SECTIONS
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
KEEP(*(.isr_vector)) /* Startup code */
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
|
|
||||||
/* The program code and other data goes into FLASH */
|
/* The program code and other data goes into FLASH */
|
||||||
.text :
|
.text :
|
||||||
|
@ -95,7 +96,7 @@ SECTIONS
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_etext = .; /* define a global symbols at end of code */
|
_etext = .; /* define a global symbols at end of code */
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
|
|
||||||
/* Constant data goes into FLASH */
|
/* Constant data goes into FLASH */
|
||||||
.rodata :
|
.rodata :
|
||||||
|
@ -104,35 +105,35 @@ SECTIONS
|
||||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
|
|
||||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >QSPI_FLASH
|
||||||
.ARM : {
|
.ARM : {
|
||||||
__exidx_start = .;
|
__exidx_start = .;
|
||||||
*(.ARM.exidx*)
|
*(.ARM.exidx*)
|
||||||
__exidx_end = .;
|
__exidx_end = .;
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
|
|
||||||
.preinit_array :
|
.preinit_array :
|
||||||
{
|
{
|
||||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
KEEP (*(.preinit_array*))
|
KEEP (*(.preinit_array*))
|
||||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
.init_array :
|
.init_array :
|
||||||
{
|
{
|
||||||
PROVIDE_HIDDEN (__init_array_start = .);
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
KEEP (*(SORT(.init_array.*)))
|
KEEP (*(SORT(.init_array.*)))
|
||||||
KEEP (*(.init_array*))
|
KEEP (*(.init_array*))
|
||||||
PROVIDE_HIDDEN (__init_array_end = .);
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
.fini_array :
|
.fini_array :
|
||||||
{
|
{
|
||||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
KEEP (*(.fini_array*))
|
KEEP (*(.fini_array*))
|
||||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
} >FLASH
|
} >QSPI_FLASH
|
||||||
|
|
||||||
/* used by the startup to initialize data */
|
/* used by the startup to initialize data */
|
||||||
_sidata = LOADADDR(.data);
|
_sidata = LOADADDR(.data);
|
||||||
|
@ -147,7 +148,7 @@ SECTIONS
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_edata = .; /* define a global symbol at data end */
|
_edata = .; /* define a global symbol at data end */
|
||||||
} >RAM_D1 AT> FLASH
|
} >RAM_D1 AT> QSPI_FLASH
|
||||||
|
|
||||||
|
|
||||||
/* Uninitialized data section */
|
/* Uninitialized data section */
|
||||||
|
|
|
@ -1,36 +1,46 @@
|
||||||
#MicroXplorer Configuration settings - do not modify
|
#MicroXplorer Configuration settings - do not modify
|
||||||
Mcu.Family=STM32H7
|
Mcu.Family=STM32H7
|
||||||
NVIC.FLASH_IRQn=true\:0\:0\:false\:false\:true\:true\:true
|
FMC.IPParameters=AddressSetupTime1,DataSetupTime1,BusTurnAroundDuration1
|
||||||
|
NVIC.FLASH_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
|
||||||
RCC.DIVQ2Freq_Value=16125000
|
RCC.DIVQ2Freq_Value=16125000
|
||||||
|
PD7.Mode=SD_4_bits_Wide_bus
|
||||||
ProjectManager.MainLocation=Core/Src
|
ProjectManager.MainLocation=Core/Src
|
||||||
SH.FMC_D7_DA7.0=FMC_D7,16b-d1
|
SH.FMC_D7_DA7.0=FMC_D7,16b-d1
|
||||||
SH.FMC_D0_DA0.ConfNb=1
|
SH.FMC_D0_DA0.ConfNb=1
|
||||||
|
PA15\ (JTDI).GPIOParameters=GPIO_Label
|
||||||
|
VP_SYS_VS_tim6.Mode=TIM6
|
||||||
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
||||||
RCC.SAI1Freq_Value=84000000
|
RCC.SAI1Freq_Value=84000000
|
||||||
RCC.CortexFreq_Value=168000000
|
RCC.CortexFreq_Value=168000000
|
||||||
SH.FMC_D6_DA6.ConfNb=1
|
SH.FMC_D6_DA6.ConfNb=1
|
||||||
SH.FMC_D9_DA9.ConfNb=1
|
SH.FMC_D9_DA9.ConfNb=1
|
||||||
|
FATFS._USE_LFN=3
|
||||||
ProjectManager.KeepUserCode=true
|
ProjectManager.KeepUserCode=true
|
||||||
Mcu.UserName=STM32H750VBTx
|
Mcu.UserName=STM32H750VBTx
|
||||||
PB10.Mode=Single Bank 1
|
PB10.Mode=Single Bank 1
|
||||||
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings=0x24000000
|
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings=0x24000000
|
||||||
RCC.HPRE=RCC_HCLK_DIV2
|
RCC.HPRE=RCC_HCLK_DIV2
|
||||||
SH.FMC_D14_DA14.0=FMC_D14,16b-d1
|
SH.FMC_D14_DA14.0=FMC_D14,16b-d1
|
||||||
|
NVIC.TIM6_DAC_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true
|
||||||
|
VP_FATFS_VS_SDIO.Mode=SDIO
|
||||||
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
|
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
|
||||||
PC10.Locked=true
|
PC10.Locked=true
|
||||||
PC10.Signal=QUADSPI_BK1_IO1
|
PC10.Signal=QUADSPI_BK1_IO1
|
||||||
PC15-OSC32_OUT\ (OSC32_OUT).Mode=LSE-External-Oscillator
|
PC15-OSC32_OUT\ (OSC32_OUT).Mode=LSE-External-Oscillator
|
||||||
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_FMC_Init-FMC-false-HAL-true,4-MX_QUADSPI_Init-QUADSPI-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
|
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_FMC_Init-FMC-false-HAL-true,4-MX_QUADSPI_Init-QUADSPI-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_SDMMC2_SD_Init-SDMMC2-false-HAL-true,7-MX_FATFS_Init-FATFS-false-HAL-false
|
||||||
SH.FMC_D6_DA6.0=FMC_D6,16b-d1
|
SH.FMC_D6_DA6.0=FMC_D6,16b-d1
|
||||||
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
|
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
|
||||||
RCC.RTCFreq_Value=32000
|
RCC.RTCFreq_Value=32000
|
||||||
PC9.Locked=true
|
PC9.Locked=true
|
||||||
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_FULL_ACCESS
|
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_FULL_ACCESS
|
||||||
|
PD6.Locked=true
|
||||||
|
PA15\ (JTDI).Signal=GPIO_Output
|
||||||
VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar
|
VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar
|
||||||
RCC.CpuClockFreq_Value=168000000
|
RCC.CpuClockFreq_Value=168000000
|
||||||
RCC.VCO2OutputFreq_Value=32250000
|
RCC.VCO2OutputFreq_Value=32250000
|
||||||
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_ACCESS_SHAREABLE
|
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_ACCESS_SHAREABLE
|
||||||
SH.FMC_D5_DA5.0=FMC_D5,16b-d1
|
SH.FMC_D5_DA5.0=FMC_D5,16b-d1
|
||||||
|
PB15.Signal=SDMMC2_D1
|
||||||
SH.FMC_NOE.ConfNb=1
|
SH.FMC_NOE.ConfNb=1
|
||||||
PinOutPanel.RotationAngle=0
|
PinOutPanel.RotationAngle=0
|
||||||
SH.FMC_NWE.0=FMC_NWE,Lcd1
|
SH.FMC_NWE.0=FMC_NWE,Lcd1
|
||||||
|
@ -39,20 +49,23 @@ RCC.MCO1PinFreq_Value=64000000
|
||||||
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
|
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
|
||||||
ProjectManager.StackSize=0x400
|
ProjectManager.StackSize=0x400
|
||||||
RCC.AHB4Freq_Value=84000000
|
RCC.AHB4Freq_Value=84000000
|
||||||
|
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||||
RCC.VCOInput3Freq_Value=250000
|
RCC.VCOInput3Freq_Value=250000
|
||||||
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_SHAREABLE
|
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_SHAREABLE
|
||||||
SH.FMC_D9_DA9.0=FMC_D9,16b-d1
|
SH.FMC_D9_DA9.0=FMC_D9,16b-d1
|
||||||
RCC.LPTIM1Freq_Value=84000000
|
RCC.LPTIM1Freq_Value=84000000
|
||||||
Mcu.IP4=RCC
|
Mcu.IP4=FREERTOS
|
||||||
Mcu.IP5=RTC
|
Mcu.IP5=NVIC
|
||||||
Mcu.IP2=NVIC
|
Mcu.IP2=FATFS
|
||||||
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
|
||||||
Mcu.IP3=QUADSPI
|
Mcu.IP3=FMC
|
||||||
Mcu.IP0=CORTEX_M7
|
Mcu.IP0=CORTEX_M7
|
||||||
|
PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
|
||||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
|
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
|
||||||
Mcu.IP1=FMC
|
Mcu.IP1=DEBUG
|
||||||
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_BUFFERABLE
|
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_BUFFERABLE
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
|
VP_FATFS_VS_SDIO.Signal=FATFS_VS_SDIO
|
||||||
RCC.DIVP3Freq_Value=16125000
|
RCC.DIVP3Freq_Value=16125000
|
||||||
RCC.SDMMCFreq_Value=84000000
|
RCC.SDMMCFreq_Value=84000000
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
|
@ -60,7 +73,7 @@ SH.FMC_D11_DA11.0=FMC_D11,16b-d1
|
||||||
RCC.HCLKFreq_Value=84000000
|
RCC.HCLKFreq_Value=84000000
|
||||||
RCC.I2C4Freq_Value=84000000
|
RCC.I2C4Freq_Value=84000000
|
||||||
PE2.Mode=Single Bank 1
|
PE2.Mode=Single Bank 1
|
||||||
Mcu.IPNb=7
|
Mcu.IPNb=11
|
||||||
ProjectManager.PreviousToolchain=
|
ProjectManager.PreviousToolchain=
|
||||||
PD4.Signal=FMC_NOE
|
PD4.Signal=FMC_NOE
|
||||||
SH.FMC_NWE.ConfNb=1
|
SH.FMC_NWE.ConfNb=1
|
||||||
|
@ -75,9 +88,11 @@ Mcu.Pin7=PB2
|
||||||
PD8.Signal=FMC_D13_DA13
|
PD8.Signal=FMC_D13_DA13
|
||||||
Mcu.Pin8=PE7
|
Mcu.Pin8=PE7
|
||||||
Mcu.Pin9=PE8
|
Mcu.Pin9=PE8
|
||||||
|
FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE
|
||||||
|
FATFS._LFN_UNICODE=0
|
||||||
Mcu.Pin0=PE2
|
Mcu.Pin0=PE2
|
||||||
Mcu.Pin1=PC14-OSC32_IN (OSC32_IN)
|
Mcu.Pin1=PC14-OSC32_IN (OSC32_IN)
|
||||||
GPIO.groupedBy=
|
GPIO.groupedBy=Group By Peripherals
|
||||||
Mcu.Pin2=PC15-OSC32_OUT (OSC32_OUT)
|
Mcu.Pin2=PC15-OSC32_OUT (OSC32_OUT)
|
||||||
RCC.HRTIMFreq_Value=84000000
|
RCC.HRTIMFreq_Value=84000000
|
||||||
Mcu.Pin3=PH0-OSC_IN (PH0)
|
Mcu.Pin3=PH0-OSC_IN (PH0)
|
||||||
|
@ -87,12 +102,13 @@ ProjectManager.ProjectBuild=false
|
||||||
PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
|
PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
|
||||||
RCC.DIVR3Freq_Value=16125000
|
RCC.DIVR3Freq_Value=16125000
|
||||||
RCC.HSE_VALUE=8000000
|
RCC.HSE_VALUE=8000000
|
||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
PB2.Signal=QUADSPI_CLK
|
PB2.Signal=QUADSPI_CLK
|
||||||
SH.FMC_D8_DA8.0=FMC_D8,16b-d1
|
SH.FMC_D8_DA8.0=FMC_D8,16b-d1
|
||||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_SIZE_128KB
|
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_SIZE_128KB
|
||||||
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true
|
Mcu.IP10=SYS
|
||||||
|
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true
|
||||||
RCC.DIVM1=8
|
RCC.DIVM1=8
|
||||||
SH.FMC_D2_DA2.0=FMC_D2,16b-d1
|
SH.FMC_D2_DA2.0=FMC_D2,16b-d1
|
||||||
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.8.0
|
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.8.0
|
||||||
|
@ -100,38 +116,45 @@ MxDb.Version=DB.6.0.10
|
||||||
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_CACHEABLE
|
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_CACHEABLE
|
||||||
RCC.DIVP1Freq_Value=168000000
|
RCC.DIVP1Freq_Value=168000000
|
||||||
CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_TEX_LEVEL1
|
CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_TEX_LEVEL1
|
||||||
|
FMC.BusTurnAroundDuration1=5
|
||||||
PE13.Signal=FMC_D10_DA10
|
PE13.Signal=FMC_D10_DA10
|
||||||
ProjectManager.BackupPrevious=false
|
ProjectManager.BackupPrevious=false
|
||||||
|
FMC.DataSetupTime1=5
|
||||||
RCC.FMCFreq_Value=84000000
|
RCC.FMCFreq_Value=84000000
|
||||||
PE9.Signal=FMC_D6_DA6
|
PE9.Signal=FMC_D6_DA6
|
||||||
|
PB14.Mode=SD_4_bits_Wide_bus
|
||||||
PB1.GPIO_Label=LCD_BL
|
PB1.GPIO_Label=LCD_BL
|
||||||
SH.FMC_D15_DA15.ConfNb=1
|
SH.FMC_D15_DA15.ConfNb=1
|
||||||
|
PC11.GPIO_Label=LED1
|
||||||
RCC.USART16Freq_Value=84000000
|
RCC.USART16Freq_Value=84000000
|
||||||
File.Version=6
|
File.Version=6
|
||||||
PC9.Mode=Single Bank 1
|
PC9.Mode=Single Bank 1
|
||||||
SH.FMC_D5_DA5.ConfNb=1
|
SH.FMC_D5_DA5.ConfNb=1
|
||||||
PE2.Signal=QUADSPI_BK1_IO2
|
PE2.Signal=QUADSPI_BK1_IO2
|
||||||
SH.FMC_D2_DA2.ConfNb=1
|
SH.FMC_D2_DA2.ConfNb=1
|
||||||
|
PA14\ (JTCK/SWCLK).Mode=Serial_Wire
|
||||||
SH.FMC_D1_DA1.0=FMC_D1,16b-d1
|
SH.FMC_D1_DA1.0=FMC_D1,16b-d1
|
||||||
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false
|
||||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_SIZE_256MB
|
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_SIZE_256MB
|
||||||
RCC.DIVR2Freq_Value=16125000
|
RCC.DIVR2Freq_Value=16125000
|
||||||
PE10.Signal=FMC_D7_DA7
|
PE10.Signal=FMC_D7_DA7
|
||||||
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
||||||
ProjectManager.HalAssertFull=false
|
ProjectManager.HalAssertFull=false
|
||||||
|
FREERTOS.configTOTAL_HEAP_SIZE=81920
|
||||||
RCC.DIVP2Freq_Value=16125000
|
RCC.DIVP2Freq_Value=16125000
|
||||||
ProjectManager.ProjectName=STM32H750_LCD
|
ProjectManager.ProjectName=STM32H750_LCD
|
||||||
RCC.APB3Freq_Value=84000000
|
RCC.APB3Freq_Value=84000000
|
||||||
PB1.PinState=GPIO_PIN_SET
|
PB1.PinState=GPIO_PIN_RESET
|
||||||
RCC.MCO2PinFreq_Value=168000000
|
RCC.MCO2PinFreq_Value=168000000
|
||||||
Mcu.Package=LQFP100
|
Mcu.Package=LQFP100
|
||||||
PB1.Signal=GPIO_Output
|
PB1.Signal=GPIO_Output
|
||||||
|
NVIC.TimeBase=TIM6_DAC_IRQn
|
||||||
SH.FMC_D0_DA0.0=FMC_D0,16b-d1
|
SH.FMC_D0_DA0.0=FMC_D0,16b-d1
|
||||||
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings=0x90000000
|
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings=0x90000000
|
||||||
RCC.EnbaleCSS=true
|
RCC.EnbaleCSS=true
|
||||||
SH.FMC_D4_DA4.ConfNb=1
|
SH.FMC_D4_DA4.ConfNb=1
|
||||||
ProjectManager.ToolChainLocation=
|
ProjectManager.ToolChainLocation=
|
||||||
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
NVIC.TimeBaseIP=TIM6
|
||||||
VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar
|
VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar
|
||||||
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings=0x60000000
|
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings=0x60000000
|
||||||
SH.FMC_D4_DA4.0=FMC_D4,16b-d1
|
SH.FMC_D4_DA4.0=FMC_D4,16b-d1
|
||||||
|
@ -139,59 +162,72 @@ RCC.DFSDMFreq_Value=84000000
|
||||||
RCC.DIVR1Freq_Value=168000000
|
RCC.DIVR1Freq_Value=168000000
|
||||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_SIZE_16MB
|
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_SIZE_16MB
|
||||||
PC14-OSC32_IN\ (OSC32_IN).Mode=LSE-External-Oscillator
|
PC14-OSC32_IN\ (OSC32_IN).Mode=LSE-External-Oscillator
|
||||||
RCC.TraceFreq_Value=64000000
|
RCC.TraceFreq_Value=168000000
|
||||||
RCC.APB4Freq_Value=84000000
|
RCC.APB4Freq_Value=84000000
|
||||||
RCC.CECFreq_Value=32000
|
RCC.CECFreq_Value=32000
|
||||||
RCC.SAI23Freq_Value=84000000
|
RCC.SAI23Freq_Value=84000000
|
||||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_ENABLE
|
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_ENABLE
|
||||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
RCC.LPUART1Freq_Value=84000000
|
RCC.LPUART1Freq_Value=84000000
|
||||||
PE7.Signal=FMC_D4_DA4
|
PE7.Signal=FMC_D4_DA4
|
||||||
|
PD6.Signal=SDMMC2_CK
|
||||||
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_SHAREABLE
|
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_SHAREABLE
|
||||||
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
|
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
|
||||||
PD15.Signal=FMC_D1_DA1
|
PD15.Signal=FMC_D1_DA1
|
||||||
SH.FMC_D3_DA3.0=FMC_D3,16b-d1
|
SH.FMC_D3_DA3.0=FMC_D3,16b-d1
|
||||||
ProjectManager.CustomerFirmwarePackage=
|
ProjectManager.CustomerFirmwarePackage=
|
||||||
RCC.Tim2OutputFreq_Value=84000000
|
RCC.Tim2OutputFreq_Value=84000000
|
||||||
NVIC.RCC_IRQn=true\:0\:0\:false\:false\:true\:true\:false
|
NVIC.RCC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false
|
||||||
RCC.DFSDMACLkFreq_Value=84000000
|
RCC.DFSDMACLkFreq_Value=84000000
|
||||||
RCC.VCO3OutputFreq_Value=32250000
|
RCC.VCO3OutputFreq_Value=32250000
|
||||||
SH.FMC_D3_DA3.ConfNb=1
|
SH.FMC_D3_DA3.ConfNb=1
|
||||||
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
|
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
|
||||||
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
|
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
|
||||||
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_FULL_ACCESS
|
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_FULL_ACCESS
|
||||||
NVIC.QUADSPI_IRQn=true\:0\:0\:false\:false\:true\:true\:true
|
NVIC.QUADSPI_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
|
||||||
ProjectManager.ProjectFileName=STM32H750_LCD.ioc
|
ProjectManager.ProjectFileName=STM32H750_LCD.ioc
|
||||||
CORTEX_M7.CPU_ICache=Enabled
|
CORTEX_M7.CPU_ICache=Enabled
|
||||||
RCC.DIVQ1=4
|
RCC.DIVQ1=4
|
||||||
Mcu.PinsNb=34
|
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
|
||||||
|
PA13\ (JTMS/SWDIO).Mode=Serial_Wire
|
||||||
|
Mcu.PinsNb=46
|
||||||
ProjectManager.NoMain=false
|
ProjectManager.NoMain=false
|
||||||
|
PC11.Locked=true
|
||||||
|
NVIC.SavedSvcallIrqHandlerGenerated=true
|
||||||
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_SHAREABLE
|
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_SHAREABLE
|
||||||
|
FATFS._USE_MUTEX=1
|
||||||
SH.FMC_D10_DA10.0=FMC_D10,16b-d1
|
SH.FMC_D10_DA10.0=FMC_D10,16b-d1
|
||||||
|
PC11.Signal=GPIO_Output
|
||||||
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_BUFFERABLE
|
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_BUFFERABLE
|
||||||
RCC.SWPMI1Freq_Value=84000000
|
RCC.SWPMI1Freq_Value=84000000
|
||||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_ENABLE
|
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_ENABLE
|
||||||
RCC.SAI4BFreq_Value=84000000
|
RCC.SAI4BFreq_Value=84000000
|
||||||
PC10.Mode=Single Bank 1
|
PC10.Mode=Single Bank 1
|
||||||
|
PD7.Signal=SDMMC2_CMD
|
||||||
PD1.Signal=FMC_D3_DA3
|
PD1.Signal=FMC_D3_DA3
|
||||||
ProjectManager.DefaultFWLocation=true
|
ProjectManager.DefaultFWLocation=true
|
||||||
PD9.Signal=FMC_D14_DA14
|
PD9.Signal=FMC_D14_DA14
|
||||||
PD5.Signal=FMC_NWE
|
PD5.Signal=FMC_NWE
|
||||||
ProjectManager.DeletePrevious=true
|
ProjectManager.DeletePrevious=true
|
||||||
|
PC11.GPIOParameters=GPIO_Label
|
||||||
SH.FMC_NOE.0=FMC_NOE,Lcd1
|
SH.FMC_NOE.0=FMC_NOE,Lcd1
|
||||||
RCC.QSPIFreq_Value=64000000
|
RCC.QSPIFreq_Value=64000000
|
||||||
|
PD6.Mode=SD_4_bits_Wide_bus
|
||||||
SH.FMC_A16_CLE.ConfNb=1
|
SH.FMC_A16_CLE.ConfNb=1
|
||||||
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings=0x20000000
|
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings=0x20000000
|
||||||
RCC.FamilyName=M
|
RCC.FamilyName=M
|
||||||
PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
|
PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
|
||||||
RCC.SPI6Freq_Value=84000000
|
RCC.SPI6Freq_Value=84000000
|
||||||
PD10.Signal=FMC_D15_DA15
|
PD10.Signal=FMC_D15_DA15
|
||||||
|
FATFS.IPParameters=_USE_LFN,_CODE_PAGE,_LFN_UNICODE,_FS_EXFAT,_USE_MUTEX,_USE_FIND,_STRF_ENCODE
|
||||||
RCC.D1CPREFreq_Value=168000000
|
RCC.D1CPREFreq_Value=168000000
|
||||||
|
FMC.AddressSetupTime1=5
|
||||||
CORTEX_M7.MPU_Control=MPU_HFNMI_PRIVDEF_NONE
|
CORTEX_M7.MPU_Control=MPU_HFNMI_PRIVDEF_NONE
|
||||||
RCC.USART234578Freq_Value=84000000
|
RCC.USART234578Freq_Value=84000000
|
||||||
RCC.SPI45Freq_Value=84000000
|
RCC.SPI45Freq_Value=84000000
|
||||||
RCC.Tim1OutputFreq_Value=84000000
|
RCC.Tim1OutputFreq_Value=84000000
|
||||||
RCC.SPI123Freq_Value=84000000
|
RCC.SPI123Freq_Value=84000000
|
||||||
|
PB3\ (JTDO/TRACESWO).Signal=SDMMC2_D2
|
||||||
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_ACCESS_BUFFERABLE
|
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_ACCESS_BUFFERABLE
|
||||||
ProjectManager.TargetToolchain=Makefile
|
ProjectManager.TargetToolchain=Makefile
|
||||||
PC15-OSC32_OUT\ (OSC32_OUT).Signal=RCC_OSC32_OUT
|
PC15-OSC32_OUT\ (OSC32_OUT).Signal=RCC_OSC32_OUT
|
||||||
|
@ -200,6 +236,7 @@ RCC.VCO1OutputFreq_Value=336000000
|
||||||
SH.FMC_D15_DA15.0=FMC_D15,16b-d1
|
SH.FMC_D15_DA15.0=FMC_D15,16b-d1
|
||||||
SH.FMC_A16_CLE.0=FMC_A16,A16_1
|
SH.FMC_A16_CLE.0=FMC_A16,A16_1
|
||||||
SH.FMC_D13_DA13.0=FMC_D13,16b-d1
|
SH.FMC_D13_DA13.0=FMC_D13,16b-d1
|
||||||
|
FATFS._CODE_PAGE=932
|
||||||
SH.FMC_D1_DA1.ConfNb=1
|
SH.FMC_D1_DA1.ConfNb=1
|
||||||
RCC.AXIClockFreq_Value=84000000
|
RCC.AXIClockFreq_Value=84000000
|
||||||
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_CACHEABLE
|
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_CACHEABLE
|
||||||
|
@ -208,104 +245,135 @@ CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_INSTRUC
|
||||||
ProjectManager.RegisterCallBack=
|
ProjectManager.RegisterCallBack=
|
||||||
RCC.USBFreq_Value=84000000
|
RCC.USBFreq_Value=84000000
|
||||||
PE11.Signal=FMC_D8_DA8
|
PE11.Signal=FMC_D8_DA8
|
||||||
|
PD7.Locked=true
|
||||||
PA1.Signal=QUADSPI_BK1_IO3
|
PA1.Signal=QUADSPI_BK1_IO3
|
||||||
RCC.CKPERFreq_Value=64000000
|
RCC.CKPERFreq_Value=64000000
|
||||||
PB1.Locked=true
|
PB1.Locked=true
|
||||||
PB10.Signal=QUADSPI_BK1_NCS
|
PB10.Signal=QUADSPI_BK1_NCS
|
||||||
NVIC.PVD_AVD_IRQn=true\:0\:0\:false\:false\:true\:true\:true
|
PB14.Signal=SDMMC2_D0
|
||||||
|
NVIC.PVD_AVD_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
|
||||||
|
Mcu.Pin40=PB4 (NJTRST)
|
||||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_ENABLE
|
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_ENABLE
|
||||||
|
Mcu.Pin41=VP_FATFS_VS_SDIO
|
||||||
|
Mcu.Pin44=VP_RTC_VS_RTC_Calendar
|
||||||
|
Mcu.Pin45=VP_SYS_VS_tim6
|
||||||
|
Mcu.Pin42=VP_FREERTOS_VS_CMSIS_V2
|
||||||
|
FATFS._STRF_ENCODE=0
|
||||||
board=custom
|
board=custom
|
||||||
|
Mcu.Pin43=VP_RTC_VS_RTC_Activate
|
||||||
ProjectManager.LastFirmware=true
|
ProjectManager.LastFirmware=true
|
||||||
|
PB15.Mode=SD_4_bits_Wide_bus
|
||||||
RCC.VCOInput1Freq_Value=1000000
|
RCC.VCOInput1Freq_Value=1000000
|
||||||
|
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
|
||||||
|
NVIC.SavedSystickIrqHandlerGenerated=true
|
||||||
RCC.AHB12Freq_Value=84000000
|
RCC.AHB12Freq_Value=84000000
|
||||||
RCC.APB2Freq_Value=84000000
|
RCC.APB2Freq_Value=84000000
|
||||||
PA1.Mode=Single Bank 1
|
PA1.Mode=Single Bank 1
|
||||||
PE14.Signal=FMC_D11_DA11
|
PE14.Signal=FMC_D11_DA11
|
||||||
|
FATFS._FS_EXFAT=1
|
||||||
PE15.Signal=FMC_D12_DA12
|
PE15.Signal=FMC_D12_DA12
|
||||||
MxCube.Version=6.1.1
|
MxCube.Version=6.1.1
|
||||||
|
Mcu.Pin37=PD6
|
||||||
SH.FMC_D13_DA13.ConfNb=1
|
SH.FMC_D13_DA13.ConfNb=1
|
||||||
|
Mcu.Pin38=PD7
|
||||||
|
Mcu.Pin35=PD4
|
||||||
PE8.Signal=FMC_D5_DA5
|
PE8.Signal=FMC_D5_DA5
|
||||||
|
Mcu.Pin36=PD5
|
||||||
RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL
|
RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL
|
||||||
RCC.FDCANFreq_Value=84000000
|
RCC.FDCANFreq_Value=84000000
|
||||||
SH.FMC_D14_DA14.ConfNb=1
|
SH.FMC_D14_DA14.ConfNb=1
|
||||||
|
Mcu.Pin39=PB3 (JTDO/TRACESWO)
|
||||||
RCC.RNGFreq_Value=48000000
|
RCC.RNGFreq_Value=48000000
|
||||||
Mcu.Pin30=PD5
|
Mcu.Pin30=PA15 (JTDI)
|
||||||
RCC.ADCFreq_Value=16125000
|
RCC.ADCFreq_Value=16125000
|
||||||
VP_SYS_VS_Systick.Mode=SysTick
|
Mcu.Pin33=PD0
|
||||||
Mcu.Pin33=VP_SYS_VS_Systick
|
|
||||||
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_FULL_ACCESS
|
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_FULL_ACCESS
|
||||||
SH.FMC_D12_DA12.0=FMC_D12,16b-d1
|
SH.FMC_D12_DA12.0=FMC_D12,16b-d1
|
||||||
Mcu.Pin31=VP_RTC_VS_RTC_Activate
|
Mcu.Pin34=PD1
|
||||||
Mcu.Pin32=VP_RTC_VS_RTC_Calendar
|
Mcu.Pin31=PC10
|
||||||
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:true
|
Mcu.Pin32=PC11
|
||||||
NVIC.HSEM1_IRQn=true\:0\:0\:false\:false\:true\:true\:true
|
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true
|
||||||
|
NVIC.HSEM1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
|
||||||
SH.FMC_D11_DA11.ConfNb=1
|
SH.FMC_D11_DA11.ConfNb=1
|
||||||
|
PB4\ (NJTRST).Mode=SD_4_bits_Wide_bus
|
||||||
|
FATFS._USE_FIND=1
|
||||||
ProjectManager.FreePins=false
|
ProjectManager.FreePins=false
|
||||||
|
PA15\ (JTDI).GPIO_Label=LED2
|
||||||
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLLSourceVirtual,QSPICLockSelection,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
|
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLLSourceVirtual,QSPICLockSelection,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
|
||||||
ProjectManager.AskForMigrate=true
|
ProjectManager.AskForMigrate=true
|
||||||
Mcu.Name=STM32H750VBTx
|
Mcu.Name=STM32H750VBTx
|
||||||
RCC.LPTIM2Freq_Value=84000000
|
RCC.LPTIM2Freq_Value=84000000
|
||||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_4GB
|
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_4GB
|
||||||
PE12.Signal=FMC_D9_DA9
|
PE12.Signal=FMC_D9_DA9
|
||||||
Mcu.Pin26=PC10
|
Mcu.Pin26=PC7
|
||||||
Mcu.Pin27=PD0
|
Mcu.Pin27=PC9
|
||||||
Mcu.Pin24=PC7
|
NVIC.SavedPendsvIrqHandlerGenerated=true
|
||||||
|
Mcu.Pin24=PD14
|
||||||
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_FULL_ACCESS
|
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_FULL_ACCESS
|
||||||
ProjectManager.UnderRoot=false
|
ProjectManager.UnderRoot=false
|
||||||
Mcu.Pin25=PC9
|
Mcu.Pin25=PD15
|
||||||
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_CACHEABLE
|
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_CACHEABLE
|
||||||
CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region1_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings,Size-Cortex_Memory_Protection_Unit_Region1_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region1_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings,Enable-Cortex_Memory_Protection_Unit_Region2_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings,Size-Cortex_Memory_Protection_Unit_Region2_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings,Enable-Cortex_Memory_Protection_Unit_Region3_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings,Size-Cortex_Memory_Protection_Unit_Region3_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region3_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region3_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region4_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings,Size-Cortex_Memory_Protection_Unit_Region4_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region4_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region4_Settings
|
CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region1_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings,Size-Cortex_Memory_Protection_Unit_Region1_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region1_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings,Enable-Cortex_Memory_Protection_Unit_Region2_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings,Size-Cortex_Memory_Protection_Unit_Region2_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings,Enable-Cortex_Memory_Protection_Unit_Region3_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings,Size-Cortex_Memory_Protection_Unit_Region3_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region3_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region3_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region4_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings,Size-Cortex_Memory_Protection_Unit_Region4_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region4_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region4_Settings
|
||||||
|
Mcu.IP8=RTC
|
||||||
|
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
||||||
|
Mcu.IP9=SDMMC2
|
||||||
PD14.Signal=FMC_D0_DA0
|
PD14.Signal=FMC_D0_DA0
|
||||||
Mcu.Pin28=PD1
|
Mcu.Pin28=PA13 (JTMS/SWDIO)
|
||||||
Mcu.IP6=SYS
|
Mcu.IP6=QUADSPI
|
||||||
Mcu.Pin29=PD4
|
Mcu.Pin29=PA14 (JTCK/SWCLK)
|
||||||
|
Mcu.IP7=RCC
|
||||||
ProjectManager.CoupleFile=false
|
ProjectManager.CoupleFile=false
|
||||||
SH.FMC_D7_DA7.ConfNb=1
|
SH.FMC_D7_DA7.ConfNb=1
|
||||||
RCC.SYSCLKFreq_VALUE=168000000
|
RCC.SYSCLKFreq_VALUE=168000000
|
||||||
Mcu.Pin22=PD14
|
Mcu.Pin22=PD10
|
||||||
|
NVIC.SDMMC2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
|
||||||
RCC.I2C123Freq_Value=84000000
|
RCC.I2C123Freq_Value=84000000
|
||||||
Mcu.Pin23=PD15
|
Mcu.Pin23=PD11
|
||||||
Mcu.Pin20=PD10
|
Mcu.Pin20=PD8
|
||||||
Mcu.Pin21=PD11
|
Mcu.Pin21=PD9
|
||||||
NVIC.ForceEnableDMAVector=true
|
NVIC.ForceEnableDMAVector=true
|
||||||
KeepUserPlacement=false
|
KeepUserPlacement=false
|
||||||
PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN
|
PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN
|
||||||
PD11.Signal=FMC_A16_CLE
|
PD11.Signal=FMC_A16_CLE
|
||||||
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
PB2.Mode=Single Bank 1
|
PB2.Mode=Single Bank 1
|
||||||
ProjectManager.CompilerOptimize=6
|
ProjectManager.CompilerOptimize=6
|
||||||
RCC.QSPICLockSelection=RCC_QSPICLKSOURCE_CLKP
|
RCC.QSPICLockSelection=RCC_QSPICLKSOURCE_CLKP
|
||||||
ProjectManager.HeapSize=0x200
|
ProjectManager.HeapSize=0x200
|
||||||
Mcu.Pin15=PE14
|
Mcu.Pin15=PE14
|
||||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
Mcu.Pin16=PE15
|
Mcu.Pin16=PE15
|
||||||
Mcu.Pin13=PE12
|
Mcu.Pin13=PE12
|
||||||
Mcu.Pin14=PE13
|
Mcu.Pin14=PE13
|
||||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_ENABLE
|
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_ENABLE
|
||||||
Mcu.Pin19=PD9
|
Mcu.Pin19=PB15
|
||||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_SIZE_512KB
|
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_SIZE_512KB
|
||||||
RCC.LPTIM345Freq_Value=84000000
|
RCC.LPTIM345Freq_Value=84000000
|
||||||
ProjectManager.ComputerToolchain=false
|
ProjectManager.ComputerToolchain=false
|
||||||
Mcu.Pin17=PB10
|
Mcu.Pin17=PB10
|
||||||
Mcu.Pin18=PD8
|
Mcu.Pin18=PB14
|
||||||
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_INSTRUCTION_ACCESS_DISABLE
|
||||||
RCC.LTDCFreq_Value=16125000
|
RCC.LTDCFreq_Value=16125000
|
||||||
RCC.SAI4AFreq_Value=84000000
|
RCC.SAI4AFreq_Value=84000000
|
||||||
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
|
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
|
||||||
Mcu.Pin11=PE10
|
Mcu.Pin11=PE10
|
||||||
Mcu.Pin12=PE11
|
Mcu.Pin12=PE11
|
||||||
|
PB3\ (JTDO/TRACESWO).Mode=SD_4_bits_Wide_bus
|
||||||
Mcu.Pin10=PE9
|
Mcu.Pin10=PE9
|
||||||
RCC.DIVQ1Freq_Value=84000000
|
RCC.DIVQ1Freq_Value=84000000
|
||||||
NVIC.FPU_IRQn=true\:0\:0\:false\:false\:true\:true\:false
|
NVIC.FPU_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false
|
||||||
PC9.Signal=QUADSPI_BK1_IO0
|
PC9.Signal=QUADSPI_BK1_IO0
|
||||||
CORTEX_M7.CPU_DCache=Enabled
|
CORTEX_M7.CPU_DCache=Enabled
|
||||||
PC7.Mode=NorPsramChipSelect1_1
|
PC7.Mode=NorPsramChipSelect1_1
|
||||||
SH.FMC_D12_DA12.ConfNb=1
|
SH.FMC_D12_DA12.ConfNb=1
|
||||||
RCC.HCLK3ClockFreq_Value=84000000
|
RCC.HCLK3ClockFreq_Value=84000000
|
||||||
|
PA15\ (JTDI).Locked=true
|
||||||
SH.FMC_D8_DA8.ConfNb=1
|
SH.FMC_D8_DA8.ConfNb=1
|
||||||
RCC.VCOInput2Freq_Value=250000
|
RCC.VCOInput2Freq_Value=250000
|
||||||
RCC.APB1Freq_Value=84000000
|
RCC.APB1Freq_Value=84000000
|
||||||
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_FULL_ACCESS
|
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_FULL_ACCESS
|
||||||
ProjectManager.DeviceId=STM32H750VBTx
|
ProjectManager.DeviceId=STM32H750VBTx
|
||||||
ProjectManager.LibraryCopy=0
|
ProjectManager.LibraryCopy=0
|
||||||
|
PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
|
||||||
PB1.GPIOParameters=PinState,GPIO_Label
|
PB1.GPIOParameters=PinState,GPIO_Label
|
||||||
|
PB4\ (NJTRST).Signal=SDMMC2_D3
|
||||||
|
|
Loading…
Reference in New Issue
Block a user