diff --git a/.mxproject b/.mxproject index 6fac82f..93753b4 100644 --- a/.mxproject +++ b/.mxproject @@ -1,5 +1,5 @@ [PreviousLibFiles] -LibFiles=Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_bus.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_crs.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_system.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_utils.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dmamux.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_fdcan.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ospi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_lpuart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_bus.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_crs.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_system.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_utils.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dmamux.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_fdcan.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ospi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_lpuart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h723xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h; +LibFiles=Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_bus.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_crs.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_system.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_utils.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dmamux.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_fdcan.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ospi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_lpuart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_adc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_adc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_bus.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_crs.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_system.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_utils.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_dmamux.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_exti.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_fdcan.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ospi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_lpuart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h723xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h; [PreviousUsedCMakes] SourceFiles=Core/Src/main.c;Core/Src/gpio.c;Core/Src/freertos.c;Core/Src/adc.c;Core/Src/dma.c;Core/Src/fdcan.c;Core/Src/octospi.c;Core/Src/spi.c;Core/Src/tim.c;Core/Src/usart.c;Core/Src/usb_otg.c;Core/Src/stm32h7xx_it.c;Core/Src/stm32h7xx_hal_msp.c;Core/Src/stm32h7xx_hal_timebase_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Core/Src/system_stm32h7xx.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Core/Src/system_stm32h7xx.c;;;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c; @@ -44,3 +44,8 @@ SourceFolderListSize=1 SourcePath#0=../Core/Src SourceFiles=; +[PreviousUsedKeilFiles] +SourceFiles=../Core/Src/main.c;../Core/Src/gpio.c;../Core/Src/freertos.c;../Core/Src/adc.c;../Core/Src/dma.c;../Core/Src/fdcan.c;../Core/Src/octospi.c;../Core/Src/spi.c;../Core/Src/tim.c;../Core/Src/usart.c;../Core/Src/usb_otg.c;../Core/Src/stm32h7xx_it.c;../Core/Src/stm32h7xx_hal_msp.c;../Core/Src/stm32h7xx_hal_timebase_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;../Middlewares/Third_Party/FreeRTOS/Source/croutine.c;../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;../Middlewares/Third_Party/FreeRTOS/Source/list.c;../Middlewares/Third_Party/FreeRTOS/Source/queue.c;../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;../Middlewares/Third_Party/FreeRTOS/Source/tasks.c;../Middlewares/Third_Party/FreeRTOS/Source/timers.c;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c;../Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;../Core/Src/system_stm32h7xx.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c;../Middlewares/Third_Party/FreeRTOS/Source/croutine.c;../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;../Middlewares/Third_Party/FreeRTOS/Source/list.c;../Middlewares/Third_Party/FreeRTOS/Source/queue.c;../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;../Middlewares/Third_Party/FreeRTOS/Source/tasks.c;../Middlewares/Third_Party/FreeRTOS/Source/timers.c;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c;../Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;../Core/Src/system_stm32h7xx.c;;;../Middlewares/Third_Party/FreeRTOS/Source/croutine.c;../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;../Middlewares/Third_Party/FreeRTOS/Source/list.c;../Middlewares/Third_Party/FreeRTOS/Source/queue.c;../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;../Middlewares/Third_Party/FreeRTOS/Source/tasks.c;../Middlewares/Third_Party/FreeRTOS/Source/timers.c;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c; +HeaderPath=../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;../Core/Inc; +CDefines=USE_PWR_LDO_SUPPLY;USE_PWR_LDO_SUPPLY;USE_PWR_LDO_SUPPLY;USE_HAL_DRIVER;STM32H723xx;USE_HAL_DRIVER;USE_HAL_DRIVER; + diff --git a/CMakeLists.txt b/CMakeLists.txt index 72fbe3c..e0eded9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,8 +62,10 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE User/component/error_detect.c User/component/filter.c User/component/freertos_cli.c + User/component/lqr.c User/component/pid.c User/component/user_math.c + User/component/vmc.c # User/device sources User/device/bmi088.c @@ -74,8 +76,9 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE User/device/motor_lk.c User/device/motor_lz.c User/device/motor_rm.c - + # User/module sources + User/module/balance_chassis.c User/module/config.c User/module/shoot.c diff --git a/CtrBoard-H7_ALL.ioc b/CtrBoard-H7_ALL.ioc index acb1683..5cc0827 100644 --- a/CtrBoard-H7_ALL.ioc +++ b/CtrBoard-H7_ALL.ioc @@ -503,7 +503,7 @@ ProjectManager.ProjectName=CtrBoard-H7_ALL ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x2000 -ProjectManager.TargetToolchain=CMake +ProjectManager.TargetToolchain=MDK-ARM V5.32 ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= diff --git a/MDK-ARM/CtrBoard-H7_ALL.uvoptx b/MDK-ARM/CtrBoard-H7_ALL.uvoptx new file mode 100644 index 0000000..88165e0 --- /dev/null +++ b/MDK-ARM/CtrBoard-H7_ALL.uvoptx @@ -0,0 +1,171 @@ + + + 1.0 +
### uVision Project, (C) Keil Software
+ + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + 0 + 0 + + + CtrBoard-H7_ALL + 0x4 + ARM-ADS + + 24000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(5BA02477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32H72x-73x_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32H723VG$Flash\STM32H72x-73x_1024.FLM) + + + 0 + + + + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + +
diff --git a/MDK-ARM/CtrBoard-H7_ALL.uvprojx b/MDK-ARM/CtrBoard-H7_ALL.uvprojx new file mode 100644 index 0000000..44c9960 --- /dev/null +++ b/MDK-ARM/CtrBoard-H7_ALL.uvprojx @@ -0,0 +1,692 @@ + + + 2.1 +
### uVision Project, (C) Keil Software
+ + + CtrBoard-H7_ALL + 0x4 + ARM-ADS + + + STM32H723VGTx + STMicroelectronics + IRAM(0x20000000-0x2001FFFF) IRAM2(0x24000000-0x2404FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(12000000) FPU3(DFPU) CPUTYPE("Cortex-M7") ELITTLE TZ + + + + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + CtrBoard-H7_ALL\ + CtrBoard-H7_ALL + 1 + 0 + 1 + 1 + 1 + ./CtrBoard-H7_ALL/ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 1 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM7 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM7 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M7" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 3 + 0 + 0 + 0 + 1 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + + + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + + + + + 0 + 0x0 + 0x0 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 1 + 0 + 5 + 3 + 1 + 1 + 0 + 0 + 0 + + + USE_PWR_LDO_SUPPLY,USE_HAL_DRIVER,STM32H723xx + + ../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + ../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include + + + + 1 + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32h723xx.s + 2 + startup_stm32h723xx.s + + + + + Application/User/Core + + + main.c + 1 + ../Core/Src/main.c + + + gpio.c + 1 + ../Core/Src/gpio.c + + + freertos.c + 1 + ../Core/Src/freertos.c + + + adc.c + 1 + ../Core/Src/adc.c + + + dma.c + 1 + ../Core/Src/dma.c + + + fdcan.c + 1 + ../Core/Src/fdcan.c + + + octospi.c + 1 + ../Core/Src/octospi.c + + + spi.c + 1 + ../Core/Src/spi.c + + + tim.c + 1 + ../Core/Src/tim.c + + + usart.c + 1 + ../Core/Src/usart.c + + + usb_otg.c + 1 + ../Core/Src/usb_otg.c + + + stm32h7xx_it.c + 1 + ../Core/Src/stm32h7xx_it.c + + + stm32h7xx_hal_msp.c + 1 + ../Core/Src/stm32h7xx_hal_msp.c + + + stm32h7xx_hal_timebase_tim.c + 1 + ../Core/Src/stm32h7xx_hal_timebase_tim.c + + + + + Drivers/STM32H7xx_HAL_Driver + + + stm32h7xx_hal_tim.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c + + + stm32h7xx_hal_tim_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c + + + stm32h7xx_hal_adc.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c + + + stm32h7xx_hal_adc_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c + + + stm32h7xx_hal_rcc.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c + + + stm32h7xx_hal_rcc_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c + + + stm32h7xx_hal_flash.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c + + + stm32h7xx_hal_flash_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c + + + stm32h7xx_hal_gpio.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c + + + stm32h7xx_hal_hsem.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c + + + stm32h7xx_hal_dma.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c + + + stm32h7xx_hal_dma_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c + + + stm32h7xx_hal_mdma.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c + + + stm32h7xx_hal_pwr.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c + + + stm32h7xx_hal_pwr_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c + + + stm32h7xx_hal_cortex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c + + + stm32h7xx_hal.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c + + + stm32h7xx_hal_i2c.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c + + + stm32h7xx_hal_i2c_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c + + + stm32h7xx_hal_exti.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c + + + stm32h7xx_hal_fdcan.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c + + + stm32h7xx_hal_ospi.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c + + + stm32h7xx_hal_spi.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c + + + stm32h7xx_hal_spi_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c + + + stm32h7xx_hal_uart.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c + + + stm32h7xx_hal_uart_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c + + + stm32h7xx_hal_pcd.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c + + + stm32h7xx_hal_pcd_ex.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c + + + stm32h7xx_ll_usb.c + 1 + ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c + + + + + Drivers/CMSIS + + + system_stm32h7xx.c + 1 + ../Core/Src/system_stm32h7xx.c + + + + + Middlewares/FreeRTOS + + + croutine.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/croutine.c + + + event_groups.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c + + + list.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/list.c + + + queue.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/queue.c + + + stream_buffer.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c + + + tasks.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/tasks.c + + + timers.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/timers.c + + + cmsis_os2.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c + + + heap_4.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c + + + port.c + 1 + ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c + + + + + + + + + + + + + + + + + + +
+ diff --git a/MDK-ARM/startup_stm32h723xx.s b/MDK-ARM/startup_stm32h723xx.s new file mode 100644 index 0000000..f45ec41 --- /dev/null +++ b/MDK-ARM/startup_stm32h723xx.s @@ -0,0 +1,619 @@ +;******************************************************************************** +;* File Name : startup_stm32h723xx.s +;* @author MCD Application Team +;* Description : STM32H7xx devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;****************************************************************************** +;* @attention +;* +;* Copyright (c) 2019 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. +;* +;******************************************************************************* + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x2000 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x1000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog interrupt ( wwdg1_it) + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection + DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line + DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 + DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 + DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 + DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 + DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 + DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 + DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 + DCD ADC_IRQHandler ; ADC1, ADC2 + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt line 0 + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt line 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt line 1 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt line 1 + DCD EXTI9_5_IRQHandler ; External Line[9:5]s + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation Interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; External Line[15:10] + DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line + DCD 0 ; Reserved + DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break Interrupt and TIM12 global interrupt + DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update Interrupt and TIM13 global interrupt + DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare Interrupt + DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 + DCD FMC_IRQHandler ; FMC + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD TIM5_IRQHandler ; TIM5 + DCD SPI3_IRQHandler ; SPI3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 + DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 + DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 + DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 + DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 + DCD ETH_IRQHandler ; Ethernet + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line + DCD FDCAN_CAL_IRQHandler ; FDCAN calibration unit interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 + DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 + DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 + DCD USART6_IRQHandler ; USART6 + DCD I2C3_EV_IRQHandler ; I2C3 event + DCD I2C3_ER_IRQHandler ; I2C3 error + DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out + DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In + DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI + DCD OTG_HS_IRQHandler ; USB OTG HS + DCD DCMI_PSSI_IRQHandler ; DCMI, PSSI + DCD 0 ; Reserved + DCD RNG_IRQHandler ; Rng + DCD FPU_IRQHandler ; FPU + DCD UART7_IRQHandler ; UART7 + DCD UART8_IRQHandler ; UART8 + DCD SPI4_IRQHandler ; SPI4 + DCD SPI5_IRQHandler ; SPI5 + DCD SPI6_IRQHandler ; SPI6 + DCD SAI1_IRQHandler ; SAI1 + DCD LTDC_IRQHandler ; LTDC + DCD LTDC_ER_IRQHandler ; LTDC error + DCD DMA2D_IRQHandler ; DMA2D + DCD 0 ; Reserved + DCD OCTOSPI1_IRQHandler ; OCTOSPI1 + DCD LPTIM1_IRQHandler ; LPTIM1 + DCD CEC_IRQHandler ; HDMI_CEC + DCD I2C4_EV_IRQHandler ; I2C4 Event + DCD I2C4_ER_IRQHandler ; I2C4 Error + DCD SPDIF_RX_IRQHandler ; SPDIF_RX + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX1 Overrun interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DFSDM1_FLT0_IRQHandler ; DFSDM Filter0 Interrupt + DCD DFSDM1_FLT1_IRQHandler ; DFSDM Filter1 Interrupt + DCD DFSDM1_FLT2_IRQHandler ; DFSDM Filter2 Interrupt + DCD DFSDM1_FLT3_IRQHandler ; DFSDM Filter3 Interrupt + DCD 0 ; Reserved + DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt + DCD TIM15_IRQHandler ; TIM15 global Interrupt + DCD TIM16_IRQHandler ; TIM16 global Interrupt + DCD TIM17_IRQHandler ; TIM17 global Interrupt + DCD MDIOS_WKUP_IRQHandler ; MDIOS Wakeup Interrupt + DCD MDIOS_IRQHandler ; MDIOS global Interrupt + DCD 0 ; Reserved + DCD MDMA_IRQHandler ; MDMA global Interrupt + DCD 0 ; Reserved + DCD SDMMC2_IRQHandler ; SDMMC2 global Interrupt + DCD HSEM1_IRQHandler ; HSEM1 global Interrupt + DCD 0 ; Reserved + DCD ADC3_IRQHandler ; ADC3 global Interrupt + DCD DMAMUX2_OVR_IRQHandler ; DMAMUX Overrun interrupt + DCD BDMA_Channel0_IRQHandler ; BDMA Channel 0 global Interrupt + DCD BDMA_Channel1_IRQHandler ; BDMA Channel 1 global Interrupt + DCD BDMA_Channel2_IRQHandler ; BDMA Channel 2 global Interrupt + DCD BDMA_Channel3_IRQHandler ; BDMA Channel 3 global Interrupt + DCD BDMA_Channel4_IRQHandler ; BDMA Channel 4 global Interrupt + DCD BDMA_Channel5_IRQHandler ; BDMA Channel 5 global Interrupt + DCD BDMA_Channel6_IRQHandler ; BDMA Channel 6 global Interrupt + DCD BDMA_Channel7_IRQHandler ; BDMA Channel 7 global Interrupt + DCD COMP1_IRQHandler ; COMP1 global Interrupt + DCD LPTIM2_IRQHandler ; LP TIM2 global interrupt + DCD LPTIM3_IRQHandler ; LP TIM3 global interrupt + DCD LPTIM4_IRQHandler ; LP TIM4 global interrupt + DCD LPTIM5_IRQHandler ; LP TIM5 global interrupt + DCD LPUART1_IRQHandler ; LP UART1 interrupt + DCD 0 ; Reserved + DCD CRS_IRQHandler ; Clock Recovery Global Interrupt + DCD ECC_IRQHandler ; ECC diagnostic Global Interrupt + DCD SAI4_IRQHandler ; SAI4 global interrupt + DCD DTS_IRQHandler ; DTS interrupt + DCD 0 ; Reserved + DCD WAKEUP_PIN_IRQHandler ; Interrupt for all 6 wake-up pins + DCD OCTOSPI2_IRQHandler ; OCTOSPI2 Interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD FMAC_IRQHandler ; FMAC Interrupt + DCD CORDIC_IRQHandler ; CORDIC Interrupt + DCD UART9_IRQHandler ; UART9 Interrupt + DCD USART10_IRQHandler ; UART10 Interrupt + DCD I2C5_EV_IRQHandler ; I2C5 Event Interrupt + DCD I2C5_ER_IRQHandler ; I2C5 Error Interrupt + DCD FDCAN3_IT0_IRQHandler ; FDCAN3 interrupt line 0 + DCD FDCAN3_IT1_IRQHandler ; FDCAN3 interrupt line 1 + DCD TIM23_IRQHandler ; TIM23 global interrupt + DCD TIM24_IRQHandler ; TIM24 global interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT ExitRun0Mode + IMPORT SystemInit + IMPORT __main + + LDR R0, =ExitRun0Mode + BLX R0 + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_AVD_IRQHandler [WEAK] + EXPORT TAMP_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Stream0_IRQHandler [WEAK] + EXPORT DMA1_Stream1_IRQHandler [WEAK] + EXPORT DMA1_Stream2_IRQHandler [WEAK] + EXPORT DMA1_Stream3_IRQHandler [WEAK] + EXPORT DMA1_Stream4_IRQHandler [WEAK] + EXPORT DMA1_Stream5_IRQHandler [WEAK] + EXPORT DMA1_Stream6_IRQHandler [WEAK] + EXPORT DMA1_Stream7_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN2_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT FDCAN2_IT1_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK] + EXPORT TIM8_UP_TIM13_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT DMA1_Stream7_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT TIM6_DAC_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Stream0_IRQHandler [WEAK] + EXPORT DMA2_Stream1_IRQHandler [WEAK] + EXPORT DMA2_Stream2_IRQHandler [WEAK] + EXPORT DMA2_Stream3_IRQHandler [WEAK] + EXPORT DMA2_Stream4_IRQHandler [WEAK] + EXPORT ETH_IRQHandler [WEAK] + EXPORT ETH_WKUP_IRQHandler [WEAK] + EXPORT FDCAN_CAL_IRQHandler [WEAK] + EXPORT DMA2_Stream5_IRQHandler [WEAK] + EXPORT DMA2_Stream6_IRQHandler [WEAK] + EXPORT DMA2_Stream7_IRQHandler [WEAK] + EXPORT USART6_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT OTG_HS_EP1_OUT_IRQHandler [WEAK] + EXPORT OTG_HS_EP1_IN_IRQHandler [WEAK] + EXPORT OTG_HS_WKUP_IRQHandler [WEAK] + EXPORT OTG_HS_IRQHandler [WEAK] + EXPORT DCMI_PSSI_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT UART8_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SPI6_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT LTDC_IRQHandler [WEAK] + EXPORT LTDC_ER_IRQHandler [WEAK] + EXPORT DMA2D_IRQHandler [WEAK] + EXPORT OCTOSPI1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT I2C4_EV_IRQHandler [WEAK] + EXPORT I2C4_ER_IRQHandler [WEAK] + EXPORT SPDIF_RX_IRQHandler [WEAK] + EXPORT DMAMUX1_OVR_IRQHandler [WEAK] + EXPORT DFSDM1_FLT0_IRQHandler [WEAK] + EXPORT DFSDM1_FLT1_IRQHandler [WEAK] + EXPORT DFSDM1_FLT2_IRQHandler [WEAK] + EXPORT DFSDM1_FLT3_IRQHandler [WEAK] + EXPORT SWPMI1_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT MDIOS_WKUP_IRQHandler [WEAK] + EXPORT MDIOS_IRQHandler [WEAK] + EXPORT MDMA_IRQHandler [WEAK] + EXPORT SDMMC2_IRQHandler [WEAK] + EXPORT HSEM1_IRQHandler [WEAK] + EXPORT ADC3_IRQHandler [WEAK] + EXPORT DMAMUX2_OVR_IRQHandler [WEAK] + EXPORT BDMA_Channel0_IRQHandler [WEAK] + EXPORT BDMA_Channel1_IRQHandler [WEAK] + EXPORT BDMA_Channel2_IRQHandler [WEAK] + EXPORT BDMA_Channel3_IRQHandler [WEAK] + EXPORT BDMA_Channel4_IRQHandler [WEAK] + EXPORT BDMA_Channel5_IRQHandler [WEAK] + EXPORT BDMA_Channel6_IRQHandler [WEAK] + EXPORT BDMA_Channel7_IRQHandler [WEAK] + EXPORT COMP1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT LPTIM4_IRQHandler [WEAK] + EXPORT LPTIM5_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT ECC_IRQHandler [WEAK] + EXPORT SAI4_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT WAKEUP_PIN_IRQHandler [WEAK] + EXPORT OCTOSPI2_IRQHandler [WEAK] + EXPORT FMAC_IRQHandler [WEAK] + EXPORT CORDIC_IRQHandler [WEAK] + EXPORT UART9_IRQHandler [WEAK] + EXPORT USART10_IRQHandler [WEAK] + EXPORT I2C5_EV_IRQHandler [WEAK] + EXPORT I2C5_ER_IRQHandler [WEAK] + EXPORT FDCAN3_IT0_IRQHandler [WEAK] + EXPORT FDCAN3_IT1_IRQHandler [WEAK] + EXPORT TIM23_IRQHandler [WEAK] + EXPORT TIM24_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_AVD_IRQHandler +TAMP_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Stream0_IRQHandler +DMA1_Stream1_IRQHandler +DMA1_Stream2_IRQHandler +DMA1_Stream3_IRQHandler +DMA1_Stream4_IRQHandler +DMA1_Stream5_IRQHandler +DMA1_Stream6_IRQHandler +ADC_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN2_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +FDCAN2_IT1_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +TIM8_BRK_TIM12_IRQHandler +TIM8_UP_TIM13_IRQHandler +TIM8_TRG_COM_TIM14_IRQHandler +TIM8_CC_IRQHandler +DMA1_Stream7_IRQHandler +FMC_IRQHandler +SDMMC1_IRQHandler +TIM5_IRQHandler +SPI3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +TIM6_DAC_IRQHandler +TIM7_IRQHandler +DMA2_Stream0_IRQHandler +DMA2_Stream1_IRQHandler +DMA2_Stream2_IRQHandler +DMA2_Stream3_IRQHandler +DMA2_Stream4_IRQHandler +ETH_IRQHandler +ETH_WKUP_IRQHandler +FDCAN_CAL_IRQHandler +DMA2_Stream5_IRQHandler +DMA2_Stream6_IRQHandler +DMA2_Stream7_IRQHandler +USART6_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +OTG_HS_EP1_OUT_IRQHandler +OTG_HS_EP1_IN_IRQHandler +OTG_HS_WKUP_IRQHandler +OTG_HS_IRQHandler +DCMI_PSSI_IRQHandler +RNG_IRQHandler +FPU_IRQHandler +UART7_IRQHandler +UART8_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SPI6_IRQHandler +SAI1_IRQHandler +LTDC_IRQHandler +LTDC_ER_IRQHandler +DMA2D_IRQHandler +OCTOSPI1_IRQHandler +LPTIM1_IRQHandler +CEC_IRQHandler +I2C4_EV_IRQHandler +I2C4_ER_IRQHandler +SPDIF_RX_IRQHandler +DMAMUX1_OVR_IRQHandler +DFSDM1_FLT0_IRQHandler +DFSDM1_FLT1_IRQHandler +DFSDM1_FLT2_IRQHandler +DFSDM1_FLT3_IRQHandler +SWPMI1_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +MDIOS_WKUP_IRQHandler +MDIOS_IRQHandler +MDMA_IRQHandler +SDMMC2_IRQHandler +HSEM1_IRQHandler +ADC3_IRQHandler +DMAMUX2_OVR_IRQHandler +BDMA_Channel0_IRQHandler +BDMA_Channel1_IRQHandler +BDMA_Channel2_IRQHandler +BDMA_Channel3_IRQHandler +BDMA_Channel4_IRQHandler +BDMA_Channel5_IRQHandler +BDMA_Channel6_IRQHandler +BDMA_Channel7_IRQHandler +COMP1_IRQHandler +LPTIM2_IRQHandler +LPTIM3_IRQHandler +LPTIM4_IRQHandler +LPTIM5_IRQHandler +LPUART1_IRQHandler +CRS_IRQHandler +ECC_IRQHandler +SAI4_IRQHandler +DTS_IRQHandler +WAKEUP_PIN_IRQHandler +OCTOSPI2_IRQHandler +FMAC_IRQHandler +CORDIC_IRQHandler +UART9_IRQHandler +USART10_IRQHandler +I2C5_EV_IRQHandler +I2C5_ER_IRQHandler +FDCAN3_IT0_IRQHandler +FDCAN3_IT1_IRQHandler +TIM23_IRQHandler +TIM24_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c new file mode 100644 index 0000000..89a912c --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -0,0 +1,775 @@ +/* + * 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 functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 +r0p1 port. */ +#define portCPUID ( * ( ( volatile uint32_t * ) 0xE000ed00 ) ) +#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) +#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case it messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Function to enable the VFP. + */ +static void vPortEnableVFP( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * The number of SysTick increments that make up one tick period. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ +volatile uint32_t ulDummy = 0; + + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + started to remove a compiler warning about the function being defined + but never called. ulDummy is used purely to quieten other warnings + about code appearing after this function is called - making ulDummy + volatile makes the compiler think the function could return and + therefore not output an 'unreachable code' warning for code that appears + after it. */ + } +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + /* Start the first task. This also clears the bit that indicates the FPU is + in use in case the FPU was used before the scheduler was started - which + would otherwise result in the unnecessary leaving of space in the SVC stack + for lazy saving of FPU registers. */ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + /* This port can be used on all revisions of the Cortex-M7 core other than + the r0p1 parts. r0p1 parts should use the port from the + /source/portable/GCC/ARM_CM7/r0p1 directory. */ + configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); + configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. Call + vTaskSwitchContext() so link time optimisation does not remove the + symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r0, r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r0, r3} \n" + " \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" + " \n" + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " isb \n" + " \n" + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ + #if WORKAROUND_PMU_CM001 == 1 + " push { r14 } \n" + " pop { pc } \n" + #endif + #endif + " \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE == 1 ) + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ::: "memory" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ::: "memory" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + out of sleep mode to execute immediately. see comments above + __disable_interrupt() call above. */ + __asm volatile( "cpsie i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + and interrupts that execute while the clock is stopped will increase + any slippage between the time maintained by the RTOS and calendar + time. */ + __asm volatile( "cpsid i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* Disable the SysTick clock without reading the + portNVIC_SYSTICK_CTRL_REG register to ensure the + portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + the time the SysTick is stopped for is accounted for as best it can + be, but using the tickless mode will inevitably result in some tiny + drift of the time maintained by the kernel with respect to calendar + time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); + + /* Determine if the SysTick clock has already counted to zero and + been set back to the current reload value (the reload back being + correct for the entire expected idle time) or if the SysTick is yet + to count to zero (in which case an interrupt other than the SysTick + must have brought the system out of sleep mode). */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt is already pending, and the SysTick count + reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + function exits, the tick value maintained by the tick is stepped + forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Exit with interrupts enabled. */ + __asm volatile( "cpsie i" ::: "memory" ); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and clear the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredictable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h b/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..d0a566a --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h @@ -0,0 +1,243 @@ +/* + * 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! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +#define portYIELD() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ::: "memory" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/User/component/lqr.c b/User/component/lqr.c new file mode 100644 index 0000000..ae3c309 --- /dev/null +++ b/User/component/lqr.c @@ -0,0 +1,167 @@ +/* + * LQR控制器实现:单腿建模 + */ + +#include "lqr.h" +#include +#include + +/* Private macros ----------------------------------------------------------- */ +#define LQR_LIMIT(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x))) + +/* Private variables -------------------------------------------------------- */ + +/* Private function prototypes ---------------------------------------------- */ +static int8_t LQR_CalculateErrorState(LQR_t *lqr); +static float LQR_PolynomialCalc(const float *coeff, float leg_length); + +/* Public functions --------------------------------------------------------- */ + +int8_t LQR_Init(LQR_t *lqr, LQR_GainMatrix_t *gain_matrix) { + if (lqr == NULL || gain_matrix == NULL) { + return -1; + } + + /* 清零结构体 */ + memset(lqr, 0, sizeof(LQR_t)); + + /* 设置增益矩阵 */ + lqr->gain_matrix = gain_matrix; + + /* 初始化当前腿长为中等值 */ + lqr->current_leg_length = 0.25f; + + /* 计算初始增益矩阵 */ + LQR_CalculateGainMatrix(lqr, lqr->current_leg_length); + + lqr->initialized = true; + + return 0; +} + +int8_t LQR_UpdateState(LQR_t *lqr, const LQR_State_t *current_state) { + if (lqr == NULL || current_state == NULL) { + return -1; + } + + /* 更新当前状态 */ + lqr->current_state = *current_state; + + /* 计算状态误差 */ + return LQR_CalculateErrorState(lqr); +} + +int8_t LQR_SetTargetState(LQR_t *lqr, const LQR_State_t *target_state) { + if (lqr == NULL || target_state == NULL) { + return -1; + } + + lqr->target_state = *target_state; + + /* 重新计算状态误差 */ + return LQR_CalculateErrorState(lqr); +} + +int8_t LQR_CalculateGainMatrix(LQR_t *lqr, float leg_length) { + if (lqr == NULL || lqr->gain_matrix == NULL) { + return -1; + } + + /* 限制腿长范围 */ + leg_length = LQR_LIMIT(leg_length, 0.1f, 0.4f); + lqr->current_leg_length = leg_length; + + /* 使用多项式拟合计算当前增益矩阵 */ + lqr->K_matrix[0][0] = LQR_PolynomialCalc(lqr->gain_matrix->k11_coeff, leg_length); /* K11: theta */ + lqr->K_matrix[0][1] = LQR_PolynomialCalc(lqr->gain_matrix->k12_coeff, leg_length); /* K12: d_theta */ + lqr->K_matrix[0][2] = LQR_PolynomialCalc(lqr->gain_matrix->k13_coeff, leg_length); /* K13: x */ + lqr->K_matrix[0][3] = LQR_PolynomialCalc(lqr->gain_matrix->k14_coeff, leg_length); /* K14: d_x */ + lqr->K_matrix[0][4] = LQR_PolynomialCalc(lqr->gain_matrix->k15_coeff, leg_length); /* K15: phi */ + lqr->K_matrix[0][5] = LQR_PolynomialCalc(lqr->gain_matrix->k16_coeff, leg_length); /* K16: d_phi */ + + lqr->K_matrix[1][0] = LQR_PolynomialCalc(lqr->gain_matrix->k21_coeff, leg_length); /* K21: theta */ + lqr->K_matrix[1][1] = LQR_PolynomialCalc(lqr->gain_matrix->k22_coeff, leg_length); /* K22: d_theta */ + lqr->K_matrix[1][2] = LQR_PolynomialCalc(lqr->gain_matrix->k23_coeff, leg_length); /* K23: x */ + lqr->K_matrix[1][3] = LQR_PolynomialCalc(lqr->gain_matrix->k24_coeff, leg_length); /* K24: d_x */ + lqr->K_matrix[1][4] = LQR_PolynomialCalc(lqr->gain_matrix->k25_coeff, leg_length); /* K25: phi */ + lqr->K_matrix[1][5] = LQR_PolynomialCalc(lqr->gain_matrix->k26_coeff, leg_length); /* K26: d_phi */ + + return 0; +} + +int8_t LQR_Control(LQR_t *lqr) { + if (lqr == NULL || !lqr->initialized) { + return -1; + } + + /* LQR控制律: u = -K * x_error + * 其中 u = [T; Tp], x_error = x_current - x_target + */ + + /* 计算轮毂力矩T */ + lqr->control_output.T = -( + lqr->K_matrix[0][0] * lqr->error_state.theta + + lqr->K_matrix[0][1] * lqr->error_state.d_theta + + lqr->K_matrix[0][2] * lqr->error_state.x + + lqr->K_matrix[0][3] * lqr->error_state.d_x + + lqr->K_matrix[0][4] * lqr->error_state.phi + + lqr->K_matrix[0][5] * lqr->error_state.d_phi + ); + + /* 计算髋关节力矩Tp */ + lqr->control_output.Tp = -( + lqr->K_matrix[1][0] * lqr->error_state.theta + + lqr->K_matrix[1][1] * lqr->error_state.d_theta + + lqr->K_matrix[1][2] * lqr->error_state.x + + lqr->K_matrix[1][3] * lqr->error_state.d_x + + lqr->K_matrix[1][4] * lqr->error_state.phi + + lqr->K_matrix[1][5] * lqr->error_state.d_phi + ); + + return 0; +} + +int8_t LQR_Reset(LQR_t *lqr) { + if (lqr == NULL) { + return -1; + } + + /* 清零状态和输出 */ + memset(&lqr->current_state, 0, sizeof(LQR_State_t)); + memset(&lqr->target_state, 0, sizeof(LQR_State_t)); + memset(&lqr->error_state, 0, sizeof(LQR_State_t)); + memset(&lqr->control_output, 0, sizeof(LQR_Output_t)); + + return 0; +} + +/* Private functions -------------------------------------------------------- */ + +static int8_t LQR_CalculateErrorState(LQR_t *lqr) { + if (lqr == NULL) { + return -1; + } + + /* 计算状态误差 */ + lqr->error_state.theta = lqr->current_state.theta - lqr->target_state.theta; + lqr->error_state.d_theta = lqr->current_state.d_theta - lqr->target_state.d_theta; + lqr->error_state.x = lqr->current_state.x - lqr->target_state.x; + lqr->error_state.d_x = lqr->current_state.d_x - lqr->target_state.d_x; + lqr->error_state.phi = lqr->current_state.phi - lqr->target_state.phi; + lqr->error_state.d_phi = lqr->current_state.d_phi - lqr->target_state.d_phi; + + return 0; +} + +static float LQR_PolynomialCalc(const float *coeff, float leg_length) { + if (coeff == NULL) { + return 0.0f; + } + + /* 计算3阶多项式: coeff[0]*L^3 + coeff[1]*L^2 + coeff[2]*L + coeff[3] */ + float L = leg_length; + float L2 = L * L; + float L3 = L2 * L; + + return coeff[0] * L3 + coeff[1] * L2 + coeff[2] * L + coeff[3]; +} diff --git a/User/component/lqr.h b/User/component/lqr.h new file mode 100644 index 0000000..e05f224 --- /dev/null +++ b/User/component/lqr.h @@ -0,0 +1,134 @@ +/* + * LQR控制器 + * 用于轮腿平衡机器人的线性二次调节器控制:单腿建模 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------- */ +#include +#include +#include + +/* Exported constants ------------------------------------------------------- */ +#define LQR_STATE_DIM 6 /* 状态向量维度: theta, d_theta, x, d_x, phi, d_phi */ +#define LQR_INPUT_DIM 2 /* 输入向量维度: T(轮毂力矩), Tp(髋关节力矩) */ +#define LQR_POLY_ORDER 4 /* 多项式拟合阶数 */ + +/* Exported types ----------------------------------------------------------- */ + +typedef struct { + float theta; /* 摆杆角度 */ + float d_theta; /* 摆杆角速度 */ + float x; /* 驱动轮位移 */ + float d_x; /* 驱动轮速度 */ + float phi; /* 机体俯仰角 */ + float d_phi; /* 机体俯仰角速度 */ +} LQR_State_t; + +typedef struct { + float T; /* 轮毂力矩 (N·m) */ + float Tp; /* 髋关节力矩 (N·m) */ +} LQR_Output_t; + +typedef struct { + /* K矩阵第一行(轮毂力矩T对应的增益) */ + float k11_coeff[LQR_POLY_ORDER]; /* K(1,1): theta */ + float k12_coeff[LQR_POLY_ORDER]; /* K(1,2): d_theta */ + float k13_coeff[LQR_POLY_ORDER]; /* K(1,3): x */ + float k14_coeff[LQR_POLY_ORDER]; /* K(1,4): d_x */ + float k15_coeff[LQR_POLY_ORDER]; /* K(1,5): phi */ + float k16_coeff[LQR_POLY_ORDER]; /* K(1,6): d_phi */ + + /* K矩阵第二行(髋关节力矩Tp对应的增益) */ + float k21_coeff[LQR_POLY_ORDER]; /* K(2,1): theta */ + float k22_coeff[LQR_POLY_ORDER]; /* K(2,2): d_theta */ + float k23_coeff[LQR_POLY_ORDER]; /* K(2,3): x */ + float k24_coeff[LQR_POLY_ORDER]; /* K(2,4): d_x */ + float k25_coeff[LQR_POLY_ORDER]; /* K(2,5): phi */ + float k26_coeff[LQR_POLY_ORDER]; /* K(2,6): d_phi */ +} LQR_GainMatrix_t; + + +/** + * @brief LQR控制器主结构体 + */ +typedef struct { + LQR_GainMatrix_t *gain_matrix; /* 增益矩阵参数指针 */ + + LQR_State_t current_state; /* 当前状态 */ + LQR_State_t target_state; /* 目标状态 */ + LQR_State_t error_state; /* 状态误差 */ + + LQR_Output_t control_output; /* 控制输出 */ + + /* 运行时变量 */ + float current_leg_length; /* 当前腿长 */ + float K_matrix[LQR_INPUT_DIM][LQR_STATE_DIM]; /* 当前增益矩阵 */ + + bool initialized; /* 初始化标志 */ + +} LQR_t; + +/* Exported functions prototypes -------------------------------------------- */ + +/** + * @brief 初始化LQR控制器 + * + * @param lqr LQR控制器结构体指针 + * @param gain_matrix 增益矩阵参数指针 + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_Init(LQR_t *lqr, LQR_GainMatrix_t *gain_matrix); + + +/** + * @brief 更新当前状态 + * + * @param lqr LQR控制器结构体指针 + * @param state 当前状态 + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_UpdateState(LQR_t *lqr, const LQR_State_t *current_state); + +/** + * @brief 设置目标状态 + * + * @param lqr LQR控制器结构体指针 + * @param target_state 目标状态 + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_SetTargetState(LQR_t *lqr, const LQR_State_t *target_state); + +/** + * @brief 根据当前腿长计算增益矩阵 + * + * @param lqr LQR控制器结构体指针 + * @param leg_length 当前腿长 (m) + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_CalculateGainMatrix(LQR_t *lqr, float leg_length); + +/** + * @brief 执行LQR控制计算 + * + * @param lqr LQR控制器结构体指针 + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_Control(LQR_t *lqr); + +/** + * @brief 重置LQR控制器 + * + * @param lqr LQR控制器结构体指针 + * @return int8_t 0-成功, 其他-失败 + */ +int8_t LQR_Reset(LQR_t *lqr); + +#ifdef __cplusplus +} +#endif diff --git a/User/component/vmc.c b/User/component/vmc.c new file mode 100644 index 0000000..f819c98 --- /dev/null +++ b/User/component/vmc.c @@ -0,0 +1,383 @@ +/* + * VMC虚拟模型控制器实现 + * + * 本文件实现了轮腿机器人的VMC (Virtual Model Control) 虚拟模型控制算法 + * 主要功能包括: + * 1. 五连杆机构的正逆运动学解算 + * 2. 虚拟力到关节力矩的映射 + * 3. 地面接触检测 + * 4. 等效摆动杆模型转换 + * + * 参考文献: + * - 韭菜的菜 知乎: 平衡步兵控制系统设计 + * - 上交轮腿电控开源方案 (2023) + */ + +#include "vmc.h" +#include + +/* Private typedef ---------------------------------------------------------- */ +/* Private define ----------------------------------------------------------- */ + +#define VMC_EPSILON (1e-6f) // 数值计算精度 +#define VMC_MAX_ITER (10) // 最大迭代次数 + +/* Private macro ------------------------------------------------------------ */ + +/** + * @brief 限制数值范围 + */ +#define VMC_CLAMP(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? (max) : (val))) + +/** + * @brief 安全开方 + */ +#define VMC_SAFE_SQRT(x) (((x) > 0) ? sqrtf(x) : 0.0f) + +/* Private variables -------------------------------------------------------- */ +/* Private function prototypes ---------------------------------------------- */ + +static int8_t VMC_ValidateParams(const VMC_Param_t *param); +static void VMC_UpdateKinematics(VMC_t *vmc, float phi1, float phi4); +static int8_t VMC_SolveClosedLoop(VMC_t *vmc); +static float VMC_ComputeNumericDerivative(float current, float previous, float dt); + +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief 初始化VMC控制器 + */ +int8_t VMC_Init(VMC_t *vmc, const VMC_Param_t *param, float sample_freq) { + if (vmc == NULL || param == NULL || sample_freq <= 0) { + return -1; + } + + // 复制参数 + memcpy(&vmc->param, param, sizeof(VMC_Param_t)); + + // 设置控制周期 + vmc->dt = 1.0f / sample_freq; + + // 重置状态 + VMC_Reset(vmc); + + vmc->initialized = true; + + return 0; +} + +/** + * @brief VMC五连杆正解算 + * + * 通过髋关节角度和机体姿态,计算足端位置和等效摆动杆参数 + * + * 坐标系定义: + * - x轴: 机体前进方向为正 + * - y轴: 竖直向下为正 + * - 角度: 顺时针为正 + */ +int8_t VMC_ForwardSolve(VMC_t *vmc, float phi1, float phi4, float body_pitch, float body_pitch_rate) { + if (vmc == NULL || !vmc->initialized) { + return -1; + } + body_pitch = -body_pitch; // 机体俯仰角取反 + + VMC_Leg_t *leg = &vmc->leg; + + // 保存历史值 + leg->last_phi0 = leg->phi0; + leg->last_L0 = leg->L0; + leg->last_d_L0 = leg->d_L0; + leg->last_d_theta = leg->d_theta; + + // 更新关节角度 + leg->phi1 = phi1; + leg->phi4 = phi4; + + // 更新运动学状态 + VMC_UpdateKinematics(vmc, phi1, phi4); + + // 求解闭环运动学 + if (VMC_SolveClosedLoop(vmc) != 0) { + return -1; + } + + // 计算足端坐标 + leg->foot_x = leg->XC - vmc->param.hip_length / 2.0f; + leg->foot_y = leg->YC; + + // 计算等效摆动杆参数 + leg->L0 = VMC_SAFE_SQRT(leg->foot_x * leg->foot_x + leg->foot_y * leg->foot_y); + leg->phi0 = atan2f(leg->foot_y, leg->foot_x); + + // 计算等效摆动杆角度(相对于机体坐标系) + leg->alpha = VMC_PI_2 - leg->phi0; + leg->theta = VMC_PI - (VMC_PI_2 + body_pitch - leg->phi0); + + // 角度归一化 + VMC_ANGLE_NORMALIZE(leg->theta); + VMC_ANGLE_NORMALIZE(leg->phi0); + + // 计算角速度和长度变化率 + leg->d_phi0 = VMC_ComputeNumericDerivative(leg->phi0, leg->last_phi0, vmc->dt); + leg->d_alpha = -leg->d_phi0; + leg->d_theta = body_pitch_rate + leg->d_phi0; + leg->d_L0 = VMC_ComputeNumericDerivative(leg->L0, leg->last_L0, vmc->dt); + + // 计算角加速度 + leg->dd_theta = VMC_ComputeNumericDerivative(leg->d_theta, leg->last_d_theta, vmc->dt); + + VMC_GroundContactDetection(vmc); // 更新地面接触状态 + return 0; +} + +/** + * @brief VMC五连杆逆解算(力矩分配) + * + * 根据期望的虚拟力和力矩,通过雅可比矩阵计算关节力矩 + */ +int8_t VMC_InverseSolve(VMC_t *vmc, float F_virtual, float T_virtual) { + if (vmc == NULL || !vmc->initialized) { + return -1; + } + + // 保存虚拟力和力矩 + vmc->leg.F_virtual = F_virtual; + vmc->leg.T_virtual = -T_virtual; + + // 计算雅可比矩阵 + if (VMC_ComputeJacobian(vmc) != 0) { + return -1; + } + + VMC_Leg_t *leg = &vmc->leg; + + // 通过雅可比转置计算关节力矩 + // tau = J^T * F_virtual + leg->tau_hip_rear = leg->J11 * vmc->leg.F_virtual + leg->J12 * vmc->leg.T_virtual; + leg->tau_hip_front = leg->J21 * vmc->leg.F_virtual + leg->J22 * vmc->leg.T_virtual; + + return 0; +} + +/** + * @brief 地面接触检测 + * + * 基于虚拟力和腿部状态估计地面法向力 + */ +float VMC_GroundContactDetection(VMC_t *vmc) { + if (vmc == NULL || !vmc->initialized) { + return 0.0f; + } + + VMC_Leg_t *leg = &vmc->leg; + + // 计算地面法向力 + // Fn = F0*cos(theta) + Tp*sin(theta)/L0 + mg + leg->Fn = leg->F_virtual * cosf(leg->theta) + + leg->T_virtual * sinf(leg->theta) / leg->L0 + + 10.0f; // 添加轮子重力,假设轮子质量约1kg + + // 地面接触判断 + leg->is_ground_contact = (leg->Fn > 20.0f); // 10N阈值 + + return leg->Fn; +} + +/** + * @brief 获取足端位置 + */ +int8_t VMC_GetFootPosition(const VMC_t *vmc, float *x, float *y) { + if (vmc == NULL || !vmc->initialized || x == NULL || y == NULL) { + return -1; + } + + *x = vmc->leg.foot_x; + *y = vmc->leg.foot_y; + + return 0; +} + +/** + * @brief 获取等效摆动杆参数 + */ +int8_t VMC_GetVirtualLegState(const VMC_t *vmc, float *length, float *angle, float *d_length, float *d_angle) { + if (vmc == NULL || !vmc->initialized) { + return -1; + } + + if (length) *length = vmc->leg.L0; + if (angle) *angle = vmc->leg.theta; + if (d_length) *d_length = vmc->leg.d_L0; + if (d_angle) *d_angle = vmc->leg.d_theta; + + return 0; +} + +/** + * @brief 获取关节输出力矩 + */ +int8_t VMC_GetJointTorques(const VMC_t *vmc, float *tau_front, float *tau_rear) { + if (vmc == NULL || !vmc->initialized || tau_front == NULL || tau_rear == NULL) { + return -1; + } + + *tau_front = vmc->leg.tau_hip_front; + *tau_rear = vmc->leg.tau_hip_rear; + + return 0; +} + +/** + * @brief 重置VMC控制器状态 + */ +void VMC_Reset(VMC_t *vmc) { + if (vmc == NULL) { + return; + } + + // 清零腿部状态 + memset(&vmc->leg, 0, sizeof(VMC_Leg_t)); + + // 设置初始值 + vmc->leg.L0 = 0.15f; // 默认腿长15cm + vmc->leg.theta = 0.0f; +} + +/** + * @brief 设置虚拟力和力矩 + */ +void VMC_SetVirtualForces(VMC_t *vmc, float F_virtual, float T_virtual) { + if (vmc == NULL || !vmc->initialized) { + return; + } + + vmc->leg.F_virtual = F_virtual; + vmc->leg.T_virtual = T_virtual; +} + +/** + * @brief 计算雅可比矩阵 + * + * 根据当前关节配置计算从虚拟力到关节力矩的雅可比矩阵 + */ +int8_t VMC_ComputeJacobian(VMC_t *vmc) { + if (vmc == NULL || !vmc->initialized) { + return -1; + } + + VMC_Leg_t *leg = &vmc->leg; + + // 检查分母不为零 + float sin_diff = sinf(leg->phi3 - leg->phi2); + if (fabsf(sin_diff) < VMC_EPSILON) { + return -1; // 奇异配置 + } + + // 计算雅可比矩阵元素 + // J11: 后髋关节到支撑力的雅可比 + leg->J11 = (vmc->param.leg_1 * sinf(leg->phi0 - leg->phi3) * + sinf(leg->phi1 - leg->phi2)) / sin_diff; + + // J12: 后髋关节到摆动力矩的雅可比 + leg->J12 = (vmc->param.leg_1 * cosf(leg->phi0 - leg->phi3) * + sinf(leg->phi1 - leg->phi2)) / (leg->L0 * sin_diff); + + // J21: 前髋关节到支撑力的雅可比 + leg->J21 = (vmc->param.leg_4 * sinf(leg->phi0 - leg->phi2) * + sinf(leg->phi3 - leg->phi4)) / sin_diff; + + // J22: 前髋关节到摆动力矩的雅可比 + leg->J22 = (vmc->param.leg_4 * cosf(leg->phi0 - leg->phi2) * + sinf(leg->phi3 - leg->phi4)) / (leg->L0 * sin_diff); + + return 0; +} + +/* Private functions -------------------------------------------------------- */ + +/** + * @brief 验证VMC参数有效性 + */ +static int8_t VMC_ValidateParams(const VMC_Param_t *param) { + if (param->hip_length <= 0 || param->leg_1 <= 0 || param->leg_2 <= 0 || + param->leg_3 <= 0 || param->leg_4 <= 0 || param->wheel_radius <= 0) { + return -1; + } + + // 检查腿部几何约束 + if (param->leg_2 + param->leg_3 <= param->leg_1 + param->leg_4) { + return -1; // 不满足闭环几何约束 + } + + return 0; +} + +/** + * @brief 更新基本运动学参数 + */ +static void VMC_UpdateKinematics(VMC_t *vmc, float phi1, float phi4) { + VMC_Leg_t *leg = &vmc->leg; + + // 计算关键点坐标 + // 点B (后髋关节末端) + leg->XB = vmc->param.leg_1 * cosf(phi1); + leg->YB = vmc->param.leg_1 * sinf(phi1); + + // 点D (前髋关节末端) + leg->XD = vmc->param.hip_length + vmc->param.leg_4 * cosf(phi4); + leg->YD = vmc->param.leg_4 * sinf(phi4); + + // 计算BD连杆长度 + float dx = leg->XD - leg->XB; + float dy = leg->YD - leg->YB; + leg->lBD = VMC_SAFE_SQRT(dx * dx + dy * dy); +} + +/** + * @brief 求解闭环运动学方程 + * + * 根据两个髋关节角度,求解中间关节角度 + */ +static int8_t VMC_SolveClosedLoop(VMC_t *vmc) { + VMC_Leg_t *leg = &vmc->leg; + + // 使用余弦定理求解phi2 + leg->A0 = 2 * vmc->param.leg_2 * (leg->XD - leg->XB); + leg->B0 = 2 * vmc->param.leg_2 * (leg->YD - leg->YB); + leg->C0 = vmc->param.leg_2 * vmc->param.leg_2 + + leg->lBD * leg->lBD - + vmc->param.leg_3 * vmc->param.leg_3; + + // 检查判别式 + float discriminant = leg->A0 * leg->A0 + leg->B0 * leg->B0 - leg->C0 * leg->C0; + if (discriminant < 0) { + return -1; // 无解 + } + + float sqrt_discriminant = VMC_SAFE_SQRT(discriminant); + + // 计算phi2 (选择合适的解) + leg->phi2 = 2 * atan2f(leg->B0 + sqrt_discriminant, leg->A0 + leg->C0); + + // 计算phi3 + leg->phi3 = atan2f(leg->YB - leg->YD + vmc->param.leg_2 * sinf(leg->phi2), + leg->XB - leg->XD + vmc->param.leg_2 * cosf(leg->phi2)); + + // 计算足端坐标点C + leg->XC = leg->XB + vmc->param.leg_2 * cosf(leg->phi2); + leg->YC = leg->YB + vmc->param.leg_2 * sinf(leg->phi2); + + return 0; +} + +/** + * @brief 计算数值微分 + */ +static float VMC_ComputeNumericDerivative(float current, float previous, float dt) { + if (dt <= 0) { + return 0.0f; + } + + return (current - previous) / dt; +} diff --git a/User/component/vmc.h b/User/component/vmc.h new file mode 100644 index 0000000..3bac3e8 --- /dev/null +++ b/User/component/vmc.h @@ -0,0 +1,195 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------- */ +#include +#include +#include + +/* Exported types ----------------------------------------------------------- */ + +/** + * @brief VMC虚拟模型控制参数结构体 + */ +typedef struct { + float hip_length; // 髋关节间距 + float leg_1; // 大腿前端长度 (L1) + float leg_2; // 大腿后端长度 (L2) + float leg_3; // 小腿长度 (L3) + float leg_4; // 小腿前端长度 (L4) + float wheel_radius; // 轮子半径 + float wheel_mass; // 轮子质量 +} VMC_Param_t; + +/** + * @brief VMC腿部运动学状态结构体 + */ +typedef struct { + // 关节角度 + float phi1; // 后髋关节角度 (rad) + float phi2; // 大腿后端角度 (rad) + float phi3; // 小腿角度 (rad) + float phi4; // 前髋关节角度 (rad) + + // 足端坐标 + float foot_x; // 足端x坐标 + float foot_y; // 足端y坐标 + + // 等效摆动杆参数 + float L0; // 等效摆动杆长度 + float d_L0; // 等效摆动杆长度变化率 + float theta; // 等效摆动杆角度 + float d_theta; // 等效摆动杆角速度 + float dd_theta; // 等效摆动杆角加速度 + + // 虚拟力和力矩 + float F_virtual; // 虚拟支撑力 + float T_virtual; // 虚拟摆动力矩 + + // 雅可比矩阵元素 + float J11, J12, J21, J22; + + // 输出力矩 + float tau_hip_front; // 前髋关节输出力矩 + float tau_hip_rear; // 后髋关节输出力矩 + + // 内部计算变量 + float XB, YB, XC, YC, XD, YD; // 各关键点坐标 + float lBD; // BD连杆长度 + float A0, B0, C0; // 运动学计算中间变量 + float phi0; // 足端极角 + float alpha; // 等效摆动杆与竖直方向夹角 + float d_phi0; // 足端极角变化率 + float d_alpha; // alpha角变化率 + + // 历史值(用于数值微分) + float last_phi0; + float last_L0; + float last_d_L0; + float last_d_theta; + + // 地面接触检测 + float Fn; // 地面法向力 + bool is_ground_contact; // 地面接触标志 +} VMC_Leg_t; + +/** + * @brief VMC控制器结构体 + */ +typedef struct { + VMC_Param_t param; // VMC参数 + VMC_Leg_t leg; // 腿部状态 + float dt; // 控制周期 + bool initialized; // 初始化标志 +} VMC_t; + +/* Exported constants ------------------------------------------------------- */ + +#define VMC_PI_2 (1.5707963267948966f) +#define VMC_PI (3.1415926535897932f) +#define VMC_2PI (6.2831853071795865f) + +/* Exported macros ---------------------------------------------------------- */ + +/** + * @brief 角度范围限制到[-PI, PI] + */ +#define VMC_ANGLE_NORMALIZE(angle) do { \ + while((angle) > VMC_PI) (angle) -= VMC_2PI; \ + while((angle) < -VMC_PI) (angle) += VMC_2PI; \ +} while(0) + +/* Exported functions prototypes -------------------------------------------- */ + +/** + * @brief 初始化VMC控制器 + * @param vmc VMC控制器实例 + * @param param VMC参数 + * @param sample_freq 采样频率 (Hz) + * @return 0:成功, -1:失败 + */ +int8_t VMC_Init(VMC_t *vmc, const VMC_Param_t *param, float sample_freq); + +/** + * @brief VMC五连杆正解算 + * @param vmc VMC控制器实例 + * @param phi1 后髋关节角度 (rad) + * @param phi4 前髋关节角度 (rad) + * @param body_pitch 机体pitch角 (rad) + * @param body_pitch_rate 机体pitch角速度 (rad/s) + * @return 0:成功, -1:失败 + */ +int8_t VMC_ForwardSolve(VMC_t *vmc, float phi1, float phi4, float body_pitch, float body_pitch_rate); + +/** + * @brief VMC五连杆逆解算(力矩分配) + * @param vmc VMC控制器实例 + * @param F_virtual 期望虚拟支撑力 (N) + * @param T_virtual 期望虚拟摆动力矩 (N*m) + * @return 0:成功, -1:失败 + */ +int8_t VMC_InverseSolve(VMC_t *vmc, float F_virtual, float T_virtual); + +/** + * @brief 地面接触检测 + * @param vmc VMC控制器实例 + * @return 地面法向力 (N) + */ +float VMC_GroundContactDetection(VMC_t *vmc); + +/** + * @brief 获取足端位置(直角坐标) + * @param vmc VMC控制器实例 + * @param x 足端x坐标输出 + * @param y 足端y坐标输出 + * @return 0:成功, -1:失败 + */ +int8_t VMC_GetFootPosition(const VMC_t *vmc, float *x, float *y); + +/** + * @brief 获取等效摆动杆参数 + * @param vmc VMC控制器实例 + * @param length 等效摆动杆长度输出 + * @param angle 等效摆动杆角度输出 + * @param d_length 等效摆动杆长度变化率输出 + * @param d_angle 等效摆动杆角速度输出 + * @return 0:成功, -1:失败 + */ +int8_t VMC_GetVirtualLegState(const VMC_t *vmc, float *length, float *angle, float *d_length, float *d_angle); + +/** + * @brief 获取关节输出力矩 + * @param vmc VMC控制器实例 + * @param tau_front 前髋关节力矩输出 + * @param tau_rear 后髋关节力矩输出 + * @return 0:成功, -1:失败 + */ +int8_t VMC_GetJointTorques(const VMC_t *vmc, float *tau_front, float *tau_rear); + +/** + * @brief 重置VMC控制器状态 + * @param vmc VMC控制器实例 + */ +void VMC_Reset(VMC_t *vmc); + +/** + * @brief 设置虚拟力和力矩 + * @param vmc VMC控制器实例 + * @param F_virtual 虚拟支撑力 (N) + * @param T_virtual 虚拟摆动力矩 (N*m) + */ +void VMC_SetVirtualForces(VMC_t *vmc, float F_virtual, float T_virtual); + +/** + * @brief 计算雅可比矩阵 + * @param vmc VMC控制器实例 + * @return 0:成功, -1:失败 + */ +int8_t VMC_ComputeJacobian(VMC_t *vmc); + +#ifdef __cplusplus +} +#endif diff --git a/User/module/balance_chassis.c b/User/module/balance_chassis.c new file mode 100644 index 0000000..11cecce --- /dev/null +++ b/User/module/balance_chassis.c @@ -0,0 +1,710 @@ +#include "module/balance_chassis.h" +#include "bsp/can.h" +#include "bsp/time.h" +#include "component/filter.h" +#include "component/user_math.h" +#include "device/motor_lz.h" +#include +#include +#include + +/** + * @brief 使能所有电机 + * @param c 底盘结构体指针 + * @return + */ +static int8_t Chassis_MotorEnable(Chassis_t *c) { + if (c == NULL) + return CHASSIS_ERR_NULL; + + for (int i = 0; i < 4; i++) { + MOTOR_LZ_Param_t *joint_param = &c->param->joint_param[i]; + MOTOR_LZ_Enable(joint_param); + } + for (int i = 0; i < 2; i++) { + MOTOR_LK_Param_t *wheel_param = &c->param->wheel_param[i]; + MOTOR_LK_MotorOn(wheel_param); + } + return CHASSIS_OK; +} + +static int8_t Chassis_MotorRelax(Chassis_t *c) { + if (c == NULL) + return CHASSIS_ERR_NULL; + for (int i = 0; i < 4; i++) { + MOTOR_LZ_Param_t *joint_param = &c->param->joint_param[i]; + MOTOR_LZ_Relax(joint_param); + } + for (int i = 0; i < 2; i++) { + MOTOR_LK_Param_t *wheel_param = &c->param->wheel_param[i]; + MOTOR_LK_Relax(wheel_param); + } + return CHASSIS_OK; +} + +static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) { + if (c == NULL) + return CHASSIS_ERR_NULL; /* 主结构体不能为空 */ + if (mode == c->mode) + return CHASSIS_OK; /* 模式未改变直接返回 */ + + // 特殊处理:从JUMP切换到WHELL_LEG_BALANCE时不重置 + // 但从WHELL_LEG_BALANCE切换到JUMP时,需要重置以触发新的跳跃 + if (c->mode == CHASSIS_MODE_JUMP && mode == CHASSIS_MODE_WHELL_LEG_BALANCE) { + c->mode = mode; + return CHASSIS_OK; + } + if (c->mode == CHASSIS_MODE_WHELL_LEG_BALANCE && mode == CHASSIS_MODE_JUMP) { + c->mode = mode; + c->state = 0; // 重置状态,确保每次切换模式时都重新初始化 + c->jump_time=0; // 重置跳跃时间,切换到JUMP模式时会触发新跳跃 + return CHASSIS_OK; + } + + Chassis_MotorEnable(c); + + PID_Reset(&c->pid.leg_length[0]); + PID_Reset(&c->pid.leg_length[1]); + PID_Reset(&c->pid.yaw); + PID_Reset(&c->pid.roll); + PID_Reset(&c->pid.tp[0]); + PID_Reset(&c->pid.tp[1]); + + // 双零点自动选择逻辑(使用user_math的CircleError函数) + float current_yaw = c->feedback.yaw.rotor_abs_angle; + float zero_point_1 = c->param->mech_zero_yaw; + float zero_point_2 = zero_point_1 + M_PI; // 第二个零点,相差180度 + + // 使用CircleError计算到两个零点的角度差(范围为M_2PI) + float error_to_zero1 = CircleError(zero_point_1, current_yaw, M_2PI); + float error_to_zero2 = CircleError(zero_point_2, current_yaw, M_2PI); + + // 选择误差绝对值更小的零点作为目标,并记录是否使用了第二个零点 + if (fabsf(error_to_zero1) <= fabsf(error_to_zero2)) { + c->yaw_control.target_yaw = zero_point_1; + c->yaw_control.is_reversed = false; // 使用第一个零点,不反转 + } else { + c->yaw_control.target_yaw = zero_point_2; + c->yaw_control.is_reversed = true; // 使用第二个零点,需要反转前后方向 + } + + // 清空位移 + c->chassis_state.position_x = 0.0f; + c->chassis_state.velocity_x = 0.0f; + c->chassis_state.last_velocity_x = 0.0f; + c->chassis_state.target_x = 0.0f; + c->chassis_state.target_velocity_x = 0.0f; + c->chassis_state.last_target_velocity_x = 0.0f; + + LQR_Reset(&c->lqr[0]); + LQR_Reset(&c->lqr[1]); + + LowPassFilter2p_Reset(&c->filter.joint_out[0], 0.0f); + LowPassFilter2p_Reset(&c->filter.joint_out[1], 0.0f); + LowPassFilter2p_Reset(&c->filter.joint_out[2], 0.0f); + LowPassFilter2p_Reset(&c->filter.joint_out[3], 0.0f); + LowPassFilter2p_Reset(&c->filter.wheel_out[0], 0.0f); + LowPassFilter2p_Reset(&c->filter.wheel_out[1], 0.0f); + + c->mode = mode; + c->state = 0; // 重置状态,确保每次切换模式时都重新初始化 + c->jump_time=0; // 重置跳跃时间,切换到JUMP模式时会触发新跳跃 + c->wz_multi=0.0f; + + return CHASSIS_OK; +} + +/* 更新机体状态估计 */ +static void Chassis_UpdateChassisState(Chassis_t *c) { + if (c == NULL) + return; + + // 从轮子编码器估计机体速度 (参考C++代码) + float left_wheel_speed_dps = c->feedback.wheel[0].rotor_speed; // dps (度每秒) + float right_wheel_speed_dps = + c->feedback.wheel[1].rotor_speed; // dps (度每秒) + + // 将dps转换为rad/s + float left_wheel_speed = left_wheel_speed_dps * M_PI / 180.0f; // rad/s + float right_wheel_speed = right_wheel_speed_dps * M_PI / 180.0f; // rad/s + + float wheel_radius = 0.072f; + + float left_wheel_linear_vel = left_wheel_speed * wheel_radius; + float right_wheel_linear_vel = right_wheel_speed * wheel_radius; + + // 机体x方向速度 (轮子中心速度) + c->chassis_state.last_velocity_x = c->chassis_state.velocity_x; + c->chassis_state.velocity_x = + (left_wheel_linear_vel + right_wheel_linear_vel) / 2.0f; + + // 在跳跃模式的起跳和收腿阶段暂停位移积分,避免轮子空转导致的位移误差 + if (!(c->mode == CHASSIS_MODE_JUMP && (c->state == 2 || c->state == 3))) { + // 积分得到位置 + c->chassis_state.position_x += c->chassis_state.velocity_x * c->dt; + } +} + + + +int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq) { + if (c == NULL || param == NULL || target_freq <= 0.0f) { + return -1; // 参数错误 + } + c->param = param; + + c->mode = CHASSIS_MODE_RELAX; + + /*初始化can*/ + BSP_CAN_Init(); + + /*初始化和注册所有电机*/ + MOTOR_LZ_Init(); + + // 注册关节电机 + for (int i = 0; i < 4; i++) { + if (MOTOR_LZ_Register(&c->param->joint_param[i]) != DEVICE_OK) { + return DEVICE_ERR; + } + } + + // 注册轮子电机 + for (int i = 0; i < 2; i++) { + if (MOTOR_LK_Register(&c->param->wheel_param[i]) != DEVICE_OK) { + return DEVICE_ERR; + } + } + + MOTOR_DM_Register(&c->param->yaw_motor); + + /*初始化VMC控制器*/ + VMC_Init(&c->vmc_[0], ¶m->vmc_param[0], target_freq); + VMC_Init(&c->vmc_[1], ¶m->vmc_param[1], target_freq); + + /*初始化pid*/ + PID_Init(&c->pid.leg_length[0], KPID_MODE_CALC_D, target_freq, + ¶m->leg_length); + PID_Init(&c->pid.leg_length[1], KPID_MODE_CALC_D, target_freq, + ¶m->leg_length); + PID_Init(&c->pid.yaw, KPID_MODE_CALC_D, target_freq, ¶m->yaw); + PID_Init(&c->pid.roll, KPID_MODE_CALC_D, target_freq, ¶m->roll); + PID_Init(&c->pid.tp[0], KPID_MODE_CALC_D, target_freq, ¶m->tp); + PID_Init(&c->pid.tp[1], KPID_MODE_CALC_D, target_freq, ¶m->tp); + + /*初始化LQR控制器*/ + LQR_Init(&c->lqr[0], ¶m->lqr_gains); + LQR_Init(&c->lqr[1], ¶m->lqr_gains); + + LowPassFilter2p_Init(&c->filter.joint_out[0], target_freq, + param->low_pass_cutoff_freq.out); + LowPassFilter2p_Init(&c->filter.joint_out[1], target_freq, + param->low_pass_cutoff_freq.out); + LowPassFilter2p_Init(&c->filter.joint_out[2], target_freq, + param->low_pass_cutoff_freq.out); + LowPassFilter2p_Init(&c->filter.joint_out[3], target_freq, + param->low_pass_cutoff_freq.out); + LowPassFilter2p_Init(&c->filter.wheel_out[0], target_freq, + param->low_pass_cutoff_freq.out); + LowPassFilter2p_Init(&c->filter.wheel_out[1], target_freq, + param->low_pass_cutoff_freq.out); + + /*初始化机体状态*/ + c->chassis_state.position_x = 0.0f; + c->chassis_state.velocity_x = 0.0f; + c->chassis_state.last_velocity_x = 0.0f; + c->chassis_state.target_x = 0.0f; + c->chassis_state.target_velocity_x = 0.0f; + c->chassis_state.last_target_velocity_x = 0.0f; + + /*初始化yaw控制状态*/ + c->yaw_control.target_yaw = 0.0f; + c->yaw_control.current_yaw = 0.0f; + c->yaw_control.yaw_force = 0.0f; + c->yaw_control.is_reversed = false; + + return CHASSIS_OK; +} + +int8_t Chassis_UpdateFeedback(Chassis_t *c) { + if (c == NULL) { + return -1; // 参数错误 + } + // 更新所有电机数据 + MOTOR_LZ_UpdateAll(); + MOTOR_LK_UpdateAll(); + + // 更新反馈数据 + for (int i = 0; i < 4; i++) { + MOTOR_LZ_t* joint_motor = MOTOR_LZ_GetMotor(&c->param->joint_param[i]); + if (joint_motor != NULL) { + c->feedback.joint[i] = joint_motor->motor.feedback; + } + } + + for (int i = 0; i < 2; i++) { + MOTOR_LK_t* wheel_motor = MOTOR_LK_GetMotor(&c->param->wheel_param[i]); + if (wheel_motor != NULL) { + c->feedback.wheel[i] = wheel_motor->motor.feedback; + } + } + + // for (int i = 0; i < 4; i++) { + // c->feedback.joint[i] = virtual_chassis.data.joint[i]; + // if (c->feedback.joint[i].rotor_abs_angle > M_PI) { + // c->feedback.joint[i].rotor_abs_angle -= M_2PI; + // } + // c->feedback.joint[i].rotor_abs_angle = + // -c->feedback.joint[i].rotor_abs_angle; // 机械零点调整 + // } + // for (int i = 0; i < 2; i++) { + // c->feedback.wheel[i] = virtual_chassis.data.wheel[i]; + // } + // c->feedback.imu.accl = virtual_chassis.data.imu.accl; + // c->feedback.imu.gyro = virtual_chassis.data.imu.gyro; + // c->feedback.imu.euler = virtual_chassis.data.imu.euler; + + // 更新机体状态估计 + Chassis_UpdateChassisState(c); + + return 0; +} + +int8_t Chassis_UpdateIMU(Chassis_t *c, const Chassis_IMU_t imu) { + if (c == NULL) { + return -1; // 参数错误 + } + c->feedback.imu = imu; + return 0; +} + +int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd) { + if (c == NULL || c_cmd == NULL) { + return CHASSIS_ERR_NULL; // 参数错误 + } + c->dt = (BSP_TIME_Get_us() - c->lask_wakeup) / + 1000000.0f; /* 计算两次调用的时间间隔,单位秒 */ + c->lask_wakeup = BSP_TIME_Get_us(); + + /*设置底盘模式*/ + if (Chassis_SetMode(c, c_cmd->mode) != CHASSIS_OK) { + return CHASSIS_ERR_MODE; // 设置模式失败 + } + + VMC_ForwardSolve(&c->vmc_[0], c->feedback.joint[0].rotor_abs_angle, + c->feedback.joint[1].rotor_abs_angle, + c->feedback.imu.euler.pit, c->feedback.imu.gyro.y); + VMC_ForwardSolve(&c->vmc_[1], c->feedback.joint[3].rotor_abs_angle, + c->feedback.joint[2].rotor_abs_angle, + c->feedback.imu.euler.pit, c->feedback.imu.gyro.y); + + /*根据底盘模式执行不同的控制逻辑*/ + switch (c->mode) { + case CHASSIS_MODE_RELAX: + // 放松模式,电机不输出 + Chassis_MotorRelax(c); + + Chassis_LQRControl(c, c_cmd); + + break; + + case CHASSIS_MODE_RECOVER: { + float fn, tp; + fn = -20.0f; + tp = 0.0f; + + Chassis_LQRControl(c, c_cmd); + + VMC_InverseSolve(&c->vmc_[0], fn, tp); + VMC_GetJointTorques(&c->vmc_[0], &c->output.joint[0], &c->output.joint[1]); + VMC_InverseSolve(&c->vmc_[1], fn, tp); + VMC_GetJointTorques(&c->vmc_[1], &c->output.joint[3], &c->output.joint[2]); + + c->output.wheel[0] = c_cmd->move_vec.vx * 0.2f; + + c->output.wheel[1] = c_cmd->move_vec.vx * 0.2f; + Chassis_Output(c); // 统一输出 + + } break; + case CHASSIS_MODE_JUMP: + // 跳跃模式状态机 + // 状态转换: 0(准备)->1(0.3s)->2(0.2s)->3(0.3s)->0(完成) + // jump_time == 0: 未开始跳跃 + // jump_time == 1: 已完成跳跃(不再触发) + // jump_time > 1: 跳跃进行中 + + // 检测是否需要开始新的跳跃(state为0且jump_time为0) + if (c->state == 0 && c->jump_time == 0) { + // 开始跳跃,进入state 1 + c->state = 1; + c->jump_time = BSP_TIME_Get_us(); + } + + // 只有在跳跃进行中时才处理状态转换(jump_time > 1) + if (c->jump_time > 1) { + // 计算已经过的时间(微秒) + uint64_t elapsed_us = BSP_TIME_Get_us() - c->jump_time; + + // 状态转换逻辑 + if (c->state == 1 && elapsed_us >= 300000) { + // state 1 保持0.3s后转到state 2 + c->state = 2; + c->jump_time = BSP_TIME_Get_us(); // 重置计时 + } else if (c->state == 2 && elapsed_us >= 230000) { + // state 2 保持0.25s后转到state 3,确保腿部充分伸展 + c->state = 3; + c->jump_time = BSP_TIME_Get_us(); // 重置计时 + } else if (c->state == 3 && elapsed_us >= 500000) { + // state 3 保持0.4s后转到state 0,确保收腿到最高 + c->state = 0; + c->jump_time = 1; // 设置为1,表示已完成跳跃,不再触发 + } + } + + // 执行LQR控制(包含PID腿长控制) + Chassis_LQRControl(c, c_cmd); + Chassis_Output(c); // 统一输出 + break; + case CHASSIS_MODE_WHELL_LEG_BALANCE: + case CHASSIS_MODE_ROTOR: + + // 执行LQR控制(包含PID腿长控制) + Chassis_LQRControl(c, c_cmd); + Chassis_Output(c); // 统一输出 + break; + + break; + default: + return CHASSIS_ERR_MODE; + } + + return CHASSIS_OK; +} + +void Chassis_Output(Chassis_t *c) { + if (c == NULL) + return; + c->output.joint[0] = + LowPassFilter2p_Apply(&c->filter.joint_out[0], c->output.joint[0]); + c->output.joint[1] = + LowPassFilter2p_Apply(&c->filter.joint_out[1], c->output.joint[1]); + c->output.joint[2] = + LowPassFilter2p_Apply(&c->filter.joint_out[2], c->output.joint[2]); + c->output.joint[3] = + LowPassFilter2p_Apply(&c->filter.joint_out[3], c->output.joint[3]); + float out[4] = {c->output.joint[0], c->output.joint[1], c->output.joint[2], + c->output.joint[3]}; + // Virtual_Chassis_SendJointTorque(&virtual_chassis, out); + c->output.wheel[0] = + LowPassFilter2p_Apply(&c->filter.wheel_out[0], c->output.wheel[0]); + c->output.wheel[1] = + LowPassFilter2p_Apply(&c->filter.wheel_out[1], c->output.wheel[1]); + // Virtual_Chassis_SendWheelCommand(&virtual_chassis, c->output.wheel[0], + // c->output.wheel[1]); + // Virtual_Chassis_SendWheelCommand(&virtual_chassis, 0.0f, + // 0.0f); // 暂时不让轮子动 +} + +int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) { + if (c == NULL || c_cmd == NULL) { + return CHASSIS_ERR_NULL; + } + + /* 运动参数(参考C++版本的状态估计) */ + static float xhat = 0.0f, x_dot_hat = 0.0f; + float target_dot_x = 0.0f; + float max_acceleration = 2.0f; // 最大加速度限制: 3 m/s² + + // 简化的速度估计(后续可以改进为C++版本的复杂滤波) + x_dot_hat = c->chassis_state.velocity_x; + xhat = c->chassis_state.position_x; + + // 目标速度设定(原始期望速度) + float raw_vx = c_cmd->move_vec.vx * 2; + + // 根据零点选择情况决定是否反转前后方向 + float desired_velocity = c->yaw_control.is_reversed ? -raw_vx : raw_vx; + + // 加速度限制处理 + float velocity_change = + desired_velocity - c->chassis_state.last_target_velocity_x; + float max_velocity_change = max_acceleration * c->dt; // 最大允许的速度变化 + + // 限制速度变化率(加速度限制) + if (velocity_change > max_velocity_change) { + velocity_change = max_velocity_change; + } else if (velocity_change < -max_velocity_change) { + velocity_change = -max_velocity_change; + } + + // 应用加速度限制后的目标速度 + target_dot_x = c->chassis_state.last_target_velocity_x + velocity_change; + c->chassis_state.target_velocity_x = target_dot_x; + c->chassis_state.last_target_velocity_x = target_dot_x; + + // 更新目标位置 + c->chassis_state.target_x += target_dot_x * c->dt; + + /* 分别计算左右腿的LQR控制 */ + /* 构建当前状态 */ + LQR_State_t current_state = {0}; + current_state.theta = c->vmc_[0].leg.theta; + current_state.d_theta = c->vmc_[0].leg.d_theta; + current_state.x = xhat; + current_state.d_x = x_dot_hat; + current_state.phi = -c->feedback.imu.euler.pit; + current_state.d_phi = -c->feedback.imu.gyro.y; + + LQR_UpdateState(&c->lqr[0], ¤t_state); + + current_state.theta = c->vmc_[1].leg.theta; + current_state.d_theta = c->vmc_[1].leg.d_theta; + LQR_UpdateState(&c->lqr[1], ¤t_state); + + /* 根据当前腿长更新增益矩阵 */ + LQR_CalculateGainMatrix(&c->lqr[0], c->vmc_[0].leg.L0); + LQR_CalculateGainMatrix(&c->lqr[1], c->vmc_[1].leg.L0); + + /* 构建目标状态 */ + LQR_State_t target_state = {0}; + + // 在跳跃收腿阶段强制摆角目标为0,确保落地时腿部竖直 + if (c->mode == CHASSIS_MODE_JUMP && c->state == 3) { + target_state.theta = 0.0f; // 强制摆杆角度为0,确保腿部竖直 + } else { + target_state.theta = 0.00; // 目标摆杆角度 + } + + target_state.d_theta = 0.0f; // 目标摆杆角速度 + target_state.phi = 11.9601*pow((0.16f + c_cmd->height * 0.25f),3) + -11.8715*pow((0.16f + c_cmd->height * 0.25f),2) + 3.87083*(0.16f + c_cmd->height * 0.25f) + -0.4154; // 目标俯仰角 + target_state.d_phi = 0.0f; // 目标俯仰角速度 + target_state.x = c->chassis_state.target_x -2.07411f*(0.16f + c_cmd->height * 0.25f) + 0.41182f; + target_state.d_x = target_dot_x; // 目标速度 + + if (c->mode != CHASSIS_MODE_ROTOR){ + c->yaw_control.current_yaw = c->feedback.yaw.rotor_abs_angle; + + // 双零点自动选择逻辑(考虑手动控制偏移,使用CircleError函数) + float manual_offset = c_cmd->move_vec.vy * M_PI_2; + float base_target_1 = c->param->mech_zero_yaw + manual_offset; + float base_target_2 = c->param->mech_zero_yaw + M_PI + manual_offset; + + // 使用CircleError计算到两个目标的角度误差 + float error_to_target1 = CircleError(base_target_1, c->yaw_control.current_yaw, M_2PI); + float error_to_target2 = CircleError(base_target_2, c->yaw_control.current_yaw, M_2PI); + + // 选择误差绝对值更小的目标,并更新反转状态 + if (fabsf(error_to_target1) <= fabsf(error_to_target2)) { + c->yaw_control.target_yaw = base_target_1; + c->yaw_control.is_reversed = false; // 使用第一个零点,不反转 + } else { + c->yaw_control.target_yaw = base_target_2; + c->yaw_control.is_reversed = true; // 使用第二个零点,需要反转前后方向 + } + + c->yaw_control.yaw_force = + PID_Calc(&c->pid.yaw, c->yaw_control.target_yaw, + c->feedback.yaw.rotor_abs_angle, 0.0f, c->dt); + }else{ + // 小陀螺模式:使用速度环控制 + c->yaw_control.current_yaw = c->feedback.imu.euler.yaw; + + // 渐增旋转速度,最大角速度约6.9 rad/s(约400度/秒) + c->wz_multi += 0.005f; + if (c->wz_multi > 1.2f) + c->wz_multi = 1.2f; + + // 目标角速度(rad/s),可根据需要调整最大速度 + float target_yaw_velocity = c->wz_multi * 1.0f; // 最大约7.2 rad/s + + // 当前角速度反馈来自IMU陀螺仪 + float current_yaw_velocity = c->feedback.imu.gyro.z; + + // 使用PID控制角速度,输出力矩 + c->yaw_control.yaw_force = + PID_Calc(&c->pid.yaw, target_yaw_velocity, + current_yaw_velocity, 0.0f, c->dt); + } + + if (c->vmc_[0].leg.is_ground_contact) { + /* 更新LQR状态 */ + LQR_SetTargetState(&c->lqr[0], &target_state); + LQR_Control(&c->lqr[0]); + } else { + // 在跳跃收腿阶段强制摆角目标为0,其他情况为0.16f + float non_contact_theta = (c->mode == CHASSIS_MODE_JUMP && c->state == 3) ? 0.0f : 0.16f; + target_state.theta = non_contact_theta; // 非接触时的腿摆角目标 + LQR_SetTargetState(&c->lqr[0], &target_state); + c->lqr[0].control_output.T = 0.0f; + c->lqr[0].control_output.Tp = + c->lqr[0].K_matrix[1][0] * (-c->vmc_[0].leg.theta + non_contact_theta) + + c->lqr[0].K_matrix[1][1] * (-c->vmc_[0].leg.d_theta + 0.0f); + c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制 + } + if (c->vmc_[1].leg.is_ground_contact){ + LQR_SetTargetState(&c->lqr[1], &target_state); + LQR_Control(&c->lqr[1]); + }else { + // 在跳跃收腿阶段强制摆角目标为0,其他情况为0.16f + float non_contact_theta = (c->mode == CHASSIS_MODE_JUMP && c->state == 3) ? 0.0f : 0.16f; + target_state.theta = non_contact_theta; // 非接触时的腿摆角目标 + LQR_SetTargetState(&c->lqr[1], &target_state); + c->lqr[1].control_output.T = 0.0f; + c->lqr[1].control_output.Tp = + c->lqr[1].K_matrix[1][0] * (-c->vmc_[1].leg.theta + non_contact_theta) + + c->lqr[1].K_matrix[1][1] * (-c->vmc_[1].leg.d_theta + 0.0f); + c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制 + } + + /* 轮毂力矩输出(参考C++版本的减速比) */ + // 在跳跃的起跳和收腿阶段强制关闭轮子输出,防止离地时轮子猛转 + if (c->mode == CHASSIS_MODE_JUMP && (c->state == 2 || c->state == 3)) { + c->output.wheel[0] = 0.0f; + c->output.wheel[1] = 0.0f; + } else { + c->output.wheel[0] = + c->lqr[0].control_output.T / 4.5f + c->yaw_control.yaw_force; + c->output.wheel[1] = + c->lqr[1].control_output.T / 4.5f - c->yaw_control.yaw_force; + } + /* 腿长控制和VMC逆解算(使用PID控制) */ + float virtual_force[2]; + float target_L0[2]; + float leg_d_length[2]; // 腿长变化率 + + /* 横滚角PID补偿计算 */ + // 使用PID控制器计算横滚角补偿长度,目标横滚角为0 + float roll_compensation_length = + PID_Calc(&c->pid.roll, 0.0f, c->feedback.imu.euler.rol, + c->feedback.imu.gyro.x, c->dt); + + // 限制补偿长度范围,防止过度补偿 + // 如果任一腿离地,限制补偿长度 + if (!c->vmc_[0].leg.is_ground_contact || !c->vmc_[1].leg.is_ground_contact) { + if (roll_compensation_length > 0.02f) + roll_compensation_length = 0.02f; + if (roll_compensation_length < -0.02f) + roll_compensation_length = -0.02f; + } else { + if (roll_compensation_length > 0.05f) + roll_compensation_length = 0.05f; + if (roll_compensation_length < -0.05f) + roll_compensation_length = -0.05f; + } + + // 目标腿长设定(包含横滚角补偿) + switch (c->state) { + case 0: // 正常状态,根据高度指令调节腿长 + target_L0[0] = 0.16f + c_cmd->height * 0.22f + roll_compensation_length; // 左腿:基础腿长 + 高度调节 + 横滚补偿 + target_L0[1] = 0.16f + c_cmd->height * 0.22f - roll_compensation_length; // 右腿:基础腿长 + 高度调节 - 横滚补偿 + break; + case 1: // 准备阶段,腿长收缩 + target_L0[0] = 0.14f + roll_compensation_length; // 左腿:收缩到较短腿长 + 横滚补偿 + target_L0[1] = 0.14f - roll_compensation_length; // 右腿:收缩到较短腿长 - 横滚补偿 + break; + case 2: // 起跳阶段,腿长快速伸展 + target_L0[0] = 0.65f; // 左腿:伸展到最大腿长(跳跃时不进行横滚补偿) + target_L0[1] = 0.65f; // 右腿:伸展到最大腿长(跳跃时不进行横滚补偿) + break; + case 3: // 收腿阶段,腿长收缩到最高 + target_L0[0] = 0.06f; // 左腿:收缩到最短腿长(确保收腿到最高) + target_L0[1] = 0.06f; // 右腿:收缩到最短腿长(确保收腿到最高) + break; + default: + target_L0[0] = 0.16f + c_cmd->height * 0.22f + roll_compensation_length; + target_L0[1] = 0.16f + c_cmd->height * 0.22f - roll_compensation_length; + break; + } + + // 腿长限幅:根据跳跃状态调整限制范围 + if (c->mode == CHASSIS_MODE_JUMP && c->state == 3) { + // 在跳跃收腿阶段,允许更短的腿长,确保收腿到最高 + if (target_L0[0] < 0.06f) target_L0[0] = 0.06f; + if (target_L0[1] < 0.06f) target_L0[1] = 0.06f; + } else { + // 正常情况下的腿长限制:最短0.10,最长0.42m + if (target_L0[0] < 0.10f) target_L0[0] = 0.10f; + if (target_L0[1] < 0.10f) target_L0[1] = 0.10f; + } + if (target_L0[0] > 0.42f) target_L0[0] = 0.42f; + if (target_L0[1] > 0.42f) target_L0[1] = 0.42f; + + // 获取腿长变化率 + VMC_GetVirtualLegState(&c->vmc_[0], NULL, NULL, &leg_d_length[0], NULL); + VMC_GetVirtualLegState(&c->vmc_[1], NULL, NULL, &leg_d_length[1], NULL); + + /* 左右腿摆角相互补偿(参考C++版本的Delta_Tp机制) */ + float Delta_Tp[2]; + // 使用tp_pid进行左右腿摆角同步控制 + // 左腿补偿力矩:使左腿theta向右腿theta靠拢 + Delta_Tp[0] = c->vmc_[0].leg.L0 * 10.0f * + PID_Calc(&c->pid.tp[0], c->vmc_[1].leg.theta, + c->vmc_[0].leg.theta, c->vmc_[0].leg.d_theta, c->dt); + // 右腿补偿力矩:使右腿theta向左腿theta靠拢(符号相反) + Delta_Tp[1] = c->vmc_[1].leg.L0 * 10.0f * + PID_Calc(&c->pid.tp[1], c->vmc_[0].leg.theta, + c->vmc_[1].leg.theta, c->vmc_[1].leg.d_theta, c->dt); + + // 左腿控制 + { + // 使用PID进行腿长控制 + float pid_output = PID_Calc(&c->pid.leg_length[0], target_L0[0], + c->vmc_[0].leg.L0, leg_d_length[0], c->dt); + + // 腿长控制力 = LQR摆杆力矩的径向分量 + PID腿长控制输出 + 基础支撑力 + virtual_force[0] = + (c->lqr[0].control_output.Tp) * sinf(c->vmc_[0].leg.theta) + + pid_output + 60.0f; + + // VMC逆解算(包含摆角补偿) + if (VMC_InverseSolve(&c->vmc_[0], virtual_force[0], + c->lqr[0].control_output.Tp + Delta_Tp[0]) == 0) { + VMC_GetJointTorques(&c->vmc_[0], &c->output.joint[0], + &c->output.joint[1]); + + } else { + // VMC失败,设为0力矩 + c->output.joint[0] = 0.0f; + c->output.joint[1] = 0.0f; + } + } + + // 右腿控制 + { + // 使用PID进行腿长控制 + float pid_output = PID_Calc(&c->pid.leg_length[1], target_L0[1], + c->vmc_[1].leg.L0, leg_d_length[1], c->dt); + + // 腿长控制力 = LQR摆杆力矩的径向分量 + PID腿长控制输出 + 基础支撑力 + virtual_force[1] = + (c->lqr[1].control_output.Tp) * sinf(c->vmc_[1].leg.theta) + + pid_output + 65.0f; + + // VMC逆解算(包含摆角补偿) + if (VMC_InverseSolve(&c->vmc_[1], virtual_force[1], + c->lqr[1].control_output.Tp + Delta_Tp[1]) == 0) { + VMC_GetJointTorques(&c->vmc_[1], &c->output.joint[3], + &c->output.joint[2]); + } else { + // VMC失败,设为0力矩 + c->output.joint[2] = 0.0f; + c->output.joint[3] = 0.0f; + } + } + + /* 安全限制 */ + for (int i = 0; i < 2; i++) { + if (fabsf(c->output.wheel[i]) > 1.0f) { + c->output.wheel[i] = (c->output.wheel[i] > 0) ? 1.0f : -1.0f; + } + } + + for (int i = 0; i < 4; i++) { + if (fabsf(c->output.joint[i]) > 20.0f) { + c->output.joint[i] = (c->output.joint[i] > 0) ? 25.0f : -25.0f; + } + } + + return CHASSIS_OK; +} + + diff --git a/User/module/balance_chassis.h b/User/module/balance_chassis.h new file mode 100644 index 0000000..ee6111e --- /dev/null +++ b/User/module/balance_chassis.h @@ -0,0 +1,239 @@ +/* + * 平衡底盘模组 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// Front +// | 1 4 | +// (1)Left| |Right(2) +// | 2 3 | + +/* Includes ----------------------------------------------------------------- */ +#include +#include +#include "component/vmc.h" +#include "component/lqr.h" +#include "component/ahrs.h" +#include "component/filter.h" +#include "component/pid.h" +#include "device/motor.h" +#include "device/motor_lk.h" +#include "device/motor_lz.h" +#include "device/motor_dm.h" + +/* Exported constants ------------------------------------------------------- */ +#define CHASSIS_OK (0) /* 运行正常 */ +#define CHASSIS_ERR (-1) /* 运行时发现了其他错误 */ +#define CHASSIS_ERR_NULL (-2) /* 运行时发现NULL指针 */ +#define CHASSIS_ERR_MODE (-3) /* 运行时配置了错误的CMD_ChassisMode_t */ +#define CHASSIS_ERR_TYPE (-4) /* 运行时配置了错误的Chassis_Type_t */ + +/* Exported macro ----------------------------------------------------------- */ +/* Exported types ----------------------------------------------------------- */ + +typedef enum { + CHASSIS_MODE_RELAX, /* 放松模式,电机不输出。一般情况底盘初始化之后的模式 */ + CHASSIS_MODE_RECOVER, /* 复位模式 */ + CHASSIS_MODE_WHELL_LEG_BALANCE, /* 轮子+腿平衡模式,底盘自我平衡 */ + CHASSIS_MODE_JUMP, /* 跳跃模式,底盘跳跃 */ + CHASSIS_MODE_ROTOR, /* 小陀螺模式,底盘高速旋转 */ +} Chassis_Mode_t; + +typedef enum { + CHASSIS_JUMP_STATE_READY, /* 准备跳跃 */ + CHASSIS_JUMP_STATE_JUMPING, /* 跳跃中 */ + CHASSIS_JUMP_STATE_LANDING, /* 着陆中 */ + CHASSIS_JUMP_STATE_END, /* 跳跃结束 */ +} Chassis_JumpState_t; + +typedef struct { + Chassis_Mode_t mode; /* 底盘模式 */ + MoveVector_t move_vec; /* 底盘运动向量 */ + float height; /* 目标高度 */ +} Chassis_CMD_t; + +typedef struct { + AHRS_Accl_t accl; /* IMU加速度计 */ + AHRS_Gyro_t gyro; /* IMU陀螺仪 */ + AHRS_Eulr_t euler; /* IMU欧拉角 */ +}Chassis_IMU_t; + +typedef struct { + MOTOR_Feedback_t joint[4]; /* 四个关节电机反馈 */ + MOTOR_Feedback_t wheel[2]; /* 两个轮子电机反馈 */ + MOTOR_Feedback_t yaw; /* 云台Yaw轴电机反馈 */ + Chassis_IMU_t imu; /* IMU数据 */ +}Chassis_Feedback_t; + +typedef struct { + float joint[4]; /* 四个关节电机输出 */ + float wheel[2]; /* 两个轮子电机输出 */ +}Chassis_Output_t; + + +/* 底盘参数的结构体,包含所有初始化用的参数,通常是const,存好几组 */ +typedef struct { + + MOTOR_LZ_Param_t joint_param[4]; // 4个电机参数 + MOTOR_LK_Param_t wheel_param[2]; // 2个轮子电机参数 + MOTOR_DM_Param_t yaw_motor; /* 云台Yaw轴电机参数 */ + VMC_Param_t vmc_param[2]; /* VMC参数 */ + LQR_GainMatrix_t lqr_gains; /* LQR增益矩阵参数 */ + + KPID_Params_t yaw; /* yaw轴PID控制参数,用于控制底盘朝向 */ + KPID_Params_t roll; /* roll轴PID控制参数,用于横滚角补偿 */ + KPID_Params_t tp; /* 摆力矩PID控制参数,用于控制摆力矩 */ + KPID_Params_t leg_length; /* 腿长PID控制参数,用于控制虚拟腿长度 */ + KPID_Params_t leg_theta; /* 摆角PID控制参数,用于控制虚拟腿摆角 */ + + float mech_zero_yaw; /* 机械零点 */ + + float theta; + float x; + float phi; + + /* 低通滤波器截止频率 */ + struct { + float in; /* 输入 */ + float out; /* 输出 */ + } low_pass_cutoff_freq; +} Chassis_Params_t; + +/* + * 运行的主结构体,所有这个文件里的函数都在操作这个结构体 + * 包含了初始化参数,中间变量,输出变量 + */ +typedef struct { + uint64_t lask_wakeup; + float dt; + + Chassis_Params_t *param; /* 底盘的参数,用Chassis_Init设定 */ + AHRS_Eulr_t *mech_zero; + + /* 模块通用 */ + Chassis_Mode_t mode; /* 底盘模式 */ + + /* 反馈信息 */ + Chassis_Feedback_t feedback; + /* 控制信息*/ + Chassis_Output_t output; + + VMC_t vmc_[2]; /* 两条腿的VMC */ + LQR_t lqr[2]; /* 两条腿的LQR控制器 */ + + int8_t state; + uint64_t jump_time; + + + float angle; + float height; + + /* 机体状态估计 */ + struct { + float position_x; /* 机体x位置 */ + float velocity_x; /* 机体x速度 */ + float last_velocity_x; /* 上一次速度用于数值微分 */ + float target_x; /* 目标x位置 */ + float target_velocity_x; /* 目标速度 */ + float last_target_velocity_x; /* 上一次目标速度 */ + } chassis_state; + + /* yaw控制相关 */ + struct { + float target_yaw; /* 目标yaw角度 */ + float current_yaw; /* 当前yaw角度 */ + float yaw_force; /* yaw轴控制力矩 */ + bool is_reversed; /* 是否使用反转的零点(180度零点),影响前后方向 */ + } yaw_control; + + float wz_multi; /* 小陀螺模式旋转方向 */ + + /* PID计算的目标值 */ + struct { + AHRS_Eulr_t chassis; + } setpoint; + + /* 反馈控制用的PID */ + struct { + KPID_t yaw; /* 跟随云台用的PID */ + KPID_t roll; /* 横滚角控制PID */ + KPID_t tp[2]; + KPID_t leg_length[2]; /* 两条腿的腿长PID */ + KPID_t leg_theta[2]; /* 两条腿的摆角PID */ + } pid; + + /* 滤波器 */ + struct { + LowPassFilter2p_t joint_out[4]; /* 关节输出滤波器 */ + LowPassFilter2p_t wheel_out[2]; /* 轮子输出滤波器 */ + } filter; + +} Chassis_t; + +/* Exported functions prototypes -------------------------------------------- */ + +/** + * \brief 初始化底盘 + * + * \param c 包含底盘数据的结构体 + * \param param 包含底盘参数的结构体指针 + * \param target_freq 任务预期的运行频率 + * + * \return 函数运行结果 + */ +int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq); + +/** + * \brief 更新底盘的反馈信息 + * + * \param c 包含底盘数据的结构体 + * \return 函数运行结果 + */ +int8_t Chassis_UpdateFeedback(Chassis_t *c); + + +/** + * @brief 更新IMU数据 + * @param c 包含底盘数据的结构体 + * @param imu IMU数据 + * @return + */ +int8_t Chassis_UpdateIMU(Chassis_t *c, const Chassis_IMU_t imu); +/** + * \brief 运行底盘控制逻辑 + * + * \param c 包含底盘数据的结构体 + * \param c_cmd 底盘控制指令 + * + * \return 函数运行结果 + */ +int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd); + +/** + * \brief LQR控制逻辑 + * + * \param c 包含底盘数据的结构体 + * \param c_cmd 底盘控制指令 + * + * \return 函数运行结果 + */ +int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd); + + + +/** + * \brief 底盘输出值 + * + * \param s 包含底盘数据的结构体 + * \param out CAN设备底盘输出结构体 + */ +void Chassis_Output(Chassis_t *c); + +#ifdef __cplusplus +} +#endif diff --git a/User/module/config.h b/User/module/config.h index 667d17f..3d9a52e 100644 --- a/User/module/config.h +++ b/User/module/config.h @@ -11,6 +11,7 @@ extern "C" { #include #include #include "module/shoot.h" +#include "module/balance_chassis.h" /** * @brief 机器人参数配置结构体 * @note 在此添加您的配置参数 @@ -18,7 +19,7 @@ extern "C" { typedef struct { /* USER CODE BEGIN Config_RobotParam */ Shoot_Params_t shoot_param; - + Chassis_Params_t chassis_param; /* USER CODE END Config_RobotParam */ } Config_RobotParam_t; diff --git a/User/task/atti_esit.c b/User/task/atti_esit.c index 7e1c6c7..b2a1b7c 100644 --- a/User/task/atti_esit.c +++ b/User/task/atti_esit.c @@ -12,6 +12,7 @@ #include "component/ahrs.h" #include "component/pid.h" #include "device/bmi088.h" +#include "module/balance_chassis.h" #include "task/user_task.h" /* USER INCLUDE END */ @@ -25,7 +26,7 @@ BMI088_t bmi088; AHRS_t gimbal_ahrs; AHRS_Magn_t magn; AHRS_Eulr_t eulr_to_send; - +Chassis_IMU_t imu_for_chassis; KPID_t imu_temp_ctrl_pid; /*默认校准参数*/ @@ -81,6 +82,13 @@ void Task_atti_esit(void *argument) { /* 根据解析出来的四元数计算欧拉角 */ AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs); + imu_for_chassis.accl = bmi088.accl; + imu_for_chassis.gyro = bmi088.gyro; + imu_for_chassis.euler = eulr_to_send; + osMessageQueueReset( + task_runtime.msgq.chassis.imu); // 重置消息队列,防止阻塞 + osMessageQueuePut(task_runtime.msgq.chassis.imu, &imu_for_chassis, 0, + 0); // 非阻塞发送底盘IMU数据 BSP_PWM_SetComp(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.5f, bmi088.temp, 0.0f, 0.0f)); osKernelUnlock(); diff --git a/User/task/ctrl_chassis.c b/User/task/ctrl_chassis.c index b2dffb7..50cc645 100644 --- a/User/task/ctrl_chassis.c +++ b/User/task/ctrl_chassis.c @@ -7,9 +7,10 @@ #include "task/user_task.h" /* USER INCLUDE BEGIN */ #include "bsp/can.h" -#include "device/motor.h" #include "device/motor_lk.h" #include "device/motor_lz.h" +#include "module/config.h" +#include "module/balance_chassis.h" /* USER INCLUDE END */ /* Private typedef ---------------------------------------------------------- */ @@ -17,16 +18,17 @@ /* Private macro ------------------------------------------------------------ */ /* Private variables -------------------------------------------------------- */ /* USER STRUCT BEGIN */ -MOTOR_LZ_Param_t motor_lz_param = { - .can = BSP_CAN_3, - .motor_id = 125, - .host_id = 0xFF, - .module = MOTOR_LZ_RSO3, - .reverse = false, - .mode = MOTOR_LZ_MODE_MOTION, +Chassis_t chassis; +Chassis_CMD_t chassis_cmd = { + .mode = CHASSIS_MODE_RELAX, // 改为RECOVER模式,让电机先启动 + .move_vec = { + .vx = 0.0f, + .vy = 0.0f, + .wz = 0.0f, + }, + .height = 0.0f, }; - -float out = 0.0f; +Chassis_IMU_t chassis_imu; /* USER STRUCT END */ /* Private function --------------------------------------------------------- */ @@ -42,19 +44,30 @@ void Task_ctrl_chassis(void *argument) { uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */ /* USER CODE INIT BEGIN */ - BSP_CAN_Init(); - MOTOR_LZ_Init(); - MOTOR_LZ_Register(&motor_lz_param); + + Chassis_Init(&chassis, &Config_GetRobotParam()->chassis_param, CTRL_CHASSIS_FREQ); /* USER CODE INIT END */ while (1) { tick += delay_tick; /* 计算下一个唤醒时刻 */ /* USER CODE BEGIN */ - MOTOR_LZ_Enable(&motor_lz_param); + if (osMessageQueueGet(task_runtime.msgq.chassis.cmd, &chassis_cmd, NULL, 0) != osOK) { + // 没有新命令,保持上次命令 + } + if (osMessageQueueGet(task_runtime.msgq.chassis.imu, &chassis_imu, NULL, 0) == osOK) { + chassis.feedback.imu = chassis_imu; + } + osMessageQueueGet(task_runtime.msgq.chassis.yaw, &chassis.feedback.yaw, NULL, 0); + + Chassis_UpdateFeedback(&chassis); + Chassis_Control(&chassis, &chassis_cmd); + /* USER CODE END */ osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */ } -} \ No newline at end of file +} + + diff --git a/User/task/init.c b/User/task/init.c index cf339ad..344d29c 100644 --- a/User/task/init.c +++ b/User/task/init.c @@ -8,6 +8,7 @@ /* USER INCLUDE BEGIN */ #include "module/shoot.h" +#include "module/balance_chassis.h" /* USER INCLUDE END */ /* Private typedef ---------------------------------------------------------- */ @@ -42,6 +43,9 @@ void Task_Init(void *argument) { /* USER MESSAGE BEGIN */ task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL); task_runtime.msgq.shoot.shoot_cmd = osMessageQueueNew(2u, sizeof(Shoot_CMD_t), NULL); + task_runtime.msgq.chassis.imu = osMessageQueueNew(2u, sizeof(Chassis_IMU_t), NULL); + task_runtime.msgq.chassis.cmd = osMessageQueueNew(2u, sizeof(Chassis_CMD_t), NULL); + task_runtime.msgq.chassis.yaw = osMessageQueueNew(2u, sizeof(MOTOR_Feedback_t), NULL); /* USER MESSAGE END */ osKernelUnlock(); // 解锁内核 diff --git a/User/task/rc.c b/User/task/rc.c index b9bd98b..cff37b6 100644 --- a/User/task/rc.c +++ b/User/task/rc.c @@ -8,6 +8,7 @@ /* USER INCLUDE BEGIN */ #include "device/dr16.h" #include "module/shoot.h" +#include "module/balance_chassis.h" /* USER INCLUDE END */ /* Private typedef ---------------------------------------------------------- */ @@ -17,7 +18,7 @@ /* USER STRUCT BEGIN */ DR16_t dr16; Shoot_CMD_t for_shoot; - +Chassis_CMD_t cmd_for_chassis; /* USER STRUCT END */ /* Private function --------------------------------------------------------- */ @@ -99,7 +100,34 @@ void Task_rc(void *argument) { // osMessageQueueReset(task_runtime.msgq.gimbal.cmd); // osMessageQueuePut(task_runtime.msgq.gimbal.cmd, &cmd_for_gimbal, 0, 0); +switch (dr16.data.sw_l) { + case DR16_SW_UP: + cmd_for_chassis.mode = CHASSIS_MODE_RELAX; + break; + case DR16_SW_MID: + // cmd_for_chassis.mode = CHASSIS_MODE_RECOVER; + cmd_for_chassis.mode = CHASSIS_MODE_WHELL_LEG_BALANCE; + break; + case DR16_SW_DOWN: + // cmd_for_chassis.mode = CHASSIS_MODE_ROTOR; + // cmd_for_chassis.mode = CHASSIS_MODE_WHELL_LEG_BALANCE; + cmd_for_chassis.mode = CHASSIS_MODE_JUMP; + break; + default: + cmd_for_chassis.mode = CHASSIS_MODE_RELAX; + break; + } + cmd_for_chassis.move_vec.vx = dr16.data.ch_l_y; + cmd_for_chassis.move_vec.vy = dr16.data.ch_l_x; + cmd_for_chassis.move_vec.wz = dr16.data.ch_r_x; + cmd_for_chassis.height = dr16.data.ch_res; + osMessageQueueReset( + task_runtime.msgq.chassis.cmd); // 重置消息队列,防止阻塞 + osMessageQueuePut(task_runtime.msgq.chassis.cmd, &cmd_for_chassis, 0, + 0); // 非阻塞发送底盘控制命令 + +/************************* 发射命令 **************************************/ for_shoot.online = dr16.header.online; switch (dr16.data.sw_r) { case DR16_SW_UP: