修改freertos时基心跳为tim14,更新引脚lable

This commit is contained in:
NeoZng 2023-02-04 15:38:05 +08:00
parent 1262f9a516
commit 429aa17fa4
32 changed files with 621 additions and 1840 deletions

File diff suppressed because one or more lines are too long

View File

@ -51,7 +51,6 @@
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
void xPortSysTickHandler(void);
#endif
#define configENABLE_FPU 1
#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,
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
/* #define xPortSysTickHandler SysTick_Handler */
#define xPortSysTickHandler SysTick_Handler
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */

View File

@ -57,10 +57,10 @@ void Error_Handler(void);
/* USER CODE END EFP */
/* 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_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_GPIO_Port GPIOH
#define INT_MAG_Pin GPIO_PIN_3
@ -76,11 +76,12 @@ void Error_Handler(void);
#define KEY_GPIO_Port GPIOA
#define CS1_ACCEL_Pin GPIO_PIN_4
#define CS1_ACCEL_GPIO_Port GPIOA
#define INT_ACCEL_Pin GPIO_PIN_4
#define INT_ACCEL_GPIO_Port GPIOC
#define INT_ACCEL_EXTI_IRQn EXTI4_IRQn
#define INT_ACC_Pin GPIO_PIN_4
#define INT_ACC_GPIO_Port GPIOC
#define INT_ACC_EXTI_IRQn EXTI4_IRQn
#define INT_GYRO_Pin GPIO_PIN_5
#define INT_GYRO_GPIO_Port GPIOC
#define INT_GYRO_EXTI_IRQn EXTI9_5_IRQn
#define SERVO_Pin GPIO_PIN_9
#define SERVO_GPIO_Port GPIOE
#define CS1_GYRO_Pin GPIO_PIN_0

View File

@ -52,7 +52,6 @@ void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void SysTick_Handler(void);
void EXTI3_IRQHandler(void);
void EXTI4_IRQHandler(void);
void DMA1_Stream1_IRQHandler(void);
@ -61,12 +60,14 @@ void DMA1_Stream3_IRQHandler(void);
void DMA1_Stream4_IRQHandler(void);
void CAN1_RX0_IRQHandler(void);
void CAN1_RX1_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void I2C2_EV_IRQHandler(void);
void I2C2_ER_IRQHandler(void);
void SPI1_IRQHandler(void);
void SPI2_IRQHandler(void);
void USART1_IRQHandler(void);
void USART3_IRQHandler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void DMA1_Stream7_IRQHandler(void);
void DMA2_Stream0_IRQHandler(void);
void DMA2_Stream2_IRQHandler(void);

View File

@ -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 */

View File

@ -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 );
}

View File

@ -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;
}
/*-----------------------------------------------------------*/

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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.

View File

@ -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>&copy; COPYRIGHT STMicroelectronics</center></h3>
*/

View File

@ -6,7 +6,7 @@
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* 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 */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
osThreadDef(instask, StartINSTASK, osPriorityNormal, 0, 1024);
defaultTaskHandle = osThreadCreate(osThread(instask), NULL);
@ -130,7 +129,6 @@ void MX_FREERTOS_Init(void) {
osThreadDef(robottask, StartROBOTTASK, osPriorityNormal, 0, 1024);
defaultTaskHandle = osThreadCreate(osThread(robottask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
@ -152,8 +150,6 @@ void StartDefaultTask(void const * argument)
/* Infinite loop */
for(;;)
{
//1kHz
led_RGB_flow_task();
osDelay(1);
}
/* USER CODE END StartDefaultTask */
@ -161,6 +157,7 @@ void StartDefaultTask(void const * argument)
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void StartINSTASK(void const * argument)
{
while (1)
@ -202,6 +199,4 @@ void StartROBOTTASK(void const * argument)
}
}
/* USER CODE END Application */

View File

@ -56,7 +56,7 @@ void MX_GPIO_Init(void)
__HAL_RCC_GPIOE_CLK_ENABLE();
/*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 */
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 */
GPIO_InitStruct.Pin = MAG_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MAG_RST_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
@ -91,7 +91,7 @@ void MX_GPIO_Init(void)
HAL_GPIO_Init(CS1_ACCEL_GPIO_Port, &GPIO_InitStruct);
/*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.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
@ -110,6 +110,9 @@ void MX_GPIO_Init(void)
HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
/* USER CODE BEGIN 2 */

View File

@ -6,7 +6,7 @@
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
@ -21,13 +21,15 @@
#include "cmsis_os.h"
#include "adc.h"
#include "can.h"
#include "crc.h"
#include "dac.h"
#include "dma.h"
#include "i2c.h"
#include "rng.h"
#include "rtc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "i2c.h"
#include "usb_device.h"
#include "gpio.h"
@ -110,11 +112,14 @@ int main(void)
MX_TIM10_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
MX_TIM8_Init();
MX_I2C2_Init();
MX_I2C3_Init();
MX_SPI2_Init();
MX_CRC_Init();
MX_DAC_Init();
/* USER CODE BEGIN 2 */
RobotInit();
/* USER CODE END 2 */
/* Call init function for freertos objects (in freertos.c) */
@ -183,6 +188,28 @@ void SystemClock_Config(void)
/* 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.
* @retval None

View File

@ -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);
}

View File

@ -20,8 +20,6 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
#include "FreeRTOS.h"
#include "task.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
@ -71,6 +69,7 @@ extern DMA_HandleTypeDef hdma_spi2_rx;
extern DMA_HandleTypeDef hdma_spi2_tx;
extern SPI_HandleTypeDef hspi1;
extern SPI_HandleTypeDef hspi2;
extern TIM_HandleTypeDef htim8;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart3_rx;
@ -79,6 +78,8 @@ extern DMA_HandleTypeDef hdma_usart6_tx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart6;
extern TIM_HandleTypeDef htim14;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -107,14 +108,11 @@ void NMI_Handler(void)
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
// 发生hardfault,点击step over会自动跳转回出错的指令,方便调试
asm("bx lr");
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
asm("bx lr");
/* USER CODE BEGIN 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 */
}
/**
* @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 */
/* 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 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 END EXTI4_IRQn 1 */
@ -318,6 +294,20 @@ void CAN1_RX1_IRQHandler(void)
/* 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.
*/
@ -402,6 +392,21 @@ void USART3_IRQHandler(void)
/* 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.
*/

View File

@ -320,9 +320,9 @@ void MX_TIM10_Init(void)
/* USER CODE END TIM10_Init 1 */
htim10.Instance = TIM10;
htim10.Init.Prescaler = 0;
htim10.Init.Prescaler = 167;
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
htim10.Init.Period = 4999;
htim10.Init.Period = 5000-1;
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
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 */
/* TIM8 clock 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 END TIM8_MspInit 1 */
@ -515,9 +519,9 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
/* USER CODE END TIM10_MspPostInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/**TIM10 GPIO Configuration
PB8 ------> TIM10_CH1
PF6 ------> TIM10_CH1
*/
GPIO_InitStruct.Pin = IMU_TEMP_Pin;
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 */
/* Peripheral clock 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 END TIM8_MspDeInit 1 */

View File

@ -39,10 +39,13 @@ BUILD_DIR = build
C_SOURCES = \
HAL_N_Middlewares/Src/main.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/can.c \
HAL_N_Middlewares/Src/crc.c \
HAL_N_Middlewares/Src/dac.c \
HAL_N_Middlewares/Src/dma.c \
HAL_N_Middlewares/Src/i2c.c \
HAL_N_Middlewares/Src/rng.c \
HAL_N_Middlewares/Src/rtc.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/stm32f4xx_it.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/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_ex.c \
HAL_N_Middlewares/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \

View File

@ -15,8 +15,10 @@
void RobotInit()
{
// 关闭中断,防止在初始化过程中发生中断
// 请不要在初始化过程中使用中断!!!
// 请不要在初始化过程中使用中断和延时函数!
// 若必须,则只允许使用DWT_Delay()
__disable_irq();
BSPInit();
#if defined(ONE_BOARD) || defined(GIMBAL_BOARD)

View File

@ -208,30 +208,30 @@ Mcu.IP9=NVIC
Mcu.IPNb=26
Mcu.Name=STM32F407I(E-G)Hx
Mcu.Package=UFBGA176
Mcu.Pin0=PB8
Mcu.Pin1=PB5
Mcu.Pin10=PC11
Mcu.Pin11=PC10
Mcu.Pin12=PA12
Mcu.Pin13=PI7
Mcu.Pin14=PI6
Mcu.Pin15=PG9
Mcu.Pin16=PD1
Mcu.Pin17=PA11
Mcu.Pin18=PF0
Mcu.Pin19=PA9
Mcu.Pin2=PG14
Mcu.Pin20=PC9
Mcu.Pin21=PA8
Mcu.Pin22=PH0-OSC_IN
Mcu.Pin23=PH1-OSC_OUT
Mcu.Pin24=PF1
Mcu.Pin25=PC6
Mcu.Pin26=PG6
Mcu.Pin0=PB5
Mcu.Pin1=PG14
Mcu.Pin10=PC10
Mcu.Pin11=PA12
Mcu.Pin12=PI7
Mcu.Pin13=PI6
Mcu.Pin14=PG9
Mcu.Pin15=PD1
Mcu.Pin16=PA11
Mcu.Pin17=PF0
Mcu.Pin18=PA9
Mcu.Pin19=PC9
Mcu.Pin2=PB4
Mcu.Pin20=PA8
Mcu.Pin21=PH0-OSC_IN
Mcu.Pin22=PH1-OSC_OUT
Mcu.Pin23=PF1
Mcu.Pin24=PC6
Mcu.Pin25=PG6
Mcu.Pin26=PF6
Mcu.Pin27=PH12
Mcu.Pin28=PG3
Mcu.Pin29=PH11
Mcu.Pin3=PB4
Mcu.Pin3=PB3
Mcu.Pin30=PH10
Mcu.Pin31=PD14
Mcu.Pin32=PA0-WKUP
@ -242,7 +242,7 @@ Mcu.Pin36=PA5
Mcu.Pin37=PC5
Mcu.Pin38=PE9
Mcu.Pin39=PE11
Mcu.Pin4=PB3
Mcu.Pin4=PA14
Mcu.Pin40=PE14
Mcu.Pin41=PB13
Mcu.Pin42=PA7
@ -253,10 +253,10 @@ Mcu.Pin46=VP_ADC1_TempSens_Input
Mcu.Pin47=VP_ADC1_Vref_Input
Mcu.Pin48=VP_CRC_VS_CRC
Mcu.Pin49=VP_FREERTOS_VS_CMSIS_V1
Mcu.Pin5=PA14
Mcu.Pin5=PA13
Mcu.Pin50=VP_RNG_VS_RNG
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.Pin54=VP_TIM4_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.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.Pin6=PA13
Mcu.Pin7=PB7
Mcu.Pin8=PB6
Mcu.Pin9=PD0
Mcu.Pin6=PB7
Mcu.Pin7=PB6
Mcu.Pin8=PD0
Mcu.Pin9=PC11
Mcu.PinsNb=60
Mcu.ThirdParty0=STMicroelectronics.X-CUBE-ALGOBUILD.1.3.0
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_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_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_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
@ -313,7 +313,10 @@ NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=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.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
@ -344,6 +347,7 @@ PA7.GPIO_PuPd=GPIO_PULLUP
PA7.Locked=true
PA7.Mode=Full_Duplex_Master
PA7.Signal=SPI1_MOSI
PA8.Locked=true
PA8.Mode=I2C
PA8.Signal=I2C3_SCL
PA9.Locked=true
@ -384,12 +388,6 @@ PB6.Signal=CAN2_TX
PB7.Locked=true
PB7.Mode=Asynchronous
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.Mode=Asynchronous
PC10.Signal=USART3_TX
@ -434,6 +432,12 @@ PF0.Mode=I2C
PF0.Signal=I2C2_SDA
PF1.Mode=I2C
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.Mode=Asynchronous
PG14.Signal=USART6_TX
@ -443,12 +447,9 @@ PG3.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PG3.GPIO_PuPd=GPIO_PULLUP
PG3.Locked=true
PG3.Signal=GPXTI3
PG6.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PG6.GPIOParameters=GPIO_Label
PG6.GPIO_Label=MAG_RST
PG6.GPIO_PuPd=GPIO_PULLUP
PG6.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PG6.Locked=true
PG6.PinState=GPIO_PIN_SET
PG6.Signal=GPIO_Output
PG9.Locked=true
PG9.Mode=Asynchronous
@ -606,8 +607,8 @@ TIM1.Period=19999
TIM1.Prescaler=167
TIM10.Channel=TIM_CHANNEL_1
TIM10.IPParameters=Period,Channel,Prescaler
TIM10.Period=4999
TIM10.Prescaler=0
TIM10.Period=5000-1
TIM10.Prescaler=167
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM4.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period
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_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_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_SYS_VS_tim14.Mode=TIM14
VP_SYS_VS_tim14.Signal=SYS_VS_tim14
VP_TIM10_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM10_VS_ClockSourceINT.Signal=TIM10_VS_ClockSourceINT
VP_TIM1_VS_ClockSourceINT.Mode=Internal

View File

@ -23,7 +23,7 @@ typedef struct _
uint8_t rx_len; // 接收长度,可能为0-8
// 接收的回调函数,用于解析接收到的数据
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
void *id; // 使用can外设的
void *id; // 使用can外设的模块指针(即id指向的模块拥有此can实例,是父子关系)
} CANInstance;
#pragma pack()

View File

@ -128,10 +128,11 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *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_WritePin(spi_instance[i]->GPIO_cs, spi_instance[i]->cs_pin, GPIO_PIN_SET);
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]);
}
return;

1
bsp/usb/bsp_usb.c Normal file
View File

@ -0,0 +1 @@
#include "bsp_usb.h"

5
bsp/usb/bsp_usb.h Normal file
View File

@ -0,0 +1,5 @@
#include "usb_device.h"
#include "usbd_cdc.h"
#include "usbd_conf.h"
#include "usbd_desc.h"

View File

@ -3,3 +3,170 @@
#include "stdlib.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)
{
}

View File

@ -1,4 +1,4 @@
#ifndef __BMI088_H__
#ifndef __BMI088_H__ // 防止重复包含
#define __BMI088_H__
#include "bsp_spi.h"
@ -7,17 +7,30 @@
#include "bsp_pwm.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
{
BMI088_CALIBRATE_MODE = 0, // 初始化时进行标定
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数
} BMI088_Work_Mode_e;
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数,
} BMI088_Calibrate_Mode_e;
/* BMI088实例结构体定义 */
typedef struct
{
// 传输模式和工作模式控制
BMI088_Work_Mode_e mode;
BMI088_Work_Mode_e work_mode;
BMI088_Calibrate_Mode_e cali_mode;
// SPI接口
SPIInstance *spi_gyro; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
SPIInstance *spi_acc; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
@ -35,6 +48,9 @@ typedef struct
float gyro_offset[3]; // 陀螺仪零偏
float gNorm; // 重力加速度模长,从标定获取
float acc_coef; // 加速度计原始数据转换系数
// 传感器灵敏度,用于计算实际值(regNdef.h中定义)
float BMI088_ACCELL_SEN;
float BMI088_GYRO_SEN;
// 用于计算两次采样的时间间隔
uint32_t bias_dwt_cnt;
} BMI088Instance;
@ -46,11 +62,20 @@ typedef struct
SPI_Init_Config_s spi_acc_config;
GPIO_Init_Config_s gyro_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;
PWM_Init_Config_s heat_pwm_config;
} 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__

View File

@ -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,两者的数据更新实际上可以异步进行,这里为了方便起见当两者数据都准备好以后再行融合

View File

@ -209,7 +209,7 @@
#define BMI088_GYRO_125_SEN 0.000066579027251980956150958662738366f
/* BMI088错误码枚举 */
enum
typedef enum
{
BMI088_NO_ERROR = 0x00,
BMI088_ACC_PWR_CTRL_ERROR = 0x01,
@ -229,6 +229,6 @@ enum
BMI088_SELF_TEST_ACCEL_ERROR = 0x80,
BMI088_SELF_TEST_GYRO_ERROR = 0x40,
BMI088_NO_SENSOR = 0xFF,
};
} BMI088_ERORR_CODE_e;
#endif

View File

@ -69,7 +69,7 @@ static void BMI088_read_muli_reg(uint8_t reg, uint8_t *buf, uint8_t len);
#elif defined(BMI088_USE_IIC)
#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_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_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
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);
HAL_Delay(1);
DWT_Delay(0.001);
// accel software reset
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
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);
HAL_Delay(1);
DWT_Delay(0.001);
// check the "who am I"
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++)
{
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]);
HAL_Delay(1);
BMI088_accel_write_single_reg(BMI088_Accel_Init_Table[write_reg_num][0], BMI088_Accel_Init_Table[write_reg_num][1]);
DWT_Delay(0.001);
BMI088_accel_read_single_reg(write_BMI088_accel_reg_data_error[write_reg_num][0], res);
HAL_Delay(1);
BMI088_accel_read_single_reg(BMI088_Accel_Init_Table[write_reg_num][0], res);
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--;
// return write_BMI088_accel_reg_data_error[write_reg_num][2];
error |= write_BMI088_accel_reg_data_error[write_reg_num][2];
// return BMI088_Accel_Init_Table[write_reg_num][2];
error |= BMI088_Accel_Init_Table[write_reg_num][2];
}
}
return BMI088_NO_ERROR;
@ -277,18 +276,19 @@ uint8_t bmi088_gyro_init(void)
{
// check commiunication
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);
HAL_Delay(1);
DWT_Delay(0.001);
// reset the gyro sensor
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
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);
HAL_Delay(1);
DWT_Delay(0.001);
// check the "who am I"
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++)
{
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]);
HAL_Delay(1);
BMI088_gyro_write_single_reg(BMI088_Gyro_Init_Table[write_reg_num][0], BMI088_Gyro_Init_Table[write_reg_num][1]);
DWT_Delay(0.001);
BMI088_gyro_read_single_reg(write_BMI088_gyro_reg_data_error[write_reg_num][0], res);
HAL_Delay(1);
BMI088_gyro_read_single_reg(BMI088_Gyro_Init_Table[write_reg_num][0], res);
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--;
// return write_BMI088_gyro_reg_data_error[write_reg_num][2];
error |= write_BMI088_accel_reg_data_error[write_reg_num][2];
// return BMI088_Gyro_Init_Table[write_reg_num][2];
error |= BMI088_Accel_Init_Table[write_reg_num][2];
}
}

View File

@ -3,16 +3,18 @@
#include "memory.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-------------------------
// the first column:the registers of IST8310. 第一列:IST8310的寄存器
// the second column: the value to be writed to the registers.第二列:需要写入的寄存器值
// 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] = {
{0x0B, 0x08, 0x01}, // enalbe interrupt and low pin polarity.开启中断,并且设置低电平
{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 int16_t temp[3];
static IST8310Instance *ist;
ist = (IST8310Instance *)(iic->id);
static int16_t temp[3]; // 用于存储解码后的数据
static IST8310Instance *ist; // 用于存储IST8310实例的指针
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++)
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)
{
// 先获取IST8310实例的指针(通过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);
// 传输完成后会进入IST8310Decode函数进行数据解析
IST8310Decode(ist_for_transfer->iic);
}
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config)
{
static const uint8_t sleepTime = 50;
uint8_t check_who_i_am = 0;
static const uint8_t sleepTime = 50; // 50ms,ist8310的复位时间
uint8_t check_who_i_am = 0; // 用于检测ist8310是否连接成功
// 这个变量只会用到一次,出了这个函数就没用了,所以不用分配空间,直接定义在栈上(因为多看一眼就会爆炸)
// 分配空间,清除flash
// 分配空间,清除flash防止已经填充的垃圾值
IST8310Instance *ist = (IST8310Instance *)malloc(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.callback = IST8310Decode;
config->gpio_conf_exti.gpio_model_callback = IST8310StartTransfer;
// 注册两个GPIO和IIC
// 分别注册两个GPIO和IIC
ist->iic = IICRegister(&config->iic_config);
ist->gpio_exti = GPIORegister(&config->gpio_conf_exti);
ist->gpio_rst = GPIORegister(&config->gpio_conf_rst);
// 重置IST8310,需要HAL_Delay等待完成Reset
// 重置IST8310,需要HAL_Delay()等待传感器完成Reset
GPIOReset(ist->gpio_rst);
HAL_Delay(sleepTime);
GPIOSet(ist->gpio_rst);
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);
if (check_who_i_am != IST8310_WHO_AM_I_VALUE)
return NULL; // while(1)
// 进行初始化配置写入并检查是否写入成功
// 进行初始化配置写入并检查是否写入成功,这里用循环把最上面初始化数组的东西都写进去
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], &check_who_i_am, 1, IIC_READ_MEM); // 读回自身id
if (check_who_i_am != ist8310_write_reg_data_error[i][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;
}

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once // 防止头文件重复包含,也可以用header guard
#include "bsp_iic.h"
#include "bsp_gpio.h"
@ -14,15 +14,16 @@
/**
* @brief IST8310
* @attention GPIO Pin的时候注意使用GPIO_PIN_x(1,2,3,...,),1,2,3!
*
*/
typedef struct tempist8310
{
IICInstance *iic; // iic实例
GPIOInstance* gpio_rst; // gpio实例,用于复位
GPIOInstance* gpio_exti; // gpio实例,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
uint8_t iic_buffer[8]; // iic接收缓冲区
float mag[3]; // 三轴磁力计数据,[x,y,z]
IICInstance *iic; // iic实例
GPIOInstance *gpio_rst; // gpio实例,用于复位
GPIOInstance *gpio_exti; // gpio实例,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
uint8_t iic_buffer[8]; // iic接收缓冲区
float mag[3]; // 三轴磁力计数据,[x,y,z]
void (*ist_module_callback)(IICInstance *); // 模块回调函数
// 后续有需要再添加
@ -31,22 +32,19 @@ typedef struct tempist8310
/**
* @brief IST8310
* @attention GPIO Pin的时候注意使用GPIO_PIN_x(1,2,3,...,),1,2,3!
*
*/
typedef struct
{
IIC_Init_Config_s iic_config; // iic初始化配置
GPIO_Init_Config_s gpio_conf_rst; // gpio初始化配置,用于复位
IIC_Init_Config_s iic_config; // iic初始化配置
GPIO_Init_Config_s gpio_conf_rst; // gpio初始化配置,用于复位ist8310,看数据手册
GPIO_Init_Config_s gpio_conf_exti; // gpio初始化配置,用于获取MAG_DRDY引脚状态,判断数据是否准备好(EXTI外部中断)
} IST8310_Init_Config_s;
/**
* @brief IST8310 .
* @note i2c总线只能挂载一个IST8310
* @note i2c总线只能挂载一个IST8310,,.
*
*/
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config);
void rest(int aa);
int nit(int bb);

3
必须做&禁止做.md Normal file
View File

@ -0,0 +1,3 @@
# 禁止在临界区使用延时,这会导致因中断关闭定时器无法进入中断更新时间,进而卡死系统
# 禁止摸鱼