修改freertos时基心跳为tim14,更新引脚lable
This commit is contained in:
parent
1262f9a516
commit
429aa17fa4
File diff suppressed because one or more lines are too long
|
@ -51,7 +51,6 @@
|
||||||
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
extern uint32_t SystemCoreClock;
|
extern uint32_t SystemCoreClock;
|
||||||
void xPortSysTickHandler(void);
|
|
||||||
#endif
|
#endif
|
||||||
#define configENABLE_FPU 1
|
#define configENABLE_FPU 1
|
||||||
#define configENABLE_MPU 0
|
#define configENABLE_MPU 0
|
||||||
|
@ -131,7 +130,7 @@ standard names. */
|
||||||
/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
|
/* 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 */
|
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
|
||||||
|
|
||||||
/* #define xPortSysTickHandler SysTick_Handler */
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
|
||||||
/* USER CODE BEGIN Defines */
|
/* USER CODE BEGIN Defines */
|
||||||
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
|
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
|
||||||
|
|
|
@ -57,10 +57,10 @@ void Error_Handler(void);
|
||||||
/* USER CODE END EFP */
|
/* USER CODE END EFP */
|
||||||
|
|
||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
#define IMU_TEMP_Pin GPIO_PIN_8
|
|
||||||
#define IMU_TEMP_GPIO_Port GPIOB
|
|
||||||
#define MAG_RST_Pin GPIO_PIN_6
|
#define MAG_RST_Pin GPIO_PIN_6
|
||||||
#define MAG_RST_GPIO_Port GPIOG
|
#define MAG_RST_GPIO_Port GPIOG
|
||||||
|
#define IMU_TEMP_Pin GPIO_PIN_6
|
||||||
|
#define IMU_TEMP_GPIO_Port GPIOF
|
||||||
#define LED_R_Pin GPIO_PIN_12
|
#define LED_R_Pin GPIO_PIN_12
|
||||||
#define LED_R_GPIO_Port GPIOH
|
#define LED_R_GPIO_Port GPIOH
|
||||||
#define INT_MAG_Pin GPIO_PIN_3
|
#define INT_MAG_Pin GPIO_PIN_3
|
||||||
|
@ -76,11 +76,12 @@ void Error_Handler(void);
|
||||||
#define KEY_GPIO_Port GPIOA
|
#define KEY_GPIO_Port GPIOA
|
||||||
#define CS1_ACCEL_Pin GPIO_PIN_4
|
#define CS1_ACCEL_Pin GPIO_PIN_4
|
||||||
#define CS1_ACCEL_GPIO_Port GPIOA
|
#define CS1_ACCEL_GPIO_Port GPIOA
|
||||||
#define INT_ACCEL_Pin GPIO_PIN_4
|
#define INT_ACC_Pin GPIO_PIN_4
|
||||||
#define INT_ACCEL_GPIO_Port GPIOC
|
#define INT_ACC_GPIO_Port GPIOC
|
||||||
#define INT_ACCEL_EXTI_IRQn EXTI4_IRQn
|
#define INT_ACC_EXTI_IRQn EXTI4_IRQn
|
||||||
#define INT_GYRO_Pin GPIO_PIN_5
|
#define INT_GYRO_Pin GPIO_PIN_5
|
||||||
#define INT_GYRO_GPIO_Port GPIOC
|
#define INT_GYRO_GPIO_Port GPIOC
|
||||||
|
#define INT_GYRO_EXTI_IRQn EXTI9_5_IRQn
|
||||||
#define SERVO_Pin GPIO_PIN_9
|
#define SERVO_Pin GPIO_PIN_9
|
||||||
#define SERVO_GPIO_Port GPIOE
|
#define SERVO_GPIO_Port GPIOE
|
||||||
#define CS1_GYRO_Pin GPIO_PIN_0
|
#define CS1_GYRO_Pin GPIO_PIN_0
|
||||||
|
|
|
@ -52,7 +52,6 @@ void MemManage_Handler(void);
|
||||||
void BusFault_Handler(void);
|
void BusFault_Handler(void);
|
||||||
void UsageFault_Handler(void);
|
void UsageFault_Handler(void);
|
||||||
void DebugMon_Handler(void);
|
void DebugMon_Handler(void);
|
||||||
void SysTick_Handler(void);
|
|
||||||
void EXTI3_IRQHandler(void);
|
void EXTI3_IRQHandler(void);
|
||||||
void EXTI4_IRQHandler(void);
|
void EXTI4_IRQHandler(void);
|
||||||
void DMA1_Stream1_IRQHandler(void);
|
void DMA1_Stream1_IRQHandler(void);
|
||||||
|
@ -61,12 +60,14 @@ void DMA1_Stream3_IRQHandler(void);
|
||||||
void DMA1_Stream4_IRQHandler(void);
|
void DMA1_Stream4_IRQHandler(void);
|
||||||
void CAN1_RX0_IRQHandler(void);
|
void CAN1_RX0_IRQHandler(void);
|
||||||
void CAN1_RX1_IRQHandler(void);
|
void CAN1_RX1_IRQHandler(void);
|
||||||
|
void EXTI9_5_IRQHandler(void);
|
||||||
void I2C2_EV_IRQHandler(void);
|
void I2C2_EV_IRQHandler(void);
|
||||||
void I2C2_ER_IRQHandler(void);
|
void I2C2_ER_IRQHandler(void);
|
||||||
void SPI1_IRQHandler(void);
|
void SPI1_IRQHandler(void);
|
||||||
void SPI2_IRQHandler(void);
|
void SPI2_IRQHandler(void);
|
||||||
void USART1_IRQHandler(void);
|
void USART1_IRQHandler(void);
|
||||||
void USART3_IRQHandler(void);
|
void USART3_IRQHandler(void);
|
||||||
|
void TIM8_TRG_COM_TIM14_IRQHandler(void);
|
||||||
void DMA1_Stream7_IRQHandler(void);
|
void DMA1_Stream7_IRQHandler(void);
|
||||||
void DMA2_Stream0_IRQHandler(void);
|
void DMA2_Stream0_IRQHandler(void);
|
||||||
void DMA2_Stream2_IRQHandler(void);
|
void DMA2_Stream2_IRQHandler(void);
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeRTOS Kernel V10.3.1
|
|
||||||
* Copyright (C) 2020 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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,272 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeRTOS Kernel V10.3.1
|
|
||||||
* Copyright (C) 2020 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeRTOS Kernel V10.3.1
|
|
||||||
* Copyright (C) 2020 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,547 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeRTOS Kernel V10.3.1
|
|
||||||
* Copyright (C) 2020 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 calls to allocate and free memory as well as the
|
|
||||||
number of free bytes remaining, but says nothing about fragmentation. */
|
|
||||||
static size_t xFreeBytesRemaining = 0U;
|
|
||||||
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
|
||||||
static size_t xNumberOfSuccessfulAllocations = 0;
|
|
||||||
static size_t xNumberOfSuccessfulFrees = 0;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
xNumberOfSuccessfulAllocations++;
|
|
||||||
}
|
|
||||||
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 ) );
|
|
||||||
xNumberOfSuccessfulFrees++;
|
|
||||||
}
|
|
||||||
( 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 );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortGetHeapStats( HeapStats_t *pxHeapStats )
|
|
||||||
{
|
|
||||||
BlockLink_t *pxBlock;
|
|
||||||
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
|
|
||||||
|
|
||||||
vTaskSuspendAll();
|
|
||||||
{
|
|
||||||
pxBlock = xStart.pxNextFreeBlock;
|
|
||||||
|
|
||||||
/* pxBlock will be NULL if the heap has not been initialised. The heap
|
|
||||||
is initialised automatically when the first allocation is made. */
|
|
||||||
if( pxBlock != NULL )
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Increment the number of blocks and record the largest block seen
|
|
||||||
so far. */
|
|
||||||
xBlocks++;
|
|
||||||
|
|
||||||
if( pxBlock->xBlockSize > xMaxSize )
|
|
||||||
{
|
|
||||||
xMaxSize = pxBlock->xBlockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Heap five will have a zero sized block at the end of each
|
|
||||||
each region - the block is only used to link to the next
|
|
||||||
heap region so it not a real block. */
|
|
||||||
if( pxBlock->xBlockSize != 0 )
|
|
||||||
{
|
|
||||||
if( pxBlock->xBlockSize < xMinSize )
|
|
||||||
{
|
|
||||||
xMinSize = pxBlock->xBlockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next block in the chain until the last block is
|
|
||||||
reached. */
|
|
||||||
pxBlock = pxBlock->pxNextFreeBlock;
|
|
||||||
} while( pxBlock != pxEnd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xTaskResumeAll();
|
|
||||||
|
|
||||||
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
|
|
||||||
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
|
|
||||||
pxHeapStats->xNumberOfFreeBlocks = xBlocks;
|
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
|
|
||||||
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
|
|
||||||
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
|
|
||||||
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
|
|
||||||
}
|
|
||||||
taskEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
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.
|
|
|
@ -1,422 +0,0 @@
|
||||||
|
|
||||||
@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
|
|
||||||
|
|
||||||
=======
|
|
||||||
|
|
||||||
### 31-August-2020 ###
|
|
||||||
=========================
|
|
||||||
+ Bug fix for G0 compilation error due to IRQn_Type mismatch between G0 and other families
|
|
||||||
- Source/CMSIS_RTOS_V2/cmsis_os2.c
|
|
||||||
+ Bug fix when using systick as timebasse for HAL
|
|
||||||
- Source/CMSIS_RTOS_V2/cmsis_os2.c
|
|
||||||
|
|
||||||
### 20-July-2020 ###
|
|
||||||
=========================
|
|
||||||
+ FreeRTOS: Update to FreeRTOS v10.3.1
|
|
||||||
|
|
||||||
+ CMSIS_RTOS_V2: update against the latest CMSIS-FreeRTOS v10.3.0 release
|
|
||||||
- CMSIS_RTOS_V2/cmsis_os2.c
|
|
||||||
- CMSIS_RTOS_V2/freertos_mpool.h
|
|
||||||
- CMSIS_RTOS_V2/freertos_os2.h
|
|
||||||
- CMSIS_RTOS_V2/os_systick.c
|
|
||||||
|
|
||||||
+ Add Tickless Idle support for CM23/CM33
|
|
||||||
- GCC/ARM_CM23/non_secure/port.c
|
|
||||||
- GCC/ARM_CM23/non_secure/portmacro.h
|
|
||||||
- GCC/ARM_CM23_NTZ/non_secure/port.c
|
|
||||||
- GCC/ARM_CM23_NTZ/non_secure/portmacro.h
|
|
||||||
- GCC/ARM_CM33/non_secure/port.c
|
|
||||||
- GCC/ARM_CM33/non_secure/portmacro.h
|
|
||||||
- GCC/ARM_CM33_NTZ/non_secure/port.c
|
|
||||||
- GCC/ARM_CM33_NTZ/non_secure/portmacro.h
|
|
||||||
- IAR/ARM_CM23/non_secure/port.c
|
|
||||||
- IAR/ARM_CM23/non_secure/portmacro.h
|
|
||||||
- IAR/ARM_CM23_NTZ/non_secure/port.c
|
|
||||||
- IAR/ARM_CM23_NTZ/non_secure/portmacro.h
|
|
||||||
- IAR/ARM_CM33/non_secure/port.c
|
|
||||||
- IAR/ARM_CM33/non_secure/portmacro.h
|
|
||||||
- IAR/ARM_CM33_NTZ/non_secure/port.c
|
|
||||||
- IAR/ARM_CM33_NTZ/non_secure/portmacro.h
|
|
||||||
|
|
||||||
+ Fix MPU hardfault bug for Cortex-M4 MPU
|
|
||||||
- GCC\ARM_CM4_MPU\port.c
|
|
||||||
- IAR\ARM_CM4_MPU\port.c
|
|
||||||
- RVDS\ARM_CM4_MPU\port.c
|
|
||||||
|
|
||||||
+ Add support for 16 MPU regions to Cortex-M4 MPU ports
|
|
||||||
- GCC/ARM_CM4_MPU/portmacro.h
|
|
||||||
- IAR/ARM_CM4_MPU/portmacro.h
|
|
||||||
- RVDS/ARM_CM4_MPU/portmacro.h
|
|
||||||
|
|
||||||
+ Update ARM_CM7_MPU source files for all compilers
|
|
||||||
- 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
|
|
||||||
|
|
||||||
### 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>
|
|
||||||
*/
|
|
|
@ -6,7 +6,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
*
|
*
|
||||||
* Copyright (c) 2022 STMicroelectronics.
|
* Copyright (c) 2023 STMicroelectronics.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This software is licensed under terms that can be found in the LICENSE file
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
@ -118,7 +118,6 @@ void MX_FREERTOS_Init(void) {
|
||||||
/* definition and creation of defaultTask */
|
/* definition and creation of defaultTask */
|
||||||
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
|
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
|
||||||
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
|
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
|
||||||
|
|
||||||
osThreadDef(instask, StartINSTASK, osPriorityNormal, 0, 1024);
|
osThreadDef(instask, StartINSTASK, osPriorityNormal, 0, 1024);
|
||||||
defaultTaskHandle = osThreadCreate(osThread(instask), NULL);
|
defaultTaskHandle = osThreadCreate(osThread(instask), NULL);
|
||||||
|
|
||||||
|
@ -130,7 +129,6 @@ void MX_FREERTOS_Init(void) {
|
||||||
|
|
||||||
osThreadDef(robottask, StartROBOTTASK, osPriorityNormal, 0, 1024);
|
osThreadDef(robottask, StartROBOTTASK, osPriorityNormal, 0, 1024);
|
||||||
defaultTaskHandle = osThreadCreate(osThread(robottask), NULL);
|
defaultTaskHandle = osThreadCreate(osThread(robottask), NULL);
|
||||||
|
|
||||||
/* USER CODE BEGIN RTOS_THREADS */
|
/* USER CODE BEGIN RTOS_THREADS */
|
||||||
/* add threads, ... */
|
/* add threads, ... */
|
||||||
/* USER CODE END RTOS_THREADS */
|
/* USER CODE END RTOS_THREADS */
|
||||||
|
@ -152,8 +150,6 @@ void StartDefaultTask(void const * argument)
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
//1kHz
|
|
||||||
led_RGB_flow_task();
|
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
/* USER CODE END StartDefaultTask */
|
/* USER CODE END StartDefaultTask */
|
||||||
|
@ -161,6 +157,7 @@ void StartDefaultTask(void const * argument)
|
||||||
|
|
||||||
/* Private application code --------------------------------------------------*/
|
/* Private application code --------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Application */
|
/* USER CODE BEGIN Application */
|
||||||
|
|
||||||
void StartINSTASK(void const * argument)
|
void StartINSTASK(void const * argument)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -202,6 +199,4 @@ void StartROBOTTASK(void const * argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* USER CODE END Application */
|
/* USER CODE END Application */
|
||||||
|
|
|
@ -56,7 +56,7 @@ void MX_GPIO_Init(void)
|
||||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(MAG_RST_GPIO_Port, MAG_RST_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(MAG_RST_GPIO_Port, MAG_RST_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(CS1_ACCEL_GPIO_Port, CS1_ACCEL_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(CS1_ACCEL_GPIO_Port, CS1_ACCEL_Pin, GPIO_PIN_SET);
|
||||||
|
@ -67,8 +67,8 @@ void MX_GPIO_Init(void)
|
||||||
/*Configure GPIO pin : PtPin */
|
/*Configure GPIO pin : PtPin */
|
||||||
GPIO_InitStruct.Pin = MAG_RST_Pin;
|
GPIO_InitStruct.Pin = MAG_RST_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
HAL_GPIO_Init(MAG_RST_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(MAG_RST_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pin : PtPin */
|
/*Configure GPIO pin : PtPin */
|
||||||
|
@ -91,7 +91,7 @@ void MX_GPIO_Init(void)
|
||||||
HAL_GPIO_Init(CS1_ACCEL_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(CS1_ACCEL_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pins : PCPin PCPin */
|
/*Configure GPIO pins : PCPin PCPin */
|
||||||
GPIO_InitStruct.Pin = INT_ACCEL_Pin|INT_GYRO_Pin;
|
GPIO_InitStruct.Pin = INT_ACC_Pin|INT_GYRO_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||||
|
@ -110,6 +110,9 @@ void MX_GPIO_Init(void)
|
||||||
HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
|
HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
|
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
|
||||||
|
|
||||||
|
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
*
|
*
|
||||||
* Copyright (c) 2022 STMicroelectronics.
|
* Copyright (c) 2023 STMicroelectronics.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This software is licensed under terms that can be found in the LICENSE file
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
@ -21,13 +21,15 @@
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
|
#include "crc.h"
|
||||||
|
#include "dac.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
#include "i2c.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "tim.h"
|
#include "tim.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "i2c.h"
|
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
@ -110,11 +112,14 @@ int main(void)
|
||||||
MX_TIM10_Init();
|
MX_TIM10_Init();
|
||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
MX_USART6_UART_Init();
|
MX_USART6_UART_Init();
|
||||||
|
MX_TIM8_Init();
|
||||||
MX_I2C2_Init();
|
MX_I2C2_Init();
|
||||||
MX_I2C3_Init();
|
MX_I2C3_Init();
|
||||||
|
MX_SPI2_Init();
|
||||||
|
MX_CRC_Init();
|
||||||
|
MX_DAC_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
RobotInit();
|
RobotInit();
|
||||||
|
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Call init function for freertos objects (in freertos.c) */
|
/* Call init function for freertos objects (in freertos.c) */
|
||||||
|
@ -183,6 +188,28 @@ void SystemClock_Config(void)
|
||||||
|
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Period elapsed callback in non blocking mode
|
||||||
|
* @note This function is called when TIM14 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 == TIM14)
|
||||||
|
{
|
||||||
|
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.
|
||||||
* @retval None
|
* @retval None
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_hal_timebase_TIM.c
|
||||||
|
* @brief HAL time base based on the hardware TIM.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx_hal.h"
|
||||||
|
#include "stm32f4xx_hal_tim.h"
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
TIM_HandleTypeDef htim14;
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function configures the TIM14 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 = 0U;
|
||||||
|
|
||||||
|
uint32_t uwPrescalerValue = 0U;
|
||||||
|
uint32_t pFLatency;
|
||||||
|
HAL_StatusTypeDef status;
|
||||||
|
|
||||||
|
/* Enable TIM14 clock */
|
||||||
|
__HAL_RCC_TIM14_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Get clock configuration */
|
||||||
|
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||||
|
|
||||||
|
/* Get APB1 prescaler */
|
||||||
|
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
|
||||||
|
/* Compute TIM14 clock */
|
||||||
|
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
|
||||||
|
{
|
||||||
|
uwTimclock = HAL_RCC_GetPCLK1Freq();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the prescaler value to have TIM14 counter clock equal to 1MHz */
|
||||||
|
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
|
||||||
|
|
||||||
|
/* Initialize TIM14 */
|
||||||
|
htim14.Instance = TIM14;
|
||||||
|
|
||||||
|
/* Initialize TIMx peripheral as follow:
|
||||||
|
+ Period = [(TIM14CLK/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
|
||||||
|
*/
|
||||||
|
htim14.Init.Period = (1000000U / 1000U) - 1U;
|
||||||
|
htim14.Init.Prescaler = uwPrescalerValue;
|
||||||
|
htim14.Init.ClockDivision = 0;
|
||||||
|
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
|
|
||||||
|
status = HAL_TIM_Base_Init(&htim14);
|
||||||
|
if (status == HAL_OK)
|
||||||
|
{
|
||||||
|
/* Start the TIM time Base generation in interrupt mode */
|
||||||
|
status = HAL_TIM_Base_Start_IT(&htim14);
|
||||||
|
if (status == HAL_OK)
|
||||||
|
{
|
||||||
|
/* Enable the TIM14 global Interrupt */
|
||||||
|
HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
|
||||||
|
/* Configure the SysTick IRQ priority */
|
||||||
|
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||||
|
{
|
||||||
|
/* Configure the TIM IRQ priority */
|
||||||
|
HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, TickPriority, 0U);
|
||||||
|
uwTickPrio = TickPriority;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = HAL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend Tick increment.
|
||||||
|
* @note Disable the tick increment by disabling TIM14 update interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SuspendTick(void)
|
||||||
|
{
|
||||||
|
/* Disable TIM14 update Interrupt */
|
||||||
|
__HAL_TIM_DISABLE_IT(&htim14, TIM_IT_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume Tick increment.
|
||||||
|
* @note Enable the tick increment by Enabling TIM14 update interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_ResumeTick(void)
|
||||||
|
{
|
||||||
|
/* Enable TIM14 Update interrupt */
|
||||||
|
__HAL_TIM_ENABLE_IT(&htim14, TIM_IT_UPDATE);
|
||||||
|
}
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "stm32f4xx_it.h"
|
#include "stm32f4xx_it.h"
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
@ -71,6 +69,7 @@ extern DMA_HandleTypeDef hdma_spi2_rx;
|
||||||
extern DMA_HandleTypeDef hdma_spi2_tx;
|
extern DMA_HandleTypeDef hdma_spi2_tx;
|
||||||
extern SPI_HandleTypeDef hspi1;
|
extern SPI_HandleTypeDef hspi1;
|
||||||
extern SPI_HandleTypeDef hspi2;
|
extern SPI_HandleTypeDef hspi2;
|
||||||
|
extern TIM_HandleTypeDef htim8;
|
||||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||||||
extern DMA_HandleTypeDef hdma_usart3_rx;
|
extern DMA_HandleTypeDef hdma_usart3_rx;
|
||||||
|
@ -79,6 +78,8 @@ extern DMA_HandleTypeDef hdma_usart6_tx;
|
||||||
extern UART_HandleTypeDef huart1;
|
extern UART_HandleTypeDef huart1;
|
||||||
extern UART_HandleTypeDef huart3;
|
extern UART_HandleTypeDef huart3;
|
||||||
extern UART_HandleTypeDef huart6;
|
extern UART_HandleTypeDef huart6;
|
||||||
|
extern TIM_HandleTypeDef htim14;
|
||||||
|
|
||||||
/* USER CODE BEGIN EV */
|
/* USER CODE BEGIN EV */
|
||||||
|
|
||||||
/* USER CODE END EV */
|
/* USER CODE END EV */
|
||||||
|
@ -107,14 +108,11 @@ void NMI_Handler(void)
|
||||||
void HardFault_Handler(void)
|
void HardFault_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||||
// 发生hardfault,点击step over会自动跳转回出错的指令,方便调试
|
|
||||||
asm("bx lr");
|
asm("bx lr");
|
||||||
/* USER CODE END HardFault_IRQn 0 */
|
/* USER CODE END HardFault_IRQn 0 */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
asm("bx lr");
|
|
||||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,28 +175,6 @@ void DebugMon_Handler(void)
|
||||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
/* USER CODE END DebugMonitor_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();
|
|
||||||
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
|
|
||||||
{
|
|
||||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
|
||||||
xPortSysTickHandler();
|
|
||||||
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
|
||||||
}
|
|
||||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
|
||||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* STM32F4xx Peripheral Interrupt Handlers */
|
/* STM32F4xx Peripheral Interrupt Handlers */
|
||||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||||
|
@ -228,7 +204,7 @@ void EXTI4_IRQHandler(void)
|
||||||
/* USER CODE BEGIN EXTI4_IRQn 0 */
|
/* USER CODE BEGIN EXTI4_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END EXTI4_IRQn 0 */
|
/* USER CODE END EXTI4_IRQn 0 */
|
||||||
HAL_GPIO_EXTI_IRQHandler(INT_ACCEL_Pin);
|
HAL_GPIO_EXTI_IRQHandler(INT_ACC_Pin);
|
||||||
/* USER CODE BEGIN EXTI4_IRQn 1 */
|
/* USER CODE BEGIN EXTI4_IRQn 1 */
|
||||||
|
|
||||||
/* USER CODE END EXTI4_IRQn 1 */
|
/* USER CODE END EXTI4_IRQn 1 */
|
||||||
|
@ -318,6 +294,20 @@ void CAN1_RX1_IRQHandler(void)
|
||||||
/* USER CODE END CAN1_RX1_IRQn 1 */
|
/* USER CODE END CAN1_RX1_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles EXTI line[9:5] interrupts.
|
||||||
|
*/
|
||||||
|
void EXTI9_5_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END EXTI9_5_IRQn 0 */
|
||||||
|
HAL_GPIO_EXTI_IRQHandler(INT_GYRO_Pin);
|
||||||
|
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END EXTI9_5_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles I2C2 event interrupt.
|
* @brief This function handles I2C2 event interrupt.
|
||||||
*/
|
*/
|
||||||
|
@ -402,6 +392,21 @@ void USART3_IRQHandler(void)
|
||||||
/* USER CODE END USART3_IRQn 1 */
|
/* USER CODE END USART3_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles TIM8 trigger and commutation interrupts and TIM14 global interrupt.
|
||||||
|
*/
|
||||||
|
void TIM8_TRG_COM_TIM14_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 0 */
|
||||||
|
HAL_TIM_IRQHandler(&htim8);
|
||||||
|
HAL_TIM_IRQHandler(&htim14);
|
||||||
|
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles DMA1 stream7 global interrupt.
|
* @brief This function handles DMA1 stream7 global interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -320,9 +320,9 @@ void MX_TIM10_Init(void)
|
||||||
|
|
||||||
/* USER CODE END TIM10_Init 1 */
|
/* USER CODE END TIM10_Init 1 */
|
||||||
htim10.Instance = TIM10;
|
htim10.Instance = TIM10;
|
||||||
htim10.Init.Prescaler = 0;
|
htim10.Init.Prescaler = 167;
|
||||||
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
|
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
htim10.Init.Period = 4999;
|
htim10.Init.Period = 5000-1;
|
||||||
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||||
htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
|
if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
|
||||||
|
@ -391,6 +391,10 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||||
/* USER CODE END TIM8_MspInit 0 */
|
/* USER CODE END TIM8_MspInit 0 */
|
||||||
/* TIM8 clock enable */
|
/* TIM8 clock enable */
|
||||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* TIM8 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 15, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
|
||||||
/* USER CODE BEGIN TIM8_MspInit 1 */
|
/* USER CODE BEGIN TIM8_MspInit 1 */
|
||||||
|
|
||||||
/* USER CODE END TIM8_MspInit 1 */
|
/* USER CODE END TIM8_MspInit 1 */
|
||||||
|
@ -515,9 +519,9 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
|
||||||
|
|
||||||
/* USER CODE END TIM10_MspPostInit 0 */
|
/* USER CODE END TIM10_MspPostInit 0 */
|
||||||
|
|
||||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||||
/**TIM10 GPIO Configuration
|
/**TIM10 GPIO Configuration
|
||||||
PB8 ------> TIM10_CH1
|
PF6 ------> TIM10_CH1
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = IMU_TEMP_Pin;
|
GPIO_InitStruct.Pin = IMU_TEMP_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
@ -576,6 +580,9 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||||
/* USER CODE END TIM8_MspDeInit 0 */
|
/* USER CODE END TIM8_MspDeInit 0 */
|
||||||
/* Peripheral clock disable */
|
/* Peripheral clock disable */
|
||||||
__HAL_RCC_TIM8_CLK_DISABLE();
|
__HAL_RCC_TIM8_CLK_DISABLE();
|
||||||
|
|
||||||
|
/* TIM8 interrupt Deinit */
|
||||||
|
HAL_NVIC_DisableIRQ(TIM8_TRG_COM_TIM14_IRQn);
|
||||||
/* USER CODE BEGIN TIM8_MspDeInit 1 */
|
/* USER CODE BEGIN TIM8_MspDeInit 1 */
|
||||||
|
|
||||||
/* USER CODE END TIM8_MspDeInit 1 */
|
/* USER CODE END TIM8_MspDeInit 1 */
|
||||||
|
|
9
Makefile
9
Makefile
|
@ -39,10 +39,13 @@ BUILD_DIR = build
|
||||||
C_SOURCES = \
|
C_SOURCES = \
|
||||||
HAL_N_Middlewares/Src/main.c \
|
HAL_N_Middlewares/Src/main.c \
|
||||||
HAL_N_Middlewares/Src/gpio.c \
|
HAL_N_Middlewares/Src/gpio.c \
|
||||||
HAL_N_Middlewares/Src/i2c.c \
|
HAL_N_Middlewares/Src/freertos.c \
|
||||||
HAL_N_Middlewares/Src/adc.c \
|
HAL_N_Middlewares/Src/adc.c \
|
||||||
HAL_N_Middlewares/Src/can.c \
|
HAL_N_Middlewares/Src/can.c \
|
||||||
|
HAL_N_Middlewares/Src/crc.c \
|
||||||
|
HAL_N_Middlewares/Src/dac.c \
|
||||||
HAL_N_Middlewares/Src/dma.c \
|
HAL_N_Middlewares/Src/dma.c \
|
||||||
|
HAL_N_Middlewares/Src/i2c.c \
|
||||||
HAL_N_Middlewares/Src/rng.c \
|
HAL_N_Middlewares/Src/rng.c \
|
||||||
HAL_N_Middlewares/Src/rtc.c \
|
HAL_N_Middlewares/Src/rtc.c \
|
||||||
HAL_N_Middlewares/Src/spi.c \
|
HAL_N_Middlewares/Src/spi.c \
|
||||||
|
@ -54,8 +57,10 @@ HAL_N_Middlewares/Src/usbd_desc.c \
|
||||||
HAL_N_Middlewares/Src/usbd_cdc_if.c \
|
HAL_N_Middlewares/Src/usbd_cdc_if.c \
|
||||||
HAL_N_Middlewares/Src/stm32f4xx_it.c \
|
HAL_N_Middlewares/Src/stm32f4xx_it.c \
|
||||||
HAL_N_Middlewares/Src/stm32f4xx_hal_msp.c \
|
HAL_N_Middlewares/Src/stm32f4xx_hal_msp.c \
|
||||||
|
HAL_N_Middlewares/Src/stm32f4xx_hal_timebase_tim.c \
|
||||||
HAL_N_Middlewares/Src/system_stm32f4xx.c \
|
HAL_N_Middlewares/Src/system_stm32f4xx.c \
|
||||||
HAL_N_Middlewares/Src/freertos.c \
|
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c \
|
||||||
|
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c \
|
||||||
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \
|
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \
|
||||||
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \
|
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \
|
||||||
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \
|
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
void RobotInit()
|
void RobotInit()
|
||||||
{
|
{
|
||||||
// 关闭中断,防止在初始化过程中发生中断
|
// 关闭中断,防止在初始化过程中发生中断
|
||||||
// 请不要在初始化过程中使用中断!!!
|
// 请不要在初始化过程中使用中断和延时函数!
|
||||||
|
// 若必须,则只允许使用DWT_Delay()
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
|
|
||||||
BSPInit();
|
BSPInit();
|
||||||
|
|
||||||
#if defined(ONE_BOARD) || defined(GIMBAL_BOARD)
|
#if defined(ONE_BOARD) || defined(GIMBAL_BOARD)
|
||||||
|
|
|
@ -208,30 +208,30 @@ Mcu.IP9=NVIC
|
||||||
Mcu.IPNb=26
|
Mcu.IPNb=26
|
||||||
Mcu.Name=STM32F407I(E-G)Hx
|
Mcu.Name=STM32F407I(E-G)Hx
|
||||||
Mcu.Package=UFBGA176
|
Mcu.Package=UFBGA176
|
||||||
Mcu.Pin0=PB8
|
Mcu.Pin0=PB5
|
||||||
Mcu.Pin1=PB5
|
Mcu.Pin1=PG14
|
||||||
Mcu.Pin10=PC11
|
Mcu.Pin10=PC10
|
||||||
Mcu.Pin11=PC10
|
Mcu.Pin11=PA12
|
||||||
Mcu.Pin12=PA12
|
Mcu.Pin12=PI7
|
||||||
Mcu.Pin13=PI7
|
Mcu.Pin13=PI6
|
||||||
Mcu.Pin14=PI6
|
Mcu.Pin14=PG9
|
||||||
Mcu.Pin15=PG9
|
Mcu.Pin15=PD1
|
||||||
Mcu.Pin16=PD1
|
Mcu.Pin16=PA11
|
||||||
Mcu.Pin17=PA11
|
Mcu.Pin17=PF0
|
||||||
Mcu.Pin18=PF0
|
Mcu.Pin18=PA9
|
||||||
Mcu.Pin19=PA9
|
Mcu.Pin19=PC9
|
||||||
Mcu.Pin2=PG14
|
Mcu.Pin2=PB4
|
||||||
Mcu.Pin20=PC9
|
Mcu.Pin20=PA8
|
||||||
Mcu.Pin21=PA8
|
Mcu.Pin21=PH0-OSC_IN
|
||||||
Mcu.Pin22=PH0-OSC_IN
|
Mcu.Pin22=PH1-OSC_OUT
|
||||||
Mcu.Pin23=PH1-OSC_OUT
|
Mcu.Pin23=PF1
|
||||||
Mcu.Pin24=PF1
|
Mcu.Pin24=PC6
|
||||||
Mcu.Pin25=PC6
|
Mcu.Pin25=PG6
|
||||||
Mcu.Pin26=PG6
|
Mcu.Pin26=PF6
|
||||||
Mcu.Pin27=PH12
|
Mcu.Pin27=PH12
|
||||||
Mcu.Pin28=PG3
|
Mcu.Pin28=PG3
|
||||||
Mcu.Pin29=PH11
|
Mcu.Pin29=PH11
|
||||||
Mcu.Pin3=PB4
|
Mcu.Pin3=PB3
|
||||||
Mcu.Pin30=PH10
|
Mcu.Pin30=PH10
|
||||||
Mcu.Pin31=PD14
|
Mcu.Pin31=PD14
|
||||||
Mcu.Pin32=PA0-WKUP
|
Mcu.Pin32=PA0-WKUP
|
||||||
|
@ -242,7 +242,7 @@ Mcu.Pin36=PA5
|
||||||
Mcu.Pin37=PC5
|
Mcu.Pin37=PC5
|
||||||
Mcu.Pin38=PE9
|
Mcu.Pin38=PE9
|
||||||
Mcu.Pin39=PE11
|
Mcu.Pin39=PE11
|
||||||
Mcu.Pin4=PB3
|
Mcu.Pin4=PA14
|
||||||
Mcu.Pin40=PE14
|
Mcu.Pin40=PE14
|
||||||
Mcu.Pin41=PB13
|
Mcu.Pin41=PB13
|
||||||
Mcu.Pin42=PA7
|
Mcu.Pin42=PA7
|
||||||
|
@ -253,10 +253,10 @@ Mcu.Pin46=VP_ADC1_TempSens_Input
|
||||||
Mcu.Pin47=VP_ADC1_Vref_Input
|
Mcu.Pin47=VP_ADC1_Vref_Input
|
||||||
Mcu.Pin48=VP_CRC_VS_CRC
|
Mcu.Pin48=VP_CRC_VS_CRC
|
||||||
Mcu.Pin49=VP_FREERTOS_VS_CMSIS_V1
|
Mcu.Pin49=VP_FREERTOS_VS_CMSIS_V1
|
||||||
Mcu.Pin5=PA14
|
Mcu.Pin5=PA13
|
||||||
Mcu.Pin50=VP_RNG_VS_RNG
|
Mcu.Pin50=VP_RNG_VS_RNG
|
||||||
Mcu.Pin51=VP_RTC_VS_RTC_Activate
|
Mcu.Pin51=VP_RTC_VS_RTC_Activate
|
||||||
Mcu.Pin52=VP_SYS_VS_Systick
|
Mcu.Pin52=VP_SYS_VS_tim14
|
||||||
Mcu.Pin53=VP_TIM1_VS_ClockSourceINT
|
Mcu.Pin53=VP_TIM1_VS_ClockSourceINT
|
||||||
Mcu.Pin54=VP_TIM4_VS_ClockSourceINT
|
Mcu.Pin54=VP_TIM4_VS_ClockSourceINT
|
||||||
Mcu.Pin55=VP_TIM5_VS_ClockSourceINT
|
Mcu.Pin55=VP_TIM5_VS_ClockSourceINT
|
||||||
|
@ -264,10 +264,10 @@ Mcu.Pin56=VP_TIM8_VS_ClockSourceINT
|
||||||
Mcu.Pin57=VP_TIM10_VS_ClockSourceINT
|
Mcu.Pin57=VP_TIM10_VS_ClockSourceINT
|
||||||
Mcu.Pin58=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
Mcu.Pin58=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||||
Mcu.Pin59=VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0
|
Mcu.Pin59=VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0
|
||||||
Mcu.Pin6=PA13
|
Mcu.Pin6=PB7
|
||||||
Mcu.Pin7=PB7
|
Mcu.Pin7=PB6
|
||||||
Mcu.Pin8=PB6
|
Mcu.Pin8=PD0
|
||||||
Mcu.Pin9=PD0
|
Mcu.Pin9=PC11
|
||||||
Mcu.PinsNb=60
|
Mcu.PinsNb=60
|
||||||
Mcu.ThirdParty0=STMicroelectronics.X-CUBE-ALGOBUILD.1.3.0
|
Mcu.ThirdParty0=STMicroelectronics.X-CUBE-ALGOBUILD.1.3.0
|
||||||
Mcu.ThirdPartyNb=1
|
Mcu.ThirdPartyNb=1
|
||||||
|
@ -289,7 +289,7 @@ NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
NVIC.DMA2_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true\:true
|
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream6_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
NVIC.DMA2_Stream6_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||||
|
@ -313,7 +313,10 @@ NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
|
||||||
NVIC.SavedPendsvIrqHandlerGenerated=true
|
NVIC.SavedPendsvIrqHandlerGenerated=true
|
||||||
NVIC.SavedSvcallIrqHandlerGenerated=true
|
NVIC.SavedSvcallIrqHandlerGenerated=true
|
||||||
NVIC.SavedSystickIrqHandlerGenerated=true
|
NVIC.SavedSystickIrqHandlerGenerated=true
|
||||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:false
|
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
|
||||||
|
NVIC.TIM8_TRG_COM_TIM14_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
|
||||||
|
NVIC.TimeBase=TIM8_TRG_COM_TIM14_IRQn
|
||||||
|
NVIC.TimeBaseIP=TIM14
|
||||||
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||||
NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||||
NVIC.USART6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
NVIC.USART6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||||
|
@ -344,6 +347,7 @@ PA7.GPIO_PuPd=GPIO_PULLUP
|
||||||
PA7.Locked=true
|
PA7.Locked=true
|
||||||
PA7.Mode=Full_Duplex_Master
|
PA7.Mode=Full_Duplex_Master
|
||||||
PA7.Signal=SPI1_MOSI
|
PA7.Signal=SPI1_MOSI
|
||||||
|
PA8.Locked=true
|
||||||
PA8.Mode=I2C
|
PA8.Mode=I2C
|
||||||
PA8.Signal=I2C3_SCL
|
PA8.Signal=I2C3_SCL
|
||||||
PA9.Locked=true
|
PA9.Locked=true
|
||||||
|
@ -384,12 +388,6 @@ PB6.Signal=CAN2_TX
|
||||||
PB7.Locked=true
|
PB7.Locked=true
|
||||||
PB7.Mode=Asynchronous
|
PB7.Mode=Asynchronous
|
||||||
PB7.Signal=USART1_RX
|
PB7.Signal=USART1_RX
|
||||||
PB8.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
|
||||||
PB8.GPIO_Label=IMU_TEMP
|
|
||||||
PB8.GPIO_PuPd=GPIO_PULLUP
|
|
||||||
PB8.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
|
||||||
PB8.Locked=true
|
|
||||||
PB8.Signal=S_TIM10_CH1
|
|
||||||
PC10.Locked=true
|
PC10.Locked=true
|
||||||
PC10.Mode=Asynchronous
|
PC10.Mode=Asynchronous
|
||||||
PC10.Signal=USART3_TX
|
PC10.Signal=USART3_TX
|
||||||
|
@ -434,6 +432,12 @@ PF0.Mode=I2C
|
||||||
PF0.Signal=I2C2_SDA
|
PF0.Signal=I2C2_SDA
|
||||||
PF1.Mode=I2C
|
PF1.Mode=I2C
|
||||||
PF1.Signal=I2C2_SCL
|
PF1.Signal=I2C2_SCL
|
||||||
|
PF6.GPIOParameters=GPIO_Label,GPIO_Speed,GPIO_PuPd
|
||||||
|
PF6.GPIO_Label=IMU_TEMP
|
||||||
|
PF6.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PF6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PF6.Locked=true
|
||||||
|
PF6.Signal=S_TIM10_CH1
|
||||||
PG14.Locked=true
|
PG14.Locked=true
|
||||||
PG14.Mode=Asynchronous
|
PG14.Mode=Asynchronous
|
||||||
PG14.Signal=USART6_TX
|
PG14.Signal=USART6_TX
|
||||||
|
@ -443,12 +447,9 @@ PG3.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
|
||||||
PG3.GPIO_PuPd=GPIO_PULLUP
|
PG3.GPIO_PuPd=GPIO_PULLUP
|
||||||
PG3.Locked=true
|
PG3.Locked=true
|
||||||
PG3.Signal=GPXTI3
|
PG3.Signal=GPXTI3
|
||||||
PG6.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
PG6.GPIOParameters=GPIO_Label
|
||||||
PG6.GPIO_Label=MAG_RST
|
PG6.GPIO_Label=MAG_RST
|
||||||
PG6.GPIO_PuPd=GPIO_PULLUP
|
|
||||||
PG6.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
|
|
||||||
PG6.Locked=true
|
PG6.Locked=true
|
||||||
PG6.PinState=GPIO_PIN_SET
|
|
||||||
PG6.Signal=GPIO_Output
|
PG6.Signal=GPIO_Output
|
||||||
PG9.Locked=true
|
PG9.Locked=true
|
||||||
PG9.Mode=Asynchronous
|
PG9.Mode=Asynchronous
|
||||||
|
@ -606,8 +607,8 @@ TIM1.Period=19999
|
||||||
TIM1.Prescaler=167
|
TIM1.Prescaler=167
|
||||||
TIM10.Channel=TIM_CHANNEL_1
|
TIM10.Channel=TIM_CHANNEL_1
|
||||||
TIM10.IPParameters=Period,Channel,Prescaler
|
TIM10.IPParameters=Period,Channel,Prescaler
|
||||||
TIM10.Period=4999
|
TIM10.Period=5000-1
|
||||||
TIM10.Prescaler=0
|
TIM10.Prescaler=167
|
||||||
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||||
TIM4.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period
|
TIM4.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period
|
||||||
TIM4.Period=65535
|
TIM4.Period=65535
|
||||||
|
@ -653,8 +654,8 @@ VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
|
||||||
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
|
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
|
||||||
VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0.Mode=DSPOoLibraryJjLibrary
|
VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0.Mode=DSPOoLibraryJjLibrary
|
||||||
VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0.Signal=STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0
|
VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0.Signal=STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.3.0_1.3.0
|
||||||
VP_SYS_VS_Systick.Mode=SysTick
|
VP_SYS_VS_tim14.Mode=TIM14
|
||||||
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
VP_SYS_VS_tim14.Signal=SYS_VS_tim14
|
||||||
VP_TIM10_VS_ClockSourceINT.Mode=Enable_Timer
|
VP_TIM10_VS_ClockSourceINT.Mode=Enable_Timer
|
||||||
VP_TIM10_VS_ClockSourceINT.Signal=TIM10_VS_ClockSourceINT
|
VP_TIM10_VS_ClockSourceINT.Signal=TIM10_VS_ClockSourceINT
|
||||||
VP_TIM1_VS_ClockSourceINT.Mode=Internal
|
VP_TIM1_VS_ClockSourceINT.Mode=Internal
|
||||||
|
|
|
@ -23,7 +23,7 @@ typedef struct _
|
||||||
uint8_t rx_len; // 接收长度,可能为0-8
|
uint8_t rx_len; // 接收长度,可能为0-8
|
||||||
// 接收的回调函数,用于解析接收到的数据
|
// 接收的回调函数,用于解析接收到的数据
|
||||||
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
|
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
|
||||||
void *id; // 使用can外设的
|
void *id; // 使用can外设的模块指针(即id指向的模块拥有此can实例,是父子关系)
|
||||||
} CANInstance;
|
} CANInstance;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
|
@ -128,10 +128,11 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||||
if (spi_instance[i]->spi_handle == hspi && // 显然同一时间一条总线只能有一个从机在接收数据
|
if (spi_instance[i]->spi_handle == hspi && // 显然同一时间一条总线只能有一个从机在接收数据
|
||||||
HAL_GPIO_ReadPin(spi_instance[i]->GPIO_cs, spi_instance[i]->cs_pin) == GPIO_PIN_RESET)
|
HAL_GPIO_ReadPin(spi_instance[i]->GPIO_cs, spi_instance[i]->cs_pin) == GPIO_PIN_RESET)
|
||||||
{
|
{
|
||||||
|
// 先拉高片选,结束传输,在判断是否有回调函数,如果有则调用回调函数
|
||||||
|
HAL_GPIO_WritePin(spi_instance[i]->GPIO_cs, spi_instance[i]->cs_pin, GPIO_PIN_SET);
|
||||||
if (spi_instance[i]->callback != NULL) // 回调函数不为空, 则调用回调函数
|
if (spi_instance[i]->callback != NULL) // 回调函数不为空, 则调用回调函数
|
||||||
{
|
{
|
||||||
// 先拉高片选,结束传输
|
|
||||||
HAL_GPIO_WritePin(spi_instance[i]->GPIO_cs, spi_instance[i]->cs_pin, GPIO_PIN_SET);
|
|
||||||
spi_instance[i]->callback(spi_instance[i]);
|
spi_instance[i]->callback(spi_instance[i]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "bsp_usb.h"
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include "usb_device.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
#include "usbd_conf.h"
|
||||||
|
#include "usbd_desc.h"
|
||||||
|
|
|
@ -3,3 +3,170 @@
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#define REG 0
|
||||||
|
#define DATA 1
|
||||||
|
#define ERROR 2
|
||||||
|
// BMI088初始化配置数组for accel,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||||
|
static uint8_t BMI088_Accel_Init_Table[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
||||||
|
{
|
||||||
|
{BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
||||||
|
{BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
||||||
|
{BMI088_ACC_CONF, BMI088_ACC_NORMAL | BMI088_ACC_800_HZ | BMI088_ACC_CONF_MUST_Set, BMI088_ACC_CONF_ERROR},
|
||||||
|
{BMI088_ACC_RANGE, BMI088_ACC_RANGE_6G, BMI088_ACC_RANGE_ERROR},
|
||||||
|
{BMI088_INT1_IO_CTRL, BMI088_ACC_INT1_IO_ENABLE | BMI088_ACC_INT1_GPIO_PP | BMI088_ACC_INT1_GPIO_LOW, BMI088_INT1_IO_CTRL_ERROR},
|
||||||
|
{BMI088_INT_MAP_DATA, BMI088_ACC_INT1_DRDY_INTERRUPT, BMI088_INT_MAP_DATA_ERROR}};
|
||||||
|
// BMI088初始化配置数组for gyro,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||||
|
static uint8_t BMI088_Gyro_Init_Table[BMI088_WRITE_GYRO_REG_NUM][3] =
|
||||||
|
{
|
||||||
|
{BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
||||||
|
{BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
||||||
|
{BMI088_GYRO_LPM1, BMI088_GYRO_NORMAL_MODE, BMI088_GYRO_LPM1_ERROR},
|
||||||
|
{BMI088_GYRO_CTRL, BMI088_DRDY_ON, BMI088_GYRO_CTRL_ERROR},
|
||||||
|
{BMI088_GYRO_INT3_INT4_IO_CONF, BMI088_GYRO_INT3_GPIO_PP | BMI088_GYRO_INT3_GPIO_LOW, BMI088_GYRO_INT3_INT4_IO_CONF_ERROR},
|
||||||
|
{BMI088_GYRO_INT3_INT4_IO_MAP, BMI088_GYRO_DRDY_IO_INT3, BMI088_GYRO_INT3_INT4_IO_MAP_ERROR}};
|
||||||
|
// @attention : 以上两个数组配合各自的初始化函数使用. 若要修改请参照BMI088 datasheet
|
||||||
|
|
||||||
|
// ---------------------------以下私有函数,用于读写BMI088寄存器--------------------------------//
|
||||||
|
/**
|
||||||
|
* @brief 读取BMI088寄存器Accel
|
||||||
|
*
|
||||||
|
* @param bmi088 待读取的BMI088实例
|
||||||
|
* @param reg 待读取的寄存器地址
|
||||||
|
* @param dataptr 读取到的数据存放的指针
|
||||||
|
* @param len 读取长度
|
||||||
|
*/
|
||||||
|
static void BMI088AccelRead(BMI088Instance *bmi088, uint8_t reg, uint8_t *dataptr, uint8_t len)
|
||||||
|
{
|
||||||
|
static uint8_t tx[8] = {0x80, 0}; // 读取,第一个字节为0x80 | reg,第二个是dummy data
|
||||||
|
tx[0] |= reg;
|
||||||
|
SPITransRecv(bmi088->spi_acc, dataptr, tx, 2); // 第一个先发送reg地址,第二个发送dummy data
|
||||||
|
SPIRecv(bmi088->spi_acc, dataptr, len); // 第三个开始发送数据,别担心,会覆盖掉前面的数据(2个字节)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 读取BMI088寄存器Gyro
|
||||||
|
*
|
||||||
|
* @param bmi088 待读取的BMI088实例
|
||||||
|
* @param reg 待读取的寄存器地址
|
||||||
|
* @param dataptr 读取到的数据存放的指针
|
||||||
|
* @param len 读取长度
|
||||||
|
*/
|
||||||
|
static void BMI088GyroRead(BMI088Instance *bmi088, uint8_t reg, uint8_t *dataptr, uint8_t len)
|
||||||
|
{
|
||||||
|
static uint8_t tx = 0x80; // 读取,第一个字节为0x80 | reg
|
||||||
|
tx |= reg;
|
||||||
|
SPITransRecv(bmi088->spi_gyro, dataptr, &tx, 1); // 发送reg地址
|
||||||
|
SPIRecv(bmi088->spi_gyro, dataptr, len); // 别担心,会覆盖掉前面的数据(1个字节)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 写accel寄存器.对spitransmit形式上的封装
|
||||||
|
* @attention 只会向目标reg写入一个字节,因为只有1个字节所以直接传值(指针是32位反而浪费)
|
||||||
|
*
|
||||||
|
* @param bmi088 待写入的BMI088实例
|
||||||
|
* @param reg 待写入的寄存器地址
|
||||||
|
* @param data 待写入的数据(注意不是指针)
|
||||||
|
*/
|
||||||
|
static void BMI088AccelWrite(BMI088Instance *bmi088, uint8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
SPITransmit(bmi088->spi_acc, &data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 写gyro寄存器.形式上的封装
|
||||||
|
* @attention 只会向目标reg写入一个字节,因为只有1个字节所以直接传值(指针是32位反而浪费)
|
||||||
|
*
|
||||||
|
* @param bmi088 待写入的BMI088实例
|
||||||
|
* @param reg 待写入的寄存器地址
|
||||||
|
* @param data 待写入的数据(注意不是指针)
|
||||||
|
*/
|
||||||
|
static void BMI088GyroWrite(BMI088Instance *bmi088, uint8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
SPITransmit(bmi088->spi_gyro, &data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------以上为私有函数,用于读写BMI088寄存器--------------------------------//
|
||||||
|
|
||||||
|
// -------------------------以下为私有函数,用于初始化BMI088acc和gyro--------------------------------//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化BMI088加速度计,提高可读性分拆功能
|
||||||
|
*
|
||||||
|
* @param bmi088 待初始化的BMI088实例
|
||||||
|
* @return uint8_t ERROR CODE if any problems here
|
||||||
|
*/
|
||||||
|
static uint8_t BMI088AccelInit(BMI088Instance *bmi088)
|
||||||
|
{
|
||||||
|
// 后续添加reset和通信检查
|
||||||
|
// code to go here ...
|
||||||
|
|
||||||
|
// 检查ID,如果不是0x1E(bmi088 whoami寄存器值),则返回错误
|
||||||
|
uint8_t whoami_check = 0;
|
||||||
|
BMI088AccelRead(bmi088, BMI088_ACC_CHIP_ID, &whoami_check, 1);
|
||||||
|
if (whoami_check != BMI088_ACC_CHIP_ID_VALUE)
|
||||||
|
return BMI088_NO_SENSOR;
|
||||||
|
|
||||||
|
// 初始化寄存器,提高可读性
|
||||||
|
uint8_t reg = 0;
|
||||||
|
uint8_t data = 1;
|
||||||
|
uint8_t error = 2;
|
||||||
|
// 使用sizeof而不是magic number,这样如果修改了数组大小,不用修改这里的代码;或者使用宏定义
|
||||||
|
for (uint8_t i = 0; i < sizeof(BMI088_Accel_Init_Table) / sizeof(BMI088_Accel_Init_Table[0]); i++)
|
||||||
|
{
|
||||||
|
reg = BMI088_Accel_Init_Table[i][REG];
|
||||||
|
data = BMI088_Accel_Init_Table[i][DATA];
|
||||||
|
BMI088AccelWrite(bmi088, reg, data); // 写入寄存器
|
||||||
|
BMI088AccelRead(bmi088, reg, &data, 1); // 写完之后立刻读回检查
|
||||||
|
if (data != BMI088_Accel_Init_Table[i][DATA])
|
||||||
|
error |= BMI088_Accel_Init_Table[i][ERROR];
|
||||||
|
//{i--;} 可以设置retry次数,如果retry次数用完了,则返回error
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化BMI088陀螺仪,提高可读性分拆功能
|
||||||
|
*
|
||||||
|
* @param bmi088 待初始化的BMI088实例
|
||||||
|
* @return uint8_t ERROR CODE
|
||||||
|
*/
|
||||||
|
static uint8_t BMI088GyroInit(BMI088Instance *bmi088)
|
||||||
|
{
|
||||||
|
// 后续添加reset和通信检查
|
||||||
|
// code to go here ...
|
||||||
|
|
||||||
|
// 检查ID,如果不是0x0F(bmi088 whoami寄存器值),则返回错误
|
||||||
|
uint8_t whoami_check = 0;
|
||||||
|
BMI088GyroRead(bmi088, BMI088_GYRO_CHIP_ID, &whoami_check, 1);
|
||||||
|
if (whoami_check != BMI088_GYRO_CHIP_ID_VALUE)
|
||||||
|
return BMI088_NO_SENSOR;
|
||||||
|
|
||||||
|
// 初始化寄存器,提高可读性
|
||||||
|
uint8_t reg = 0;
|
||||||
|
uint8_t data = 1;
|
||||||
|
uint8_t error = 2;
|
||||||
|
// 使用sizeof而不是magic number,这样如果修改了数组大小,不用修改这里的代码;或者使用宏定义
|
||||||
|
for (uint8_t i = 0; i < sizeof(BMI088_Gyro_Init_Table) / sizeof(BMI088_Gyro_Init_Table[0]); i++)
|
||||||
|
{
|
||||||
|
reg = BMI088_Gyro_Init_Table[i][REG];
|
||||||
|
data = BMI088_Gyro_Init_Table[i][DATA];
|
||||||
|
BMI088GyroWrite(bmi088, reg, data); // 写入寄存器
|
||||||
|
BMI088GyroRead(bmi088, reg, &data, 1); // 写完之后立刻读回检查
|
||||||
|
if (data != BMI088_Gyro_Init_Table[i][DATA])
|
||||||
|
error |= BMI088_Gyro_Init_Table[i][ERROR];
|
||||||
|
//{i--;} 可以设置retry次数,如果retry次数用完了,则返回error
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
// -------------------------以上为私有函数,用于初始化BMI088acc和gyro--------------------------------//
|
||||||
|
|
||||||
|
// 考虑阻塞模式和非阻塞模式的兼容性,通过条件编译(则需要在编译前修改宏定义)或runtime参数判断
|
||||||
|
// runtime的开销不大(一次性判断),但是需要修改函数原型,增加参数,代码长度增加(但不多)
|
||||||
|
// runtime如何修改callback?根据参数选择是否给spi传入callback,如果是阻塞模式,则不传入callback,如果是非阻塞模式,则传入callback(bsp会检查是否NULL)
|
||||||
|
// 条件编译的开销小,但是需要修改宏定义,增加编译时间,同时人力介入
|
||||||
|
// 根据实际情况选择(说了和没说一样!)
|
||||||
|
|
||||||
|
BMI088Instance *BMI088Register(BMI088_Init_Config_s *config)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __BMI088_H__
|
#ifndef __BMI088_H__ // 防止重复包含
|
||||||
#define __BMI088_H__
|
#define __BMI088_H__
|
||||||
|
|
||||||
#include "bsp_spi.h"
|
#include "bsp_spi.h"
|
||||||
|
@ -7,17 +7,30 @@
|
||||||
#include "bsp_pwm.h"
|
#include "bsp_pwm.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#define BMI088_PRE_CALI_ACC_X_OFFSET 0.0f
|
||||||
|
#define BMI088_PRE_CALI_ACC_Y_OFFSET 0.0f
|
||||||
|
// macro to go here... 预设标定参数
|
||||||
|
|
||||||
|
// bmi088工作模式枚举
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BMI088_BLOCK_PERIODIC_MODE = 0, // 阻塞模式,周期性读取
|
||||||
|
BMI088_BLOCK_TRIGGER_MODE, // 阻塞模式,触发读取(中断)
|
||||||
|
} BMI088_Work_Mode_e;
|
||||||
|
|
||||||
|
// bmi088标定方式枚举,若使用预设标定参数,注意修改预设参数
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
BMI088_CALIBRATE_MODE = 0, // 初始化时进行标定
|
BMI088_CALIBRATE_MODE = 0, // 初始化时进行标定
|
||||||
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数
|
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数,
|
||||||
} BMI088_Work_Mode_e;
|
} BMI088_Calibrate_Mode_e;
|
||||||
|
|
||||||
/* BMI088实例结构体定义 */
|
/* BMI088实例结构体定义 */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// 传输模式和工作模式控制
|
// 传输模式和工作模式控制
|
||||||
BMI088_Work_Mode_e mode;
|
BMI088_Work_Mode_e work_mode;
|
||||||
|
BMI088_Calibrate_Mode_e cali_mode;
|
||||||
// SPI接口
|
// SPI接口
|
||||||
SPIInstance *spi_gyro; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
SPIInstance *spi_gyro; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
||||||
SPIInstance *spi_acc; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
SPIInstance *spi_acc; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
||||||
|
@ -35,6 +48,9 @@ typedef struct
|
||||||
float gyro_offset[3]; // 陀螺仪零偏
|
float gyro_offset[3]; // 陀螺仪零偏
|
||||||
float gNorm; // 重力加速度模长,从标定获取
|
float gNorm; // 重力加速度模长,从标定获取
|
||||||
float acc_coef; // 加速度计原始数据转换系数
|
float acc_coef; // 加速度计原始数据转换系数
|
||||||
|
// 传感器灵敏度,用于计算实际值(regNdef.h中定义)
|
||||||
|
float BMI088_ACCELL_SEN;
|
||||||
|
float BMI088_GYRO_SEN;
|
||||||
// 用于计算两次采样的时间间隔
|
// 用于计算两次采样的时间间隔
|
||||||
uint32_t bias_dwt_cnt;
|
uint32_t bias_dwt_cnt;
|
||||||
} BMI088Instance;
|
} BMI088Instance;
|
||||||
|
@ -46,11 +62,20 @@ typedef struct
|
||||||
SPI_Init_Config_s spi_acc_config;
|
SPI_Init_Config_s spi_acc_config;
|
||||||
GPIO_Init_Config_s gyro_int_config;
|
GPIO_Init_Config_s gyro_int_config;
|
||||||
GPIO_Init_Config_s acc_int_config;
|
GPIO_Init_Config_s acc_int_config;
|
||||||
BMI088_Work_Mode_e mode;
|
BMI088_Work_Mode_e work_mode;
|
||||||
|
BMI088_Calibrate_Mode_e cali_mode;
|
||||||
PID_Init_Config_s heat_pid_config;
|
PID_Init_Config_s heat_pid_config;
|
||||||
PWM_Init_Config_s heat_pwm_config;
|
PWM_Init_Config_s heat_pwm_config;
|
||||||
} BMI088_Init_Config_s;
|
} BMI088_Init_Config_s;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化BMI088,返回BMI088实例指针
|
||||||
|
* @note 一般一个开发板只有一个BMI088,所以这里就叫BMI088Init而不是Register
|
||||||
|
*
|
||||||
|
* @param config bmi088初始化配置
|
||||||
|
* @return BMI088Instance* 实例指针
|
||||||
|
*/
|
||||||
|
BMI088Instance *BMI088Register(BMI088_Init_Config_s *config);
|
||||||
|
|
||||||
#endif // !__BMI088_H__
|
#endif // !__BMI088_H__
|
|
@ -0,0 +1,52 @@
|
||||||
|
# BMI088
|
||||||
|
|
||||||
|
## 数据读写规则(so called 16-bit protocol)
|
||||||
|
|
||||||
|
加速度计读取read:
|
||||||
|
1. bit 0 :1 bit 1-7: reg address
|
||||||
|
2. dummy read,加速度计此时返回的数据无效
|
||||||
|
3. 真正的数据从第三个字节开始.
|
||||||
|
|
||||||
|
通过SPI传输三个字节(分三次)
|
||||||
|
byte1: 1(读)+7位寄存器地址
|
||||||
|
byte2: 没用
|
||||||
|
byte3: 读取到的数据
|
||||||
|
|
||||||
|
write写入:
|
||||||
|
1. bit 0: 0 bit1-7: reg address
|
||||||
|
2. 要写入寄存器的数据(注意没有dummy byte)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**注意,陀螺仪和加速度计的读取不同**
|
||||||
|
|
||||||
|
陀螺仪gyro读取read:
|
||||||
|
1. bit 0 :1 bit1-7: reg address
|
||||||
|
2. 读回的数据
|
||||||
|
|
||||||
|
通过SPI传输两个字节(分两次)
|
||||||
|
byte1: 1(读)+7位寄存器地址
|
||||||
|
byte2: 读取到的数据
|
||||||
|
|
||||||
|
write写入:
|
||||||
|
1. bit0 : 0 bit1-7 : reg address
|
||||||
|
2. 写入的数据
|
||||||
|
|
||||||
|
|
||||||
|
## IT非阻塞模式下BMI088读取流程
|
||||||
|
|
||||||
|
数据准备完成标志位:`uint8_t BMI088_READY_FLAG` 总共8个位 也可以用位域可读性更高
|
||||||
|
|
||||||
|
1. 当accel int中断发生,开启DMA SPI传输,完成后将acc ready置位
|
||||||
|
2. 当gyro int中断发生,开启DMA SPI传输,完成后将gyro ready置位
|
||||||
|
3. 当温度数据中断发生,开启DMA传输,完成后将温度标志位置位
|
||||||
|
|
||||||
|
> 由于DMA传输非阻塞,启动传输后只有到传输完成时才会拉高片选结束SPI transfer,因此需要在callback中加入标志位置位的操作.
|
||||||
|
这可以通过条件编译完成.
|
||||||
|
|
||||||
|
温度数据不需要和accel和gyro同步,它不参与姿态解算,可以不用管.
|
||||||
|
|
||||||
|
当加速度数据和陀螺仪数据都准备完成之后,唤醒姿态解算任务INs_taSk,进行一次解算.唤醒可以通过软件开启EXTI中断,在中断中调用实时系统的vTaskNotifyFromISR()完成,也可以将任务ready标志位置位,当运行到对应位置时检查标志位判断是否要进行任务.时间间隔不是大问题,inS_TAsK中有dwt用于计算两次任务执行的间隔,它将会自动处理好bias的大小
|
||||||
|
`__HAL_GPIO_EXTI_GENERATE_SWIT()` `HAL_EXTI_GENERATE_SWI()`
|
||||||
|
|
||||||
|
of course,两者的数据更新实际上可以异步进行,这里为了方便起见当两者数据都准备好以后再行融合
|
|
@ -209,7 +209,7 @@
|
||||||
#define BMI088_GYRO_125_SEN 0.000066579027251980956150958662738366f
|
#define BMI088_GYRO_125_SEN 0.000066579027251980956150958662738366f
|
||||||
|
|
||||||
/* BMI088错误码枚举 */
|
/* BMI088错误码枚举 */
|
||||||
enum
|
typedef enum
|
||||||
{
|
{
|
||||||
BMI088_NO_ERROR = 0x00,
|
BMI088_NO_ERROR = 0x00,
|
||||||
BMI088_ACC_PWR_CTRL_ERROR = 0x01,
|
BMI088_ACC_PWR_CTRL_ERROR = 0x01,
|
||||||
|
@ -229,6 +229,6 @@ enum
|
||||||
BMI088_SELF_TEST_ACCEL_ERROR = 0x80,
|
BMI088_SELF_TEST_ACCEL_ERROR = 0x80,
|
||||||
BMI088_SELF_TEST_GYRO_ERROR = 0x40,
|
BMI088_SELF_TEST_GYRO_ERROR = 0x40,
|
||||||
BMI088_NO_SENSOR = 0xFF,
|
BMI088_NO_SENSOR = 0xFF,
|
||||||
};
|
} BMI088_ERORR_CODE_e;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void BMI088_read_muli_reg(uint8_t reg, uint8_t *buf, uint8_t len);
|
||||||
#elif defined(BMI088_USE_IIC)
|
#elif defined(BMI088_USE_IIC)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t write_BMI088_accel_reg_data_error[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
static uint8_t BMI088_Accel_Init_Table[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
||||||
{
|
{
|
||||||
{BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
{BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
||||||
{BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
{BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
||||||
|
@ -80,7 +80,7 @@ static uint8_t write_BMI088_accel_reg_data_error[BMI088_WRITE_ACCEL_REG_NUM][3]
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t write_BMI088_gyro_reg_data_error[BMI088_WRITE_GYRO_REG_NUM][3] =
|
static uint8_t BMI088_Gyro_Init_Table[BMI088_WRITE_GYRO_REG_NUM][3] =
|
||||||
{
|
{
|
||||||
{BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
{BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
||||||
{BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
{BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
||||||
|
@ -235,19 +235,18 @@ uint8_t bmi088_accel_init(void)
|
||||||
{
|
{
|
||||||
// check commiunication
|
// check commiunication
|
||||||
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
// accel software reset
|
// accel software reset
|
||||||
BMI088_accel_write_single_reg(BMI088_ACC_SOFTRESET, BMI088_ACC_SOFTRESET_VALUE);
|
BMI088_accel_write_single_reg(BMI088_ACC_SOFTRESET, BMI088_ACC_SOFTRESET_VALUE);
|
||||||
HAL_Delay(BMI088_LONG_DELAY_TIME);
|
// HAL_Delay(BMI088_LONG_DELAY_TIME);
|
||||||
|
DWT_Delay(0.08);
|
||||||
// check commiunication is normal after reset
|
// check commiunication is normal after reset
|
||||||
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
BMI088_accel_read_single_reg(BMI088_ACC_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
// check the "who am I"
|
// check the "who am I"
|
||||||
if (res != BMI088_ACC_CHIP_ID_VALUE)
|
if (res != BMI088_ACC_CHIP_ID_VALUE)
|
||||||
|
@ -257,17 +256,17 @@ uint8_t bmi088_accel_init(void)
|
||||||
for (write_reg_num = 0; write_reg_num < BMI088_WRITE_ACCEL_REG_NUM; write_reg_num++)
|
for (write_reg_num = 0; write_reg_num < BMI088_WRITE_ACCEL_REG_NUM; write_reg_num++)
|
||||||
{
|
{
|
||||||
|
|
||||||
BMI088_accel_write_single_reg(write_BMI088_accel_reg_data_error[write_reg_num][0], write_BMI088_accel_reg_data_error[write_reg_num][1]);
|
BMI088_accel_write_single_reg(BMI088_Accel_Init_Table[write_reg_num][0], BMI088_Accel_Init_Table[write_reg_num][1]);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
BMI088_accel_read_single_reg(write_BMI088_accel_reg_data_error[write_reg_num][0], res);
|
BMI088_accel_read_single_reg(BMI088_Accel_Init_Table[write_reg_num][0], res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
if (res != write_BMI088_accel_reg_data_error[write_reg_num][1])
|
if (res != BMI088_Accel_Init_Table[write_reg_num][1])
|
||||||
{
|
{
|
||||||
// write_reg_num--;
|
// write_reg_num--;
|
||||||
// return write_BMI088_accel_reg_data_error[write_reg_num][2];
|
// return BMI088_Accel_Init_Table[write_reg_num][2];
|
||||||
error |= write_BMI088_accel_reg_data_error[write_reg_num][2];
|
error |= BMI088_Accel_Init_Table[write_reg_num][2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BMI088_NO_ERROR;
|
return BMI088_NO_ERROR;
|
||||||
|
@ -277,18 +276,19 @@ uint8_t bmi088_gyro_init(void)
|
||||||
{
|
{
|
||||||
// check commiunication
|
// check commiunication
|
||||||
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
// reset the gyro sensor
|
// reset the gyro sensor
|
||||||
BMI088_gyro_write_single_reg(BMI088_GYRO_SOFTRESET, BMI088_GYRO_SOFTRESET_VALUE);
|
BMI088_gyro_write_single_reg(BMI088_GYRO_SOFTRESET, BMI088_GYRO_SOFTRESET_VALUE);
|
||||||
HAL_Delay(BMI088_LONG_DELAY_TIME);
|
// HAL_Delay(BMI088_LONG_DELAY_TIME);
|
||||||
|
DWT_Delay(0.08);
|
||||||
// check commiunication is normal after reset
|
// check commiunication is normal after reset
|
||||||
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
BMI088_gyro_read_single_reg(BMI088_GYRO_CHIP_ID, res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
// check the "who am I"
|
// check the "who am I"
|
||||||
if (res != BMI088_GYRO_CHIP_ID_VALUE)
|
if (res != BMI088_GYRO_CHIP_ID_VALUE)
|
||||||
|
@ -298,17 +298,17 @@ uint8_t bmi088_gyro_init(void)
|
||||||
for (write_reg_num = 0; write_reg_num < BMI088_WRITE_GYRO_REG_NUM; write_reg_num++)
|
for (write_reg_num = 0; write_reg_num < BMI088_WRITE_GYRO_REG_NUM; write_reg_num++)
|
||||||
{
|
{
|
||||||
|
|
||||||
BMI088_gyro_write_single_reg(write_BMI088_gyro_reg_data_error[write_reg_num][0], write_BMI088_gyro_reg_data_error[write_reg_num][1]);
|
BMI088_gyro_write_single_reg(BMI088_Gyro_Init_Table[write_reg_num][0], BMI088_Gyro_Init_Table[write_reg_num][1]);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
BMI088_gyro_read_single_reg(write_BMI088_gyro_reg_data_error[write_reg_num][0], res);
|
BMI088_gyro_read_single_reg(BMI088_Gyro_Init_Table[write_reg_num][0], res);
|
||||||
HAL_Delay(1);
|
DWT_Delay(0.001);
|
||||||
|
|
||||||
if (res != write_BMI088_gyro_reg_data_error[write_reg_num][1])
|
if (res != BMI088_Gyro_Init_Table[write_reg_num][1])
|
||||||
{
|
{
|
||||||
write_reg_num--;
|
write_reg_num--;
|
||||||
// return write_BMI088_gyro_reg_data_error[write_reg_num][2];
|
// return BMI088_Gyro_Init_Table[write_reg_num][2];
|
||||||
error |= write_BMI088_accel_reg_data_error[write_reg_num][2];
|
error |= BMI088_Accel_Init_Table[write_reg_num][2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,18 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
static IST8310Instance *ist8310_instance = NULL;
|
// 一般这个模块只有一个实例,所以直接保存在这里,实际上不保存也可以,application可以自己保存
|
||||||
|
static IST8310Instance *ist8310_instance = NULL; // 用于存储IST8310实例的指针
|
||||||
|
|
||||||
|
#define IST8310_WRITE_REG_NUM 4 // 方便阅读
|
||||||
|
#define IST8310_DATA_REG 0x03 // ist8310的数据寄存器
|
||||||
|
#define IST8310_WHO_AM_I 0x00 // ist8310 id 寄存器值
|
||||||
|
#define IST8310_WHO_AM_I_VALUE 0x10 // 用于检测是否连接成功,读取ist8310的whoami会返回该值
|
||||||
|
|
||||||
// -------------------初始化写入数组,只使用一次,详见datasheet-------------------------
|
// -------------------初始化写入数组,只使用一次,详见datasheet-------------------------
|
||||||
// the first column:the registers of IST8310. 第一列:IST8310的寄存器
|
// the first column:the registers of IST8310. 第一列:IST8310的寄存器
|
||||||
// the second column: the value to be writed to the registers.第二列:需要写入的寄存器值
|
// the second column: the value to be writed to the registers.第二列:需要写入的寄存器值
|
||||||
// the third column: return error value.第三列:返回的错误码
|
// the third column: return error value.第三列:返回的错误码
|
||||||
#define IST8310_WRITE_REG_NUM 4
|
|
||||||
#define IST8310_DATA_REG 0x03 // 数据寄存器
|
|
||||||
#define IST8310_WHO_AM_I 0x00 // ist8310 id 寄存器值
|
|
||||||
#define IST8310_WHO_AM_I_VALUE 0x10 // ist8310 id 寄存器值,用于检测是否连接成功
|
|
||||||
static uint8_t ist8310_write_reg_data_error[IST8310_WRITE_REG_NUM][3] = {
|
static uint8_t ist8310_write_reg_data_error[IST8310_WRITE_REG_NUM][3] = {
|
||||||
{0x0B, 0x08, 0x01}, // enalbe interrupt and low pin polarity.开启中断,并且设置低电平
|
{0x0B, 0x08, 0x01}, // enalbe interrupt and low pin polarity.开启中断,并且设置低电平
|
||||||
{0x41, 0x09, 0x02}, // average 2 times.平均采样两次
|
{0x41, 0x09, 0x02}, // average 2 times.平均采样两次
|
||||||
|
@ -27,64 +29,72 @@ static uint8_t ist8310_write_reg_data_error[IST8310_WRITE_REG_NUM][3] = {
|
||||||
*/
|
*/
|
||||||
static void IST8310Decode(IICInstance *iic)
|
static void IST8310Decode(IICInstance *iic)
|
||||||
{
|
{
|
||||||
static int16_t temp[3];
|
static int16_t temp[3]; // 用于存储解码后的数据
|
||||||
static IST8310Instance *ist;
|
static IST8310Instance *ist; // 用于存储IST8310实例的指针
|
||||||
ist = (IST8310Instance *)(iic->id);
|
ist = (IST8310Instance *)(iic->id); // iic的id保存了IST8310实例的指针(父指针)
|
||||||
|
|
||||||
memcpy(temp, ist->iic_buffer, 6 * sizeof(uint8_t));
|
memcpy(temp, ist->iic_buffer, 6 * sizeof(uint8_t)); // 不要强制转换,直接cpy
|
||||||
for (uint8_t i = 0; i < 3; i++)
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
ist->mag[i] = (float)temp[i] * MAG_SEN;
|
ist->mag[i] = (float)temp[i] * MAG_SEN; // 乘以灵敏度转换成uT(微特斯拉)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXTI中断回调函数,说明DRDY拉低.主机启动传输并在结束后调用IST8310Decode进行数据解析
|
/**
|
||||||
// 注意IICAccessMem是阻塞的
|
* @brief EXTI中断回调函数,说明DRDY拉低.主机启动传输并在结束后调用IST8310Decode进行数据解析
|
||||||
|
* @note 注意IICAccessMem是阻塞的
|
||||||
|
*
|
||||||
|
* @param gpio 发生中断的GPIO实例
|
||||||
|
*/
|
||||||
static void IST8310StartTransfer(GPIOInstance *gpio)
|
static void IST8310StartTransfer(GPIOInstance *gpio)
|
||||||
{
|
{
|
||||||
|
// 先获取IST8310实例的指针(通过gpio实例的父指针id)
|
||||||
IST8310Instance *ist_for_transfer = (IST8310Instance *)gpio->id;
|
IST8310Instance *ist_for_transfer = (IST8310Instance *)gpio->id;
|
||||||
|
// 中断说明ist已经准备好读取数据寄存器;6个字节,读取后会进入IST8310Decode函数
|
||||||
IICAccessMem(ist_for_transfer->iic, IST8310_DATA_REG, ist_for_transfer->iic_buffer, 6, IIC_READ_MEM);
|
IICAccessMem(ist_for_transfer->iic, IST8310_DATA_REG, ist_for_transfer->iic_buffer, 6, IIC_READ_MEM);
|
||||||
|
// 传输完成后会进入IST8310Decode函数进行数据解析
|
||||||
IST8310Decode(ist_for_transfer->iic);
|
IST8310Decode(ist_for_transfer->iic);
|
||||||
}
|
}
|
||||||
|
|
||||||
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config)
|
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config)
|
||||||
{
|
{
|
||||||
static const uint8_t sleepTime = 50;
|
static const uint8_t sleepTime = 50; // 50ms,ist8310的复位时间
|
||||||
uint8_t check_who_i_am = 0;
|
uint8_t check_who_i_am = 0; // 用于检测ist8310是否连接成功
|
||||||
|
// 这个变量只会用到一次,出了这个函数就没用了,所以不用分配空间,直接定义在栈上(因为多看一眼就会爆炸)
|
||||||
|
|
||||||
// 分配空间,清除flash
|
// 分配空间,清除flash防止已经填充的垃圾值
|
||||||
IST8310Instance *ist = (IST8310Instance *)malloc(sizeof(IST8310Instance));
|
IST8310Instance *ist = (IST8310Instance *)malloc(sizeof(IST8310Instance));
|
||||||
memset(ist, 0, sizeof(IST8310Instance));
|
memset(ist, 0, sizeof(IST8310Instance));
|
||||||
|
|
||||||
// c语言赋值从右到左
|
// c语言赋值从右到左,全部指向同一个地址(这些bspinstnace的父节点都是ist,即ist拥有这些instances)
|
||||||
config->iic_config.id = config->gpio_conf_exti.id = config->gpio_conf_rst.id = ist;
|
config->iic_config.id = config->gpio_conf_exti.id = config->gpio_conf_rst.id = ist;
|
||||||
// 传入回调函数
|
// 传入回调函数
|
||||||
config->iic_config.callback = IST8310Decode;
|
config->iic_config.callback = IST8310Decode;
|
||||||
config->gpio_conf_exti.gpio_model_callback = IST8310StartTransfer;
|
config->gpio_conf_exti.gpio_model_callback = IST8310StartTransfer;
|
||||||
// 注册两个GPIO和IIC
|
// 分别注册两个GPIO和IIC
|
||||||
ist->iic = IICRegister(&config->iic_config);
|
ist->iic = IICRegister(&config->iic_config);
|
||||||
ist->gpio_exti = GPIORegister(&config->gpio_conf_exti);
|
ist->gpio_exti = GPIORegister(&config->gpio_conf_exti);
|
||||||
ist->gpio_rst = GPIORegister(&config->gpio_conf_rst);
|
ist->gpio_rst = GPIORegister(&config->gpio_conf_rst);
|
||||||
|
|
||||||
// 重置IST8310,需要HAL_Delay等待完成Reset
|
// 重置IST8310,需要HAL_Delay()等待传感器完成Reset
|
||||||
GPIOReset(ist->gpio_rst);
|
GPIOReset(ist->gpio_rst);
|
||||||
HAL_Delay(sleepTime);
|
HAL_Delay(sleepTime);
|
||||||
GPIOSet(ist->gpio_rst);
|
GPIOSet(ist->gpio_rst);
|
||||||
HAL_Delay(sleepTime);
|
HAL_Delay(sleepTime);
|
||||||
|
|
||||||
// 读取IST8310的ID,如果不是0x10,则返回错误
|
// 读取IST8310的ID,如果不是0x10(whoami macro的值),则返回错误
|
||||||
IICAccessMem(ist->iic, IST8310_WHO_AM_I, &check_who_i_am, 1, IIC_READ_MEM);
|
IICAccessMem(ist->iic, IST8310_WHO_AM_I, &check_who_i_am, 1, IIC_READ_MEM);
|
||||||
if (check_who_i_am != IST8310_WHO_AM_I_VALUE)
|
if (check_who_i_am != IST8310_WHO_AM_I_VALUE)
|
||||||
return NULL; // while(1)
|
return NULL; // while(1)
|
||||||
|
|
||||||
// 进行初始化配置写入并检查是否写入成功
|
// 进行初始化配置写入并检查是否写入成功,这里用循环把最上面初始化数组的东西都写进去
|
||||||
for (uint8_t i = 0; i < IST8310_WRITE_REG_NUM; i++)
|
for (uint8_t i = 0; i < IST8310_WRITE_REG_NUM; i++)
|
||||||
{ // 写入配置
|
{ // 写入配置,写一句就读一下看看ist8310是否仍然在线
|
||||||
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &ist8310_write_reg_data_error[i][1], 1, IIC_WRITE_MEM);
|
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &ist8310_write_reg_data_error[i][1], 1, IIC_WRITE_MEM);
|
||||||
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &check_who_i_am, 1, IIC_READ_MEM); // 读回自身id
|
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &check_who_i_am, 1, IIC_READ_MEM); // 读回自身id
|
||||||
if (check_who_i_am != ist8310_write_reg_data_error[i][1])
|
if (check_who_i_am != ist8310_write_reg_data_error[i][1])
|
||||||
while (1)
|
while (1)
|
||||||
ist8310_write_reg_data_error[i][2]; // 掉线/写入失败/未知错误,返回对应的错误码
|
ist8310_write_reg_data_error[i][2]; // 掉线/写入失败/未知错误,会返回对应的错误码
|
||||||
}
|
}
|
||||||
|
|
||||||
ist8310_instance = ist;
|
ist8310_instance = ist; // 保存ist8310实例的指针
|
||||||
return ist;
|
return ist;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once // 防止头文件重复包含,也可以用header guard
|
||||||
|
|
||||||
#include "bsp_iic.h"
|
#include "bsp_iic.h"
|
||||||
#include "bsp_gpio.h"
|
#include "bsp_gpio.h"
|
||||||
|
@ -14,15 +14,16 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief IST8310 实例定义
|
* @brief IST8310 实例定义
|
||||||
|
* @attention 配置GPIO Pin的时候注意使用GPIO_PIN_x(1,2,3,...,这是一个宏),而不是1,2,3的整形!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct tempist8310
|
typedef struct tempist8310
|
||||||
{
|
{
|
||||||
IICInstance *iic; // iic实例
|
IICInstance *iic; // iic实例
|
||||||
GPIOInstance* gpio_rst; // gpio实例,用于复位
|
GPIOInstance *gpio_rst; // gpio实例,用于复位
|
||||||
GPIOInstance* gpio_exti; // gpio实例,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
|
GPIOInstance *gpio_exti; // gpio实例,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
|
||||||
uint8_t iic_buffer[8]; // iic接收缓冲区
|
uint8_t iic_buffer[8]; // iic接收缓冲区
|
||||||
float mag[3]; // 三轴磁力计数据,[x,y,z]
|
float mag[3]; // 三轴磁力计数据,[x,y,z]
|
||||||
|
|
||||||
void (*ist_module_callback)(IICInstance *); // 模块回调函数
|
void (*ist_module_callback)(IICInstance *); // 模块回调函数
|
||||||
// 后续有需要再添加
|
// 后续有需要再添加
|
||||||
|
@ -31,22 +32,19 @@ typedef struct tempist8310
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief IST8310 初始化配置结构体
|
* @brief IST8310 初始化配置结构体
|
||||||
|
* @attention 配置GPIO Pin的时候注意使用GPIO_PIN_x(1,2,3,...,这是一个宏),而不是1,2,3的整形!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IIC_Init_Config_s iic_config; // iic初始化配置
|
IIC_Init_Config_s iic_config; // iic初始化配置
|
||||||
GPIO_Init_Config_s gpio_conf_rst; // gpio初始化配置,用于复位
|
GPIO_Init_Config_s gpio_conf_rst; // gpio初始化配置,用于复位ist8310,看数据手册
|
||||||
GPIO_Init_Config_s gpio_conf_exti; // gpio初始化配置,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
|
GPIO_Init_Config_s gpio_conf_exti; // gpio初始化配置,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
|
||||||
} IST8310_Init_Config_s;
|
} IST8310_Init_Config_s;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief IST8310 初始化.
|
* @brief IST8310 初始化.
|
||||||
* @note 一条i2c总线只能挂载一个IST8310
|
* @note 注意一条i2c总线只能挂载一个IST8310,他们的地址是固定的,不能改变.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config);
|
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config);
|
||||||
|
|
||||||
void rest(int aa);
|
|
||||||
|
|
||||||
int nit(int bb);
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# 禁止在临界区使用延时,这会导致因中断关闭定时器无法进入中断更新时间,进而卡死系统
|
||||||
|
|
||||||
|
# 禁止摸鱼
|
Loading…
Reference in New Issue