From f5e277c240b9211a1f047b88788f34f3dd5a97c2 Mon Sep 17 00:00:00 2001 From: ethan <ethan.tao@ewellix.com> Date: Sat, 08 Apr 2023 18:33:01 +0800 Subject: [PATCH] first commit --- Device/src/Ems_config.h | 27 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c | 0 Driver/Src/gpio.c | 0 MCU/stm32l4xx_it.c | 21 APP/main.c | 14 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h | 0 MCU/stm32l4xx_hal_msp.c | 0 Ems/common/Ems_def.h | 107 + MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c | 0 Ems/ems.h | 24 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h | 0 MCU/STM32L4xx_HAL_Driver/LICENSE.txt | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_can.h | 0 MCU/STM32L4xx_HAL_Driver/License.md | 0 MCU/CMSIS/Include/cmsis_armclang_ltm.h | 0 MCU/CMSIS/Include/core_cm35p.h | 0 Device/inc/Hal_adc.h | 14 Device/src/os_clock.c | 19 Driver/Src/crc.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c | 0 Ems/common/Ems_assert.h | 29 Device/src/dev_pwm.c | 84 Device/inc/as5601.h | 94 MCU/CMSIS/Include/core_cm33.h | 0 Driver/Inc/dma.h | 0 MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l443xx.h | 0 Driver/Src/i2c.c | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h | 0 MCU/stm32l4xx_it.h | 1 MCU/CMSIS/LICENSE.txt | 0 MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h | 0 Device/src/dev_pwm.h | 47 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h | 0 Driver/Src/can.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c | 0 Driver/Inc/adc.h | 2 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h | 0 Driver/Inc/gpio.h | 0 Driver/Src/drv_pwm.c | 184 + MCU/CMSIS/Include/cmsis_compiler.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h | 0 MCU/CMSIS/Include/core_cm7.h | 0 Device/src/dev_time.c | 43 Driver/Inc/crc.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h | 0 Driver/Inc/main.h | 0 Ems/common/Ems_export.c | 242 ++ MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c | 0 MCU/CMSIS/Include/core_sc000.h | 0 MCU/CMSIS/Include/core_cm3.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h | 0 Driver/Src/Hal_adc.c | 87 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c | 0 Ems/3rd/Shell/shell_ext.h | 33 Driver/Inc/can.h | 0 MCU/CMSIS/Device/ST/STM32L4xx/License.md | 0 Ems/3rd/Shell/shell_ext.c | 447 ++++ MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h | 0 Ems/3rd/Shell/shell_companion.c | 87 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h | 0 MCU/CMSIS/Include/core_armv81mml.h | 0 Driver/Src/dma.c | 0 Device/src/dev_list.h | 21 MCU/CMSIS/Include/cmsis_armcc.h | 0 MCU/CMSIS/Include/mpu_armv8.h | 0 Device/src/dev_pin.c | 121 + MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c | 0 MCU/CMSIS/Include/core_cm23.h | 0 MCU/CMSIS/Include/cmsis_armclang.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c | 0 MCU/CMSIS/Include/core_sc300.h | 0 MCU/system_stm32l4xx.c | 0 MCU/CMSIS/Include/cmsis_iccarm.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c | 0 MCU/CMSIS/Include/core_cm0.h | 0 CAHB_L4_PH.ioc | 9 MCU/CMSIS/Include/core_cm4.h | 0 Ems/3rd/Shell/shell_cmd_list.c | 103 + MCU/stm32l4xx_hal_conf.h | 0 Device/inc/os_task.h | 2 Ems/common/Ems_export.h | 249 ++ Device/inc/Hal_gpio.h | 24 Device/src/dev_as5601.c | 24 Driver/Inc/stm32l4xx_it.h | 1 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c | 0 MCU/CMSIS/Include/core_armv8mbl.h | 0 Driver/Inc/tim.h | 0 MCU/CMSIS/Device/ST/STM32L4xx/LICENSE.txt | 0 Device/inc/os_clock.h | 9 Driver/Inc/stm32l4xx_hal_conf.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h | 0 Device/src/bsp.h | 25 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c | 0 Ems/3rd/Shell/shell.h | 477 ++++ MCU/CMSIS/Include/cmsis_gcc.h | 0 MCU/CMSIS/Include/core_armv8mml.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h | 0 Device/src/bsp.c | 105 + Device/src/dev_pin.h | 61 Ems/3rd/Shell/shell.c | 1972 ++++++++++++++++++++ MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h | 0 Driver/Src/drv_gpio.c | 86 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h | 0 Makefile | 13 Device/src/os_task.c | 7 MCU/CMSIS/Include/mpu_armv7.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c | 0 .mxproject | 6 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc_ex.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h | 0 MCU/CMSIS/Include/core_cm1.h | 0 MCU/CMSIS/Include/tz_context.h | 0 Driver/Inc/i2c.h | 0 MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc.h | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c | 0 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c | 0 Driver/Src/clock.c | 21 Device/src/ems_object.c | 186 + MCU/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h | 0 MCU/CMSIS/Include/core_cm0plus.h | 0 Driver/Src/adc.c | 0 /dev/null | 111 - Device/src/ems_object.h | 80 Ems/3rd/Shell/shell_cfg.h | 183 + Driver/Inc/clock.h | 7 Driver/Src/drv_pin.c | 209 ++ Ems/common/Ems_common.h | 52 Driver/Src/tim.c | 0 Ems/common/Ems_common.c | 46 MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c | 0 MCU/CMSIS/Include/cmsis_version.h | 0 146 files changed, 5,642 insertions(+), 174 deletions(-) diff --git a/.mxproject b/.mxproject index 6cd1355..8991315 100644 --- a/.mxproject +++ b/.mxproject @@ -5,7 +5,7 @@ SourceFiles=;; [PreviousUsedMakefileFiles] -SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\adc.c;Core\Src\can.c;Core\Src\crc.c;Core\Src\dma.c;Core\Src\i2c.c;Core\Src\tim.c;Core\Src\stm32l4xx_it.c;Core\Src\stm32l4xx_hal_msp.c;Core\Src\stm32l4xx_hal_timebase_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;;; +SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\adc.c;Core\Src\can.c;Core\Src\crc.c;Core\Src\dma.c;Core\Src\i2c.c;Core\Src\tim.c;Core\Src\stm32l4xx_it.c;Core\Src\stm32l4xx_hal_msp.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_crc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;;; HeaderPath=Drivers\STM32L4xx_HAL_Driver\Inc;Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32L4xx\Include;Drivers\CMSIS\Include;Core\Inc; CDefines=USE_HAL_DRIVER;STM32L443xx;USE_HAL_DRIVER;USE_HAL_DRIVER; @@ -25,7 +25,7 @@ HeaderFolderListSize=1 HeaderPath#0=C:/Workspace/Software/CAHB_L4_PH/Core/Inc HeaderFiles=; -SourceFileListSize=11 +SourceFileListSize=10 SourceFiles#0=C:/Workspace/Software/CAHB_L4_PH/Core/Src/gpio.c SourceFiles#1=C:/Workspace/Software/CAHB_L4_PH/Core/Src/adc.c SourceFiles#2=C:/Workspace/Software/CAHB_L4_PH/Core/Src/can.c @@ -35,8 +35,6 @@ SourceFiles#6=C:/Workspace/Software/CAHB_L4_PH/Core/Src/tim.c SourceFiles#7=C:/Workspace/Software/CAHB_L4_PH/Core/Src/stm32l4xx_it.c SourceFiles#8=C:/Workspace/Software/CAHB_L4_PH/Core/Src/stm32l4xx_hal_msp.c -SourceFiles#9=C:/Workspace/Software/CAHB_L4_PH/Core/Src/stm32l4xx_hal_timebase_tim.c -SourceFiles#10=C:/Workspace/Software/CAHB_L4_PH/Core/Src/main.c SourceFolderListSize=1 SourcePath#0=C:/Workspace/Software/CAHB_L4_PH/Core/Src SourceFiles=; diff --git a/APP/main.c b/APP/main.c index 2e1dd22..5ab694d 100644 --- a/APP/main.c +++ b/APP/main.c @@ -1,6 +1,16 @@ #include "main.h" #include "os_task.h" - +#include "os_clock.h" +#include "clock.h" +#include "adc.h" +#include "can.h" +#include "crc.h" +#include "dma.h" +#include "i2c.h" +#include "tim.h" +#include "gpio.h" +#include "Hal_gpio.h" +#include "Hal_adc.h" static void GPIO_FunctionTestTask(void *p) { *p; @@ -27,6 +37,8 @@ MX_DMA_Init(); MX_TIM15_Init(); + Hal_ADCInit(); + OSTaskCreate(GPIO_FunctionTestTask, 1, 1, NULL); OSSchedule(&OS_GetTick); diff --git a/CAHB_Hal/inc/os_clock.h b/CAHB_Hal/inc/os_clock.h deleted file mode 100644 index e1919c8..0000000 --- a/CAHB_Hal/inc/os_clock.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef OS_CLOCK_H -#define OS_CLOCK_H - -extern void Ostick_config(void); -// void Ostick_ReInit(void); -void HAL_IncTick(void); -#endif \ No newline at end of file diff --git a/CAHB_Hal/src/os_clock.c b/CAHB_Hal/src/os_clock.c deleted file mode 100644 index 810c3db..0000000 --- a/CAHB_Hal/src/os_clock.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "os_clock.h" -#include "os_task.h" -#include "stm32l4xx_hal.h" - - -// void SysTick_Handler(void) -// { -// OS_TickFlag = 1; -// } - -// void Ostick_ReInit(void) -// { - -// } - - -void HAL_IncTick(void) -{ -// uwTick += (uint32_t)uwTickFreq; -OS_TickFlag = 1; - -} diff --git a/CAHB_L4_PH.ioc b/CAHB_L4_PH.ioc index 2a6bebb..1ff559b 100644 --- a/CAHB_L4_PH.ioc +++ b/CAHB_L4_PH.ioc @@ -109,7 +109,7 @@ Mcu.Pin31=VP_ADC1_TempSens_Input Mcu.Pin32=VP_ADC1_Vbat_Input Mcu.Pin33=VP_CRC_VS_CRC -Mcu.Pin34=VP_SYS_VS_tim6 +Mcu.Pin34=VP_SYS_VS_Systick Mcu.Pin35=VP_TIM1_VS_ClockSourceINT Mcu.Pin36=VP_TIM1_VS_ClockSourceITR Mcu.Pin37=VP_TIM1_VS_no_output4 @@ -136,9 +136,6 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true -NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:true -NVIC.TimeBase=TIM6_DAC_IRQn -NVIC.TimeBaseIP=TIM6 NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false PA0.GPIOParameters=GPIO_Label PA0.GPIO_Label=EXT_END @@ -365,8 +362,8 @@ VP_ADC1_Vbat_Input.Signal=ADC1_Vbat_Input VP_CRC_VS_CRC.Mode=CRC_Activate VP_CRC_VS_CRC.Signal=CRC_VS_CRC -VP_SYS_VS_tim6.Mode=TIM6 -VP_SYS_VS_tim6.Signal=SYS_VS_tim6 +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_TIM1_VS_ClockSourceINT.Mode=Internal VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT VP_TIM1_VS_ClockSourceITR.Mode=TriggerSource_ITR3 diff --git a/Core/Src/stm32l4xx_hal_timebase_tim.c b/Core/Src/stm32l4xx_hal_timebase_tim.c deleted file mode 100644 index ef21c4a..0000000 --- a/Core/Src/stm32l4xx_hal_timebase_tim.c +++ /dev/null @@ -1,111 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32l4xx_hal_timebase_TIM.c - * @brief HAL time base based on the hardware TIM. - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal.h" -#include "stm32l4xx_hal_tim.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -TIM_HandleTypeDef htim6; -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief This function configures the TIM6 as a time base source. - * The time source is configured to have 1ms time base with a dedicated - * Tick interrupt priority. - * @note This function is called automatically at the beginning of program after - * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). - * @param TickPriority: Tick interrupt priority. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) -{ - RCC_ClkInitTypeDef clkconfig; - uint32_t uwTimclock = 0; - uint32_t uwPrescalerValue = 0; - uint32_t pFLatency; - /*Configure the TIM6 IRQ priority */ - HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0); - - /* Enable the TIM6 global Interrupt */ - HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); - - /* Enable TIM6 clock */ - __HAL_RCC_TIM6_CLK_ENABLE(); - - /* Get clock configuration */ - HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); - - /* Compute TIM6 clock */ - uwTimclock = HAL_RCC_GetPCLK1Freq(); - /* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */ - uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); - - /* Initialize TIM6 */ - htim6.Instance = TIM6; - - /* Initialize TIMx peripheral as follow: - + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base. - + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. - + ClockDivision = 0 - + Counter direction = Up - */ - htim6.Init.Period = (1000000U / 1000U) - 1U; - htim6.Init.Prescaler = uwPrescalerValue; - htim6.Init.ClockDivision = 0; - htim6.Init.CounterMode = TIM_COUNTERMODE_UP; - - if(HAL_TIM_Base_Init(&htim6) == HAL_OK) - { - /* Start the TIM time Base generation in interrupt mode */ - return HAL_TIM_Base_Start_IT(&htim6); - } - - /* Return function status */ - return HAL_ERROR; -} - -/** - * @brief Suspend Tick increment. - * @note Disable the tick increment by disabling TIM6 update interrupt. - * @param None - * @retval None - */ -void HAL_SuspendTick(void) -{ - /* Disable TIM6 update Interrupt */ - __HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE); -} - -/** - * @brief Resume Tick increment. - * @note Enable the tick increment by Enabling TIM6 update interrupt. - * @param None - * @retval None - */ -void HAL_ResumeTick(void) -{ - /* Enable TIM6 Update interrupt */ - __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE); -} - diff --git a/Device/inc/Hal_adc.h b/Device/inc/Hal_adc.h new file mode 100644 index 0000000..1be9e1d --- /dev/null +++ b/Device/inc/Hal_adc.h @@ -0,0 +1,14 @@ +#ifndef HAL_ADC_H +#define HAL_ADC_H + +#define PCB_TEMPERATURE_CHANNEL (0) +#define BUS_VOLTAGE_CHANNEL (1U) +#define BUS_CURRENT_CHANNEL (2U) +#define PHASE_CURRENT_CHANNEL (3U) +#define MCU_TEMPERATURE_CHANNEL (4U) +#define MCU_VOLTAGE_CHANNEL (5U) +#define MAX_ADC_CHANNEL_NUM (6U) + +extern void Hal_ADCInit(void); +extern uint16_t Hal_GetADCChannelValue(uint8_t channel); +#endif /*end of file*/ diff --git a/Device/inc/Hal_gpio.h b/Device/inc/Hal_gpio.h new file mode 100644 index 0000000..5c12756 --- /dev/null +++ b/Device/inc/Hal_gpio.h @@ -0,0 +1,24 @@ +#ifndef HAL_GPIO_H +#define HAL_GPIO_H +#include "stdint.h" + + + +extern void Hal_ExtendEndSetActive(void); +extern void Hal_ExtendEndSetInactive(void); +extern void Hal_RetractEndSetActive(void); +extern void Hal_RetractEndSetInactive(void); +extern void Hal_AlarmSetActive(void); +extern void Hal_AlarmSetInactive(void); +extern void Hal_SensorPowerEnable(void); +extern void Hal_SensorPowerDisable(void); +extern void Hal_MCU2PowerEnable(void); +extern void Hal_MCU2PowerDisable(void); +extern void Hal_CANEnable(void); +extern void Hal_CANDisable(void); +extern void Hal_HBridgeEnable(void); +extern void Hal_HBridgeDisable(void); +extern uint8_t Hal_GetExtendInLevel(void); +extern uint8_t Hal_GetRetactInLevel(void); + +#endif diff --git a/Device/inc/as5601.h b/Device/inc/as5601.h new file mode 100644 index 0000000..165e432 --- /dev/null +++ b/Device/inc/as5601.h @@ -0,0 +1,94 @@ +#ifndef AS5601_H +#define AS5061_H + +typedef struct AS5601_Magnet +{ + unsigned char magnet_status; + unsigned char AGC; + unsigned char MAGNITUDE_H4; + unsigned char MAGNITUDE_L8; +} AS5601_Magnet_t; + +typedef struct AS5601 +{ + unsigned char id; + unsigned char status; + AS5601_Magnet_t magnet; + unsigned short zero_pos; + unsigned short angle; + unsigned short raw_angle; +} AS5601_t; + +typedef union AS5601_CONF +{ + unsigned short conf; + struct + { + unsigned char sf : 2; + unsigned char FTH : 3; + unsigned char WD : 1; + unsigned char reserved1 : 2; + unsigned char PM : 2; + unsigned char HYST : 2; + unsigned char reserved2 : 4; + } bit; +} AS5601_CONF_t; + +typedef struct AS5601_Config +{ + unsigned short zero_pos; + AS5601_CONF_t CONF; + unsigned char ABN; + unsigned char PUSHTHR; +} AS5601_Config_t; + +typedef enum AS5601PowerMode +{ + NOM = 0x0, + LPM1 = 1, + LPM2 = 2, + LPM3 = 3 +} AS5601PowerMode_t; + +typedef enum AS5601Hysteresis +{ + OFF = 0x0, + LSB1 = 0x1, + LSB2 = 0x2, + LSB3 = 0x3 +} AS5601Hysteresis_t; + +typedef enum AS5601SlowFilter +{ + SlowFilter_16x = 0x0, + SlowFilter_8x = 0x1, + SlowFilter_4x = 0x2, + SlowFilter_2x = 0x3 +} AS5601SlowFilter_t; + +typedef enum AS5601FastFilter +{ + FastFilter_slow = 0x0, + FastFilter_6LSB = 0x1, + FastFilter_7LSB = 0x2, + FastFilter_9LSB = 0x3, + FastFilter_18LSB = 0x4, + FastFilter_21LSB = 0x5, + FastFilter_24LSB = 0x6, + FastFilter_10LSB = 0x7 +} AS5601FastFilter_t; +typedef enum AS5601ABN +{ + ABN_61Hz = 0x0, + ABN_122Hz = 0x1, + ABN_244Hz = 0x2, + ABN_488Hz = 0x3, + ABN_976Hz = 0x4, + ABN_1k9Hz = 0x5, + ABN_3k9Hz = 0x6, + ABN_7k8Hz = 0x7, + ABN_15k6Hz = 0x8 +} AS5601ABN_t; + +extern uint16_t Hal_GetHallSensorRawValue(uint8_t channel); +#endif diff --git a/Device/inc/os_clock.h b/Device/inc/os_clock.h new file mode 100644 index 0000000..e3b83ac --- /dev/null +++ b/Device/inc/os_clock.h @@ -0,0 +1,9 @@ +#ifndef OS_CLOCK_H +#define OS_CLOCK_H +extern volatile int OS_TickFlag; + +// void Ostick_ReInit(void); +void os_SetTickFlag(void); +int os_GetTickFlag(void); +void os_ClearTickFlag(void); +#endif \ No newline at end of file diff --git a/CAHB_Hal/inc/os_task.h b/Device/inc/os_task.h similarity index 93% rename from CAHB_Hal/inc/os_task.h rename to Device/inc/os_task.h index 5449660..cf65848 100644 --- a/CAHB_Hal/inc/os_task.h +++ b/Device/inc/os_task.h @@ -22,7 +22,7 @@ int OSTaskCreate(TASK_FUNC func, int tick, int work_tick, void *par); void OSSchedule(GETTICK_t GetTick); void OS_GetTick(void); - extern volatile int OS_TickFlag; + extern volatile int OS_Init_time_cnt; #ifdef __cplusplus } diff --git a/Device/src/Ems_config.h b/Device/src/Ems_config.h new file mode 100644 index 0000000..67d1293 --- /dev/null +++ b/Device/src/Ems_config.h @@ -0,0 +1,27 @@ +/** + * @file Ems_config.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_CONFIG_H +#define EMS_CONFIG_H + +/* public config ------------------------------------------------------------ */ +/* CMSIS OS related -------------------------------------- */ +#define EMS_RTOS_CMSIS_OS_EN (0) +#define EMS_RTOS_TICK_MS (1) + +/* QPC related ------------------------------------------- */ +#define EMS_QPC_EN (0) +#define EMS_EVENT_DATA_SIZE (128) +#define EMS_EVENT_POOL_SIZE (64) + +#endif /* EMS_CONFIG_H */ + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/bsp.c b/Device/src/bsp.c new file mode 100644 index 0000000..22b0f9b --- /dev/null +++ b/Device/src/bsp.c @@ -0,0 +1,105 @@ + +/** + * @file bsp.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#include "bsp.h" +#include "stm32l4xx_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* private function prototype ----------------------------------------------- */ +static void _error_handler(void); +static void _system_clock_config(void); + +/* includes ----------------------------------------------------------------- */ +/** + * @brief BSP initialization. + * @retval None + */ +void bsp_init(void) +{ + HAL_Init(); + SystemClock_Config(); +} + +/* private functions -------------------------------------------------------- */ +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 3; + RCC_OscInitStruct.PLL.PLLN = 32; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) + { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef __cplusplus +} +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/bsp.h b/Device/src/bsp.h new file mode 100644 index 0000000..0396739 --- /dev/null +++ b/Device/src/bsp.h @@ -0,0 +1,25 @@ +/** + * @file bsp.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef BSP_H +#define BSP_H + +#ifdef __cplusplus +extern "C" { +#endif + +void bsp_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Device/src/dev_as5601.c b/Device/src/dev_as5601.c new file mode 100644 index 0000000..9798084 --- /dev/null +++ b/Device/src/dev_as5601.c @@ -0,0 +1,24 @@ +#include "as5601.h" +#include "i2c.h" +#include "Hal_gpio.h" +#include "stm32l4xx_hal_i2c" + + +#define AS5601_ADDRESS (0x6C) /**< in the as5601 datasheet the address (0x36) is expressed in 7 bit but needs to be left shifted by 1, giving 0x6C*/ + +#define ZMCO_ADDR (0x00) +#define ZPOS_ADDR (0x01) +#define CONF_ADDR (0x07) +#define ABN_ADDR (0x09) +#define PUSHTHR_ADDR (0x0A) +#define RAWANGLE_ADDR (0x0C) +#define ANGLE_ADDR (0x0E) +#define STATUS_ADDR (0x0B) +#define AGC_ADDR (0x1A) +#define MAGNITUDE_ADDR (0x1B) +#define BURN_CMD (0xFF) + +#define BURN_SETTING (0x40) +#define BURN_ANGLE (0x80) + +extern uint16_t Hal_GetHallSensorRawValue(uint8_t channel); \ No newline at end of file diff --git a/Device/src/dev_list.h b/Device/src/dev_list.h new file mode 100644 index 0000000..0605f46 --- /dev/null +++ b/Device/src/dev_list.h @@ -0,0 +1,21 @@ +/** + * @file dev_list.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ +#ifndef __DEV_LIST_H__ +#define __DEV_LIST_H__ + +#include "Ems_object.h" + +extern eio_object_t *led3; +extern eio_object_t *led4; + +#endif /* __DEV_LIST_H__ */ + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/dev_pin.c b/Device/src/dev_pin.c new file mode 100644 index 0000000..67a7be9 --- /dev/null +++ b/Device/src/dev_pin.c @@ -0,0 +1,121 @@ + +/** + * @file Ems_pin.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ +#include <string.h> +#include "dev_pin.h" +#include "ems_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EMS_TAG("EMS_PIN") + +static ems_ops_t _obj_ops = +{ + .open = NULL, + .close = NULL, + .read = NULL, + .write = NULL, +}; + +/** + * @brief EMS pin initialization. + * @param me this pointer + * @param name pin's name. + * @param mode pin's mode. + * @retval None + */ +void ems_pin_register(ems_pin_t * const me, + const char *name, + const ems_pin_ops_t *ops, + void *user_data) +{ + ems_assert(me != NULL); + ems_assert(name != NULL); + ems_assert(ops != NULL); + + ems_obj_attr_t attr = + { + .user_data = user_data, + .standlone = true, + .type = EMS_OBJ_PIN, + }; + + ems_register(&me->super, name, &_obj_ops, &attr); + + me->ops = ops; + me->ops->init(me); + me->status = me->ops->get_status(me); +} + +/** + * @brief + * + * @param me + * @param mode + */ +void ems_pin_set_mode(ems_object_t * const me, uint8_t mode) +{ + ems_assert(me != NULL); + + ems_pin_t *pin = (ems_pin_t *)me; + if (pin->mode != mode) + { + pin->ops->set_mode(pin, mode); + pin->mode = mode; + } +} + + +/** + * @brief + * + * @param me + * @return true + * @return false + */ +bool ems_pin_get_status(ems_object_t * const me) +{ + ems_assert(me != NULL); + ems_pin_t *pin = (ems_pin_t *)me; + + pin->status = pin->ops->get_status(pin); + + return pin->status; +} + +/** + * @brief + * + * @param me + * @param status + */ +void ems_pin_set_status(ems_object_t * const me, bool status) +{ + ems_assert(me != NULL); + + ems_pin_t *pin = (ems_pin_t *)me; + ems_assert(pin->mode == PIN_MODE_OUTPUT || pin->mode == PIN_MODE_OUTPUT_OD); + + if (status != pin->status) + { + pin->ops->set_status(pin, status); + ems_pin_get_status(me); + ems_assert(pin->status == status); + } +} + +#ifdef __cplusplus +} +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/dev_pin.h b/Device/src/dev_pin.h new file mode 100644 index 0000000..423ee87 --- /dev/null +++ b/Device/src/dev_pin.h @@ -0,0 +1,61 @@ +/* + * eLesson Project + * Copyright (c) 2023, EventOS Team, <event-os@outlook.com> + */ + +#ifndef EMS_PIN_H +#define EMS_PIN_H + +/* includes ----------------------------------------------------------------- */ +#include "eio_object.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum pin_mode +{ + PIN_MODE_INPUT = 0, + PIN_MODE_INPUT_PULLUP, + PIN_MODE_INPUT_PULLDOWN, + PIN_MODE_OUTPUT_PP, + PIN_MODE_OUTPUT_OD, + + PIN_MODE_MAX +}; + + +typedef struct eio_pin +{ + eio_object_t super; + + const struct ems_pin_ops *ops; + uint8_t mode; + bool status; +} ems_pin_t; + +typedef struct ems_pin_ops +{ + void (* init)(ems_pin_t * const me); + void (* set_mode)(ems_pin_t * const me, uint8_t mode); + bool (* get_status)(ems_pin_t * const me); + void (* set_status)(ems_pin_t * const me, bool status); +} ems_pin_ops_t; + + +void ems_pin_register(ems_pin_t * const me, + const char *name, + const ems_pin_ops_t *ops, + void *user_data); + +void ems_pin_set_mode(eio_object_t * const me, uint8_t mode); +bool ems_pin_get_status(eio_object_t * const me); +void ems_pin_set_status(eio_object_t * const me, bool status); + +#ifdef __cplusplus +} +#endif + +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/dev_pwm.c b/Device/src/dev_pwm.c new file mode 100644 index 0000000..a7f6c8d --- /dev/null +++ b/Device/src/dev_pwm.c @@ -0,0 +1,84 @@ +/** + * @file dev_pwm.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#include <string.h> +#include "dev_pwm.h" +#include "ems_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EMS_TAG("EMS_PWM") + +/* private variables -------------------------------------------------------- */ +static ems_ops_t _obj_ops = +{ + .open = NULL, + .close = NULL, + .read = NULL, + .write = NULL, +}; + +/** + * @brief + * + * @param me + * @param name + * @param ops + * @param user_data + */ +void ems_pwm_register(ems_pwm_t * const me, + const char *name, + const ems_pwm_ops_t *ops, + void *user_data) +{ + ems_assert(me != NULL); + ems_assert(name != NULL); + ems_assert(ops != NULL); + + ems_obj_attr_t attr = + { + .user_data = user_data, + .standlone = true, + .type = EMS_OBJ_PWM, + }; + + ems_register(&me->super, name, &_obj_ops, &attr); + + me->ops = ops; + me->duty_ratio = 0; + me->ops->init(me); +} + +/** + * @brief + * + * @param me + * @param duty_ratio + */ +void ems_pwm_set_duty(ems_object_t * const me, uint8_t duty_ratio) +{ + ems_assert(me != NULL); + ems_assert(duty_ratio <= 100); + ems_assert(me->attr.type == EMS_OBJ_PWM); + + ems_pwm_t *pwm = (ems_pwm_t *)me; + if (duty_ratio != pwm->duty_ratio) + { + pwm->ops->set_duty(pwm, duty_ratio); + pwm->duty_ratio = duty_ratio; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/Device/src/dev_pwm.h b/Device/src/dev_pwm.h new file mode 100644 index 0000000..942b2d5 --- /dev/null +++ b/Device/src/dev_pwm.h @@ -0,0 +1,47 @@ +/** + * @file dev_pwm.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_PWM_H +#define EMS_PWM_H + +#include "ems_object.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ems_pwm +{ + ems_object_t super; + + const struct ems_pwm_ops *ops; + uint8_t duty_ratio; +} ems_pwm_t; + +typedef struct ems_pwm_ops +{ + void (* init)(ems_pwm_t * const me); + void (* set_duty)(ems_pwm_t * const me, uint8_t duty_ratio); +} ems_pwm_ops_t; + + +void ems_pwm_register(ems_pwm_t * const me, + const char *name, + const ems_pwm_ops_t *ops, + void *user_data); + +void ems_pwm_set_duty(ems_object_t * const me, uint8_t duty_ratio); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Device/src/dev_time.c b/Device/src/dev_time.c new file mode 100644 index 0000000..79f9ef4 --- /dev/null +++ b/Device/src/dev_time.c @@ -0,0 +1,43 @@ +/** + * @file dev_time.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ +#include "ems_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static uint32_t sys_time_ms = 0; + +/* public functions --------------------------------------------------------- */ +/** + * @brief SysTick ISR function. + * @retval None + */ +uint32_t ems_time_ms(void) +{ + return sys_time_ms; +} + +/* private functions -------------------------------------------------------- */ +/** + * @brief SysTick ISR function. + * @retval None + */ +void SysTick_Handler(void) +{ + sys_time_ms ++; +} + +#ifdef __cplusplus +} +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Device/src/ems_object.c b/Device/src/ems_object.c new file mode 100644 index 0000000..671ff25 --- /dev/null +++ b/Device/src/ems_object.c @@ -0,0 +1,186 @@ +/** + * @file Ems_object.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +/* includes ----------------------------------------------------------------- */ +#include <string.h> +#include "ems_object.h" +#include "ems_assert.h" + +/* private variables -------------------------------------------------------- */ +static ems_object_t *ems_list = NULL; + +/* public functions --------------------------------------------------------- */ +/** + * @brief + * + * @param me + * @param name + * @param ops + * @param attr + */ +void ems_register(ems_object_t *const me, const char *name, + const ems_ops_t *ops, + ems_obj_attr_t *attr) +{ + ems_assert(me != NULL); + ems_assert(name != NULL); + ems_assert(ops != NULL); + ems_assert(attr != NULL); + + me->name = name; + me->ops = ops; + + me->next = ems_list; + ems_list = me; + + memcpy(&me->attr, attr, sizeof(ems_obj_attr_t)); +} + +/** + * @brief + * + * @param name + * @return ems_object_t* + */ +ems_object_t *ems_find(const char *name) +{ + ems_assert(name != NULL); + ems_object_t *obj = ems_list; + while (obj != NULL) + { + if (strcmp(obj->name, name) == 0) + { + break; + } + obj = obj->next; + } + + return obj; +} + +/** + * @brief + * + * @param me + * @return ems_err_t + */ +ems_err_t ems_open(ems_object_t *const me) +{ + ems_assert(me->ops->open != NULL); + + ems_err_t ret = EMS_OK; + + if (me->attr.standlone) + { + if (me->count_open != 0) + { + ret = EMS_ERROR; + goto exit; + } + } + + ret = me->ops->open(me); + if (ret == EMS_OK) + { + me->count_open++; + } + +exit: + return ret; +} + +/** + * @brief + * + * @param me + * @return ems_err_t + */ +ems_err_t ems_close(ems_object_t *const me) +{ + ems_assert(me->ops->close != NULL); + + ems_err_t ret = EMS_OK; + + if (me->count_open > 0) + { + ret = me->ops->close(me); + if (ret == EMS_OK) + { + me->count_open--; + goto exit; + } + } + else + { + ret = EMS_ERROR; + } + +exit: + return ret; +} + +/** + * @brief + * + * @param me + * @param buffer + * @param size + * @return int32_t + */ +int32_t ems_read(ems_object_t *const me, void *buffer, uint32_t size) +{ + ems_assert(me != NULL); + ems_assert(buffer != NULL); + ems_assert(size != 0); + ems_assert(me->ops->read != NULL); + + int32_t ret = 0; + + if (me->count_open != 0) + { + ret = me->ops->read(me, buffer, size); + } + else + { + ret = (int32_t)EMS_ERROR; + } + + return ret; +} + +/** + * @brief + * + * @param me + * @param buffer + * @param size + * @return int32_t + */ +int32_t ems_write(ems_object_t *const me, const void *buffer, uint32_t size) +{ + ems_assert(me != NULL); + ems_assert(buffer != NULL); + ems_assert(size != 0); + ems_assert(me->ops->write != NULL); + + int32_t ret = 0; + + if (me->count_open != 0) + { + ret = me->ops->write(me, buffer, size); + } + else + { + ret = (int32_t)EMS_ERROR; + } + + return ret; +} diff --git a/Device/src/ems_object.h b/Device/src/ems_object.h new file mode 100644 index 0000000..9223c56 --- /dev/null +++ b/Device/src/ems_object.h @@ -0,0 +1,80 @@ +/** + * @file Ems_object.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef Ems_OBJECT_H +#define Ems_OBJECT_H + +/* includes ----------------------------------------------------------------- */ +#include <stdbool.h> +#include <stdint.h> +#include "Ems_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* public define ------------------------------------------------------------ */ +enum ems_obect_type +{ + EMS_OBJ_PIN = 0, + EMS_OBJ_PWM, + EMS_OBJ_ADC, + EMS_OBJ_DAC, + EMS_OBJ_UART, + EMS_OBJ_SPI, + EMS_OBJ_I2C, + EMS_OBJ_CAN, + EMS_OBJ_MAX +}; + +/* public typedef ----------------------------------------------------------- */ +typedef struct ems_obj_attr +{ + void *user_data; + uint8_t type; + bool standlone; +} ems_obj_attr_t; + +typedef struct ems_object +{ + struct ems_object *next; + const char *name; + const struct ems_ops *ops; + uint16_t count_open; + ems_obj_attr_t attr; +} ems_object_t; + +typedef struct ems_ops +{ + ems_err_t (* open)(ems_object_t * const me); + ems_err_t (* close)(ems_object_t * const me); + int32_t (* read)(ems_object_t * const me, void *buffer, uint32_t size); + int32_t (* write)(ems_object_t * const me, const void *buffer, uint32_t size); +} ems_ops_t; + + +/* For io-level driver. */ +void ems_register(ems_object_t * const me, const char *name, + const ems_ops_t *ops, + ems_obj_attr_t *attr); + +/* For high-level code. */ +ems_object_t *ems_find(const char *name); +ems_err_t ems_open(ems_object_t * const me); +ems_err_t ems_close(ems_object_t * const me); +int32_t ems_read(ems_object_t * const me, void *buffer, uint32_t size); +int32_t ems_write(ems_object_t * const me, const void *buffer, uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* EMS_OBJECT_H */ diff --git a/Device/src/os_clock.c b/Device/src/os_clock.c new file mode 100644 index 0000000..c35b312 --- /dev/null +++ b/Device/src/os_clock.c @@ -0,0 +1,19 @@ +#include "os_clock.h" +#include "os_task.h" +#include "stm32l4xx_hal.h" + +volatile int OS_TickFlag = 0; + +void os_SetTickFlag(void) +{ + OS_TickFlag = 1; +} +int os_GetTickFlag(void) +{ + return OS_TickFlag; +} +void os_ClearTickFlag(void) +{ + OS_TickFlag = 0; +} + diff --git a/CAHB_Hal/src/os_task.c b/Device/src/os_task.c similarity index 94% rename from CAHB_Hal/src/os_task.c rename to Device/src/os_task.c index 6388027..f454daf 100644 --- a/CAHB_Hal/src/os_task.c +++ b/Device/src/os_task.c @@ -1,10 +1,11 @@ #include "os_task.h" +#include "os_clock.h" // extern int OS_TickFlag = 0; static OS_TASK_MSG *g_p_task = NULL; static int g_task_cnt = 0; static int g_task_pos = 0; -volatile int OS_TickFlag = 0; + /** * @brief * @@ -84,7 +85,7 @@ void OS_GetTick(void) { - while (1 != OS_TickFlag) + while (1 != os_GetTickFlag()) ; - OS_TickFlag = 0; + os_ClearTickFlag(); } diff --git a/Core/Inc/adc.h b/Driver/Inc/adc.h similarity index 96% rename from Core/Inc/adc.h rename to Driver/Inc/adc.h index 218e684..42107d4 100644 --- a/Core/Inc/adc.h +++ b/Driver/Inc/adc.h @@ -33,7 +33,7 @@ /* USER CODE END Includes */ extern ADC_HandleTypeDef hadc1; - +extern DMA_HandleTypeDef hdma_adc1; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ diff --git a/Core/Inc/can.h b/Driver/Inc/can.h similarity index 100% rename from Core/Inc/can.h rename to Driver/Inc/can.h diff --git a/Driver/Inc/clock.h b/Driver/Inc/clock.h new file mode 100644 index 0000000..d101473 --- /dev/null +++ b/Driver/Inc/clock.h @@ -0,0 +1,7 @@ +#ifndef CLOCK_H +#define CLOCK_H +#include "stdint.h" +extern void SystemClock_Config(void); +extern void assert_failed(uint8_t *file, uint32_t line); +extern void Error_Handler(void); +#endif diff --git a/Core/Inc/crc.h b/Driver/Inc/crc.h similarity index 100% rename from Core/Inc/crc.h rename to Driver/Inc/crc.h diff --git a/Core/Inc/dma.h b/Driver/Inc/dma.h similarity index 100% rename from Core/Inc/dma.h rename to Driver/Inc/dma.h diff --git a/Core/Inc/gpio.h b/Driver/Inc/gpio.h similarity index 100% rename from Core/Inc/gpio.h rename to Driver/Inc/gpio.h diff --git a/Core/Inc/i2c.h b/Driver/Inc/i2c.h similarity index 100% rename from Core/Inc/i2c.h rename to Driver/Inc/i2c.h diff --git a/Core/Inc/main.h b/Driver/Inc/main.h similarity index 100% rename from Core/Inc/main.h rename to Driver/Inc/main.h diff --git a/Core/Inc/stm32l4xx_hal_conf.h b/Driver/Inc/stm32l4xx_hal_conf.h similarity index 100% rename from Core/Inc/stm32l4xx_hal_conf.h rename to Driver/Inc/stm32l4xx_hal_conf.h diff --git a/Core/Inc/stm32l4xx_it.h b/Driver/Inc/stm32l4xx_it.h similarity index 97% rename from Core/Inc/stm32l4xx_it.h rename to Driver/Inc/stm32l4xx_it.h index 83f5517..cbfc055 100644 --- a/Core/Inc/stm32l4xx_it.h +++ b/Driver/Inc/stm32l4xx_it.h @@ -56,7 +56,6 @@ void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Channel1_IRQHandler(void); -void TIM6_DAC_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Core/Inc/tim.h b/Driver/Inc/tim.h similarity index 100% rename from Core/Inc/tim.h rename to Driver/Inc/tim.h diff --git a/Driver/Src/Hal_adc.c b/Driver/Src/Hal_adc.c new file mode 100644 index 0000000..ede0888 --- /dev/null +++ b/Driver/Src/Hal_adc.c @@ -0,0 +1,87 @@ +#include "stdint.h" +#include "main.h" +#include "adc.h" +#include "Hal_adc.h" + +#include "dma.h" +#include "stm32l4xx_hal_dma.h" +/** + * @brief half PWM duty trigger start adc. when adc convert complete and trigger DMA interrupt. do filt in the interrupt callbackfun. + * + */ +typedef void (*ADC_RESULTFILTER_t)(uint16_t input, uint16_t *output); +extern uint16_t Hal_GetADCChannelValue(uint8_t channel); +static void Hal_AdcDmaCallback(DMA_HandleTypeDef *_hdma); +static void Hal_PCBTemperatureFilter(uint16_t input, uint16_t *output); +static void Hal_BusVoltageFilter(uint16_t input, uint16_t *output); +static void Hal_BusCurrentFilter(uint16_t input, uint16_t *output); +static void Hal_PhaseCurrentFilter(uint16_t input, uint16_t *output); +static void Hal_MCUTemperFilter(uint16_t input, uint16_t *output); +static void Hal_MCUVoltageFilter(uint16_t input, uint16_t *output); + +static uint16_t Hal_O_AdcFilterResult[7] = {0}; +static volatile uint16_t Hal_ADC_DMA_RawResult[7] = {0}; +static const ADC_RESULTFILTER_t Hal_adcResultFilterFun[MAX_ADC_CHANNEL_NUM] = {Hal_PCBTemperatureFilter, Hal_BusVoltageFilter, Hal_BusCurrentFilter, Hal_PhaseCurrentFilter, Hal_MCUTemperFilter, Hal_MCUVoltageFilter}; + +/** + * @brief + * + */ +extern void Hal_ADCInit(void) +{ + + HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_CPLT_CB_ID, Hal_AdcDmaCallback); + HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&Hal_ADC_DMA_RawResult, 6); +} + +extern uint16_t Hal_GetADCChannelValue(uint8_t channel) +{ + uint16_t retvalue = 0; + if (channel < MAX_ADC_CHANNEL_NUM) + { + retvalue = Hal_O_AdcFilterResult[channel]; + } + else + { + } + return retvalue; +} +static void Hal_AdcDmaCallback(DMA_HandleTypeDef *_hdma) +{ + uint8_t i = 0; + for (i = 0; i < MAX_ADC_CHANNEL_NUM; i++) + { + Hal_adcResultFilterFun[i](Hal_ADC_DMA_RawResult[i], &Hal_O_AdcFilterResult[i]); + } +} + +static void Hal_PCBTemperatureFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 3u * (temp >> 2u) + (input >> 2u); +} +static void Hal_BusVoltageFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 7u * (temp >> 3u) + (input >> 3u); +} +static void Hal_BusCurrentFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 3u * (temp >> 2u) + (input >> 2u); +} +static void Hal_PhaseCurrentFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 3u * (temp >> 2u) + (input >> 2u); +} +static void Hal_MCUTemperFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 3u * (temp >> 2u) + (input >> 2u); +} +static void Hal_MCUVoltageFilter(uint16_t input, uint16_t *output) +{ + uint16_t temp = *output; + *output = 3u * (temp >> 2u) + (input >> 2u); +} \ No newline at end of file diff --git a/Core/Src/adc.c b/Driver/Src/adc.c similarity index 100% rename from Core/Src/adc.c rename to Driver/Src/adc.c diff --git a/Core/Src/can.c b/Driver/Src/can.c similarity index 100% rename from Core/Src/can.c rename to Driver/Src/can.c diff --git a/Core/Src/clock.c b/Driver/Src/clock.c similarity index 87% rename from Core/Src/clock.c rename to Driver/Src/clock.c index 1bf3abd..498345a 100644 --- a/Core/Src/clock.c +++ b/Driver/Src/clock.c @@ -52,7 +52,6 @@ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ -void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -116,26 +115,6 @@ /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ - -/** - * @brief Period elapsed callback in non blocking mode - * @note This function is called when TIM6 interrupt took place, inside - * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment - * a global variable "uwTick" used as application time base. - * @param htim : TIM handle - * @retval None - */ -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - /* USER CODE BEGIN Callback 0 */ - - /* USER CODE END Callback 0 */ - if (htim->Instance == TIM6) { - HAL_IncTick(); - } - /* USER CODE BEGIN Callback 1 */ - /* USER CODE END Callback 1 */ -} /** * @brief This function is executed in case of error occurrence. diff --git a/Core/Src/crc.c b/Driver/Src/crc.c similarity index 100% rename from Core/Src/crc.c rename to Driver/Src/crc.c diff --git a/Core/Src/dma.c b/Driver/Src/dma.c similarity index 100% rename from Core/Src/dma.c rename to Driver/Src/dma.c diff --git a/Driver/Src/drv_gpio.c b/Driver/Src/drv_gpio.c new file mode 100644 index 0000000..8c0afb4 --- /dev/null +++ b/Driver/Src/drv_gpio.c @@ -0,0 +1,86 @@ +#include "Hal_gpio.h" +#include "gpio.h" +#include "main.h" +#include "stm32l4xx_hal_gpio.h" + +extern void Hal_ExtendEndSetActive(void) +{ + HAL_GPIO_WritePin(EXT_END_GPIO_Port,EXT_END_Pin,GPIO_PIN_SET); +} + +extern void Hal_ExtendEndSetInactive(void) +{ + HAL_GPIO_WritePin(EXT_END_GPIO_Port,EXT_END_Pin,GPIO_PIN_RESET); +} + +extern void Hal_RetractEndSetActive(void) +{ + HAL_GPIO_WritePin(RET_END_GPIO_Port,RET_END_Pin,GPIO_PIN_SET); +} + +extern void Hal_RetractEndSetInactive(void) +{ + HAL_GPIO_WritePin(RET_END_GPIO_Port,RET_END_Pin,GPIO_PIN_RESET); +} + +extern void Hal_AlarmSetActive(void) +{ + HAL_GPIO_WritePin(ALARM_C_GPIO_Port,ALARM_C_Pin,GPIO_PIN_RESET); +} + +extern void Hal_AlarmSetInactive(void) +{ + HAL_GPIO_WritePin(ALARM_C_GPIO_Port,ALARM_C_Pin,GPIO_PIN_RESET); +} + + +extern void Hal_SensorPowerEnable(void) +{ + HAL_GPIO_WritePin(SENSOR_EN_GPIO_Port,SENSOR_EN_Pin,GPIO_PIN_RESET); +} + +extern void Hal_SensorPowerDisable(void) +{ + HAL_GPIO_WritePin(SENSOR_EN_GPIO_Port,SENSOR_EN_Pin,GPIO_PIN_SET); +} + +extern void Hal_MCU2PowerEnable(void) +{ + HAL_GPIO_WritePin(POWER_MCU2_GPIO_Port,POWER_MCU2_Pin,GPIO_PIN_SET); +} + +extern void Hal_MCU2PowerDisable(void) +{ + HAL_GPIO_WritePin(POWER_MCU2_GPIO_Port,POWER_MCU2_Pin,GPIO_PIN_RESET); +} + +extern void Hal_CANEnable(void) +{ + HAL_GPIO_WritePin(CAN_STB_GPIO_Port,CAN_STB_Pin,GPIO_PIN_RESET); +} + +extern void Hal_CANDisable(void) +{ + HAL_GPIO_WritePin(CAN_STB_GPIO_Port,CAN_STB_Pin,GPIO_PIN_SET); +} + +extern void Hal_HBridgeEnable(void) +{ + HAL_GPIO_WritePin(DRV_L_EN_GPIO_Port,DRV_L_EN_Pin,GPIO_PIN_SET); +} + +extern void Hal_HBridgeDisable(void) +{ + HAL_GPIO_WritePin(DRV_L_EN_GPIO_Port,DRV_L_EN_Pin,GPIO_PIN_RESET); +} + + +extern uint8_t Hal_GetExtendInLevel(void) +{ + return HAL_GPIO_ReadPin(EXTEND_IN_GPIO_Port,EXTEND_IN_Pin); +} + +extern uint8_t Hal_GetRetactInLevel(void) +{ + return HAL_GPIO_ReadPin(RETRACT_IN_GPIO_Port,RETRACT_IN_Pin); +} \ No newline at end of file diff --git a/Driver/Src/drv_pin.c b/Driver/Src/drv_pin.c new file mode 100644 index 0000000..d99910e --- /dev/null +++ b/Driver/Src/drv_pin.c @@ -0,0 +1,209 @@ + +/** + * @file drv_pin.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ +#include <string.h> +#include "ems_pin.h" +#include "ems_assert.h" +#include "ems_def.h" +#include "ems_export.h" +#include "stm32l4xx_hal.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + EMS_TAG("Driver_PIN") + + /* public typedef ----------------------------------------------------------- */ + typedef struct ems_pin_data + { + ems_pin_t *device; + const char *name; + GPIO_TypeDef *gpio_x; + uint16_t pin; + GPIO_PinState Init_level; + } ems_pin_data_t; + + /* private function prototype ----------------------------------------------- */ + static void _init(ems_pin_t *const me); + static void _set_mode(ems_pin_t *const me, uint8_t mode); + static bool _get_status(ems_pin_t *const me); + static void _set_status(ems_pin_t *const me, bool status); + + /* private variables -------------------------------------------------------- */ + static ems_pin_t ems_l_pin[14] = {0}; + + static const ems_pin_ops_t pin_driver_ops = + { + .init = _init, + .set_mode = _set_mode, + .get_status = _get_status, + .set_status = _set_status, + }; + + const static ems_pin_data_t ems_pin_driver_data[] = + { + {&ems_l_pin[0], "CAN_DET", GPIOC, GPIO_PIN_15, GPIO_PIN_RESET}, + {&ems_l_pin[1], "EXT_END", GPIOA, GPIO_PIN_0, GPIO_PIN_RESET}, + {&ems_l_pin[2], "RET_END", GPIOA, GPIO_PIN_1, GPIO_PIN_RESET}, + {&ems_l_pin[3], "SENSOR_EN", GPIOA, GPIO_PIN_4, GPIO_PIN_RESET}, + {&ems_l_pin[4], "ALARM", GPIOA, GPIO_PIN_5, GPIO_PIN_RESET}, + {&ems_l_pin[5], "INCSIMA", GPIOA, GPIO_PIN_6, GPIO_PIN_RESET}, + {&ems_l_pin[6], "INCSIMB", GPIOA, GPIO_PIN_7, GPIO_PIN_RESET}, + {&ems_l_pin[7], "POWER_MCU2", GPIOB, GPIO_PIN_2, GPIO_PIN_RESET}, + {&ems_l_pin[8], "EXT_IN", GPIOB, GPIO_PIN_10, GPIO_PIN_RESET}, + {&ems_l_pin[9], "RET_IN", GPIOB, GPIO_PIN_11, GPIO_PIN_RESET}, + {&ems_l_pin[10], "CAN_STB", GPIOB, GPIO_PIN_12, GPIO_PIN_RESET}, + {&ems_l_pin[11], "DRV_L_EN", GPIOB, GPIO_PIN_3, GPIO_PIN_RESET}, + {&ems_l_pin[12], "DIAG_M1", GPIOB, GPIO_PIN_4, GPIO_PIN_RESET}, + {&ems_l_pin[13], "DIAG_M2", GPIOB, GPIO_PIN_5, GPIO_PIN_RESET}, + }; +#define PIN_NUM (sizeof(ems_pin_driver_data) / sizeof(ems_pin_data_t)) + /* public functions --------------------------------------------------------- */ + static void ems_pin_dirver_init(void) + { + for (uint32_t i = 0; i < PIN_NUM; i++) + { + /* Enable the clock. */ + if (ems_pin_driver_data[i].gpio_x == GPIOA) + { + __HAL_RCC_GPIOA_CLK_ENABLE(); + } + else if (ems_pin_driver_data[i].gpio_x == GPIOB) + { + __HAL_RCC_GPIOB_CLK_ENABLE(); + } + else if (ems_pin_driver_data[i].gpio_x == GPIOC) + { + __HAL_RCC_GPIOC_CLK_ENABLE(); + } + else + { + ; + } + + /* Device registering. */ + ems_pin_register(ems_pin_driver_data[i].device, + ems_pin_driver_data[i].name, + &pin_driver_ops, + &ems_pin_driver_data[i]); + } + } + INIT_IO_DRIVER_EXPORT(ems_pin_dirver_init); + + /* private functions -------------------------------------------------------- */ + /** + * @brief The PIN driver initialization function. + * @param me PIN device handle. + * @retval None. + */ + static void _init(ems_pin_t *const me) + { + ems_pin_data_t *driver_data = (ems_pin_data_t *)me->super.attr.user_data; + + /* Configure GPIO pin. */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pin = driver_data->pin; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(driver_data->gpio_x, &GPIO_InitStruct); + + HAL_GPIO_WritePin(driver_data->gpio_x, + driver_data->pin, + GPIO_PIN_RESET); + } + + /** + * @brief The PIN driver set_mode function. + * @param me PIN device handle. + * @retval None. + */ + static void _set_mode(ems_pin_t *const me, uint8_t mode) + { + ems_assert(me != NULL); + ems_assert(mode < PIN_MODE_MAX); + + ems_pin_data_t *driver_data = (ems_pin_data_t *)me->super.attr.user_data; + + /* Configure GPIO pin. */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if (mode == PIN_MODE_INPUT) + { + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + } + else if (mode == PIN_MODE_INPUT_PULLUP) + { + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + } + else if (mode == PIN_MODE_INPUT_PULLDOWN) + { + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + } + else if (mode == PIN_MODE_OUTPUT_PP) + { + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + } + else if (mode == PIN_MODE_OUTPUT_OD) + { + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + } + GPIO_InitStruct.Pin = driver_data->pin; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(driver_data->gpio_x, &GPIO_InitStruct); + } + + /** + * @brief The PIN driver set_mode function. + * @param me PIN device handle. + * @retval GPIO status. + */ + static bool _get_status(ems_pin_t *const me) + { + ems_assert(me != NULL); + ems_assert(mode < PIN_MODE_MAX); + + ems_pin_data_t *driver_data = (ems_pin_data_t *)me->super.attr.user_data; + + GPIO_PinState status = HAL_GPIO_ReadPin(driver_data->gpio_x, driver_data->pin); + + return (status == GPIO_PIN_SET) ? true : false; + } + + /** + * @brief The PIN driver set_status function. + * @param me PIN device handle. + * @param status GPIO status. + * @retval None. + */ + static void _set_status(ems_pin_t *const me, bool status) + { + ems_assert(me != NULL); + ems_assert(mode < PIN_MODE_MAX); + + ems_pin_data_t *driver_data = (ems_pin_data_t *)me->super.attr.user_data; + + HAL_GPIO_WritePin(driver_data->gpio_x, + driver_data->pin, + status ? GPIO_PIN_SET : GPIO_PIN_RESET); + } + +#ifdef __cplusplus +} +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Driver/Src/drv_pwm.c b/Driver/Src/drv_pwm.c new file mode 100644 index 0000000..c82d794 --- /dev/null +++ b/Driver/Src/drv_pwm.c @@ -0,0 +1,184 @@ + +/* + * eLesson Project + * Copyright (c) 2023, EventOS Team, <event-os@outlook.com> + */ + +/* includes ----------------------------------------------------------------- */ +#include "eio_pwm.h" +#include "stm32g0xx_hal.h" +#include "ems_export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* public typedef ----------------------------------------------------------- */ +typedef struct eio_pwm_data +{ + eio_pwm_t *device; + const char *name; + GPIO_TypeDef *gpio_x; + uint16_t pin; + uint32_t alternate; + TIM_HandleTypeDef *htim; + uint32_t channel; +} eio_pwm_data_t; + +/* private function prototype ----------------------------------------------- */ +static void _init(eio_pwm_t * const me); +static void _set_duty(eio_pwm_t * const me, uint8_t duty_ratio); + +static void _timer_pwm_init(eio_pwm_data_t *data); +static void _gpio_pwm_init(eio_pwm_data_t *data); + +/* private variables -------------------------------------------------------- */ +static eio_pwm_t pwm_led3; +static eio_pwm_t pwm_led4; +static eio_pwm_t pwm_adc_in; + +static TIM_HandleTypeDef htim1; +static TIM_HandleTypeDef htim15; + +static eio_pwm_data_t pwm_driver_data[] = +{ + { + &pwm_led3, "pwmled3", + GPIOC, GPIO_PIN_8, GPIO_AF2_TIM1, &htim1, TIM_CHANNEL_1, + }, + { + &pwm_led4, "pwmled4", + GPIOC, GPIO_PIN_9, GPIO_AF2_TIM1, &htim1, TIM_CHANNEL_2, + }, + { + &pwm_adc_in, "adc_in", + GPIOC, GPIO_PIN_1, GPIO_AF2_TIM15, &htim15, TIM_CHANNEL_1, + }, +}; + +static const eio_pwm_ops_t pwm_driver_ops = +{ + .init = _init, + .set_duty = _set_duty, +}; + +/* public functions --------------------------------------------------------- */ +static void driver_pwm_init(void) +{ + __HAL_RCC_TIM1_CLK_ENABLE(); + __HAL_RCC_TIM15_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + + htim1.Instance = TIM1; + htim1.Init.Prescaler = 63; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 999; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_PWM_Init(&htim1); + + htim15.Instance = TIM15; + htim15.Init.Prescaler = 63; + htim15.Init.CounterMode = TIM_COUNTERMODE_UP; + htim15.Init.Period = 999; + htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim15.Init.RepetitionCounter = 0; + htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_PWM_Init(&htim15); + + for (uint32_t i = 0; + i < sizeof(pwm_driver_data) / sizeof(eio_pwm_data_t); i ++) + { + /* Device registering. */ + eio_pwm_register(pwm_driver_data[i].device, + pwm_driver_data[i].name, + &pwm_driver_ops, + &pwm_driver_data[i]); + } +} +INIT_IO_DRIVER_EXPORT(driver_pwm_init); + +/* private functions -------------------------------------------------------- */ +static void _init(eio_pwm_t * const me) +{ + eio_pwm_data_t *data = me->super.attr.user_data; + + + _timer_pwm_init(data); + _gpio_pwm_init(data); + + HAL_TIM_PWM_Start(data->htim, data->channel); +} + +static void _set_duty(eio_pwm_t * const me, uint8_t duty) +{ + eio_pwm_data_t *data = me->super.attr.user_data; + + HAL_TIM_PWM_Stop(data->htim, data->channel); + + TIM_OC_InitTypeDef sConfigOC = {0}; + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = duty * 10; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + HAL_TIM_PWM_ConfigChannel(data->htim, &sConfigOC, data->channel); + + HAL_TIM_PWM_Start(data->htim, data->channel); +} + +static void _timer_pwm_init(eio_pwm_data_t *data) +{ + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + HAL_TIMEx_MasterConfigSynchronization(data->htim, &sMasterConfig); + + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + HAL_TIM_PWM_ConfigChannel(data->htim, &sConfigOC, data->channel); + + sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; + sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; + sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; + sBreakDeadTimeConfig.DeadTime = 0; + sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; + sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; + sBreakDeadTimeConfig.BreakFilter = 0; + sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT; + sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE; + sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH; + sBreakDeadTimeConfig.Break2Filter = 0; + sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT; + sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; + HAL_TIMEx_ConfigBreakDeadTime(data->htim, &sBreakDeadTimeConfig); +} + +static void _gpio_pwm_init(eio_pwm_data_t *data) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = data->pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = data->alternate; + HAL_GPIO_Init(data->gpio_x, &GPIO_InitStruct); +} + +#ifdef __cplusplus +} +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Core/Src/gpio.c b/Driver/Src/gpio.c similarity index 100% rename from Core/Src/gpio.c rename to Driver/Src/gpio.c diff --git a/Core/Src/i2c.c b/Driver/Src/i2c.c similarity index 100% rename from Core/Src/i2c.c rename to Driver/Src/i2c.c diff --git a/Core/Src/tim.c b/Driver/Src/tim.c similarity index 100% rename from Core/Src/tim.c rename to Driver/Src/tim.c diff --git a/Ems/3rd/Shell/shell.c b/Ems/3rd/Shell/shell.c new file mode 100644 index 0000000..29c3d25 --- /dev/null +++ b/Ems/3rd/Shell/shell.c @@ -0,0 +1,1972 @@ +/** + * @file shell.c + * @author Letter (NevermindZZT@gmail.com) + * @version 3.0.0 + * @date 2019-12-30 + * + * @copyright (c) 2020 Letter + * + */ + +#include <stdint.h> +#include "shell.h" +#include "string.h" +#include "stdio.h" +#include "stdarg.h" +#include "shell_ext.h" + + +#if SHELL_USING_CMD_EXPORT == 1 +/** + * @brief 默认用户 + */ +const char shellCmdDefaultUser[] = SHELL_DEFAULT_USER; +const char shellPasswordDefaultUser[] = SHELL_DEFAULT_USER_PASSWORD; +const char shellDesDefaultUser[] = "default user"; +SHELL_USED const ShellCommand shellUserDefault SHELL_SECTION("shellCommand") = +{ + .attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER), + .data.user.name = shellCmdDefaultUser, + .data.user.password = shellPasswordDefaultUser, + .data.user.desc = shellDesDefaultUser +}; +#endif + +#if SHELL_USING_CMD_EXPORT == 1 + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000) + extern const unsigned int shellCommand$$Base; + extern const unsigned int shellCommand$$Limit; + #elif defined(__ICCARM__) || defined(__ICCRX__) + #pragma section="shellCommand" + #elif defined(__GNUC__) + extern const unsigned int _shell_command_start; + extern const unsigned int _shell_command_end; + #endif +#else + extern const ShellCommand shellCommandList[]; + extern const unsigned short shellCommandCount; +#endif + + +/** + * @brief shell 常量文本索引 + */ +enum +{ +#if SHELL_SHOW_INFO == 1 + SHELL_TEXT_INFO, /**< shell信息 */ +#endif + SHELL_TEXT_CMD_TOO_LONG, /**< 命令过长 */ + SHELL_TEXT_CMD_LIST, /**< 可执行命令列表标题 */ + SHELL_TEXT_VAR_LIST, /**< 变量列表标题 */ + SHELL_TEXT_USER_LIST, /**< 用户列表标题 */ + SHELL_TEXT_KEY_LIST, /**< 按键列表标题 */ + SHELL_TEXT_CMD_NOT_FOUND, /**< 命令未找到 */ + SHELL_TEXT_POINT_CANNOT_MODIFY, /**< 指针变量不允许修改 */ + SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY, /**< 只读变量不允许修改 */ + SHELL_TEXT_NOT_VAR, /**< 命令不是变量 */ + SHELL_TEXT_VAR_NOT_FOUND, /**< 变量未找到 */ + SHELL_TEXT_HELP_HEADER, /**< help头 */ + SHELL_TEXT_PASSWORD_HINT, /**< 密码输入提示 */ + SHELL_TEXT_PASSWORD_ERROR, /**< 密码错误 */ + SHELL_TEXT_CLEAR_CONSOLE, /**< 清空控制台 */ + SHELL_TEXT_CLEAR_LINE, /**< 清空当前行 */ + SHELL_TEXT_TYPE_CMD, /**< 命令类型 */ + SHELL_TEXT_TYPE_VAR, /**< 变量类型 */ + SHELL_TEXT_TYPE_USER, /**< 用户类型 */ + SHELL_TEXT_TYPE_KEY, /**< 按键类型 */ + SHELL_TEXT_TYPE_NONE, /**< 非法类型 */ +#if SHELL_EXEC_UNDEF_FUNC == 1 + SHELL_TEXT_PARAM_ERROR, /**< 参数错误 */ +#endif +}; + + +static const char *shellText[] = +{ +#if SHELL_SHOW_INFO == 1 + [SHELL_TEXT_INFO] = + "\r\n" + "eLab project\r\n" + "Version: "SHELL_VERSION"\r\n" + "Copyright: (c) 2023 eLab Team & GouGe\r\n", +#endif + [SHELL_TEXT_CMD_TOO_LONG] = + "\r\nWarning: Command is too long\r\n", + [SHELL_TEXT_CMD_LIST] = + "\r\nCommand List:\r\n", + [SHELL_TEXT_VAR_LIST] = + "\r\nVar List:\r\n", + [SHELL_TEXT_USER_LIST] = + "\r\nUser List:\r\n", + [SHELL_TEXT_KEY_LIST] = + "\r\nKey List:\r\n", + [SHELL_TEXT_CMD_NOT_FOUND] = + "Command not Found\r\n", + [SHELL_TEXT_POINT_CANNOT_MODIFY] = + "can't set pointer\r\n", + [SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY] = + "can't set read only var\r\n", + [SHELL_TEXT_NOT_VAR] = + " is not a var\r\n", + [SHELL_TEXT_VAR_NOT_FOUND] = + "Var not Fount\r\n", + [SHELL_TEXT_HELP_HEADER] = + "command help of ", + [SHELL_TEXT_PASSWORD_HINT] = + "\r\nPlease input password:", + [SHELL_TEXT_PASSWORD_ERROR] = + "\r\npassword error\r\n", + [SHELL_TEXT_CLEAR_CONSOLE] = + "\033[2J\033[1H", + [SHELL_TEXT_CLEAR_LINE] = + "\033[2K\r", + [SHELL_TEXT_TYPE_CMD] = + "CMD ", + [SHELL_TEXT_TYPE_VAR] = + "VAR ", + [SHELL_TEXT_TYPE_USER] = + "USER", + [SHELL_TEXT_TYPE_KEY] = + "KEY ", + [SHELL_TEXT_TYPE_NONE] = + "NONE", +#if SHELL_EXEC_UNDEF_FUNC == 1 + [SHELL_TEXT_PARAM_ERROR] = + "Parameter error\r\n", +#endif +}; + + +/** + * @brief shell对象表 + */ +static Shell *shellList[SHELL_MAX_NUMBER] = {NULL}; + + +static void shellAdd(Shell *shell); +static void shellWritePrompt(Shell *shell, unsigned char newline); +static void shellWriteReturnValue(Shell *shell, int value); +static int shellShowVar(Shell *shell, ShellCommand *command); +static void shellSetUser(Shell *shell, const ShellCommand *user); +ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength); +static void shellWriteCommandHelp(Shell *shell, char *cmd); + +void shellEcho(Shell *shell, unsigned int enable) +{ + if(enable == 0) + { + shell->echo = 0; + } + else + { + shell->echo = 1; + } +} + +/** + * @brief shell 初始化 + * + * @param shell shell对象 + */ +void shellInit(Shell *shell, char *buffer, unsigned short size) +{ + shell->parser.length = 0; + shell->parser.cursor = 0; + shell->info.user = NULL; + shell->status.isChecked = 1; + + shell->parser.buffer = buffer; + shell->parser.bufferSize = size / (SHELL_HISTORY_MAX_NUMBER + 1); + shell->echo = 1; + +#if SHELL_HISTORY_MAX_NUMBER > 0 + shell->history.offset = 0; + shell->history.number = 0; + shell->history.record = 0; + for (short i = 0; i < SHELL_HISTORY_MAX_NUMBER; i++) + { + shell->history.item[i] = buffer + shell->parser.bufferSize * (i + 1); + } +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + +#if SHELL_USING_CMD_EXPORT == 1 + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000) + shell->commandList.base = (ShellCommand *)(&shellCommand$$Base); + shell->commandList.count = ((unsigned int)(&shellCommand$$Limit) + - (unsigned int)(&shellCommand$$Base)) + / sizeof(ShellCommand); + + #elif defined(__ICCARM__) || defined(__ICCRX__) + shell->commandList.base = (ShellCommand *)(__section_begin("shellCommand")); + shell->commandList.count = ((unsigned int)(__section_end("shellCommand")) + - (unsigned int)(__section_begin("shellCommand"))) + / sizeof(ShellCommand); + #elif defined(__GNUC__) + shell->commandList.base = (ShellCommand *)(&_shell_command_start); + shell->commandList.count = ((unsigned int)(&_shell_command_end) + - (unsigned int)(&_shell_command_start)) + / sizeof(ShellCommand); + #else + #error not supported compiler, please use command table mode + #endif +#else + shell->commandList.base = (ShellCommand *)shellCommandList; + shell->commandList.count = shellCommandCount; +#endif + + shellAdd(shell); + + shellSetUser(shell, shellSeekCommand(shell, + SHELL_DEFAULT_USER, + shell->commandList.base, + 0)); + shellWritePrompt(shell, 1); +} + + +/** + * @brief 添加shell + * + * @param shell shell对象 + */ +static void shellAdd(Shell *shell) +{ + for (short i = 0; i < SHELL_MAX_NUMBER; i++) + { + if (shellList[i] == NULL) + { + shellList[i] = shell; + return; + } + } +} + + +/** + * @brief 获取当前活动shell + * + * @return Shell* 当前活动shell对象 + */ +Shell* shellGetCurrent(void) +{ + for (short i = 0; i < SHELL_MAX_NUMBER; i++) + { + if (shellList[i] && shellList[i]->status.isActive) + { + return shellList[i]; + } + } + return NULL; +} + + +/** + * @brief shell写字符 + * + * @param shell shell对象 + * @param data 字符数据 + */ +static void shellWriteByte(Shell *shell, char data) +{ + shell->write(&data, 1); +} + + +/** + * @brief shell 写字符串 + * + * @param shell shell对象 + * @param string 字符串数据 + * + * @return unsigned short 写入字符的数量 + */ +unsigned short shellWriteString(Shell *shell, const char *string) +{ + unsigned short count = 0; + const char *p = string; + SHELL_ASSERT(shell->write, return 0); + while(*p++) + { + count ++; + } + return shell->write((char *)string, count); +} + + +/** + * @brief shell 写命令描述字符串 + * + * @param shell shell对象 + * @param string 字符串数据 + * + * @return unsigned short 写入字符的数量 + */ +static unsigned short shellWriteCommandDesc(Shell *shell, const char *string) +{ + unsigned short count = 0; + const char *p = string; + SHELL_ASSERT(shell->write, return 0); + while (*p && *p != '\r' && *p != '\n') + { + p++; + count++; + } + + if (count > 36) + { + shell->write((char *)string, 36); + shell->write("...", 3); + } + else + { + shell->write((char *)string, count); + } + return count > 36 ? 36 : 39; +} + + +/** + * @brief shell写命令提示符 + * + * @param shell shell对象 + * @param newline 新行 + * + */ +static void shellWritePrompt(Shell *shell, unsigned char newline) +{ + if (shell->status.isChecked) + { + if (newline) + { + shellWriteString(shell, "\r\n"); + } + shellWriteString(shell, shell->info.user->data.user.name); + shellWriteString(shell, ":"); + shellWriteString(shell, shell->info.path ? shell->info.path : "/"); + shellWriteString(shell, "$ "); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PASSWORD_HINT]); + } +} + + +#if SHELL_PRINT_BUFFER > 0 +/** + * @brief shell格式化输出 + * + * @param shell shell对象 + * @param fmt 格式化字符串 + * @param ... 参数 + */ +void shellPrint(Shell *shell, char *fmt, ...) +{ + char buffer[SHELL_PRINT_BUFFER]; + va_list vargs; + + SHELL_ASSERT(shell, return); + + va_start(vargs, fmt); + vsnprintf(buffer, SHELL_PRINT_BUFFER - 1, fmt, vargs); + va_end(vargs); + + shellWriteString(shell, buffer); +} +#endif + + +#if SHELL_SCAN_BUFFER > 0 +/** + * @brief shell格式化输入 + * + * @param shell shell对象 + * @param fmt 格式化字符串 + * @param ... 参数 + */ +void shellScan(Shell *shell, char *fmt, ...) +{ + char buffer[SHELL_SCAN_BUFFER]; + va_list vargs; + short index = 0; + + SHELL_ASSERT(shell, return); + + if (shell->read) + { + do { + if (shell->read(&buffer[index], 1) == 1) + { + shell->write(&buffer[index], 1); + index++; + } + } while (buffer[index -1] != '\r' && buffer[index -1] != '\n' && index < SHELL_SCAN_BUFFER); + shellWriteString(shell, "\r\n"); + buffer[index] = '\0'; + } + + va_start(vargs, fmt); + vsscanf(buffer, fmt, vargs); + va_end(vargs); +} +#endif + + +/** + * @brief shell 检查命令权限 + * + * @param shell shell对象 + * @param command ShellCommand + * + * @return signed char 0 当前用户具有该命令权限 + * @return signec char -1 当前用户不具有该命令权限 + */ +signed char shellCheckPermission(Shell *shell, ShellCommand *command) +{ + return ((!command->attr.attrs.permission + || command->attr.attrs.type == SHELL_TYPE_USER + || (command->attr.attrs.permission + & shell->info.user->attr.attrs.permission)) + && (shell->status.isChecked + || command->attr.attrs.enableUnchecked)) + ? 0 : -1; +} + + +/** + * @brief int转16进制字符串 + * + * @param value 数值 + * @param buffer 缓冲 + * + * @return signed char 转换后有效数据长度 + */ +signed char shellToHex(unsigned int value, char *buffer) +{ + char byte; + unsigned char i = 8; + buffer[8] = 0; + while (value) + { + byte = value & 0x0000000F; + buffer[--i] = (byte > 9) ? (byte + 87) : (byte + 48); + value >>= 4; + } + return 8 - i; +} + + +/** +* @brief int转10进制字符串 + * + * @param value 数值 + * @param buffer 缓冲 + * + * @return signed char 转换后有效数据长度 + */ +signed char shellToDec(int value, char *buffer) +{ + unsigned char i = 11; + int v = value; + if (value < 0) + { + v = -value; + } + buffer[11] = 0; + while (v) + { + buffer[--i] = v % 10 + 48; + v /= 10; + } + if (value < 0) + { + buffer[--i] = '-'; + } + if (value == 0) { + buffer[--i] = '0'; + } + return 11 - i; +} + + +/** + * @brief shell字符串复制 + * + * @param dest 目标字符串 + * @param src 源字符串 + * @return unsigned short 字符串长度 + */ +static unsigned short shellStringCopy(char *dest, char* src) +{ + unsigned short count = 0; + while (*(src + count)) + { + *(dest + count) = *(src + count); + count++; + } + *(dest + count) = 0; + return count; +} + + +/** + * @brief shell字符串比较 + * + * @param dest 目标字符串 + * @param src 源字符串 + * @return unsigned short 匹配长度 + */ +static unsigned short shellStringCompare(char* dest, char *src) +{ + unsigned short match = 0; + unsigned short i = 0; + + while (*(dest +i) && *(src + i)) + { + if (*(dest + i) != *(src +i)) + { + break; + } + match ++; + i++; + } + return match; +} + + +/** + * @brief shell获取命令名 + * + * @param command 命令 + * @return const char* 命令名 + */ +static const char* shellGetCommandName(ShellCommand *command) +{ + static char buffer[9]; + for (unsigned char i = 0; i < 9; i++) + { + buffer[i] = '0'; + } + if (command->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + return command->data.cmd.name; + } + else if (command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + return command->data.var.name; + } + else if (command->attr.attrs.type <= SHELL_TYPE_USER) + { + return command->data.user.name; + } + else + { + shellToHex(command->data.key.value, buffer); + return buffer; + } +} + + +/** + * @brief shell获取命令描述 + * + * @param command 命令 + * @return const char* 命令描述 + */ +static const char* shellGetCommandDesc(ShellCommand *command) +{ + if (command->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + return command->data.cmd.desc; + } + else if (command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + return command->data.var.desc; + } + else if (command->attr.attrs.type <= SHELL_TYPE_USER) + { + return command->data.user.desc; + } + else + { + return command->data.key.desc; + } +} + +/** + * @brief shell 列出命令条目 + * + * @param shell shell对象 + * @param item 命令条目 + */ +void shellListItem(Shell *shell, ShellCommand *item) +{ + short spaceLength; + + spaceLength = 22 - shellWriteString(shell, shellGetCommandName(item)); + spaceLength = (spaceLength > 0) ? spaceLength : 4; + do { + shellWriteByte(shell, ' '); + } while (--spaceLength); + if (item->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_CMD]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_VAR]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_USER) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_USER]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_KEY) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_KEY]); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_NONE]); + } +#if SHELL_HELP_SHOW_PERMISSION == 1 + shellWriteString(shell, " "); + for (signed char i = 7; i >= 0; i--) + { + shellWriteByte(shell, item->attr.attrs.permission & (1 << i) ? 'x' : '-'); + } +#endif + shellWriteString(shell, " "); + shellWriteCommandDesc(shell, shellGetCommandDesc(item)); + shellWriteString(shell, "\r\n"); +} + + +/** + * @brief shell列出可执行命令 + * + * @param shell shell对象 + */ +void shellListCommand(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_CMD_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type <= SHELL_TYPE_CMD_FUNC + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出变量 + * + * @param shell shell对象 + */ +void shellListVar(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_VAR_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_CMD_FUNC + && base[i].attr.attrs.type <= SHELL_TYPE_VAR_NODE + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出用户 + * + * @param shell shell对象 + */ +void shellListUser(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_USER_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_VAR_NODE + && base[i].attr.attrs.type <= SHELL_TYPE_USER + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出按键 + * + * @param shell shell对象 + */ +void shellListKey(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_KEY_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_USER + && base[i].attr.attrs.type <= SHELL_TYPE_KEY + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出所有命令 + * + * @param shell shell对象 + */ +void shellListAll(Shell *shell) +{ +#if SHELL_HELP_LIST_USER == 1 + shellListUser(shell); +#endif + shellListCommand(shell); +#if SHELL_HELP_LIST_VAR == 1 + shellListVar(shell); +#endif +#if SHELL_HELP_LIST_KEY == 1 + shellListKey(shell); +#endif +} + + +/** + * @brief shell删除命令行数据 + * + * @param shell shell对象 + * @param length 删除长度 + */ +static const char *shell_delete_string[] = +{ + "\b \b", + " \b", +}; +void shellDeleteCommandLine(Shell *shell, unsigned char length) +{ + while (length--) + { + shellWriteString(shell, shell_delete_string[(uint8_t)(shell->backsapceMode)]); + } +} + + +/** + * @brief shell 清空命令行输入 + * + * @param shell shell对象 + */ +void shellClearCommandLine(Shell *shell) +{ + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shellWriteByte(shell, ' '); + } + shellDeleteCommandLine(shell, shell->parser.length); +} + + +/** + * @brief shell插入一个字符到光标位置 + * + * @param shell shell对象 + * @param data 字符数据 + */ +void shellInsertByte(Shell *shell, char data) +{ + /* 判断输入数据是否过长 */ + if (shell->parser.length >= shell->parser.bufferSize - 1) + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_TOO_LONG]); + shellWritePrompt(shell, 1); + shellWriteString(shell, shell->parser.buffer); + return; + } + + /* 插入数据 */ + if (shell->parser.cursor == shell->parser.length) + { + shell->parser.buffer[shell->parser.length++] = data; + shell->parser.buffer[shell->parser.length] = 0; + shell->parser.cursor++; + if(shell->echo == 1) + { + shellWriteByte(shell, data); + } + } + else if (shell->parser.cursor < shell->parser.length) + { + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shell->parser.buffer[shell->parser.cursor + i] = + shell->parser.buffer[shell->parser.cursor + i - 1]; + } + shell->parser.buffer[shell->parser.cursor++] = data; + shell->parser.buffer[++shell->parser.length] = 0; + for (short i = shell->parser.cursor - 1; i < shell->parser.length; i++) + { + shellWriteByte(shell, shell->parser.buffer[i]); + } + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shellWriteByte(shell, '\b'); + } + } +} + + +/** + * @brief shell 删除字节 + * + * @param shell shell对象 + * @param direction 删除方向 {@code 1}删除光标前字符 {@code -1}删除光标处字符 + */ +void shellDeleteByte(Shell *shell, signed char direction) +{ + char offset = (direction == -1) ? 1 : 0; + + if ((shell->parser.cursor == 0 && direction == 1) + || (shell->parser.cursor == shell->parser.length && direction == -1)) + { + return; + } + if (shell->parser.cursor == shell->parser.length && direction == 1) + { + shell->parser.cursor--; + shell->parser.length--; + shell->parser.buffer[shell->parser.length] = 0; + shellDeleteCommandLine(shell, 1); + } + else + { + for (short i = offset; i < shell->parser.length - shell->parser.cursor; i++) + { + shell->parser.buffer[shell->parser.cursor + i - 1] = + shell->parser.buffer[shell->parser.cursor + i]; + } + shell->parser.length--; + if (!offset) + { + shell->parser.cursor--; + shellWriteByte(shell, '\b'); + } + shell->parser.buffer[shell->parser.length] = 0; + for (short i = shell->parser.cursor; i < shell->parser.length; i++) + { + shellWriteByte(shell, shell->parser.buffer[i]); + } + shellWriteByte(shell, ' '); + for (short i = shell->parser.length - shell->parser.cursor + 1; i > 0; i--) + { + shellWriteByte(shell, '\b'); + } + } +} + + +/** + * @brief shell 解析参数 + * + * @param shell shell对象 + */ +static void shellParserParam(Shell *shell) +{ + unsigned char quotes = 0; + unsigned char record = 1; + + for (short i = 0; i < SHELL_PARAMETER_MAX_NUMBER; i++) + { + shell->parser.param[i] = NULL; + } + + shell->parser.paramCount = 0; + for (unsigned short i = 0; i < shell->parser.length; i++) + { + if (quotes != 0 + || (shell->parser.buffer[i] != ' ' + && shell->parser.buffer[i] != 0)) + { + if (shell->parser.buffer[i] == '\"') + { + quotes = quotes ? 0 : 1; + } + if (record == 1) + { + if (shell->parser.paramCount < SHELL_PARAMETER_MAX_NUMBER) + { + shell->parser.param[shell->parser.paramCount++] = + &(shell->parser.buffer[i]); + } + record = 0; + } + if (shell->parser.buffer[i] == '\\' + && shell->parser.buffer[i + 1] != 0) + { + i++; + } + } + else + { + shell->parser.buffer[i] = 0; + record = 1; + } + } +} + + +/** + * @brief shell去除字符串参数头尾的双引号 + * + * @param shell shell对象 + */ +static void shellRemoveParamQuotes(Shell *shell) +{ + unsigned short paramLength; + for (unsigned short i = 0; i < shell->parser.paramCount; i++) + { + if (shell->parser.param[i][0] == '\"') + { + shell->parser.param[i][0] = 0; + shell->parser.param[i] = &shell->parser.param[i][1]; + } + paramLength = strlen(shell->parser.param[i]); + if (shell->parser.param[i][paramLength - 1] == '\"') + { + shell->parser.param[i][paramLength - 1] = 0; + } + } +} + + +/** + * @brief shell匹配命令 + * + * @param shell shell对象 + * @param cmd 命令 + * @param base 匹配命令表基址 + * @param compareLength 匹配字符串长度 + * @return ShellCommand* 匹配到的命令 + */ +ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength) +{ + const char *name; + unsigned short count = shell->commandList.count - + ((int)base - (int)shell->commandList.base) / sizeof(ShellCommand); + for (unsigned short i = 0; i < count; i++) + { + if (base[i].attr.attrs.type == SHELL_TYPE_KEY + || shellCheckPermission(shell, &base[i]) != 0) + { + continue; + } + name = shellGetCommandName(&base[i]); + if (!compareLength) + { + if (strcmp(cmd, name) == 0) + { + return &base[i]; + } + } + else + { + if (strncmp(cmd, name, compareLength) == 0) + { + return &base[i]; + } + } + } + return NULL; +} + + +/** + * @brief shell 获取变量值 + * + * @param shell shell对象 + * @param command 命令 + * @return int 变量值 + */ +int shellGetVarValue(Shell *shell, ShellCommand *command) +{ + int value = 0; + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_INT: + value = *((int *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_SHORT: + value = *((short *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_CHAR: + value = *((char *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_STRING: + case SHELL_TYPE_VAR_POINT: + value = (int)(command->data.var.value); + break; + case SHELL_TYPE_VAR_NODE: + value = ((ShellNodeVarAttr *)command->data.var.value)->get ? + ((ShellNodeVarAttr *)command->data.var.value) + ->get(((ShellNodeVarAttr *)command->data.var.value)->var) : 0; + break; + default: + break; + } + return value; +} + + +/** + * @brief shell设置变量值 + * + * @param shell shell对象 + * @param command 命令 + * @param value 值 + * @return int 返回变量值 + */ +int shellSetVarValue(Shell *shell, ShellCommand *command, int value) +{ + if (command->attr.attrs.readOnly) + { + shellWriteString(shell, shellText[SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY]); + } + else + { + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_INT: + *((int *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_SHORT: + *((short *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_CHAR: + *((char *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_STRING: + shellStringCopy(((char *)(command->data.var.value)), (char *)value); + break; + case SHELL_TYPE_VAR_POINT: + shellWriteString(shell, shellText[SHELL_TEXT_POINT_CANNOT_MODIFY]); + break; + case SHELL_TYPE_VAR_NODE: + if (((ShellNodeVarAttr *)command->data.var.value)->set) + { + if (((ShellNodeVarAttr *)command->data.var.value)->var) + { + ((ShellNodeVarAttr *)command->data.var.value) + ->set(((ShellNodeVarAttr *)command->data.var.value)->var, value); + } + else + { + ((ShellNodeVarAttr *)command->data.var.value)->set(value); + } + } + break; + default: + break; + } + } + return shellShowVar(shell, command); +} + + +/** + * @brief shell变量输出 + * + * @param shell shell对象 + * @param command 命令 + * @return int 返回变量值 + */ +static int shellShowVar(Shell *shell, ShellCommand *command) +{ + char buffer[12] = "00000000000"; + int value = shellGetVarValue(shell, command); + + shellWriteString(shell, command->data.var.name); + shellWriteString(shell, " = "); + + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_STRING: + shellWriteString(shell, "\""); + shellWriteString(shell, (char *)value); + shellWriteString(shell, "\""); + break; + // case SHELL_TYPE_VAR_INT: + // case SHELL_TYPE_VAR_SHORT: + // case SHELL_TYPE_VAR_CHAR: + // case SHELL_TYPE_VAR_POINT: + default: + shellWriteString(shell, &buffer[11 - shellToDec(value, buffer)]); + shellWriteString(shell, ", 0x"); + for (short i = 0; i < 11; i++) + { + buffer[i] = '0'; + } + shellToHex(value, buffer); + shellWriteString(shell, buffer); + break; + } + + shellWriteString(shell, "\r\n"); + return value; +} + + +/** + * @brief shell设置变量 + * + * @param name 变量名 + * @param value 变量值 + * @return int 返回变量值 + */ +int shellSetVar(char *name, int value) +{ + Shell *shell = shellGetCurrent(); + if (shell == NULL) + { + return 0; + } + ShellCommand *command = shellSeekCommand(shell, + name, + shell->commandList.base, + 0); + if (!command) + { + shellWriteString(shell, shellText[SHELL_TEXT_VAR_NOT_FOUND]); + return 0; + } + if (command->attr.attrs.type < SHELL_TYPE_VAR_INT + || command->attr.attrs.type > SHELL_TYPE_VAR_NODE) + { + shellWriteString(shell, name); + shellWriteString(shell, shellText[SHELL_TEXT_NOT_VAR]); + return 0; + } + return shellSetVarValue(shell, command, value); +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +setVar, shellSetVar, set var); + + +/** + * @brief shell运行命令 + * + * @param shell shell对象 + * @param command 命令 + * + * @return unsigned int 命令返回值 + */ +unsigned int shellRunCommand(Shell *shell, ShellCommand *command) +{ + int returnValue = 0; + shell->status.isActive = 1; + if (command->attr.attrs.type == SHELL_TYPE_CMD_MAIN) + { + shellRemoveParamQuotes(shell); + returnValue = command->data.cmd.function(shell->parser.paramCount, + shell->parser.param); + if (!command->attr.attrs.disableReturn) + { + shellWriteReturnValue(shell, returnValue); + } + } + else if (command->attr.attrs.type == SHELL_TYPE_CMD_FUNC) + { + returnValue = shellExtRun(shell, + command, + shell->parser.paramCount, + shell->parser.param); + if (!command->attr.attrs.disableReturn) + { + shellWriteReturnValue(shell, returnValue); + } + } + else if (command->attr.attrs.type >= SHELL_TYPE_VAR_INT + && command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + shellShowVar(shell, command); + } + else if (command->attr.attrs.type == SHELL_TYPE_USER) + { + shellSetUser(shell, command); + } + shell->status.isActive = 0; + + return returnValue; +} + + +/** + * @brief shell校验密码 + * + * @param shell shell对象 + */ +static void shellCheckPassword(Shell *shell) +{ + if (strcmp(shell->parser.buffer, shell->info.user->data.user.password) == 0) + { + shell->status.isChecked = 1; + #if SHELL_SHOW_INFO == 1 + shellWriteString(shell, shellText[SHELL_TEXT_INFO]); + #endif + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PASSWORD_ERROR]); + } + shell->parser.length = 0; + shell->parser.cursor = 0; +} + + +/** + * @brief shell设置用户 + * + * @param shell shell对象 + * @param user 用户 + */ +static void shellSetUser(Shell *shell, const ShellCommand *user) +{ + shell->info.user = user; + shell->status.isChecked = + ((user->data.user.password && strlen(user->data.user.password) != 0) + && (shell->parser.paramCount < 2 + || strcmp(user->data.user.password, shell->parser.param[1]) != 0)) + ? 0 : 1; + +#if SHELL_CLS_WHEN_LOGIN == 1 + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_CONSOLE]); +#endif +#if SHELL_SHOW_INFO == 1 + if (shell->status.isChecked) + { + shellWriteString(shell, shellText[SHELL_TEXT_INFO]); + } +#endif +} + + +/** + * @brief shell写返回值 + * + * @param shell shell对象 + * @param value 返回值 + */ +static void shellWriteReturnValue(Shell *shell, int value) +{ + char buffer[12] = "00000000000"; + shellWriteString(shell, "Return: "); + shellWriteString(shell, &buffer[11 - shellToDec(value, buffer)]); + shellWriteString(shell, ", 0x"); + for (short i = 0; i < 11; i++) + { + buffer[i] = '0'; + } + shellToHex(value, buffer); + shellWriteString(shell, buffer); + shellWriteString(shell, "\r\n"); +} + + +#if SHELL_HISTORY_MAX_NUMBER > 0 +/** + * @brief shell历史记录添加 + * + * @param shell shell对象 + */ +static void shellHistoryAdd(Shell *shell) +{ + shell->history.offset = 0; + if (shell->history.number > 0 + && strcmp(shell->history.item[(shell->history.record == 0 ? + SHELL_HISTORY_MAX_NUMBER : shell->history.record) - 1], + shell->parser.buffer) == 0) + { + return; + } + if (shellStringCopy(shell->history.item[shell->history.record], + shell->parser.buffer) != 0) + { + shell->history.record++; + } + if (++shell->history.number > SHELL_HISTORY_MAX_NUMBER) + { + shell->history.number = SHELL_HISTORY_MAX_NUMBER; + } + if (shell->history.record >= SHELL_HISTORY_MAX_NUMBER) + { + shell->history.record = 0; + } +} + + +/** + * @brief shell历史记录查找 + * + * @param shell shell对象 + * @param dir 方向 {@code <0}往上查找 {@code >0}往下查找 + */ +static void shellHistory(Shell *shell, signed char dir) +{ + if (dir > 0) + { + if (shell->history.offset-- <= + -((shell->history.number > shell->history.record) ? + shell->history.number : shell->history.record)) + { + shell->history.offset = -((shell->history.number > shell->history.record) + ? shell->history.number : shell->history.record); + } + } + else if (dir < 0) + { + if (++shell->history.offset > 0) + { + shell->history.offset = 0; + return; + } + } + else + { + return; + } + shellClearCommandLine(shell); + if (shell->history.offset == 0) + { + shell->parser.cursor = shell->parser.length = 0; + } + else + { + if ((shell->parser.length = shellStringCopy(shell->parser.buffer, + shell->history.item[(shell->history.record + SHELL_HISTORY_MAX_NUMBER + + shell->history.offset) % SHELL_HISTORY_MAX_NUMBER])) == 0) + { + return; + } + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + } + +} +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + + +/** + * @brief shell 常规输入 + * + * @param shell shell 对象 + * @param data 输入字符 + */ +void shellNormalInput(Shell *shell, char data) +{ + shell->status.tabFlag = 0; + shellInsertByte(shell, data); +} + + +/** + * @brief shell运行命令 + * + * @param shell shell对象 + */ +void shellExec(Shell *shell) +{ + + if (shell->parser.length == 0) + { + return; + } + + shell->parser.buffer[shell->parser.length] = 0; + + if (shell->status.isChecked) + { + #if SHELL_HISTORY_MAX_NUMBER > 0 + shellHistoryAdd(shell); + #endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + shellParserParam(shell); + shell->parser.length = shell->parser.cursor = 0; + if (shell->parser.paramCount == 0) + { + return; + } + shellWriteString(shell, "\r\n"); + + ShellCommand *command = shellSeekCommand(shell, + shell->parser.param[0], + shell->commandList.base, + 0); + if (command != NULL) + { + shellRunCommand(shell, command); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); + } + } + else + { + shellCheckPassword(shell); + } +} + + +#if SHELL_HISTORY_MAX_NUMBER > 0 +/** + * @brief shell上方向键输入 + * + * @param shell shell对象 + */ +void shellUp(Shell *shell) +{ + shellHistory(shell, 1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x1B5B4100, shellUp, up); + + +/** + * @brief shell下方向键输入 + * + * @param shell shell对象 + */ +void shellDown(Shell *shell) +{ + shellHistory(shell, -1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x1B5B4200, shellDown, down); +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + + +/** + * @brief shell右方向键输入 + * + * @param shell shell对象 + */ +void shellRight(Shell *shell) +{ + if (shell->parser.cursor < shell->parser.length) + { + shellWriteByte(shell, shell->parser.buffer[shell->parser.cursor++]); + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B4300, shellRight, right); + + +/** + * @brief shell左方向键输入 + * + * @param shell shell对象 + */ +void shellLeft(Shell *shell) +{ + if (shell->parser.cursor > 0) + { + shellWriteByte(shell, '\b'); + shell->parser.cursor--; + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B4400, shellLeft, left); + + +/** + * @brief shell Tab按键处理 + * + * @param shell shell对象 + */ +void shellTab(Shell *shell) +{ + unsigned short maxMatch = shell->parser.bufferSize; + unsigned short lastMatchIndex = 0; + unsigned short matchNum = 0; + unsigned short length; + + if (shell->parser.length == 0) + { + shellListAll(shell); + shellWritePrompt(shell, 1); + } + else if (shell->parser.length > 0) + { + shell->parser.buffer[shell->parser.length] = 0; + ShellCommand *base = (ShellCommand *)shell->commandList.base; + for (short i = 0; i < shell->commandList.count; i++) + { + if (shellCheckPermission(shell, &base[i]) == 0 + && shellStringCompare(shell->parser.buffer, + (char *)shellGetCommandName(&base[i])) + == shell->parser.length) + { + if (matchNum != 0) + { + if (matchNum == 1) + { + shellWriteString(shell, "\r\n"); + } + shellListItem(shell, &base[lastMatchIndex]); + length = + shellStringCompare((char *)shellGetCommandName(&base[lastMatchIndex]), + (char *)shellGetCommandName(&base[i])); + maxMatch = (maxMatch > length) ? length : maxMatch; + } + lastMatchIndex = i; + matchNum++; + } + } + if (matchNum == 0) + { + return; + } + if (matchNum == 1) + { + shellClearCommandLine(shell); + } + if (matchNum != 0) + { + shell->parser.length = + shellStringCopy(shell->parser.buffer, + (char *)shellGetCommandName(&base[lastMatchIndex])); + } + if (matchNum > 1) + { + shellListItem(shell, &base[lastMatchIndex]); + shellWritePrompt(shell, 1); + shell->parser.length = maxMatch; + } + shell->parser.buffer[shell->parser.length] = 0; + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + } + + if (SHELL_GET_TICK()) + { + if (matchNum == 1 + && shell->status.tabFlag + && SHELL_GET_TICK() - shell->info.activeTime < SHELL_DOUBLE_Clike_TIME) + { + #if SHELL_QUICK_HELP == 1 + shellWriteString(shell, "\r\n"); + shellWriteCommandHelp(shell, shell->parser.buffer); + shellWritePrompt(shell, 1); + shellWriteString(shell, shell->parser.buffer); + #else + shellClearCommandLine(shell); + for (short i = shell->parser.length; i >= 0; i--) + { + shell->parser.buffer[i + 5] = shell->parser.buffer[i]; + } + shellStringCopy(shell->parser.buffer, "help"); + shell->parser.buffer[4] = ' '; + shell->parser.length += 5; + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + #endif + } + else + { + shell->status.tabFlag = 1; + } + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x09000000, shellTab, tab); + + +/** + * @brief shell 退格 + * + * @param shell shell对象 + */ +void shellBackspace(Shell *shell) +{ + shellDeleteByte(shell, 1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x08000000, shellBackspace, backspace); +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x7F000000, shellBackspace, backspace); + + +/** + * @brief shell 删除 + * + * @param shell shell对象 + */ +void shellDelete(Shell *shell) +{ + shellDeleteByte(shell, -1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B337E, shellDelete, delete); + + +/** + * @brief shell 回车处理 + * + * @param shell shell对象 + */ +void shellEnter(Shell *shell) +{ + shellExec(shell); + shellWritePrompt(shell, 1); +} +#if SHELL_ENTER_LF == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0A000000, shellEnter, enter); +#endif +#if SHELL_ENTER_CR == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0D000000, shellEnter, enter); +#endif +#if SHELL_ENTER_CRLF == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0D0A0000, shellEnter, enter); +#endif + +/** + * @brief shell 写命令帮助信息 + * + * @param shell shell对象 + * @param cmd 命令字符串 + */ +static void shellWriteCommandHelp(Shell *shell, char *cmd) +{ + ShellCommand *command = shellSeekCommand(shell, + cmd, + shell->commandList.base, + 0); + if (command) + { + shellWriteString(shell, shellText[SHELL_TEXT_HELP_HEADER]); + shellWriteString(shell, shellGetCommandName(command)); + shellWriteString(shell, "\r\n"); + shellWriteString(shell, shellGetCommandDesc(command)); + shellWriteString(shell, "\r\n"); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); + } +} + +/** + * @brief shell help + * + * @param argc 参数个数 + * @param argv 参数 + */ +void shellHelp(int argc, char *argv[]) +{ + Shell *shell = shellGetCurrent(); + SHELL_ASSERT(shell, return); + if (argc == 1) + { + shellListAll(shell); + } + else if (argc > 1) + { + shellWriteCommandHelp(shell, argv[1]); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, +help, shellHelp, show command info\r\nhelp [cmd]); + +/** + * @brief shell 输入处理 + * + * @param shell shell对象 + * @param data 输入数据 + */ +void shellHandler(Shell *shell, char data) +{ + SHELL_ASSERT(data, return); + SHELL_LOCK(shell); + +#if SHELL_LOCK_TIMEOUT > 0 + if (shell->info.user->data.user.password + && strlen(shell->info.user->data.user.password) != 0 + && SHELL_GET_TICK()) + { + if (SHELL_GET_TICK() - shell->info.activeTime > SHELL_LOCK_TIMEOUT) + { + shell->status.isChecked = 0; + } + } +#endif + + /* 根据记录的按键键值计算当前字节在按键键值中的偏移 */ + char keyByteOffset = 24; + int keyFilter = 0x00000000; + if ((shell->parser.keyValue & 0x0000FF00) != 0x00000000) + { + keyByteOffset = 0; + keyFilter = 0xFFFFFF00; + } + else if ((shell->parser.keyValue & 0x00FF0000) != 0x00000000) + { + keyByteOffset = 8; + keyFilter = 0xFFFF0000; + } + else if ((shell->parser.keyValue & 0xFF000000) != 0x00000000) + { + keyByteOffset = 16; + keyFilter = 0xFF000000; + } + + /* 遍历ShellCommand列表,尝试进行按键键值匹配 */ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + for (short i = 0; i < shell->commandList.count; i++) + { + /* 判断是否是按键定义并验证权限 */ + if (base[i].attr.attrs.type == SHELL_TYPE_KEY + && shellCheckPermission(shell, &(base[i])) == 0) + { + /* 对输入的字节同按键键值进行匹配 */ + if ((base[i].data.key.value & keyFilter) == shell->parser.keyValue + && (base[i].data.key.value & (0xFF << keyByteOffset)) + == (data << keyByteOffset)) + { + shell->parser.keyValue |= data << keyByteOffset; + data = 0x00; + if (keyByteOffset == 0 + || (base[i].data.key.value & (0xFF << (keyByteOffset - 8))) + == 0x00000000) + { + if (base[i].data.key.function) + { + base[i].data.key.function(shell); + } + shell->parser.keyValue = 0x00000000; + break; + } + } + } + } + + if (data != 0x00) + { + shell->parser.keyValue = 0x00000000; + shellNormalInput(shell, data); + } + + if (SHELL_GET_TICK()) + { + shell->info.activeTime = SHELL_GET_TICK(); + } + SHELL_UNLOCK(shell); +} + + +#if SHELL_SUPPORT_END_LINE == 1 +void shellWriteEndLine(Shell *shell, char *buffer, int len) +{ + SHELL_LOCK(shell); + if (!shell->status.isActive) + { + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_LINE]); + } + shell->write(buffer, len); + + if (!shell->status.isActive) + { + shellWritePrompt(shell, 0); + if (shell->parser.length > 0) + { + shellWriteString(shell, shell->parser.buffer); + for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++) + { + shellWriteByte(shell, '\b'); + } + } + } + SHELL_UNLOCK(shell); +} +#endif /** SHELL_SUPPORT_END_LINE == 1 */ + + +/** + * @brief shell 任务 + * + * @param param 参数(shell对象) + * + */ +void shellTask(void *param) +{ + Shell *shell = (Shell *)param; + char data; +#if SHELL_TASK_WHILE == 1 + while(1) + { +#endif + if (shell->read && shell->read(&data, 1) == 1) + { + shellHandler(shell, data); + } +#if SHELL_TASK_WHILE == 1 + } +#endif +} + +/** + * @brief shell 输出用户列表(shell调用) + */ +void shellUsers(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListUser(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +users, shellUsers, list all user); + + +/** + * @brief shell 输出命令列表(shell调用) + */ +void shellCmds(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListCommand(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +cmds, shellCmds, list all cmd); + + +/** + * @brief shell 输出变量列表(shell调用) + */ +void shellVars(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListVar(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +vars, shellVars, list all var); + + +/** + * @brief shell 输出按键列表(shell调用) + */ +void shellKeys(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListKey(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +keys, shellKeys, list all key); + + +/** + * @brief shell 清空控制台(shell调用) + */ +void shellClear(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_CONSOLE]); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +clear, shellClear, clear console); + + +/** + * @brief shell执行命令 + * + * @param shell shell对象 + * @param cmd 命令字符串 + * @return int 返回值 + */ +int shellRun(Shell *shell, const char *cmd) +{ + SHELL_ASSERT(shell && cmd, return -1); + char active = shell->status.isActive; + if (strlen(cmd) > shell->parser.bufferSize - 1) + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_TOO_LONG]); + return -1; + } + else + { + shell->parser.length = shellStringCopy(shell->parser.buffer, (char *)cmd); + shellExec(shell); + shell->status.isActive = active; + return 0; + } +} + + +#if SHELL_EXEC_UNDEF_FUNC == 1 +/** + * @brief shell执行未定义函数 + * + * @param argc 参数个数 + * @param argv 参数 + * @return int 返回值 + */ +int shellExecute(int argc, char *argv[]) +{ + Shell *shell = shellGetCurrent(); + if (shell && argc >= 2) + { + int (*func)() = (int (*)())shellExtParsePara(shell, argv[1]); + ShellCommand command = { + .attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) + |SHELL_CMD_DISABLE_RETURN, + .data.cmd.function = func, + }; + return shellExtRun(shell, &command, argc - 1, &argv[1]); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PARAM_ERROR]); + return -1; + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, +exec, shellExecute, execute function undefined); +#endif + diff --git a/Ems/3rd/Shell/shell.h b/Ems/3rd/Shell/shell.h new file mode 100644 index 0000000..0201a63 --- /dev/null +++ b/Ems/3rd/Shell/shell.h @@ -0,0 +1,477 @@ +/** + * @file shell.h + * @author Letter (NevermindZZT@gmail.com) + * @brief letter shell + * @version 3.0.0 + * @date 2019-12-30 + * + * @copyright (c) 2020 Letter + * + */ + +#ifndef __SHELL_H__ +#define __SHELL_H__ + +#include "shell_cfg.h" + +#define SHELL_VERSION "3.1.1" /**< 版本号 */ + + +/** + * @brief shell 断言 + * + * @param expr 表达式 + * @param action 断言失败操作 + */ +#define SHELL_ASSERT(expr, action) \ + if (!(expr)) { \ + action; \ + } + +#if SHELL_USING_LOCK == 1 +#define SHELL_LOCK(shell) shell->lock(shell) +#define SHELL_UNLOCK(shell) shell->unlock(shell) +#else +#define SHELL_LOCK(shell) +#define SHELL_UNLOCK(shell) +#endif /** SHELL_USING_LOCK == 1 */ +/** + * @brief shell 命令权限 + * + * @param permission 权限级别 + */ +#define SHELL_CMD_PERMISSION(permission) \ + (permission & 0x000000FF) + +/** + * @brief shell 命令类型 + * + * @param type 类型 + */ +#define SHELL_CMD_TYPE(type) \ + ((type & 0x0000000F) << 8) + +/** + * @brief 使能命令在未校验密码的情况下使用 + */ +#define SHELL_CMD_ENABLE_UNCHECKED \ + (1 << 12) + +/** + * @brief 禁用返回值打印 + */ +#define SHELL_CMD_DISABLE_RETURN \ + (1 << 13) + +/** + * @brief 只读属性(仅对变量生效) + */ +#define SHELL_CMD_READ_ONLY \ + (1 << 14) + +/** + * @brief 命令参数数量 + */ +#define SHELL_CMD_PARAM_NUM(num) \ + ((num & 0x0000000F)) << 16 + +#ifndef SHELL_SECTION + #if defined(__CC_ARM) || defined(__CLANG_ARM) + #define SHELL_SECTION(x) __attribute__((section(x))) + #elif defined (__IAR_SYSTEMS_ICC__) + #define SHELL_SECTION(x) @ x + #elif defined(__GNUC__) + #define SHELL_SECTION(x) __attribute__((section(x))) + #else + #define SHELL_SECTION(x) + #endif +#endif + +#ifndef SHELL_USED + #if defined(__CC_ARM) || defined(__CLANG_ARM) + #define SHELL_USED __attribute__((used)) + #elif defined (__IAR_SYSTEMS_ICC__) + #define SHELL_USED __root + #elif defined(__GNUC__) + #define SHELL_USED __attribute__((used)) + #else + #define SHELL_USED + #endif +#endif + +/** + * @brief shell float型参数转换 + */ +#define SHELL_PARAM_FLOAT(x) (*(float *)(&x)) + +/** + * @brief shell 代理函数名 + */ +#define SHELL_AGENCY_FUNC_NAME(_func) agency##_func + +/** + * @brief shell代理函数定义 + * + * @param _func 被代理的函数 + * @param ... 代理参数 + */ +#define SHELL_AGENCY_FUNC(_func, ...) \ + void SHELL_AGENCY_FUNC_NAME(_func)(int p1, int p2, int p3, int p4, int p5, int p6, int p7) \ + { _func(__VA_ARGS__); } + +#if SHELL_USING_CMD_EXPORT == 1 + + /** + * @brief shell 命令定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + */ + #define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \ + const char shellCmd##_name[] = #_name; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellCommand##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr, \ + .data.cmd.name = shellCmd##_name, \ + .data.cmd.function = (int (*)())_func, \ + .data.cmd.desc = shellDesc##_name \ + } + + /** + * @brief shell 代理命令定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + * @param ... 代理参数 + */ + #define SHELL_EXPORT_CMD_AGENCY(_attr, _name, _func, _desc, ...) \ + SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \ + SHELL_EXPORT_CMD(_attr, _name, SHELL_AGENCY_FUNC_NAME(_func), _desc) + + /** + * @brief shell 变量定义 + * + * @param _attr 变量属性 + * @param _name 变量名 + * @param _value 变量值 + * @param _desc 变量描述 + */ + #define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \ + const char shellCmd##_name[] = #_name; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellVar##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr, \ + .data.var.name = shellCmd##_name, \ + .data.var.value = (void *)_value, \ + .data.var.desc = shellDesc##_name \ + } + + /** + * @brief shell 用户定义 + * + * @param _attr 用户属性 + * @param _name 用户名 + * @param _password 用户密码 + * @param _desc 用户描述 + */ + #define SHELL_EXPORT_USER(_attr, _name, _password, _desc) \ + const char shellCmd##_name[] = #_name; \ + const char shellPassword##_name[] = #_password; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellUser##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \ + .data.user.name = shellCmd##_name, \ + .data.user.password = shellPassword##_name, \ + .data.user.desc = shellDesc##_name \ + } + + /** + * @brief shell 按键定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + */ + #define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \ + const char shellDesc##_value[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellKey##_value SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \ + .data.key.value = _value, \ + .data.key.function = (void (*)(Shell *))_func, \ + .data.key.desc = shellDesc##_value \ + } + + /** + * @brief shell 代理按键定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + * @param ... 代理参数 + */ + #define SHELL_EXPORT_KEY_AGENCY(_attr, _value, _func, _desc, ...) \ + SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \ + SHELL_EXPORT_KEY(_attr, _value, SHELL_AGENCY_FUNC_NAME(_func), _desc) +#else + /** + * @brief shell 命令item定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + */ + #define SHELL_CMD_ITEM(_attr, _name, _func, _desc) \ + { \ + .attr.value = _attr, \ + .data.cmd.name = #_name, \ + .data.cmd.function = (int (*)())_func, \ + .data.cmd.desc = #_desc \ + } + + /** + * @brief shell 变量item定义 + * + * @param _attr 变量属性 + * @param _name 变量名 + * @param _value 变量值 + * @param _desc 变量描述 + */ + #define SHELL_VAR_ITEM(_attr, _name, _value, _desc) \ + { \ + .attr.value = _attr, \ + .data.var.name = #_name, \ + .data.var.value = (void *)_value, \ + .data.var.desc = #_desc \ + } + + /** + * @brief shell 用户item定义 + * + * @param _attr 用户属性 + * @param _name 用户名 + * @param _password 用户密码 + * @param _desc 用户描述 + */ + #define SHELL_USER_ITEM(_attr, _name, _password, _desc) \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \ + .data.user.name = #_name, \ + .data.user.password = #_password, \ + .data.user.desc = #_desc \ + } + + /** + * @brief shell 按键item定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + */ + #define SHELL_KEY_ITEM(_attr, _value, _func, _desc) \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \ + .data.key.value = _value, \ + .data.key.function = (void (*)(Shell *))_func, \ + .data.key.desc = #_desc \ + } + + #define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) + #define SHELL_EXPORT_CMD_AGENCY(_attr, _name, _func, _desc, ...) + #define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) + #define SHELL_EXPORT_USER(_attr, _name, _password, _desc) + #define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) + #define SHELL_EXPORT_KEY_AGENCY(_attr, _name, _func, _desc, ...) +#endif /** SHELL_USING_CMD_EXPORT == 1 */ + +/** + * @brief shell command类型 + */ +typedef enum +{ + SHELL_TYPE_CMD_MAIN = 0, /**< main形式命令 */ + SHELL_TYPE_CMD_FUNC, /**< C函数形式命令 */ + SHELL_TYPE_VAR_INT, /**< int型变量 */ + SHELL_TYPE_VAR_SHORT, /**< short型变量 */ + SHELL_TYPE_VAR_CHAR, /**< char型变量 */ + SHELL_TYPE_VAR_STRING, /**< string型变量 */ + SHELL_TYPE_VAR_POINT, /**< 指针型变量 */ + SHELL_TYPE_VAR_NODE, /**< 节点变量 */ + SHELL_TYPE_USER, /**< 用户 */ + SHELL_TYPE_KEY, /**< 按键 */ +} ShellCommandType; + +/** + * @brief shell backspace mode类型 + */ +typedef enum +{ + SHELL_BACKSPACE_MODE_BACK_SPACE_BACK = 0, + SHELL_BACKSPACE_MODE_SPACE_BACK, +} ShellBackspaceModeType; + +/** + * @brief Shell定义 + */ +typedef struct shell_def +{ + struct + { + const struct shell_command *user; /**< 当前用户 */ + int activeTime; /**< shell激活时间 */ + char *path; /**< 当前shell路径 */ + #if SHELL_USING_COMPANION == 1 + struct shell_companion_object *companions; /**< 伴生对象 */ + #endif + } info; + struct + { + unsigned short length; /**< 输入数据长度 */ + unsigned short cursor; /**< 当前光标位置 */ + char *buffer; /**< 输入缓冲 */ + char *param[SHELL_PARAMETER_MAX_NUMBER]; /**< 参数 */ + unsigned short bufferSize; /**< 输入缓冲大小 */ + unsigned short paramCount; /**< 参数数量 */ + int keyValue; /**< 输入按键键值 */ + } parser; +#if SHELL_HISTORY_MAX_NUMBER > 0 + struct + { + char *item[SHELL_HISTORY_MAX_NUMBER]; /**< 历史记录 */ + unsigned short number; /**< 历史记录数 */ + unsigned short record; /**< 当前记录位置 */ + signed short offset; /**< 当前历史记录偏移 */ + } history; +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + struct + { + void *base; /**< 命令表基址 */ + unsigned short count; /**< 命令数量 */ + } commandList; + struct + { + unsigned char isChecked : 1; /**< 密码校验通过 */ + unsigned char isActive : 1; /**< 当前活动Shell */ + unsigned char tabFlag : 1; /**< tab标志 */ + } status; + signed short (*read)(char *, unsigned short); /**< shell读函数 */ + signed short (*write)(char *, unsigned short); /**< shell写函数 */ +#if SHELL_USING_LOCK == 1 + int (*lock)(struct shell_def *); /**< shell 加锁 */ + int (*unlock)(struct shell_def *); /**< shell 解锁 */ +#endif + int echo; + ShellBackspaceModeType backsapceMode; +} Shell; + + +/** + * @brief shell command定义 + */ +typedef struct shell_command +{ + union + { + struct + { + unsigned char permission : 8; /**< command权限 */ + ShellCommandType type : 4; /**< command类型 */ + unsigned char enableUnchecked : 1; /**< 在未校验密码的情况下可用 */ + unsigned char disableReturn : 1; /**< 禁用返回值输出 */ + unsigned char readOnly : 1; /**< 只读 */ + unsigned char reserve : 1; /**< 保留 */ + unsigned char paramNum : 4; /**< 参数数量 */ + } attrs; + int value; + } attr; /**< 属性 */ + union + { + struct + { + const char *name; /**< 命令名 */ + int (*function)(); /**< 命令执行函数 */ + const char *desc; /**< 命令描述 */ + } cmd; /**< 命令定义 */ + struct + { + const char *name; /**< 变量名 */ + void *value; /**< 变量值 */ + const char *desc; /**< 变量描述 */ + } var; /**< 变量定义 */ + struct + { + const char *name; /**< 用户名 */ + const char *password; /**< 用户密码 */ + const char *desc; /**< 用户描述 */ + } user; /**< 用户定义 */ + struct + { + int value; /**< 按键键值 */ + void (*function)(Shell *); /**< 按键执行函数 */ + const char *desc; /**< 按键描述 */ + } key; /**< 按键定义 */ + } data; +} ShellCommand; + +/** + * @brief shell节点变量属性 + */ +typedef struct +{ + void *var; /**< 变量引用 */ + int (*get)(); /**< 变量get方法 */ + int (*set)(); /**< 变量set方法 */ +} ShellNodeVarAttr; + + +#define shellSetPath(_shell, _path) (_shell)->info.path = _path +#define shellGetPath(_shell) ((_shell)->info.path) + +void shellInit(Shell *shell, char *buffer, unsigned short size); +void shellEcho(Shell *shell, unsigned int enable); +unsigned short shellWriteString(Shell *shell, const char *string); +void shellPrint(Shell *shell, char *fmt, ...); +void shellScan(Shell *shell, char *fmt, ...); +Shell* shellGetCurrent(void); +void shellHandler(Shell *shell, char data); +void shellWriteEndLine(Shell *shell, char *buffer, int len); +void shellTask(void *param); +int shellRun(Shell *shell, const char *cmd); + + + +#if SHELL_USING_COMPANION == 1 +/** + * @brief shell伴生对象定义 + */ +typedef struct shell_companion_object +{ + int id; /**< 伴生对象ID */ + void *obj; /**< 伴生对象 */ + struct shell_companion_object *next; /**< 下一个伴生对象 */ +} ShellCompanionObj; + + +signed char shellCompanionAdd(Shell *shell, int id, void *object); +signed char shellCompanionDel(Shell *shell, int id); +void *shellCompanionGet(Shell *shell, int id); +#endif + +#endif + + diff --git a/Ems/3rd/Shell/shell_cfg.h b/Ems/3rd/Shell/shell_cfg.h new file mode 100644 index 0000000..d0c5887 --- /dev/null +++ b/Ems/3rd/Shell/shell_cfg.h @@ -0,0 +1,183 @@ +/** + * @file shell_cfg.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell config + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_CFG_H__ +#define __SHELL_CFG_H__ + + +/** + * @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义 + * 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell + * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()` + */ +#define SHELL_TASK_WHILE 1 + +/** + * @brief 是否使用命令导出方式 + * 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令 + * 定义shell命令,关闭此宏的情况下,需要使用命令表的方式 + */ +#define SHELL_USING_CMD_EXPORT 1 + +/** + * @brief 是否使用shell伴生对象 + * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 + */ +#define SHELL_USING_COMPANION 0 + +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 0 + +/** + * @brief 是否在输出命令列表中列出用户 + */ +#define SHELL_HELP_LIST_USER 0 + +/** + * @brief 是否在输出命令列表中列出变量 + */ +#define SHELL_HELP_LIST_VAR 0 + +/** + * @brief 是否在输出命令列表中列出按键 + */ +#define SHELL_HELP_LIST_KEY 0 + +/** + * @brief 是否在输出命令列表中展示命令权限 + */ +#define SHELL_HELP_SHOW_PERMISSION 1 + +/** + * @brief 使用LF作为命令行回车触发 + * 可以和SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_LF 1 + +/** + * @brief 使用CR作为命令行回车触发 + * 可以和SHELL_ENTER_LF同时开启 + */ +#define SHELL_ENTER_CR 1 + +/** + * @brief 使用CRLF作为命令行回车触发 + * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_CRLF 0 + +/** + * @brief 使用执行未导出函数的功能 + * 启用后,可以通过`exec [addr] [args]`直接执行对应地址的函数 + * @attention 如果地址错误,可能会直接引起程序崩溃 + */ +#define SHELL_EXEC_UNDEF_FUNC 0 + +/** + * @brief shell命令参数最大数量 + * 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码 + */ +#define SHELL_PARAMETER_MAX_NUMBER 8 + +/** + * @brief 历史命令记录数量 + */ +#define SHELL_HISTORY_MAX_NUMBER 5 + +/** + * @brief 双击间隔(ms) + * 使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔 + */ +#define SHELL_DOUBLE_Clike_TIME 200 + +/** + * @brief 快速帮助 + * 作用于双击tab的场景,当使能此宏时,双击tab不会对命令进行help补全,而是直接显示对应命令的帮助信息 + */ +#define SHELL_QUICK_HELP 1 + + +/** + * @brief 管理的最大shell数量 + */ +#define SHELL_MAX_NUMBER 5 + +/** + * @brief shell格式化输出的缓冲大小 + * 为0时不使用shell格式化输出 + */ +#define SHELL_PRINT_BUFFER 128 + +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 0 + +/** + * @brief 获取系统时间(ms) + * 定义此宏为获取系统Tick,如`HAL_GetTick()` + * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 + */ +#define SHELL_GET_TICK() 0 + +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 0 + +/** + * @brief shell内存分配 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_MALLOC(size) 0 + +/** + * @brief shell内存释放 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_FREE(obj) 0 + +/** + * @brief 是否显示shell信息 + */ +#define SHELL_SHOW_INFO 1 + +/** + * @brief 是否在登录后清除命令行 + */ +#define SHELL_CLS_WHEN_LOGIN 1 + +/** + * @brief shell默认用户 + */ +#define SHELL_DEFAULT_USER "eLab" + +/** + * @brief shell默认用户密码 + * 若默认用户不需要密码,设为"" + */ +//#define SHELL_DEFAULT_USER_PASSWORD "123456" +#define SHELL_DEFAULT_USER_PASSWORD "" + +/** + * @brief shell自动锁定超时 + * shell当前用户密码有效的时候生效,超时后会自动重新锁定shell + * 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位 + * @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效 + */ +#define SHELL_LOCK_TIMEOUT 0 * 60 * 1000 + +#endif diff --git a/Ems/3rd/Shell/shell_cmd_list.c b/Ems/3rd/Shell/shell_cmd_list.c new file mode 100644 index 0000000..139a531 --- /dev/null +++ b/Ems/3rd/Shell/shell_cmd_list.c @@ -0,0 +1,103 @@ +/** + * @file shell_cmd_list.c + * @author Letter (NevermindZZT@gmail.com) + * @brief shell cmd list + * @version 3.0.0 + * @date 2020-01-17 + * + * @copyright (c) 2020 Letter + * + */ + +#include "shell.h" + +#if SHELL_USING_CMD_EXPORT != 1 + +extern int shellSetVar(char *name, int value); +extern void shellUp(Shell *shell); +extern void shellDown(Shell *shell); +extern void shellRight(Shell *shell); +extern void shellLeft(Shell *shell); +extern void shellTab(Shell *shell); +extern void shellBackspace(Shell *shell); +extern void shellDelete(Shell *shell); +extern void shellEnter(Shell *shell); +extern void shellHelp(int argc, char *argv[]); +extern void shellUsers(void); +extern void shellCmds(void); +extern void shellVars(void); +extern void shellKeys(void); +extern void shellClear(void); +#if SHELL_EXEC_UNDEF_FUNC == 1 +extern int shellExecute(int argc, char *argv[]); +#endif + +SHELL_AGENCY_FUNC(shellRun, shellGetCurrent(), (const char *)p1); + + +/** + * @brief shell命令表 + * + */ +const ShellCommand shellCommandList[] = +{ + {.attr.value=SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER), + .data.user.name = SHELL_DEFAULT_USER, + .data.user.password = SHELL_DEFAULT_USER_PASSWORD, + .data.user.desc = "default user"}, + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + setVar, shellSetVar, set var), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4100, shellUp, up), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4200, shellDown, down), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B4300, shellRight, right), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B4400, shellLeft, left), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x09000000, shellTab, tab), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x08000000, shellBackspace, backspace), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x7F000000, shellDelete, delete), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B337E, shellDelete, delete), +#if SHELL_ENTER_LF == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0A000000, shellEnter, enter), +#endif +#if SHELL_ENTER_CR == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0D000000, shellEnter, enter), +#endif +#if SHELL_ENTER_CRLF == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0D0A0000, shellEnter, enter), +#endif + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, + help, shellHelp, show command info\r\nhelp [cmd]), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + users, shellUsers, list all user), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + cmds, shellCmds, list all cmd), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + vars, shellVars, list all var), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + keys, shellKeys, list all key), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + clear, shellClear, clear console), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + sh, SHELL_AGENCY_FUNC_NAME(shellRun), run command directly), +#if SHELL_EXEC_UNDEF_FUNC == 1 + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, + exec, shellExecute, execute function undefined), +#endif +}; + + +/** + * @brief shell命令表大小 + * + */ +const unsigned short shellCommandCount + = sizeof(shellCommandList) / sizeof(ShellCommand); + +#endif diff --git a/Ems/3rd/Shell/shell_companion.c b/Ems/3rd/Shell/shell_companion.c new file mode 100644 index 0000000..eb494c7 --- /dev/null +++ b/Ems/3rd/Shell/shell_companion.c @@ -0,0 +1,87 @@ +/** + * @file shell_companion.c + * @author Letter (nevermindzzt@gmail.com) + * @brief shell companion object support + * @version 3.0.3 + * @date 2020-07-22 + * + * @copyright (c) 2020 Letter + * + */ + #include "shell.h" + +#if SHELL_USING_COMPANION == 1 +/** + * @brief shell添加伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @param object 伴生对象 + * @return signed char 0 添加成功 -1 添加失败 + */ +signed char shellCompanionAdd(Shell *shell, int id, void *object) +{ + ShellCompanionObj *companions = shell->info.companions; + ShellCompanionObj *node = SHELL_MALLOC(sizeof(ShellCompanionObj)); + SHELL_ASSERT(node, return -1); + node->id = id; + node->obj = object; + node->next = companions; + shell->info.companions = node; + return 0; +} + +/** + * @brief shell删除伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @return signed char 0 删除成功 -1 无匹配对象 + */ +signed char shellCompanionDel(Shell *shell, int id) +{ + ShellCompanionObj *companions = shell->info.companions; + ShellCompanionObj *front = companions; + while (companions) + { + if (companions->id == id) + { + if (companions == shell->info.companions && !(companions->next)) + { + shell->info.companions = (void *)0; + } + else + { + front->next = companions->next; + } + SHELL_FREE(companions); + return 0; + } + front = companions; + companions = companions->next; + } + return -1; +} + +/** + * @brief shell获取伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @return void* 伴生对象,无匹配对象时返回NULL + */ +void *shellCompanionGet(Shell *shell, int id) +{ + SHELL_ASSERT(shell, return (void *)0); + ShellCompanionObj *companions = shell->info.companions; + while (companions) + { + if (companions->id == id) + { + return companions->obj; + } + companions = companions->next; + } + return (void *)0; +} +#endif /** SHELL_USING_COMPANION == 1 */ diff --git a/Ems/3rd/Shell/shell_ext.c b/Ems/3rd/Shell/shell_ext.c new file mode 100644 index 0000000..7fbbc61 --- /dev/null +++ b/Ems/3rd/Shell/shell_ext.c @@ -0,0 +1,447 @@ +/** + * @file shell_ext.c + * @author Letter (NevermindZZT@gmail.com) + * @brief shell extensions + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#include "shell_cfg.h" +#include "shell.h" +#include "shell_ext.h" + + +extern ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength); +extern int shellGetVarValue(Shell *shell, ShellCommand *command); + +/** + * @brief 判断数字进制 + * + * @param string 参数字符串 + * @return ShellNumType 进制 + */ +static ShellNumType shellExtNumType(char *string) +{ + char *p = string; + ShellNumType type = NUM_TYPE_DEC; + + if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) + { + type = NUM_TYPE_HEX; + } + else if ((*p == '0') && ((*(p + 1) == 'b') || (*(p + 1) == 'B'))) + { + type = NUM_TYPE_BIN; + } + else if (*p == '0') + { + type = NUM_TYPE_OCT; + } + + while (*p++) + { + if (*p == '.' && *(p + 1) != 0) + { + type = NUM_TYPE_FLOAT; + break; + } + } + + return type; +} + + +/** + * @brief 字符转数字 + * + * @param code 字符 + * @return char 数字 + */ +static char shellExtToNum(char code) +{ + if ((code >= '0') && (code <= '9')) + { + return code -'0'; + } + else if ((code >= 'a') && (code <= 'f')) + { + return code - 'a' + 10; + } + else if ((code >= 'A') && (code <= 'F')) + { + return code - 'A' + 10; + } + else + { + return 0; + } +} + + +/** + * @brief 解析字符参数 + * + * @param string 字符串参数 + * @return char 解析出的字符 + */ +static char shellExtParseChar(char *string) +{ + char *p = string + 1; + char value = 0; + + if (*p == '\\') + { + switch (*(p + 1)) + { + case 'b': + value = '\b'; + break; + case 'r': + value = '\r'; + break; + case 'n': + value = '\n'; + break; + case 't': + value = '\t'; + break; + case '0': + value = 0; + break; + default: + value = *(p + 1); + break; + } + } + else + { + value = *p; + } + return value; +} + + +/** + * @brief 解析字符串参数 + * + * @param string 字符串参数 + * @return char* 解析出的字符串 + */ +static char* shellExtParseString(char *string) +{ + char *p = string; + unsigned short index = 0; + + if (*string == '\"') + { + p = ++string; + } + + while (*p) + { + if (*p == '\\') + { + *(string + index) = shellExtParseChar(p - 1); + p++; + } + else if (*p == '\"') + { + *(string + index) = 0; + } + else + { + *(string + index) = *p; + } + p++; + index ++; + } + *(string + index) = 0; + return string; +} + + +/** + * @brief 解析数字参数 + * + * @param string 字符串参数 + * @return unsigned int 解析出的数字 + */ +static unsigned int shellExtParseNumber(char *string) +{ + ShellNumType type = NUM_TYPE_DEC; + char radix = 10; + char *p = string; + char offset = 0; + signed char sign = 1; + unsigned int valueInt = 0; + float valueFloat = 0.0; + unsigned int devide = 0; + + if (*string == '-') + { + sign = -1; + } + + type = shellExtNumType(string + ((sign == -1) ? 1 : 0)); + + switch ((char)type) + { + case NUM_TYPE_HEX: + radix = 16; + offset = 2; + break; + + case NUM_TYPE_OCT: + radix = 8; + offset = 1; + break; + + case NUM_TYPE_BIN: + radix = 2; + offset = 2; + break; + + default: + break; + } + + p = string + offset + ((sign == -1) ? 1 : 0); + + while (*p) + { + if (*p == '.') + { + devide = 1; + p++; + continue; + } + valueInt = valueInt * radix + shellExtToNum(*p); + devide *= 10; + p++; + } + if (type == NUM_TYPE_FLOAT && devide != 0) + { + valueFloat = (float)valueInt / devide * sign; + return *(unsigned int *)(&valueFloat); + } + else + { + return valueInt * sign; + } +} + + +/** + * @brief 解析变量参数 + * + * @param shell shell对象 + * @param var 变量 + * @return unsigned int 变量值 + */ +static unsigned int shellExtParseVar(Shell *shell, char *var) +{ + ShellCommand *command = shellSeekCommand(shell, + var + 1, + shell->commandList.base, + 0); + if (command) + { + return shellGetVarValue(shell, command); + } + else + { + return 0; + } +} + + +/** + * @brief 解析参数 + * + * @param shell shell对象 + * @param string 参数 + * @return unsigned int 解析结果 + */ +unsigned int shellExtParsePara(Shell *shell, char *string) +{ + if (*string == '\'' && *(string + 1)) + { + return (unsigned int)shellExtParseChar(string); + } + else if (*string == '-' || (*string >= '0' && *string <= '9')) + { + return (unsigned int)shellExtParseNumber(string); + } + else if (*string == '$' && *(string + 1)) + { + return shellExtParseVar(shell, string); + } + else if (*string) + { + return (unsigned int)shellExtParseString(string); + } + return 0; +} + + +/** + * @brief 执行命令 + * + * @param shell shell对象 + * @param command 命令 + * @param argc 参数个数 + * @param argv 参数 + * @return int 返回值 + */ +int shellExtRun(Shell *shell, ShellCommand *command, int argc, char *argv[]) +{ + unsigned int params[SHELL_PARAMETER_MAX_NUMBER] = {0}; + int paramNum = command->attr.attrs.paramNum > (argc - 1) ? + command->attr.attrs.paramNum : (argc - 1); + for (int i = 0; i < argc - 1; i++) + { + params[i] = shellExtParsePara(shell, argv[i + 1]); + } + switch (paramNum) + { +#if SHELL_PARAMETER_MAX_NUMBER >= 1 + case 0: + return command->data.cmd.function(); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 1 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 2 + case 1: + return command->data.cmd.function(params[0]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 2 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 3 + case 2: + return command->data.cmd.function(params[0], params[1]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 3 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 4 + case 3: + return command->data.cmd.function(params[0], params[1], + params[2]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 4 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 5 + case 4: + return command->data.cmd.function(params[0], params[1], + params[2], params[3]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 5 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 6 + case 5: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 6 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 7 + case 6: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 7 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 8 + case 7: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 8 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 9 + case 8: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 9 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 10 + case 9: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 10 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 11 + case 10: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 11 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 12 + case 11: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9], + params[10]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 12 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 13 + case 12: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9], + params[10], params[11]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 13 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 14 + case 13: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9], + params[10], params[11], + params[12]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 14 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 15 + case 14: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9], + params[10], params[11], + params[12], params[13]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 15 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 16 + case 15: + return command->data.cmd.function(params[0], params[1], + params[2], params[3], + params[4], params[5], + params[6], params[7], + params[8], params[9], + params[10], params[11], + params[12], params[13], + params[14]); + // break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 16 */ + default: + return -1; + // break; + } +} + diff --git a/Ems/3rd/Shell/shell_ext.h b/Ems/3rd/Shell/shell_ext.h new file mode 100644 index 0000000..2e6158c --- /dev/null +++ b/Ems/3rd/Shell/shell_ext.h @@ -0,0 +1,33 @@ +/** + * @file shell_ext.h + * @author Letter (NevermindZZT@gmail.com) + * @brief shell extensions + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_EXT_H__ +#define __SHELL_EXT_H__ + +#include "shell.h" + +/** + * @brief 数字类型 + * + */ +typedef enum +{ + NUM_TYPE_DEC, /**< 十进制整型 */ + NUM_TYPE_BIN, /**< 二进制整型 */ + NUM_TYPE_OCT, /**< 八进制整型 */ + NUM_TYPE_HEX, /**< 十六进制整型 */ + NUM_TYPE_FLOAT /**< 浮点型 */ +} ShellNumType; + +unsigned int shellExtParsePara(Shell *shell, char *string); +int shellExtRun(Shell *shell, ShellCommand *command, int argc, char *argv[]); + +#endif diff --git a/Ems/common/Ems_assert.h b/Ems/common/Ems_assert.h new file mode 100644 index 0000000..6e728be --- /dev/null +++ b/Ems/common/Ems_assert.h @@ -0,0 +1,29 @@ +/** + * @file Ems_assert.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_ASSERT_H +#define EMS_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* public define ------------------------------------------------------------ */ +#define EMS_TAG(tag) +#define ems_assert(ex) ((void)0) + +#ifdef __cplusplus +} +#endif + +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/common/Ems_common.c b/Ems/common/Ems_common.c new file mode 100644 index 0000000..1af335f --- /dev/null +++ b/Ems/common/Ems_common.c @@ -0,0 +1,46 @@ +/** + * @file Ems_common.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +/* include ------------------------------------------------------------------ */ +#include "ems.h" + +/* public function ---------------------------------------------------------- */ +/** + * @brief eLab debug uart weak initialization function. + * @param baudrate The uart port baudrate. + * @retval None + */ +EMS_WEAK void ems_debug_uart_init(uint32_t baudrate) +{ + (void)baudrate; +} + +EMS_WEAK int16_t ems_debug_uart_send(void *buffer, uint16_t size) +{ + (void)buffer; + (void)size; + + return 0; +} + +EMS_WEAK int16_t ems_debug_uart_receive(void *buffer, uint16_t size) +{ + (void)buffer; + (void)size; + + return 0; +} + +EMS_WEAK void ems_debug_uart_buffer_clear(void) +{ +} + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/common/Ems_common.h b/Ems/common/Ems_common.h new file mode 100644 index 0000000..a5ac527 --- /dev/null +++ b/Ems/common/Ems_common.h @@ -0,0 +1,52 @@ +/** + * @file Ems_common.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_COMMON_H +#define EMS_COMMON_H + +/* includes ----------------------------------------------------------------- */ +#include <stdint.h> + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +#include "ems_port.h" +#include "cmsis_os.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* public typedef ----------------------------------------------------------- */ +/* time related. */ +uint32_t ems_time_ms(void); + +/* uart debug related. */ +void ems_debug_uart_init(uint32_t baudrate); +int16_t ems_debug_uart_send(void *buffer, uint16_t size); +int16_t ems_debug_uart_receive(void *buffer, uint16_t size); +void ems_debug_uart_buffer_clear(void); + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +/* thread related. */ +osThreadId_t ems_thread_init(ems_thread_t *const me, + void (*entry)(void *parameter), + const char *name, void *data, + void *stack, uint32_t stack_size, + uint8_t priority); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/common/Ems_def.h b/Ems/common/Ems_def.h new file mode 100644 index 0000000..23d233c --- /dev/null +++ b/Ems/common/Ems_def.h @@ -0,0 +1,107 @@ +/** + * @file Ems_def.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_DEF_H +#define EMS_DEF_H + +/* includes ----------------------------------------------------------------- */ +#include <stdint.h> +#include "EMS_config.h" + +#if (EMS_QPC_EN != 0) +#include "qpc.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* public typedef ----------------------------------------------------------- */ +typedef enum EMS_err +{ + EMS_OK = 0, + EMS_ERROR = -1, + EMS_ERR_EMPTY = -2, + EMS_ERR_FULL = -3, + EMS_ERR_TIMEOUT = -4, + EMS_ERR_BUSY = -5, + EMS_ERR_NO_MEMORY = -6, + EMS_ERR_IO = -7, + EMS_ERR_INVALID = -8, + EMS_ERR_MEM_OVERLAY = -9, + EMS_ERR_MALLOC = -10, + EMS_ERR_NOT_ENOUGH = -11, +} ems_err_t; + +#if (EMS_QPC_EN != 0) + +typedef struct EMS_event +{ + QEvt super; + uint8_t data[EMS_EVENT_DATA_SIZE]; +} EMS_event_t; + +#endif + +/** + * Cast a member of a structure out to the containing structure. + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#ifndef container_of +#define container_of(pointer, type, member) \ + ({ \ + void *__pointer = (void *)(pointer); \ + ((type *)(__pointer - offsetof(type, member))); \ + }) +#endif + +#ifndef offsetof +#define offsetof(type, member) ((uint32_t)&((type *)0)->member) +#endif + +/* Compiler Related Definitions */ +#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */ + #include <stdarg.h> + #define EMS_SECTION(x) __attribute__((section(x))) + #define EMS_USED __attribute__((used)) + #define EMS_ALIGN(n) __attribute__((aligned(n))) + #define EMS_WEAK __attribute__((weak)) + #define EMS_INLINE static __inline + +#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */ + #include <stdarg.h> + #define EMS_SECTION(x) @ x + #define EMS_USED __root + #define EMS_PRAGMA(x) _Pragma(#x) + #define EMS_ALIGN(n) EMS_PRAGMA(data_alignment=n) + #define EMS_WEAK __weak + #define EMS_INLINE static inline + +#elif defined (__GNUC__) /* GNU GCC Compiler */ + #include <stdarg.h> + #define EMS_SECTION(x) __attribute__((section(x))) + #define EMS_USED __attribute__((used)) + #define EMS_ALIGN(n) __attribute__((aligned(n))) + #define EMS_WEAK __attribute__((weak)) + #define EMS_INLINE static __inline +#else + #error The compiler is not supported! +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/common/Ems_export.c b/Ems/common/Ems_export.c new file mode 100644 index 0000000..ca6706d --- /dev/null +++ b/Ems/common/Ems_export.c @@ -0,0 +1,242 @@ +/** + * @file Ems_export.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +/* include ------------------------------------------------------------------ */ +#include <stdlib.h> +#include <stdint.h> +#include "ems_export.h" +#include "ems_common.h" + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +#include "cmsis_os.h" +#endif + +#if (EMS_QPC_EN != 0) +Q_DEFINE_THIS_FILE +#include "qpc.h" +#endif + +/* private function prototype ----------------------------------------------- */ +static void module_null_init(void); +static void _export_func_execute(uint8_t level); +#if (EMS_RTOS_CMSIS_OS_EN != 0) +static void _entry_start_poll(void *para); +#endif + +/* private variables -------------------------------------------------------- */ +INIT_BSP_EXPORT(module_null_init); +POLL_EXPORT(module_null_init, (1000 * 60 * 60)); + +static const uint32_t export_id_table[EXPORT_MAX + 1] = +{ + EXPORT_ID_INIT, + EXPORT_ID_INIT, + EXPORT_ID_INIT, + EXPORT_ID_INIT, + EXPORT_ID_INIT, +#if (EMS_RTOS_CMSIS_OS_EN != 0) + EXPORT_ID_INIT, +#endif +#if (EMS_QPC_EN != 0) + EXPORT_ID_INIT, +#endif + EXPORT_ID_INIT, + EXPORT_ID_POLL, +}; + +static ems_export_t *export_init_table = NULL; +static ems_export_t *export_poll_table = NULL; + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +/** + * @brief The thread attribute for testing. + */ +static const osThreadAttr_t thread_attr_start_poll = +{ + .name = "ThreadStartPoll", + .attr_bits = osThreadDetached, + .priority = osPriorityNormal, + .stack_size = 2048, +}; +#endif + +/* public function ---------------------------------------------------------- */ +/** + * @brief eLab unit test exporting function. + * @retval None + */ +void ems_unit_test(void) +{ + _export_func_execute(EXPORT_TEST); +} + +/** + * @brief eLab polling exporting function. + * @retval None + */ +void ems_run(void) +{ + /* Start polling function in metal eLab, or start the RTOS kernel in RTOS + eLab. */ +#if (EMS_RTOS_CMSIS_OS_EN != 0) + osKernelInitialize(); + osThreadNew(_entry_start_poll, NULL, &thread_attr_start_poll); + osKernelStart(); +#else + /* Initialize all module in eLab. */ + for (uint8_t level = EXPORT_BSP; level <= EXPORT_APP; level ++) + { + _export_func_execute(level); + } + + /* Start polling function in metal eLab. */ + while (1) + { + _export_func_execute(EXPORT_MAX); + } +#endif +} + +/* private function --------------------------------------------------------- */ +/** + * @brief Get the export table. + */ +static ems_export_t * _get_export_table(uint8_t level) +{ + ems_export_t *func_block = + level < EXPORT_MAX ? + ((ems_export_t *)&init_module_null_init) : + ((ems_export_t *)&poll_module_null_init); + + while (1) + { + uint32_t address_last = ((uint32_t)func_block - sizeof(ems_export_t)); + ems_export_t *table = (ems_export_t *)address_last; + if (table->magic_head != export_id_table[level] || + table->magic_tail != export_id_table[level]) + { + break; + } + func_block = table; + } + + return func_block; +} + +/** + * @brief eLab exporting function executing. + * @param level export level. + * @retval None + */ +static void _export_func_execute(uint8_t level) +{ + uint32_t export_id = export_id_table[level]; + + /* Get the start address of exported poll table. */ + if (export_init_table == NULL) + { + export_init_table = _get_export_table(EXPORT_BSP); + } + if (export_poll_table == NULL) + { + export_poll_table = _get_export_table(EXPORT_MAX); + } + + /* Execute the poll function in the specific level. */ + ems_export_t *export_table = level < EXPORT_MAX ? + export_init_table : export_poll_table; + for (uint32_t i = 0; ; i ++) + { + if (export_table[i].magic_head == export_id && + export_table[i].magic_tail == export_id) + { + if (export_table[i].level == level && level <= EXPORT_APP) + { + ((void (*)(void))export_table[i].func)(); + } +#if (EMS_RTOS_CMSIS_OS_EN != 0) + else if (export_table[i].level == level && level == EXPORT_THREAD) + { + ems_thread_init((ems_thread_t *)export_table[i].object, + (void (*)(void *))export_table[i].func, + export_table[i].name, export_table[i].data, + export_table[i].stack, + export_table[i].stack_size, + export_table[i].priority); + } +#endif +#if (EMS_QPC_EN != 0) + else if (export_table[i].level == level && level == EXPORT_HSM) + { + QActive_ctor((QActive *)export_table[i].object, + Q_STATE_CAST(export_table[i].func)); + QACTIVE_START((QActive *)export_table[i].object, + export_table[i].priority, + export_table[i].data, export_table[i].queue_size, + export_table[i].stack, export_table[i].stack_size, + (QEvt *)0); + } +#endif + else if (export_table[i].level == level && level == EXPORT_MAX) + { + ems_export_poll_data_t *data = export_table[i].data; + while (ems_time_ms() >= data->timeout_ms) + { + data->timeout_ms += export_table[i].period_ms; + ((void (*)(void))export_table[i].func)(); + } + } + } + else + { + break; + } + } +} + +void ao_led_init(void); + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +/** + * @brief eLab startup and poll function. + * @retval None + */ +static void _entry_start_poll(void *para) +{ + /* Initialize all module in eLab. */ + for (uint8_t level = EXPORT_BSP; level <= EXPORT_APP; level ++) + { + _export_func_execute(level); + } + _export_func_execute(EXPORT_THREAD); +#if (EMS_QPC_EN != 0) + _export_func_execute(EXPORT_HSM); +#endif + + /* Start polling function in metal eLab. */ + while (1) + { + _export_func_execute(EXPORT_MAX); + osDelay(10); + } +} +#endif + +/** + * @brief eLab null exporting function. + * @retval None + */ +static void module_null_init(void) +{ + /* NULL */ +} + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/common/Ems_export.h b/Ems/common/Ems_export.h new file mode 100644 index 0000000..07f1678 --- /dev/null +++ b/Ems/common/Ems_export.h @@ -0,0 +1,249 @@ +/** + * @file Ems_export.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef __EMS_EXPORT_H__ +#define __EMS_EXPORT_H__ + +/* include ------------------------------------------------------------------ */ +#include <stdint.h> +#include "ems_def.h" +#if (EMS_RTOS_CMSIS_OS_EN != 0) +#include "ems_port.h" +#endif + +#if (EMS_QPC_EN != 0) +#include "qpc.h" +#endif + +/* public define ------------------------------------------------------------ */ +#define EXPORT_ID_INIT (0xa5a5a5a5) +#define EXPORT_ID_POLL (0xbeefbeef) + +/* public define ------------------------------------------------------------ */ +enum ems_export_level +{ + EXPORT_BSP = 0, + EXPORT_IO_DRIVER, + EXPORT_COMPONENT, + EXPORT_DEVICE, + EXPORT_APP, +#if (EMS_RTOS_CMSIS_OS_EN != 0) + EXPORT_THREAD, +#endif +#if (EMS_QPC_EN != 0) + EXPORT_HSM, +#endif + EXPORT_TEST, + + EXPORT_MAX, +}; + +/* public typedef ----------------------------------------------------------- */ +typedef struct ems_export_poll_data +{ + uint32_t timeout_ms; +} ems_export_poll_data_t; + +typedef struct ems_export +{ + uint32_t magic_head; + const char *name; + void *data; + void *stack; + void *object; + void *func; + uint16_t stack_size; + uint16_t queue_size; + uint16_t priority; + uint16_t level; + uint32_t period_ms; + uint32_t temp[6]; + uint32_t magic_tail; +} ems_export_t; + +/* private function --------------------------------------------------------- */ +void ems_unit_test(void); +void ems_run(void); + +/* public export ------------------------------------------------------------ */ +/** + * @brief Initialization function exporting macro. + * @param _func The polling function. + * @param _level The export level. See enum ems_export_level. + * @retval None. + */ +#define INIT_EXPORT(_func, _level) \ +EMS_USED const ems_export_t init_##_func EMS_SECTION("ems_export") = \ + { \ + .name = "init", \ + .func = (void *)&_func, \ + .level = _level, \ + .magic_head = EXPORT_ID_INIT, \ + .magic_tail = EXPORT_ID_INIT, \ + } + +#if (EMS_QPC_EN != 0) +#if (EMS_RTOS_CMSIS_OS_EN != 0) +/** + * @brief State machine exporting macro. + * @param _name name of the state machine. + * @param me The state machine object. + * @param _state_init The initial state of the state machine. + * @param _priority The priority of the state machine. + * @param _queue_size The queue size of the state machine. + * @param _stack_size The stack size of the state machine's internal thread. + * @retval None. + */ +#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size, _stack_size)\ + static QEvt const * sm_##_name##_queue[_queue_size]; \ + static uint8_t sm_##_name##_stack[_stack_size]; \ + EMS_USED const ems_export_t sm_##_name EMS_SECTION("ems_export") = \ + { \ + .name = (const char *)#_name, \ + .object = (void *)me, \ + .func = (void *)(&_state_init), \ + .data = (void *)sm_##_name##_queue, \ + .queue_size = _queue_size, \ + .stack = (void *)sm_##_name##_stack, \ + .stack_size = _stack_size, \ + .priority = _priority, \ + .level = EXPORT_HSM, \ + .magic_head = EXPORT_ID_INIT, \ + .magic_tail = EXPORT_ID_INIT, \ + } +#else + +/** + * @brief State machine exporting macro. + * @param _name name of the state machine. + * @param me The state machine object. + * @param _state_init The initial state of the state machine. + * @param _priority The priority of the state machine. + * @param _queue_size The queue size of the state machine. + * @retval None. + */ +#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size) \ + static QEvt const * sm_##_name##_queue[_queue_size]; \ + EMS_USED const ems_export_t sm_##_name EMS_SECTION("ems_export") = \ + { \ + .name = (const char *)#_name, \ + .object = (void *)me, \ + .func = (void *)(&_state_init), \ + .data = (void *)sm_##_name##_queue, \ + .queue_size = _queue_size, \ + .priority = _priority, \ + .level = EXPORT_HSM, \ + .magic_head = EXPORT_ID_INIT, \ + .magic_tail = EXPORT_ID_INIT, \ + } +#endif +#else +#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size, _stack_size) +#endif + +#if (EMS_RTOS_CMSIS_OS_EN != 0) +/** + * @brief Thread exporting macro. + * @param _name name of the state machine. + * @param _entry The thread entry function. + * @param _priority The priority of the state machine. + * @param _data user data. + * @param _stack_size The stack size of the state machine. + * @retval None. + */ +#define THREAD_EXPORT(_name, _entry, _priority, _data, _stack_size) \ + static ems_thread_t thread_##_name; \ + static uint8_t thread_##_name##_stack[_stack_size]; \ + EMS_USED const ems_export_t thread##_name EMS_SECTION("ems_export") = \ + { \ + .func = (void *)&_entry, \ + .name = #_name, \ + .data = (void *)_data, \ + .object = (void *)&thread_##_name, \ + .stack = (void *)thread_##_name##_stack, \ + .stack_size = _stack_size, \ + .priority = _priority, \ + .level = EXPORT_THREAD, \ + .magic_head = EXPORT_ID_INIT, \ + .magic_tail = EXPORT_ID_INIT, \ + } +#else +#define THREAD_EXPORT(_name, _entry, _priority, _data, _stack_size) +#endif + +/** + * @brief Poll function exporting macro. + * @param _func The polling function. + * @param _period_ms The polling period in ms. + * @retval None. + */ +#define POLL_EXPORT(_func, _period_ms) \ + static ems_export_poll_data_t poll_##_func##_data = \ + { \ + .timeout_ms = 0, \ + }; \ + EMS_USED const ems_export_t poll_##_func EMS_SECTION("expoll") = \ + { \ + .name = "poll", \ + .func = (void *)&_func, \ + .data = (void *)&poll_##_func##_data, \ + .level = EXPORT_MAX, \ + .period_ms = (uint32_t)(_period_ms), \ + .magic_head = EXPORT_ID_POLL, \ + .magic_tail = EXPORT_ID_POLL, \ + } + +/* public function ---------------------------------------------------------- */ +/** + * @brief Initialization function in BSP layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_BSP_EXPORT(_func) INIT_EXPORT(_func, EXPORT_BSP) + +/** + * @brief Initialization function in IO driver layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_IO_DRIVER_EXPORT(_func) INIT_EXPORT(_func, EXPORT_IO_DRIVER) + +/** + * @brief Initialization function in component layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_COMPONENT_EXPORT(_func) INIT_EXPORT(_func, EXPORT_COMPONENT) + +/** + * @brief Initialization function in device layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_DEV_EXPORT(_func) INIT_EXPORT(_func, EXPORT_DEVICE) + +/** + * @brief Initialization function in appliation layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_APP_EXPORT(_func) INIT_EXPORT(_func, EXPORT_APP) + +/** + * @brief Testing function in unit test layer. + * @param _func The initialization function. + * @retval None. + */ +#define INIT_EXPORT_TEST(_func) INIT_EXPORT(_func, EXPORT_TEST) + +#endif /* __EMS_EXPORT_H__ */ + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Ems/ems.h b/Ems/ems.h new file mode 100644 index 0000000..5ba0b60 --- /dev/null +++ b/Ems/ems.h @@ -0,0 +1,24 @@ +/** + * @file ems.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-04-05 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef EMS_H +#define EMS_H + +/* includes ----------------------------------------------------------------- */ +#include "common/ems_def.h" +#include "common/ems_assert.h" +#include "common/ems_export.h" +#include "common/ems_common.h" + + +#endif + +/* ----------------------------- end of file -------------------------------- */ diff --git a/Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l443xx.h b/MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l443xx.h similarity index 100% rename from Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l443xx.h rename to MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l443xx.h diff --git a/Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h b/MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h similarity index 100% rename from Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h rename to MCU/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h diff --git a/Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h b/MCU/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h similarity index 100% rename from Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h rename to MCU/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h diff --git a/Drivers/CMSIS/Device/ST/STM32L4xx/LICENSE.txt b/MCU/CMSIS/Device/ST/STM32L4xx/LICENSE.txt similarity index 100% rename from Drivers/CMSIS/Device/ST/STM32L4xx/LICENSE.txt rename to MCU/CMSIS/Device/ST/STM32L4xx/LICENSE.txt diff --git a/Drivers/CMSIS/Device/ST/STM32L4xx/License.md b/MCU/CMSIS/Device/ST/STM32L4xx/License.md similarity index 100% rename from Drivers/CMSIS/Device/ST/STM32L4xx/License.md rename to MCU/CMSIS/Device/ST/STM32L4xx/License.md diff --git a/Drivers/CMSIS/Include/cmsis_armcc.h b/MCU/CMSIS/Include/cmsis_armcc.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_armcc.h rename to MCU/CMSIS/Include/cmsis_armcc.h diff --git a/Drivers/CMSIS/Include/cmsis_armclang.h b/MCU/CMSIS/Include/cmsis_armclang.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_armclang.h rename to MCU/CMSIS/Include/cmsis_armclang.h diff --git a/Drivers/CMSIS/Include/cmsis_armclang_ltm.h b/MCU/CMSIS/Include/cmsis_armclang_ltm.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_armclang_ltm.h rename to MCU/CMSIS/Include/cmsis_armclang_ltm.h diff --git a/Drivers/CMSIS/Include/cmsis_compiler.h b/MCU/CMSIS/Include/cmsis_compiler.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_compiler.h rename to MCU/CMSIS/Include/cmsis_compiler.h diff --git a/Drivers/CMSIS/Include/cmsis_gcc.h b/MCU/CMSIS/Include/cmsis_gcc.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_gcc.h rename to MCU/CMSIS/Include/cmsis_gcc.h diff --git a/Drivers/CMSIS/Include/cmsis_iccarm.h b/MCU/CMSIS/Include/cmsis_iccarm.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_iccarm.h rename to MCU/CMSIS/Include/cmsis_iccarm.h diff --git a/Drivers/CMSIS/Include/cmsis_version.h b/MCU/CMSIS/Include/cmsis_version.h similarity index 100% rename from Drivers/CMSIS/Include/cmsis_version.h rename to MCU/CMSIS/Include/cmsis_version.h diff --git a/Drivers/CMSIS/Include/core_armv81mml.h b/MCU/CMSIS/Include/core_armv81mml.h similarity index 100% rename from Drivers/CMSIS/Include/core_armv81mml.h rename to MCU/CMSIS/Include/core_armv81mml.h diff --git a/Drivers/CMSIS/Include/core_armv8mbl.h b/MCU/CMSIS/Include/core_armv8mbl.h similarity index 100% rename from Drivers/CMSIS/Include/core_armv8mbl.h rename to MCU/CMSIS/Include/core_armv8mbl.h diff --git a/Drivers/CMSIS/Include/core_armv8mml.h b/MCU/CMSIS/Include/core_armv8mml.h similarity index 100% rename from Drivers/CMSIS/Include/core_armv8mml.h rename to MCU/CMSIS/Include/core_armv8mml.h diff --git a/Drivers/CMSIS/Include/core_cm0.h b/MCU/CMSIS/Include/core_cm0.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm0.h rename to MCU/CMSIS/Include/core_cm0.h diff --git a/Drivers/CMSIS/Include/core_cm0plus.h b/MCU/CMSIS/Include/core_cm0plus.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm0plus.h rename to MCU/CMSIS/Include/core_cm0plus.h diff --git a/Drivers/CMSIS/Include/core_cm1.h b/MCU/CMSIS/Include/core_cm1.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm1.h rename to MCU/CMSIS/Include/core_cm1.h diff --git a/Drivers/CMSIS/Include/core_cm23.h b/MCU/CMSIS/Include/core_cm23.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm23.h rename to MCU/CMSIS/Include/core_cm23.h diff --git a/Drivers/CMSIS/Include/core_cm3.h b/MCU/CMSIS/Include/core_cm3.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm3.h rename to MCU/CMSIS/Include/core_cm3.h diff --git a/Drivers/CMSIS/Include/core_cm33.h b/MCU/CMSIS/Include/core_cm33.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm33.h rename to MCU/CMSIS/Include/core_cm33.h diff --git a/Drivers/CMSIS/Include/core_cm35p.h b/MCU/CMSIS/Include/core_cm35p.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm35p.h rename to MCU/CMSIS/Include/core_cm35p.h diff --git a/Drivers/CMSIS/Include/core_cm4.h b/MCU/CMSIS/Include/core_cm4.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm4.h rename to MCU/CMSIS/Include/core_cm4.h diff --git a/Drivers/CMSIS/Include/core_cm7.h b/MCU/CMSIS/Include/core_cm7.h similarity index 100% rename from Drivers/CMSIS/Include/core_cm7.h rename to MCU/CMSIS/Include/core_cm7.h diff --git a/Drivers/CMSIS/Include/core_sc000.h b/MCU/CMSIS/Include/core_sc000.h similarity index 100% rename from Drivers/CMSIS/Include/core_sc000.h rename to MCU/CMSIS/Include/core_sc000.h diff --git a/Drivers/CMSIS/Include/core_sc300.h b/MCU/CMSIS/Include/core_sc300.h similarity index 100% rename from Drivers/CMSIS/Include/core_sc300.h rename to MCU/CMSIS/Include/core_sc300.h diff --git a/Drivers/CMSIS/Include/mpu_armv7.h b/MCU/CMSIS/Include/mpu_armv7.h similarity index 100% rename from Drivers/CMSIS/Include/mpu_armv7.h rename to MCU/CMSIS/Include/mpu_armv7.h diff --git a/Drivers/CMSIS/Include/mpu_armv8.h b/MCU/CMSIS/Include/mpu_armv8.h similarity index 100% rename from Drivers/CMSIS/Include/mpu_armv8.h rename to MCU/CMSIS/Include/mpu_armv8.h diff --git a/Drivers/CMSIS/Include/tz_context.h b/MCU/CMSIS/Include/tz_context.h similarity index 100% rename from Drivers/CMSIS/Include/tz_context.h rename to MCU/CMSIS/Include/tz_context.h diff --git a/Drivers/CMSIS/LICENSE.txt b/MCU/CMSIS/LICENSE.txt similarity index 100% rename from Drivers/CMSIS/LICENSE.txt rename to MCU/CMSIS/LICENSE.txt diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/MCU/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h rename to MCU/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_can.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_can.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_can.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_can.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_crc_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h diff --git a/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h b/MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h rename to MCU/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h diff --git a/Drivers/STM32L4xx_HAL_Driver/LICENSE.txt b/MCU/STM32L4xx_HAL_Driver/LICENSE.txt similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/LICENSE.txt rename to MCU/STM32L4xx_HAL_Driver/LICENSE.txt diff --git a/Drivers/STM32L4xx_HAL_Driver/License.md b/MCU/STM32L4xx_HAL_Driver/License.md similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/License.md rename to MCU/STM32L4xx_HAL_Driver/License.md diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c diff --git a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c b/MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c similarity index 100% rename from Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c rename to MCU/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c diff --git a/Core/Inc/stm32l4xx_hal_conf.h b/MCU/stm32l4xx_hal_conf.h similarity index 100% copy from Core/Inc/stm32l4xx_hal_conf.h copy to MCU/stm32l4xx_hal_conf.h diff --git a/Core/Src/stm32l4xx_hal_msp.c b/MCU/stm32l4xx_hal_msp.c similarity index 100% rename from Core/Src/stm32l4xx_hal_msp.c rename to MCU/stm32l4xx_hal_msp.c diff --git a/Core/Src/stm32l4xx_it.c b/MCU/stm32l4xx_it.c similarity index 93% rename from Core/Src/stm32l4xx_it.c rename to MCU/stm32l4xx_it.c index 76594d9..6042337 100644 --- a/Core/Src/stm32l4xx_it.c +++ b/MCU/stm32l4xx_it.c @@ -22,6 +22,7 @@ #include "stm32l4xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include "os_clock.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -56,8 +57,6 @@ /* External variables --------------------------------------------------------*/ extern DMA_HandleTypeDef hdma_adc1; -extern TIM_HandleTypeDef htim6; - /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -185,9 +184,9 @@ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ - + os_SetTickFlag(); /* USER CODE END SysTick_IRQn 0 */ - + HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ @@ -212,20 +211,6 @@ /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */ /* USER CODE END DMA1_Channel1_IRQn 1 */ -} - -/** - * @brief This function handles TIM6 global interrupt, DAC channel1 and channel2 underrun error interrupts. - */ -void TIM6_DAC_IRQHandler(void) -{ - /* USER CODE BEGIN TIM6_DAC_IRQn 0 */ - - /* USER CODE END TIM6_DAC_IRQn 0 */ - HAL_TIM_IRQHandler(&htim6); - /* USER CODE BEGIN TIM6_DAC_IRQn 1 */ - - /* USER CODE END TIM6_DAC_IRQn 1 */ } /* USER CODE BEGIN 1 */ diff --git a/Core/Inc/stm32l4xx_it.h b/MCU/stm32l4xx_it.h similarity index 97% copy from Core/Inc/stm32l4xx_it.h copy to MCU/stm32l4xx_it.h index 83f5517..cbfc055 100644 --- a/Core/Inc/stm32l4xx_it.h +++ b/MCU/stm32l4xx_it.h @@ -56,7 +56,6 @@ void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Channel1_IRQHandler(void); -void TIM6_DAC_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Core/Src/system_stm32l4xx.c b/MCU/system_stm32l4xx.c similarity index 100% rename from Core/Src/system_stm32l4xx.c rename to MCU/system_stm32l4xx.c diff --git a/Makefile b/Makefile index 8af1291..0d469b8 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.15.2] date: [Tue Nov 01 16:45:18 CST 2022] +# File automatically-generated by tool: [projectgenerator] version: [3.15.2] date: [Wed Nov 30 15:04:45 CST 2022] ########################################################################################################################## # ------------------------------------------------ @@ -37,8 +37,10 @@ # C sources C_SOURCES = \ APP/main.c \ -CAHB_Hal/src/os_clock.c\ -CAHB_Hal/src/os_task.c\ +CAHB_Hal/src/os_clock.c \ +CAHB_Hal/src/os_task.c \ +CAHB_Hal/src/Hal_gpio.c \ +CAHB_Hal/src/Hal_adc.c \ Core/Src/clock.c \ Core/Src/gpio.c \ Core/Src/adc.c \ @@ -48,7 +50,6 @@ Core/Src/tim.c \ Core/Src/stm32l4xx_it.c \ Core/Src/stm32l4xx_hal_msp.c \ -Core/Src/stm32l4xx_hal_timebase_tim.c \ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c \ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c \ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c \ @@ -72,7 +73,7 @@ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c \ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c \ Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c \ -Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c +Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c \ # ASM sources ASM_SOURCES = \ @@ -129,7 +130,7 @@ # C includes C_INCLUDES = \ --ICAHB_Hal/inc\ +-ICAHB_Hal/inc \ -ICore/Inc \ -IDrivers/STM32L4xx_HAL_Driver/Inc \ -IDrivers/STM32L4xx_HAL_Driver/Inc/Legacy \ -- Gitblit v1.8.0