2023-05-3

This commit is contained in:
gitea committed 2023-05-03 18:18:03 +08:00
1 parent 633d9b872b
commit 063c3fcc07
74 files changed
+26281 -13954

No files matched your search

+42 -34
View File
@@ -1,5 +1,5 @@
[PreviousLibFiles] [PreviousLibFiles]
LibFiles=Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_bus.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_system.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_utils.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_crs.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ramfunc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gpio.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gpio_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_gpio.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dma.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dma_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_pwr.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_pwr_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_pwr.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_cortex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_cortex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_def.h;Drivers\STM32G0xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_exti.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_exti.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_crc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_crc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_crc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dac.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_dac.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dac_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_iwdg.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_uart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_usart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_lpuart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_uart_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rtc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_rtc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rtc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_spi.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_spi_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_tim.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_tim_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_tim.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_wwdg.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_wwdg.h;Middlewares\Third_Party\FreeRTOS\Source\include\croutine.h;Middlewares\Third_Party\FreeRTOS\Source\include\deprecated_definitions.h;Middlewares\Third_Party\FreeRTOS\Source\include\event_groups.h;Middlewares\Third_Party\FreeRTOS\Source\include\FreeRTOS.h;Middlewares\Third_Party\FreeRTOS\Source\include\list.h;Middlewares\Third_Party\FreeRTOS\Source\include\message_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_prototypes.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_wrappers.h;Middlewares\Third_Party\FreeRTOS\Source\include\portable.h;Middlewares\Third_Party\FreeRTOS\Source\include\projdefs.h;Middlewares\Third_Party\FreeRTOS\Source\include\queue.h;Middlewares\Third_Party\FreeRTOS\Source\include\semphr.h;Middlewares\Third_Party\FreeRTOS\Source\include\stack_macros.h;Middlewares\Third_Party\FreeRTOS\Source\include\StackMacros.h;Middlewares\Third_Party\FreeRTOS\Source\include\stream_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\task.h;Middlewares\Third_Party\FreeRTOS\Source\include\timers.h;Middlewares\Third_Party\FreeRTOS\Source\include\atomic.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_mpool.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_os2.h;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM0\portmacro.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_dma.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_dmamux.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;Drivers\STM32G0xx_HAL_Driver\SLine truncated LibFiles=Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_bus.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_system.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_utils.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_crs.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ramfunc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gpio.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gpio_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_gpio.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dma.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_dma_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_pwr.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_pwr_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_pwr.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_cortex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_cortex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_def.h;Drivers\STM32G0xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_exti.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_exti.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_crc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_crc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_crc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_iwdg.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_uart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_usart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_lpuart.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_uart_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rtc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_rtc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rtc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_spi.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_spi_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_tim.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_tim_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_tim.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_wwdg.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_wwdg.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_dma.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_dmamux.h;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_adc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_adc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_rcc_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_rcc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_bus.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_system.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_utils.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_ll_crs.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ex.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_flash_ramfunc.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gpio.h;Drivers\STM32G0xx_HAL_Driver\Inc\stm32g0xx_hal_gLine truncated
[PreviousUsedIarFiles] [PreviousUsedIarFiles]
SourceFiles=..\Core\Src\main.c;..\Core\Src\stm32g0xx_it.c;..\Core\Src\stm32g0xx_hal_msp.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;;; SourceFiles=..\Core\Src\main.c;..\Core\Src\stm32g0xx_it.c;..\Core\Src\stm32g0xx_hal_msp.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;;;
@@ -7,49 +7,57 @@ HeaderPath=..\Drivers\STM32G0xx_HAL_Driver\Inc;..\Drivers\STM32G0xx_HAL_Driver\I
CDefines=USE_HAL_DRIVER;STM32G0B1xx;USE_HAL_DRIVER;USE_HAL_DRIVER; CDefines=USE_HAL_DRIVER;STM32G0B1xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousUsedKeilFiles] [PreviousUsedKeilFiles]
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\app_freertos.c;..\Core\Src\adc.c;..\Core\Src\crc.c;..\Core\Src\dac.c;..\Core\Src\dma.c;..\Core\Src\iwdg.c;..\Core\Src\usart.c;..\Core\Src\rtc.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\wwdg.c;..\Core\Src\stm32g0xx_it.c;..\Core\Src\stm32g0xx_hal_msp.c;..\Core\Src\stm32g0xx_hal_timebase_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM0\port.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dac_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_ParLine truncated SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\crc.c;..\Core\Src\dma.c;..\Core\Src\iwdg.c;..\Core\Src\usart.c;..\Core\Src\rtc.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\wwdg.c;..\Core\Src\stm32g0xx_it.c;..\Core\Src\stm32g0xx_hal_msp.c;..\Core\Src\stm32g0xx_hal_timebase_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_adc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_adc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rcc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_rcc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_flash_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_gpio.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_dma_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_ll_dma.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_pwr_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_cortex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_exti.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_crc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_iwdg.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_rtc_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_spi_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_tim_ex.c;..\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_wwdg.c;..\Drivers\CMSIS\Device\ST\STM32G0xx\Source\Templates\system_stm32g0xx.c;..\Core\Src\system_stm32g0xx.c;;;
HeaderPath=..\Drivers\STM32G0xx_HAL_Driver\Inc;..\Drivers\STM32G0xx_HAL_Driver\Inc\Legacy;..\Middlewares\Third_Party\FreeRTOS\Source\include;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM0;..\Drivers\CMSIS\Device\ST\STM32G0xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc; HeaderPath=..\Drivers\STM32G0xx_HAL_Driver\Inc;..\Drivers\STM32G0xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32G0xx\Include;..\Drivers\CMSIS\Include;..\Middlewares\Third_Party\RealThread_RTOS\include\;..\Middlewares\Third_Party\RealThread_RTOS\bsp\_template\cubemx_config;..\Core\Inc;..\RT-Thread;
CDefines=CMSIS_device_header:<stm32g0xx.h>;USE_HAL_DRIVER;STM32G0B1xx;USE_HAL_DRIVER;USE_HAL_DRIVER; CDefines=USE_HAL_DRIVER;STM32G0B1xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousGenFiles] [PreviousGenFiles]
AdvancedFolderStructure=true AdvancedFolderStructure=true
HeaderFileListSize=15 HeaderFileListSize=14
HeaderFiles#0=..\Core\Inc\gpio.h HeaderFiles#0=..\Core\Inc\gpio.h
HeaderFiles#1=..\Core\Inc\FreeRTOSConfig.h HeaderFiles#1=..\RT-Thread\rtconfig.h
HeaderFiles#2=..\Core\Inc\adc.h HeaderFiles#2=..\Core\Inc\adc.h
HeaderFiles#3=..\Core\Inc\crc.h HeaderFiles#3=..\Core\Inc\crc.h
HeaderFiles#4=..\Core\Inc\dac.h HeaderFiles#4=..\Core\Inc\dma.h
HeaderFiles#5=..\Core\Inc\dma.h HeaderFiles#5=..\Core\Inc\iwdg.h
HeaderFiles#6=..\Core\Inc\iwdg.h HeaderFiles#6=..\Core\Inc\usart.h
HeaderFiles#7=..\Core\Inc\usart.h HeaderFiles#7=..\Core\Inc\rtc.h
HeaderFiles#8=..\Core\Inc\rtc.h HeaderFiles#8=..\Core\Inc\spi.h
HeaderFiles#9=..\Core\Inc\spi.h HeaderFiles#9=..\Core\Inc\tim.h
HeaderFiles#10=..\Core\Inc\tim.h HeaderFiles#10=..\Core\Inc\wwdg.h
HeaderFiles#11=..\Core\Inc\wwdg.h HeaderFiles#11=..\Core\Inc\stm32g0xx_it.h
HeaderFiles#12=..\Core\Inc\stm32g0xx_it.h HeaderFiles#12=..\Core\Inc\stm32g0xx_hal_conf.h
HeaderFiles#13=..\Core\Inc\stm32g0xx_hal_conf.h HeaderFiles#13=..\Core\Inc\main.h
HeaderFiles#14=..\Core\Inc\main.h HeaderFolderListSize=2
HeaderFolderListSize=1
HeaderPath#0=..\Core\Inc HeaderPath#0=..\Core\Inc
HeaderPath#1=..\RT-Thread
HeaderFiles=; HeaderFiles=;
SourceFileListSize=16 SourceFileListSize=14
SourceFiles#0=..\Core\Src\gpio.c SourceFiles#0=..\Core\Src\gpio.c
SourceFiles#1=..\Core\Src\app_freertos.c SourceFiles#1=..\Core\Src\adc.c
SourceFiles#2=..\Core\Src\adc.c SourceFiles#2=..\Core\Src\crc.c
SourceFiles#3=..\Core\Src\crc.c SourceFiles#3=..\Core\Src\dma.c
SourceFiles#4=..\Core\Src\dac.c SourceFiles#4=..\Core\Src\iwdg.c
SourceFiles#5=..\Core\Src\dma.c SourceFiles#5=..\Core\Src\usart.c
SourceFiles#6=..\Core\Src\iwdg.c SourceFiles#6=..\Core\Src\rtc.c
SourceFiles#7=..\Core\Src\usart.c SourceFiles#7=..\Core\Src\spi.c
SourceFiles#8=..\Core\Src\rtc.c SourceFiles#8=..\Core\Src\tim.c
SourceFiles#9=..\Core\Src\spi.c SourceFiles#9=..\Core\Src\wwdg.c
SourceFiles#10=..\Core\Src\tim.c SourceFiles#10=..\Core\Src\stm32g0xx_it.c
SourceFiles#11=..\Core\Src\wwdg.c SourceFiles#11=..\Core\Src\stm32g0xx_hal_msp.c
SourceFiles#12=..\Core\Src\stm32g0xx_it.c SourceFiles#12=..\Core\Src\stm32g0xx_hal_timebase_tim.c
SourceFiles#13=..\Core\Src\stm32g0xx_hal_msp.c SourceFiles#13=..\Core\Src\main.c
SourceFiles#14=..\Core\Src\stm32g0xx_hal_timebase_tim.c
SourceFiles#15=..\Core\Src\main.c
SourceFolderListSize=1 SourceFolderListSize=1
SourcePath#0=..\Core\Src SourcePath#0=..\Core\Src
SourceFiles=; SourceFiles=;
[ThirdPartyIp]
ThirdPartyIpNumber=1
ThirdPartyIpName#0=RealThread.RT-Thread.3.1.5
[ThirdPartyIp#RealThread.RT-Thread.3.1.5]
include=..\Middlewares\Third_Party\RealThread_RTOS\include;
sourceAsm=..\Middlewares\Third_Party\RealThread_RTOS\libcpu\arm\cortex-m0\context_rvds.S;
header=..\Middlewares\Third_Party\RealThread_RTOS\bsp\_template\cubemx_config\rtconfig.h;
source=..\Middlewares\Third_Party\RealThread_RTOS\src\clock.c;..\Middlewares\Third_Party\RealThread_RTOS\src\components.c;..\Middlewares\Third_Party\RealThread_RTOS\src\cpu.c;..\Middlewares\Third_Party\RealThread_RTOS\src\idle.c;..\Middlewares\Third_Party\RealThread_RTOS\src\ipc.c;..\Middlewares\Third_Party\RealThread_RTOS\src\irq.c;..\Middlewares\Third_Party\RealThread_RTOS\src\kservice.c;..\Middlewares\Third_Party\RealThread_RTOS\src\mem.c;..\Middlewares\Third_Party\RealThread_RTOS\src\memheap.c;..\Middlewares\Third_Party\RealThread_RTOS\src\mempool.c;..\Middlewares\Third_Party\RealThread_RTOS\src\object.c;..\Middlewares\Third_Party\RealThread_RTOS\src\scheduler.c;..\Middlewares\Third_Party\RealThread_RTOS\src\slab.c;..\Middlewares\Third_Party\RealThread_RTOS\src\thread.c;..\Middlewares\Third_Party\RealThread_RTOS\src\timer.c;..\Middlewares\Third_Party\RealThread_RTOS\libcpu\arm\cortex-m0\cpuport.c;..\Middlewares\Third_Party\RealThread_RTOS\bsp\_template\cubemx_config\board.c;..\Middlewares\Third_Party\RealThread_RTOS\components\device\device.c;
+62
View File
@@ -0,0 +1,62 @@
#include "usart-board.h"
UartDrv_t g_DebugDrv; // 调试串口驱动
UartDrv_t g_U4851Drv; // 4851 驱动
UartDrv_t g_U4852Drv; // 4852 驱动
UartDrv_t g_U4853Drv; // 4853 驱动
UartDrv_t g_ViewDrv; // View 驱动
UartDrv_t g_ETH1Drv; // 以太网通道1 驱动
UartDrv_t g_ETH2Drv; // 以太网通道1 驱动
UartDrv_t g_GSMDrv; // 以太网通道1 驱动
UartDrv_t g_LoRaDrv; // LoRa 模块驱动
/********************************************
函数名称:UartInfoInit
输入参数:串口句柄
输出参数:NULL
功能描述:初始化一个串口
********************************************/
void UartInfoInit()
{
}
void RelayInfoInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = RelayInfo.Relay1.mode;
GPIO_InitStruct.Pull = RelayInfo.Relay1.Pull;
GPIO_InitStruct.Speed = RelayInfo.Relay1.Speed;
GPIO_InitStruct.Pin = RelayInfo.Relay1.pin;
HAL_GPIO_Init (RelayInfo.Relay1.GPIOx, &GPIO_InitStruct);
HAL_GPIO_WritePin(RelayInfo.Relay1.GPIOx,RelayInfo.Relay1.pin,GPIO_PIN_RESET);
GPIO_InitStruct.Mode = RelayInfo.Relay2.mode;
GPIO_InitStruct.Pull = RelayInfo.Relay2.Pull;
GPIO_InitStruct.Speed = RelayInfo.Relay2.Speed;
GPIO_InitStruct.Pin = RelayInfo.Relay2.pin;
HAL_GPIO_Init (RelayInfo.Relay2.GPIOx, &GPIO_InitStruct);
HAL_GPIO_WritePin(RelayInfo.Relay2.GPIOx,RelayInfo.Relay2.pin,GPIO_PIN_RESET);
}
void RelayOpenDoor(void)
{
HAL_GPIO_WritePin(RelayInfo.Relay1.GPIOx,RelayInfo.Relay1.pin,GPIO_PIN_SET);
}
void RelayCloseDoor(void)
{
HAL_GPIO_WritePin(RelayInfo.Relay1.GPIOx,RelayInfo.Relay1.pin,GPIO_PIN_RESET);
}
void RelayOpenK2(void)
{
HAL_GPIO_WritePin(RelayInfo.Relay2.GPIOx,RelayInfo.Relay2.pin,GPIO_PIN_SET);
}
void RelayCloseK2(void)
{
HAL_GPIO_WritePin(RelayInfo.Relay2.GPIOx,RelayInfo.Relay2.pin,GPIO_PIN_RESET);
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef _UART_BOARD_H
#define _UART_BOARD_H
#include <stdint.h>
typedef enum UartId_t
{
LpUart1,
LpUart2,
Uart1,
Uart2,
Uart3,
Uart4,
Uart5,
Uart6,
}UartId_t;
typedef enum UartPara_t{
_8N1,
_8E1,
_8O1,
_7O1,
_7E1,
_7N1,
}UartPara_t;
typedef struct UartDrv_t
{
UartId_t Id;// 串口号
uint32_t BaudRate;// 波特率
UartPara_t Para; // 数据位
char * rx_buffer;
uint16_t rx_size;
uint32_t rx_ready;// 接受完成等待处理
}UartDrv_t;
#endif
+60 -31
View File
@@ -1,44 +1,73 @@
#include "FreeRTOS.h"
#include "task.h"
#include "main.h" #include "main.h"
#include "cmsis_os.h"
#include "os-app.h" #include "os-app.h"
#include <stdio.h> #include <stdio.h>
#include "modbus-m.h" #include <rtthread.h>
#include "net-app.h" #include <net-app.h>
#
osThreadId_t NetworkThreadHandle; // Óû§×Ô¶¨ÒåÏß³Ì ALIGN(RT_ALIGN_SIZE)
static char thread_stack[4096];
const osThreadAttr_t NetworkThread_attributes = { static struct rt_thread netapp_thread;
.name = "networkThread",
.priority = (osPriority_t) osPriorityLow,
.stack_size = 1024 * 4
};
static netWorkInterface_t s_interface;
enum { static enum {
netDrvInit = 0, // 初始化网络驱动
} netDrvJoin = 1, // 等待网络注册成功
netDrvSend = 2, // 发送数据
netDrvRecv = 3, // 读取数据
netDrvIdle = 4, // 读取数据
}eDrvStatus;
static netWorkInterface_t interface;
void NetworkTask(void * argument) static void thread_entry(void * argument)
{ {
if (s_interface.Init != NULL) eDrvStatus = netDrvInit;
{ rt_kprintf("%s was start!\r\n",__FILE__);
s_interface.Init(); // 注册网络驱动
} // 注册网络驱动
while (1) while (1)
{ {
switch (eDrvStatus)
{
osDelay(5000); case netDrvInit:
} break;
case netDrvJoin:
break;
case netDrvSend:
break;
case netDrvRecv:
break;
case netDrvIdle:
break;
default :
break;
}
rt_thread_delay(10);
}
}
void NET_APPThreadStart(void )
{
/* 创建线程1,名称是thread1,入口是thread1_entry*/
rt_thread_init(&netapp_thread, "netapp_thread",
thread_entry, RT_NULL,
&thread_stack[0],
sizeof(thread_stack),
NET_APP_THREAD_PRIORITY, NET_APP_THREAD_TIMESLICE);
rt_thread_startup(&netapp_thread);
return ;
} }
-146
View File
@@ -1,146 +0,0 @@
/* USER CODE BEGIN Header */
/*
* FreeRTOS Kernel V10.3.1
* Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* USER CODE END Header */
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#ifndef CMSIS_device_header
#define CMSIS_device_header "stm32g0xx.h"
#endif /* CMSIS_device_header */
#define configENABLE_FPU 0
#define configENABLE_MPU 0
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)20480)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 256
/* CMSIS-RTOS V2 flags */
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
#define configUSE_OS2_THREAD_ENUMERATE 1
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
#define configUSE_OS2_THREAD_FLAGS 1
#define configUSE_OS2_TIMER 1
#define configUSE_OS2_MUTEX 1
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
/* USER CODE END Defines */
#endif /* FREERTOS_CONFIG_H */
-52
View File
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dac.h
* @brief This file contains all the function prototypes for
* the dac.c file
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DAC_H__
#define __DAC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern DAC_HandleTypeDef hdac1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DAC1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DAC_H__ */
+1 -1
View File
@@ -39,7 +39,7 @@ extern "C" {
/* #define HAL_COMP_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */
#define HAL_CRC_MODULE_ENABLED #define HAL_CRC_MODULE_ENABLED
/* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */
#define HAL_DAC_MODULE_ENABLED /* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_EXTI_MODULE_ENABLED */
/* #define HAL_FDCAN_MODULE_ENABLED */ /* #define HAL_FDCAN_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */
-1
View File
@@ -47,7 +47,6 @@
/* Exported functions prototypes ---------------------------------------------*/ /* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void); void NMI_Handler(void);
void HardFault_Handler(void);
void DMA1_Channel1_IRQHandler(void); void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel2_3_IRQHandler(void); void DMA1_Channel2_3_IRQHandler(void);
void DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQHandler(void); void DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQHandler(void);
+1 -1
View File
@@ -44,7 +44,7 @@ extern "C" {
#define LPUART_MAX_LENGTH 1200 #define LPUART_MAX_LENGTH 1200
#define USART1_MAX_LENGTH 1200 #define USART1_MAX_LENGTH 1200
#define USART2_MAX_LENGTH 1200 #define USART2_MAX_LENGTH 1200
#define USART4_MAX_LENGTH 1200 // 以太� #define USART4_MAX_LENGTH 1200 //
#define USART5_MAX_LENGTH 255 #define USART5_MAX_LENGTH 255
-149
View File
@@ -1,149 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : app_freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "os-app.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
typedef StaticEventGroup_t osStaticEventGroupDef_t;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
extern osThreadId_t osAppThreadHandle;
extern const osThreadAttr_t osAppThread_attributes;
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 128 * 4
};
/* Definitions for SYSTEM_EVENT */
osEventFlagsId_t SYSTEM_EVENTHandle;
osStaticEventGroupDef_t SysEventControlBlock;
const osEventFlagsAttr_t SYSTEM_EVENT_attributes = {
.name = "SYSTEM_EVENT",
.cb_mem = &SysEventControlBlock,
.cb_size = sizeof(SysEventControlBlock),
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
osAppThreadHandle = osThreadNew(MainTask, NULL, &osAppThread_attributes);
//osThreadDef (maintask, MainTask, osPriorityIdle, 0, 1024);
//MainHandle = osThreadCreate (osThread (maintask), NULL);
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* Create the event(s) */
/* creation of SYSTEM_EVENT */
SYSTEM_EVENTHandle = osEventFlagsNew(&SYSTEM_EVENT_attributes);
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for (;;)
{
//USART2->TDR = 0x31;
osDelay (1000);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
+1 -1
View File
@@ -39,7 +39,7 @@ void MX_CRC_Init(void)
hcrc.Instance = CRC; hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
hcrc.Init.GeneratingPolynomial = 0X8005; hcrc.Init.GeneratingPolynomial = 7;
hcrc.Init.CRCLength = CRC_POLYLENGTH_16B; hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
hcrc.Init.InitValue = 0xFFFF; hcrc.Init.InitValue = 0xFFFF;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
-180
View File
@@ -1,180 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dac.c
* @brief This file provides code for the configuration
* of the DAC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dac.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
DAC_HandleTypeDef hdac1;
/* DAC1 init function */
void MX_DAC1_Init(void)
{
/* USER CODE BEGIN DAC1_Init 0 */
/* USER CODE END DAC1_Init 0 */
DAC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN DAC1_Init 1 */
/* USER CODE END DAC1_Init 1 */
/** DAC Initialization
*/
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler();
}
/** DAC channel OUT1 config
*/
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/** DAC channel OUT2 config
*/
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DAC1_Init 2 */
if (HAL_DAC_Start (&hdac1, DAC_CHANNEL_1) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/*##-4- Set DAC channel1 DHR12RD register ################################################*/
if (HAL_DAC_SetValue (&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2500) != HAL_OK)
{
/* Setting value Error */
Error_Handler();
}
if (HAL_DAC_Start (&hdac1, DAC_CHANNEL_2) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/*##-4- Set DAC channel1 DHR12RD register ################################################*/
if (HAL_DAC_SetValue (&hdac1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 2500) != HAL_OK)
{
/* Setting value Error */
Error_Handler();
}
/* USER CODE END DAC1_Init 2 */
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(dacHandle->Instance==DAC1)
{
/* USER CODE BEGIN DAC1_MspInit 0 */
/* USER CODE END DAC1_MspInit 0 */
/* DAC1 clock enable */
__HAL_RCC_DAC1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**DAC1 GPIO Configuration
PA4 ------> DAC1_OUT1
PA5 ------> DAC1_OUT2
*/
GPIO_InitStruct.Pin = DAC1_Pin|DAC2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN DAC1_MspInit 1 */
/* USER CODE END DAC1_MspInit 1 */
}
}
void HAL_DAC_MspDeInit(DAC_HandleTypeDef* dacHandle)
{
if(dacHandle->Instance==DAC1)
{
/* USER CODE BEGIN DAC1_MspDeInit 0 */
/* USER CODE END DAC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_DAC1_CLK_DISABLE();
/**DAC1 GPIO Configuration
PA4 ------> DAC1_OUT1
PA5 ------> DAC1_OUT2
*/
HAL_GPIO_DeInit(GPIOA, DAC1_Pin|DAC2_Pin);
/* USER CODE BEGIN DAC1_MspDeInit 1 */
/* USER CODE END DAC1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
// ÉèÖÃvalue
void MX_DAC_SET_VALUE (int channel, uint16_t value)
{
switch (channel)
{
case 1:
if (HAL_DAC_SetValue (&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value) != HAL_OK)
{
/* Setting value Error */
Error_Handler();
}
break;
case 2:
if (HAL_DAC_SetValue (&hdac1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value) != HAL_OK)
{
/* Setting value Error */
Error_Handler();
}
break;
default :
break;
}
}
/* USER CODE END 1 */
+3 -3
View File
@@ -44,13 +44,13 @@ void MX_DMA_Init(void)
/* DMA interrupt init */ /* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */ /* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 3, 0); HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_3_IRQn interrupt configuration */ /* DMA1_Channel2_3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3, 0); HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
/* DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn interrupt configuration */ /* DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn, 3, 0); HAL_NVIC_SetPriority(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn); HAL_NVIC_EnableIRQ(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn);
} }
+8
View File
@@ -38,6 +38,8 @@
* Output * Output
* EVENT_OUT * EVENT_OUT
* EXTI * EXTI
PA4 ------> COMP_DAC11_group
PA5 ------> COMP_DAC12_group
*/ */
void MX_GPIO_Init(void) void MX_GPIO_Init(void)
{ {
@@ -81,6 +83,12 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ETH_STA_GPIO_Port, &GPIO_InitStruct); HAL_GPIO_Init(ETH_STA_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PAPin PAPin */
GPIO_InitStruct.Pin = DAC1_Pin|DAC2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PBPin PBPin PBPin */ /*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Pin = U485_RT_Pin|LORA_TX_Pin|LORA_RX_Pin|SPI2_NSS_Pin; GPIO_InitStruct.Pin = U485_RT_Pin|LORA_TX_Pin|LORA_RX_Pin|SPI2_NSS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+2 -14
View File
@@ -18,10 +18,8 @@
/* USER CODE END Header */ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "main.h"
#include "cmsis_os.h"
#include "adc.h" #include "adc.h"
#include "crc.h" #include "crc.h"
#include "dac.h"
#include "dma.h" #include "dma.h"
#include "iwdg.h" #include "iwdg.h"
#include "usart.h" #include "usart.h"
@@ -33,7 +31,7 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include <rtthread.h>
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
@@ -58,7 +56,6 @@
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
/* USER CODE END PFP */ /* USER CODE END PFP */
@@ -99,7 +96,6 @@ int main(void)
MX_DMA_Init(); MX_DMA_Init();
MX_ADC1_Init(); MX_ADC1_Init();
MX_CRC_Init(); MX_CRC_Init();
MX_DAC1_Init();
MX_IWDG_Init(); MX_IWDG_Init();
MX_LPUART1_UART_Init(); MX_LPUART1_UART_Init();
MX_LPUART2_UART_Init(); MX_LPUART2_UART_Init();
@@ -119,17 +115,9 @@ int main(void)
MX_SPI2_Init(); MX_SPI2_Init();
MX_TIM15_Init(); MX_TIM15_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
// ³õʼÍê³É ͨ¹ýÏÖ³É
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
while (1) while (1)
+1 -1
View File
@@ -96,7 +96,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI2 interrupt Init */ /* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_3_IRQn, 3, 0); HAL_NVIC_SetPriority(SPI2_3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI2_3_IRQn); HAL_NVIC_EnableIRQ(SPI2_3_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE BEGIN SPI2_MspInit 1 */
-2
View File
@@ -70,8 +70,6 @@ void HAL_MspInit(void)
__HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/ /* System interrupt init*/
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 3, 0);
/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
*/ */
+2 -17
View File
@@ -75,7 +75,7 @@ extern TIM_HandleTypeDef htim2;
/* USER CODE BEGIN EV */ /* USER CODE BEGIN EV */
extern void MX_UART_IRQHandle (void); extern void MX_UART_IRQHandle (void);
extern void uart_SystemTick (void); extern void uart_SystemTick (void);
extern void main_Systick (void); //extern void main_Systick (void);
/* USER CODE END EV */ /* USER CODE END EV */
/******************************************************************************/ /******************************************************************************/
@@ -96,21 +96,6 @@ void NMI_Handler(void)
/* USER CODE END NonMaskableInt_IRQn 1 */ /* USER CODE END NonMaskableInt_IRQn 1 */
} }
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/******************************************************************************/ /******************************************************************************/
/* STM32G0xx Peripheral Interrupt Handlers */ /* STM32G0xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */ /* Add here the Interrupt Handlers for the used peripherals. */
@@ -169,7 +154,7 @@ void TIM2_IRQHandler(void)
{ {
/* USER CODE BEGIN TIM2_IRQn 0 */ /* USER CODE BEGIN TIM2_IRQn 0 */
uart_SystemTick(); uart_SystemTick();
main_Systick(); //main_Systick();
MX_IWDG_Reload(); MX_IWDG_Reload();
MX_WWDG_Relad(); MX_WWDG_Relad();
/* USER CODE END TIM2_IRQn 0 */ /* USER CODE END TIM2_IRQn 0 */
+2 -2
View File
@@ -399,7 +399,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
__HAL_RCC_TIM7_CLK_ENABLE(); __HAL_RCC_TIM7_CLK_ENABLE();
/* TIM7 interrupt Init */ /* TIM7 interrupt Init */
HAL_NVIC_SetPriority(TIM7_LPTIM2_IRQn, 3, 0); HAL_NVIC_SetPriority(TIM7_LPTIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM7_LPTIM2_IRQn); HAL_NVIC_EnableIRQ(TIM7_LPTIM2_IRQn);
/* USER CODE BEGIN TIM7_MspInit 1 */ /* USER CODE BEGIN TIM7_MspInit 1 */
@@ -415,7 +415,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
__HAL_RCC_TIM14_CLK_ENABLE(); __HAL_RCC_TIM14_CLK_ENABLE();
/* TIM14 interrupt Init */ /* TIM14 interrupt Init */
HAL_NVIC_SetPriority(TIM14_IRQn, 3, 0); HAL_NVIC_SetPriority(TIM14_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM14_IRQn); HAL_NVIC_EnableIRQ(TIM14_IRQn);
/* USER CODE BEGIN TIM14_MspInit 1 */ /* USER CODE BEGIN TIM14_MspInit 1 */
+8 -8
View File
@@ -427,7 +427,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
__HAL_LINKDMA(uartHandle,hdmarx,hdma_lpuart1_rx); __HAL_LINKDMA(uartHandle,hdmarx,hdma_lpuart1_rx);
/* LPUART1 interrupt Init */ /* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn); HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspInit 1 */ /* USER CODE BEGIN LPUART1_MspInit 1 */
@@ -464,7 +464,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* LPUART2 interrupt Init */ /* LPUART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_LPUART2_IRQn, 3, 0); HAL_NVIC_SetPriority(USART2_LPUART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_LPUART2_IRQn); HAL_NVIC_EnableIRQ(USART2_LPUART2_IRQn);
/* USER CODE BEGIN LPUART2_MspInit 1 */ /* USER CODE BEGIN LPUART2_MspInit 1 */
@@ -501,7 +501,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USART1 interrupt Init */ /* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE BEGIN USART1_MspInit 1 */
@@ -538,7 +538,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */ /* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_LPUART2_IRQn, 3, 0); HAL_NVIC_SetPriority(USART2_LPUART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_LPUART2_IRQn); HAL_NVIC_EnableIRQ(USART2_LPUART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE BEGIN USART2_MspInit 1 */
@@ -575,7 +575,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USART3 interrupt Init */ /* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn); HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */ /* USER CODE BEGIN USART3_MspInit 1 */
@@ -603,7 +603,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART4 interrupt Init */ /* USART4 interrupt Init */
HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn); HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn);
/* USER CODE BEGIN USART4_MspInit 1 */ /* USER CODE BEGIN USART4_MspInit 1 */
@@ -631,7 +631,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USART5 interrupt Init */ /* USART5 interrupt Init */
HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn); HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn);
/* USER CODE BEGIN USART5_MspInit 1 */ /* USER CODE BEGIN USART5_MspInit 1 */
@@ -659,7 +659,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART6 interrupt Init */ /* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 3, 0); HAL_NVIC_SetPriority(USART3_4_5_6_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn); HAL_NVIC_EnableIRQ(USART3_4_5_6_LPUART1_IRQn);
/* USER CODE BEGIN USART6_MspInit 1 */ /* USER CODE BEGIN USART6_MspInit 1 */
+63 -68
View File
@@ -30,14 +30,6 @@ CRC.IPParameters=InputDataInversionMode,OutputDataInversionMode,DefaultPolynomia
CRC.InitValue=0xFFFF CRC.InitValue=0xFFFF
CRC.InputDataInversionMode=CRC_INPUTDATA_INVERSION_BYTE CRC.InputDataInversionMode=CRC_INPUTDATA_INVERSION_BYTE
CRC.OutputDataInversionMode=CRC_OUTPUTDATA_INVERSION_ENABLE CRC.OutputDataInversionMode=CRC_OUTPUTDATA_INVERSION_ENABLE
DAC1.DAC2_OutputBuffer-DAC_OUT2_ExtAndInt=DAC_OUTPUTBUFFER_ENABLE
DAC1.DAC_Channel-DAC_OUT1_ExtAndInt=DAC_CHANNEL_1
DAC1.DAC_Channel-DAC_OUT2_ExtAndInt=DAC_CHANNEL_2
DAC1.DAC_SampleAndHold-DAC_OUT1_ExtAndInt=DAC_SAMPLEANDHOLD_DISABLE
DAC1.DAC_SampleAndHold-DAC_OUT2_ExtAndInt=DAC_SAMPLEANDHOLD_DISABLE
DAC1.DAC_Trigger-DAC_OUT1_ExtAndInt=DAC_TRIGGER_NONE
DAC1.DAC_Trigger-DAC_OUT2_ExtAndInt=DAC_TRIGGER_NONE
DAC1.IPParameters=DAC_Channel-DAC_OUT2_ExtAndInt,DAC_Channel-DAC_OUT1_ExtAndInt,DAC_SampleAndHold-DAC_OUT1_ExtAndInt,DAC_SampleAndHold-DAC_OUT2_ExtAndInt,DAC2_OutputBuffer-DAC_OUT2_ExtAndInt,DAC_Trigger-DAC_OUT1_ExtAndInt,DAC_Trigger-DAC_OUT2_ExtAndInt
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.EventEnable=DISABLE Dma.ADC1.0.EventEnable=DISABLE
Dma.ADC1.0.Instance=DMA1_Channel1 Dma.ADC1.0.Instance=DMA1_Channel1
@@ -75,13 +67,6 @@ Dma.LPUART1_RX.1.SyncSignalID=NONE
Dma.Request0=ADC1 Dma.Request0=ADC1
Dma.Request1=LPUART1_RX Dma.Request1=LPUART1_RX
Dma.RequestsNb=2 Dma.RequestsNb=2
FREERTOS.Events01=SYSTEM_EVENT,Static,SysEventControlBlock
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,configUSE_TIMERS,Events01,FootprintOK,configUSE_STATS_FORMATTING_FUNCTIONS
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.configTOTAL_HEAP_SIZE=20480
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
FREERTOS.configUSE_TIMERS=1
File.Version=6 File.Version=6
GPIO.groupedBy=Group By Peripherals GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false KeepUserPlacement=false
@@ -89,31 +74,29 @@ Mcu.CPN=STM32G0B1VET6
Mcu.Family=STM32G0 Mcu.Family=STM32G0
Mcu.IP0=ADC1 Mcu.IP0=ADC1
Mcu.IP1=CRC Mcu.IP1=CRC
Mcu.IP10=RTC Mcu.IP10=SYS
Mcu.IP11=SPI2 Mcu.IP11=TIM1
Mcu.IP12=SYS Mcu.IP12=TIM3
Mcu.IP13=TIM1 Mcu.IP13=TIM6
Mcu.IP14=TIM3 Mcu.IP14=TIM7
Mcu.IP15=TIM6 Mcu.IP15=TIM14
Mcu.IP16=TIM7 Mcu.IP16=TIM15
Mcu.IP17=TIM14 Mcu.IP17=USART1
Mcu.IP18=TIM15 Mcu.IP18=USART2
Mcu.IP19=USART1 Mcu.IP19=USART3
Mcu.IP2=DAC1 Mcu.IP2=DMA
Mcu.IP20=USART2 Mcu.IP20=USART4
Mcu.IP21=USART3 Mcu.IP21=USART5
Mcu.IP22=USART4 Mcu.IP22=USART6
Mcu.IP23=USART5 Mcu.IP23=WWDG
Mcu.IP24=USART6 Mcu.IP3=IWDG
Mcu.IP25=WWDG Mcu.IP4=LPUART1
Mcu.IP3=DMA Mcu.IP5=LPUART2
Mcu.IP4=FREERTOS Mcu.IP6=NVIC
Mcu.IP5=IWDG Mcu.IP7=RCC
Mcu.IP6=LPUART1 Mcu.IP8=RTC
Mcu.IP7=LPUART2 Mcu.IP9=SPI2
Mcu.IP8=NVIC Mcu.IPNb=24
Mcu.IP9=RCC
Mcu.IPNb=26
Mcu.Name=STM32G0B1V(B-C-E)Tx Mcu.Name=STM32G0B1V(B-C-E)Tx
Mcu.Package=LQFP100 Mcu.Package=LQFP100
Mcu.Pin0=PB9 Mcu.Pin0=PB9
@@ -170,46 +153,48 @@ Mcu.Pin54=PB7
Mcu.Pin55=PB8 Mcu.Pin55=PB8
Mcu.Pin56=VP_ADC1_TempSens_Input Mcu.Pin56=VP_ADC1_TempSens_Input
Mcu.Pin57=VP_CRC_VS_CRC Mcu.Pin57=VP_CRC_VS_CRC
Mcu.Pin58=VP_FREERTOS_VS_CMSIS_V2 Mcu.Pin58=VP_IWDG_VS_IWDG
Mcu.Pin59=VP_IWDG_VS_IWDG Mcu.Pin59=VP_RTC_VS_RTC_Activate
Mcu.Pin6=PC12 Mcu.Pin6=PC12
Mcu.Pin60=VP_RTC_VS_RTC_Activate Mcu.Pin60=VP_SYS_VS_tim2
Mcu.Pin61=VP_SYS_VS_tim2 Mcu.Pin61=VP_SYS_VS_DBSignals
Mcu.Pin62=VP_SYS_VS_DBSignals Mcu.Pin62=VP_TIM6_VS_ClockSourceINT
Mcu.Pin63=VP_TIM6_VS_ClockSourceINT Mcu.Pin63=VP_TIM7_VS_ClockSourceINT
Mcu.Pin64=VP_TIM7_VS_ClockSourceINT Mcu.Pin64=VP_TIM14_VS_ClockSourceINT
Mcu.Pin65=VP_TIM14_VS_ClockSourceINT Mcu.Pin65=VP_WWDG_VS_WWDG
Mcu.Pin66=VP_WWDG_VS_WWDG Mcu.Pin66=VP_RealThread.RT-Thread_VS_RTOSJjkernel_3.1.5_3.1.5
Mcu.Pin67=VP_RealThread.RT-Thread_VS_RTOSJjdevice_3.1.5_3.1.5
Mcu.Pin7=PC13 Mcu.Pin7=PC13
Mcu.Pin8=PC14-OSC32_IN (PC14) Mcu.Pin8=PC14-OSC32_IN (PC14)
Mcu.Pin9=PC15-OSC32_OUT (PC15) Mcu.Pin9=PC15-OSC32_OUT (PC15)
Mcu.PinsNb=67 Mcu.PinsNb=68
Mcu.ThirdPartyNb=0 Mcu.ThirdParty0=RealThread.RT-Thread.3.1.5
Mcu.ThirdPartyNb=1
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32G0B1VETx Mcu.UserName=STM32G0B1VETx
MxCube.Version=6.7.0 MxCube.Version=6.7.0
MxDb.Version=DB.6.0.70 MxDb.Version=DB.6.0.70
NVIC.DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn=true\:3\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.DMA1_Channel1_IRQn=true\:3\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.DMA1_Channel2_3_IRQn=true\:3\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA1_Channel2_3_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.ForceEnableDMAVector=true NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.PendSV_IRQn=true\:3\:0\:false\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SPI2_3_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.SPI2_3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
NVIC.SVC_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:true NVIC.SVC_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:true
NVIC.SavedPendsvIrqHandlerGenerated=true NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:3\:0\:false\:false\:false\:true\:false\:true\:false NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:true\:false
NVIC.TIM14_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.TIM14_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
NVIC.TIM2_IRQn=true\:3\:0\:false\:false\:true\:false\:false\:true\:true NVIC.TIM2_IRQn=true\:3\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TIM7_LPTIM2_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.TIM7_LPTIM2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
NVIC.TimeBase=TIM2_IRQn NVIC.TimeBase=TIM2_IRQn
NVIC.TimeBaseIP=TIM2 NVIC.TimeBaseIP=TIM2
NVIC.USART1_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
NVIC.USART2_LPUART2_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.USART2_LPUART2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
NVIC.USART3_4_5_6_LPUART1_IRQn=true\:3\:0\:false\:false\:true\:true\:true\:true\:true NVIC.USART3_4_5_6_LPUART1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true\:true
PA0.GPIOParameters=GPIO_Label PA0.GPIOParameters=GPIO_Label
PA0.GPIO_Label=ADC1 PA0.GPIO_Label=ADC1
PA0.Locked=true PA0.Locked=true
@@ -466,7 +451,7 @@ ProjectManager.StackSize=0x2000
ProjectManager.TargetToolchain=MDK-ARM V5.32 ProjectManager.TargetToolchain=MDK-ARM V5.32
ProjectManager.ToolChainLocation= ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_CRC_Init-CRC-false-HAL-true,6-MX_DAC1_Init-DAC1-false-HAL-true,7-MX_IWDG_Init-IWDG-false-HAL-true,8-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,9-MX_LPUART2_UART_Init-LPUART2-false-HAL-true,10-MX_USART1_UART_Init-USART1-false-HAL-true,11-MX_USART2_UART_Init-USART2-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_USART4_UART_Init-USART4-false-HAL-true,14-MX_USART5_UART_Init-USART5-false-HAL-true,15-MX_USART6_UART_Init-USART6-false-HAL-true,16-MX_RTC_Init-RTC-false-HAL-true,17-MX_TIM1_Init-TIM1-false-HAL-true,18-MX_TIM3_Init-TIM3-false-HAL-true,19-MX_WWDG_Init-WWDG-false-HAL-true,20-MX_TIM6_Init-TIM6-false-HAL-true,21-MX_TIM7_Init-TIM7-false-HAL-true,22-MX_TIM14_Init-TIM14-false-HAL-true,23-MX_SPI2_Init-SPI2-false-HAL-true,24-MX_TIM15_Init-TIM15-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_CRC_Init-CRC-false-HAL-true,6-MX_IWDG_Init-IWDG-false-HAL-true,7-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,8-MX_LPUART2_UART_Init-LPUART2-false-HAL-true,9-MX_USART1_UART_Init-USART1-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_USART4_UART_Init-USART4-false-HAL-true,13-MX_USART5_UART_Init-USART5-false-HAL-true,14-MX_USART6_UART_Init-USART6-false-HAL-true,15-MX_RTC_Init-RTC-false-HAL-true,16-MX_TIM1_Init-TIM1-false-HAL-true,17-MX_TIM3_Init-TIM3-false-HAL-true,18-MX_WWDG_Init-WWDG-false-HAL-true,19-MX_TIM6_Init-TIM6-false-HAL-true,20-MX_TIM7_Init-TIM7-false-HAL-true,21-MX_TIM14_Init-TIM14-false-HAL-true,22-MX_SPI2_Init-SPI2-false-HAL-true,23-MX_TIM15_Init-TIM15-false-HAL-true
RCC.ADCFreq_Value=64000000 RCC.ADCFreq_Value=64000000
RCC.AHBFreq_Value=64000000 RCC.AHBFreq_Value=64000000
RCC.APBFreq_Value=64000000 RCC.APBFreq_Value=64000000
@@ -512,9 +497,17 @@ RCC.USART3Freq_Value=64000000
RCC.USBFreq_Value=48000000 RCC.USBFreq_Value=48000000
RCC.VCOInputFreq_Value=8000000 RCC.VCOInputFreq_Value=8000000
RCC.VCOOutputFreq_Value=128000000 RCC.VCOOutputFreq_Value=128000000
SH.COMP_DAC11_group.0=DAC1_OUT1,DAC_OUT1_ExtAndInt RealThread.RT-Thread.3.1.5.IPParameters=RTOSJjkernel,RTOSJjdevice,RT_MAIN_THREAD_STACK_SIZE
RealThread.RT-Thread.3.1.5.RTOSJjdevice=true
RealThread.RT-Thread.3.1.5.RTOSJjdevice_Checked=true
RealThread.RT-Thread.3.1.5.RTOSJjkernel=true
RealThread.RT-Thread.3.1.5.RTOSJjkernel_Checked=true
RealThread.RT-Thread.3.1.5.RTOSJjshell_Checked=false
RealThread.RT-Thread.3.1.5.RT_MAIN_THREAD_STACK_SIZE=4096
RealThread.RT-Thread.3.1.5_SwParameter=RTOSJjkernel\:true;RTOSJjshell\:true;RTOSJjdevice\:true;
SH.COMP_DAC11_group.0=DAC1_OUT1
SH.COMP_DAC11_group.ConfNb=1 SH.COMP_DAC11_group.ConfNb=1
SH.COMP_DAC12_group.0=DAC1_OUT2,DAC_OUT2_ExtAndInt SH.COMP_DAC12_group.0=DAC1_OUT2
SH.COMP_DAC12_group.ConfNb=1 SH.COMP_DAC12_group.ConfNb=1
SH.S_TIM15_CH1.0=TIM15_CH1,PWM Generation1 CH1 SH.S_TIM15_CH1.0=TIM15_CH1,PWM Generation1 CH1
SH.S_TIM15_CH1.ConfNb=1 SH.S_TIM15_CH1.ConfNb=1
@@ -577,12 +570,14 @@ VP_ADC1_TempSens_Input.Mode=IN-TempSens
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
VP_CRC_VS_CRC.Mode=CRC_Activate VP_CRC_VS_CRC.Mode=CRC_Activate
VP_CRC_VS_CRC.Signal=CRC_VS_CRC VP_CRC_VS_CRC.Signal=CRC_VS_CRC
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
VP_RealThread.RT-Thread_VS_RTOSJjdevice_3.1.5_3.1.5.Mode=RTOSJjdevice
VP_RealThread.RT-Thread_VS_RTOSJjdevice_3.1.5_3.1.5.Signal=RealThread.RT-Thread_VS_RTOSJjdevice_3.1.5_3.1.5
VP_RealThread.RT-Thread_VS_RTOSJjkernel_3.1.5_3.1.5.Mode=RTOSJjkernel
VP_RealThread.RT-Thread_VS_RTOSJjkernel_3.1.5_3.1.5.Signal=RealThread.RT-Thread_VS_RTOSJjkernel_3.1.5_3.1.5
VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals
VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals
VP_SYS_VS_tim2.Mode=TIM2 VP_SYS_VS_tim2.Mode=TIM2
File diff suppressed because it is too large. Load diff
+329 -239
View File
@@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>3</nTsel> <nTsel>4</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@@ -114,9 +114,14 @@
<tDlgDll></tDlgDll> <tDlgDll></tDlgDll>
<tDlgPa></tDlgPa> <tDlgPa></tDlgPa>
<tIfile></tIfile> <tIfile></tIfile>
<pMon>BIN\CMSIS_AGDI.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>JL2CM3</Key>
<Name>-U12456 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC8000 -FN1 -FF0STM32G0Bx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32G0B1VETx$CMSIS\Flash\STM32G0Bx_512.FLM)</Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>CMSIS_AGDI</Key> <Key>CMSIS_AGDI</Key>
@@ -135,7 +140,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>DLGTARM</Key> <Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)</Name> <Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@@ -145,10 +150,27 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>DLGUARM</Key> <Key>DLGUARM</Key>
<Name></Name> <Name>d</Name>
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>88</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>134248304</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>D:\Project\娴嬫帶涓€浣撻椄\GB01V\g0b1vetx-board\Core\Src\main.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\GB01VETx\../Core/Src/main.c\88</Expression>
</Bp>
</Breakpoint>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>
</Tracepoint> </Tracepoint>
@@ -238,18 +260,6 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>../Core/Src/app_freertos.c</PathWithFileName>
<FilenameWithoutPath>app_freertos.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>4</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Core/Src/adc.c</PathWithFileName> <PathWithFileName>../Core/Src/adc.c</PathWithFileName>
<FilenameWithoutPath>adc.c</FilenameWithoutPath> <FilenameWithoutPath>adc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -257,7 +267,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>5</FileNumber> <FileNumber>4</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -269,19 +279,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>6</FileNumber> <FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Core/Src/dac.c</PathWithFileName>
<FilenameWithoutPath>dac.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>7</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -293,7 +291,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>8</FileNumber> <FileNumber>6</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -305,7 +303,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>9</FileNumber> <FileNumber>7</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -317,7 +315,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>10</FileNumber> <FileNumber>8</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -329,7 +327,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>11</FileNumber> <FileNumber>9</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -341,7 +339,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>12</FileNumber> <FileNumber>10</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -353,7 +351,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>13</FileNumber> <FileNumber>11</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -365,7 +363,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>14</FileNumber> <FileNumber>12</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -377,7 +375,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>15</FileNumber> <FileNumber>13</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -389,7 +387,7 @@
</File> </File>
<File> <File>
<GroupNumber>1</GroupNumber> <GroupNumber>1</GroupNumber>
<FileNumber>16</FileNumber> <FileNumber>14</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -409,7 +407,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>2</GroupNumber> <GroupNumber>2</GroupNumber>
<FileNumber>17</FileNumber> <FileNumber>15</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -421,7 +419,7 @@
</File> </File>
<File> <File>
<GroupNumber>2</GroupNumber> <GroupNumber>2</GroupNumber>
<FileNumber>18</FileNumber> <FileNumber>16</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -433,7 +431,7 @@
</File> </File>
<File> <File>
<GroupNumber>2</GroupNumber> <GroupNumber>2</GroupNumber>
<FileNumber>19</FileNumber> <FileNumber>17</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -447,13 +445,13 @@
<Group> <Group>
<GroupName>midderware/easyfalsh</GroupName> <GroupName>midderware/easyfalsh</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber> <FileNumber>18</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -465,7 +463,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber> <FileNumber>19</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -477,7 +475,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber> <FileNumber>20</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -489,7 +487,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber> <FileNumber>21</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -501,7 +499,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber> <FileNumber>22</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -513,7 +511,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber> <FileNumber>23</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -527,13 +525,13 @@
<Group> <Group>
<GroupName>midderware/easylogger</GroupName> <GroupName>midderware/easylogger</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>26</FileNumber> <FileNumber>24</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -545,7 +543,7 @@
</File> </File>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>27</FileNumber> <FileNumber>25</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -557,7 +555,7 @@
</File> </File>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>28</FileNumber> <FileNumber>26</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -577,7 +575,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>5</GroupNumber> <GroupNumber>5</GroupNumber>
<FileNumber>29</FileNumber> <FileNumber>27</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -597,7 +595,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>30</FileNumber> <FileNumber>28</FileNumber>
<FileType>2</FileType> <FileType>2</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -609,7 +607,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>31</FileNumber> <FileNumber>29</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -623,13 +621,13 @@
<Group> <Group>
<GroupName>Drivers/STM32G0xx_HAL_Driver</GroupName> <GroupName>Drivers/STM32G0xx_HAL_Driver</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>32</FileNumber> <FileNumber>30</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -641,7 +639,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>33</FileNumber> <FileNumber>31</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -653,7 +651,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>34</FileNumber> <FileNumber>32</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -665,7 +663,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>35</FileNumber> <FileNumber>33</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -677,7 +675,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>36</FileNumber> <FileNumber>34</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -689,7 +687,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>37</FileNumber> <FileNumber>35</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -701,7 +699,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>38</FileNumber> <FileNumber>36</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -713,7 +711,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>39</FileNumber> <FileNumber>37</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -725,7 +723,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>40</FileNumber> <FileNumber>38</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -737,7 +735,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>41</FileNumber> <FileNumber>39</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -749,7 +747,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>42</FileNumber> <FileNumber>40</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -761,7 +759,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>43</FileNumber> <FileNumber>41</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -773,7 +771,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>44</FileNumber> <FileNumber>42</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -785,7 +783,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>45</FileNumber> <FileNumber>43</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -797,7 +795,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>46</FileNumber> <FileNumber>44</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -809,7 +807,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>47</FileNumber> <FileNumber>45</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -821,7 +819,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>48</FileNumber> <FileNumber>46</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -833,7 +831,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>49</FileNumber> <FileNumber>47</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -845,7 +843,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>50</FileNumber> <FileNumber>48</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -857,31 +855,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>51</FileNumber> <FileNumber>49</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dac.c</PathWithFileName>
<FilenameWithoutPath>stm32g0xx_hal_dac.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>52</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dac_ex.c</PathWithFileName>
<FilenameWithoutPath>stm32g0xx_hal_dac_ex.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>53</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -893,7 +867,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>54</FileNumber> <FileNumber>50</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -905,7 +879,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>55</FileNumber> <FileNumber>51</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -917,7 +891,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>56</FileNumber> <FileNumber>52</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -929,7 +903,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>57</FileNumber> <FileNumber>53</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -941,7 +915,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>58</FileNumber> <FileNumber>54</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -953,7 +927,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>59</FileNumber> <FileNumber>55</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -965,7 +939,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>60</FileNumber> <FileNumber>56</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -977,7 +951,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>61</FileNumber> <FileNumber>57</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -989,7 +963,7 @@
</File> </File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>62</FileNumber> <FileNumber>58</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@@ -1009,134 +983,6 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
</Group> </Group>
<Group>
<GroupName>Middlewares/FreeRTOS</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>63</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/croutine.c</PathWithFileName>
<FilenameWithoutPath>croutine.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>64</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c</PathWithFileName>
<FilenameWithoutPath>event_groups.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>65</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/list.c</PathWithFileName>
<FilenameWithoutPath>list.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>66</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/queue.c</PathWithFileName>
<FilenameWithoutPath>queue.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>67</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c</PathWithFileName>
<FilenameWithoutPath>stream_buffer.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>68</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/tasks.c</PathWithFileName>
<FilenameWithoutPath>tasks.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>69</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/timers.c</PathWithFileName>
<FilenameWithoutPath>timers.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>70</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c</PathWithFileName>
<FilenameWithoutPath>cmsis_os2.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>71</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c</PathWithFileName>
<FilenameWithoutPath>heap_4.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>72</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c</PathWithFileName>
<FilenameWithoutPath>port.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group> <Group>
<GroupName>::CMSIS</GroupName> <GroupName>::CMSIS</GroupName>
<tvExp>0</tvExp> <tvExp>0</tvExp>
@@ -1145,4 +991,248 @@
<RteFlg>1</RteFlg> <RteFlg>1</RteFlg>
</Group> </Group>
<Group>
<GroupName>Middlewares/RT-Thread/RTOS/kernel</GroupName>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>59</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/libcpu/arm/cortex-m0/context_rvds.S</PathWithFileName>
<FilenameWithoutPath>context_rvds.S</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>60</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/clock.c</PathWithFileName>
<FilenameWithoutPath>clock.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>61</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/components.c</PathWithFileName>
<FilenameWithoutPath>components.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>62</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/cpu.c</PathWithFileName>
<FilenameWithoutPath>cpu.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>63</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/idle.c</PathWithFileName>
<FilenameWithoutPath>idle.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>64</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/ipc.c</PathWithFileName>
<FilenameWithoutPath>ipc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>65</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/irq.c</PathWithFileName>
<FilenameWithoutPath>irq.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>66</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/kservice.c</PathWithFileName>
<FilenameWithoutPath>kservice.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>67</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/mem.c</PathWithFileName>
<FilenameWithoutPath>mem.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>68</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/memheap.c</PathWithFileName>
<FilenameWithoutPath>memheap.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>69</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/mempool.c</PathWithFileName>
<FilenameWithoutPath>mempool.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>70</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/object.c</PathWithFileName>
<FilenameWithoutPath>object.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>71</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/scheduler.c</PathWithFileName>
<FilenameWithoutPath>scheduler.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>72</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/slab.c</PathWithFileName>
<FilenameWithoutPath>slab.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>73</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/thread.c</PathWithFileName>
<FilenameWithoutPath>thread.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>74</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/src/timer.c</PathWithFileName>
<FilenameWithoutPath>timer.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>75</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/libcpu/arm/cortex-m0/cpuport.c</PathWithFileName>
<FilenameWithoutPath>cpuport.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>76</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/bsp/_template/cubemx_config/board.c</PathWithFileName>
<FilenameWithoutPath>board.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>Middlewares/RT-Thread/RTOS/device</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>77</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Middlewares/Third_Party/RealThread_RTOS/components/device/device.c</PathWithFileName>
<FilenameWithoutPath>device.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
</ProjectOpt> </ProjectOpt>
+10 -10
View File
@@ -10,7 +10,7 @@
<TargetName>GB01VETx</TargetName> <TargetName>GB01VETx</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060960::V5.06 update 7 (build 960)::ARMCC</pCCUsed> <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>
<uAC6>0</uAC6> <uAC6>0</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
@@ -185,7 +185,6 @@
<uocXRam>0</uocXRam> <uocXRam>0</uocXRam>
<RvdsVP>0</RvdsVP> <RvdsVP>0</RvdsVP>
<RvdsMve>0</RvdsMve> <RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<hadIRAM2>0</hadIRAM2> <hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2> <hadIROM2>0</hadIROM2>
<StupSel>8</StupSel> <StupSel>8</StupSel>
@@ -337,9 +336,9 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls /> <MiscControls />
<Define>USE_HAL_DRIVER,STM32G0B1xx,CMSIS_device_header=&lt;stm32g0xx.h&gt;</Define> <Define>USE_HAL_DRIVER,STM32G0B1xx</Define>
<Undefine /> <Undefine />
<IncludePath>../Core/Inc;../Drivers/STM32G0xx_HAL_Driver/Inc;../Drivers/STM32G0xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32G0xx/Include;../Drivers/CMSIS/Include;../middleware/sfud/inc;../middleware/nr_micro_shell/inc;../middleware/xcmd/inc;../middleware/easyflash/inc;../App;../middleware/easylogger/inc;../Comm;../middleware/fifo;../middleware/at-command/include;../middleware/softimer;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM0;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2</IncludePath> <IncludePath>../Core/Inc;../Drivers/STM32G0xx_HAL_Driver/Inc;../Drivers/STM32G0xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32G0xx/Include;../Drivers/CMSIS/Include;../middleware/sfud/inc;../middleware/nr_micro_shell/inc;../middleware/xcmd/inc;../middleware/easyflash/inc;../App;../middleware/easylogger/inc;../Comm;../middleware/fifo;../middleware/at-command/include;../middleware/softimer;../RT-Thread;../Middlewares/Third_Party/RealThread_RTOS/include/;../Middlewares/Third_Party/RealThread_RTOS/bsp/_template/cubemx_config</IncludePath>
</VariousControls> </VariousControls>
</Cads> </Cads>
<Aads> <Aads>
@@ -352,12 +351,12 @@
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc> <uSurpInc>0</uSurpInc>
<useXO>0</useXO> <useXO>0</useXO>
<ClangAsOpt>4</ClangAsOpt> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls /> <MiscControls />
<Define /> <Define />
<Undefine /> <Undefine />
<IncludePath>..\Core\Inc</IncludePath> <IncludePath />
</VariousControls> </VariousControls>
</Aads> </Aads>
<LDads> <LDads>
@@ -380,7 +379,7 @@
</TargetArmAds> </TargetArmAds>
</TargetOption> </TargetOption>
<Groups> <Groups>
<Group><GroupName>Application/User/Core</GroupName><Files><File><FileName>main.c</FileName><FileType>1</FileType><FilePath>../Core/Src/main.c</FilePath></File><File><FileName>gpio.c</FileName><FileType>1</FileType><FilePath>../Core/Src/gpio.c</FilePath></File><File><FileName>app_freertos.c</FileName><FileType>1</FileType><FilePath>../Core/Src/app_freertos.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>adc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/adc.c</FilePath></File><File><FileName>crc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/crc.c</FilePath></File><File><FileName>dac.c</FileName><FileType>1</FileType><FilePath>../Core/Src/dac.c</FilePath></File><File><FileName>dma.c</FileName><FileType>1</FileType><FilePath>../Core/Src/dma.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>iwdg.c</FileName><FileType>1</FileType><FilePath>../Core/Src/iwdg.c</FilePath></File><File><FileName>usart.c</FileName><FileType>1</FileType><FilePath>../Core/Src/usart.c</FilePath></File><File><FileName>rtc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/rtc.c</FilePath></File><File><FileName>spi.c</FileName><FileType>1</FileType><FilePath>../Core/Src/spi.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>tim.c</FileName><FileType>1</FileType><FilePath>../Core/Src/tim.c</FilePath></File><File><FileName>wwdg.c</FileName><FileType>1</FileType><FilePath>../Core/Src/wwdg.c</FilePath></File><File><FileName>stm32g0xx_it.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_it.c</FilePath></File><File><FileName>stm32g0xx_hal_msp.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_hal_msp.c</FilePath></File><File><FileName>stm32g0xx_hal_timebase_tim.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_hal_timebase_tim.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OLine truncated <Group><GroupName>Application/User/Core</GroupName><Files><File><FileName>main.c</FileName><FileType>1</FileType><FilePath>../Core/Src/main.c</FilePath></File><File><FileName>gpio.c</FileName><FileType>1</FileType><FilePath>../Core/Src/gpio.c</FilePath></File><File><FileName>adc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/adc.c</FilePath></File><File><FileName>crc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/crc.c</FilePath></File><File><FileName>dma.c</FileName><FileType>1</FileType><FilePath>../Core/Src/dma.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>iwdg.c</FileName><FileType>1</FileType><FilePath>../Core/Src/iwdg.c</FilePath></File><File><FileName>usart.c</FileName><FileType>1</FileType><FilePath>../Core/Src/usart.c</FilePath></File><File><FileName>rtc.c</FileName><FileType>1</FileType><FilePath>../Core/Src/rtc.c</FilePath></File><File><FileName>spi.c</FileName><FileType>1</FileType><FilePath>../Core/Src/spi.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>tim.c</FileName><FileType>1</FileType><FilePath>../Core/Src/tim.c</FilePath></File><File><FileName>wwdg.c</FileName><FileType>1</FileType><FilePath>../Core/Src/wwdg.c</FilePath></File><File><FileName>stm32g0xx_it.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_it.c</FilePath></File><File><FileName>stm32g0xx_hal_msp.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_hal_msp.c</FilePath></File><File><FileName>stm32g0xx_hal_timebase_tim.c</FileName><FileType>1</FileType><FilePath>../Core/Src/stm32g0xx_hal_timebase_tim.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File></Files></Group>
<Group> <Group>
<GroupName>midderware/sfud</GroupName> <GroupName>midderware/sfud</GroupName>
<Files> <Files>
@@ -467,15 +466,16 @@
</Files> </Files>
</Group> </Group>
<Group><GroupName>Drivers/CMSIS</GroupName><Files><File><FileName>startup_stm32g0b1xx.s</FileName><FileType>2</FileType><FilePath>.\startup_stm32g0b1xx.s</FilePath></File><File><FileName>system_stm32g0xx.c</FileName><FileType>1</FileType><FilePath>../Core/Src/system_stm32g0xx.c</FilePath></File></Files></Group> <Group><GroupName>Drivers/CMSIS</GroupName><Files><File><FileName>startup_stm32g0b1xx.s</FileName><FileType>2</FileType><FilePath>.\startup_stm32g0b1xx.s</FilePath></File><File><FileName>system_stm32g0xx.c</FileName><FileType>1</FileType><FilePath>../Core/Src/system_stm32g0xx.c</FilePath></File></Files></Group>
<Group><GroupName>Drivers/STM32G0xx_HAL_Driver</GroupName><Files><File><FileName>stm32g0xx_hal_adc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc.c</FilePath></File><File><FileName>stm32g0xx_hal_adc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_adc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_adc.c</FilePath></File><File><FileName>stm32g0xx_hal_rcc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c</FilePath></File><File><FileName>stm32g0xx_hal_rcc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_rcc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_rcc.c</FilePath></File><File><FileName>stm32g0xx_hal_flash.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash.c</FilePath></File><File><FileName>stm32g0xx_hal_flash_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_gpio.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_gpio.c</FilePath></File><File><FileName>stm32g0xx_hal_dma.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma.c</FilePath></File><File><FileName>stm32g0xx_hal_dma_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_dma.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_dma.c</FilePath></File><File><FileName>stm32g0xx_hal_pwr.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr.c</FilePath></File><File><FileName>stm32g0xx_hal_pwr_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_cortex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cortex.c</FilePath></File><File><FileName>stm32g0xx_hal.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal.c</FilePath></File><File><FileName>stm32g0xx_hal_exti.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_exti.c</FilePath></File><File><FileName>stm32g0xx_hal_crc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_crc.c</FilePath></File><File><FileName>stm32g0xx_hal_crc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_crc_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_dac.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dac.c</FilePath></File><File><FileName>stm32g0xx_hal_dac_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dac_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_iwdg.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_iwdg.c</FilePath></File><File><FileName>stm32g0xx_hal_uart.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart.c</FilePath></File><File><FileName>stm32g0xx_hal_uart_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_rtc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rtc.c</FilePath></File><File><FileName>stm32g0xx_hal_rtc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rtc_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_spi.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_spi.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn>Line truncated <Group><GroupName>Drivers/STM32G0xx_HAL_Driver</GroupName><Files><File><FileName>stm32g0xx_hal_adc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc.c</FilePath></File><File><FileName>stm32g0xx_hal_adc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_adc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_adc.c</FilePath></File><File><FileName>stm32g0xx_hal_rcc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c</FilePath></File><File><FileName>stm32g0xx_hal_rcc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_rcc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_rcc.c</FilePath></File><File><FileName>stm32g0xx_hal_flash.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash.c</FilePath></File><File><FileName>stm32g0xx_hal_flash_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_gpio.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_gpio.c</FilePath></File><File><FileName>stm32g0xx_hal_dma.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma.c</FilePath></File><File><FileName>stm32g0xx_hal_dma_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma_ex.c</FilePath></File><File><FileName>stm32g0xx_ll_dma.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_dma.c</FilePath></File><File><FileName>stm32g0xx_hal_pwr.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr.c</FilePath></File><File><FileName>stm32g0xx_hal_pwr_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_cortex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cortex.c</FilePath></File><File><FileName>stm32g0xx_hal.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal.c</FilePath></File><File><FileName>stm32g0xx_hal_exti.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_exti.c</FilePath></File><File><FileName>stm32g0xx_hal_crc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_crc.c</FilePath></File><File><FileName>stm32g0xx_hal_crc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_crc_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_iwdg.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_iwdg.c</FilePath></File><File><FileName>stm32g0xx_hal_uart.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart.c</FilePath></File><File><FileName>stm32g0xx_hal_uart_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_rtc.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rtc.c</FilePath></File><File><FileName>stm32g0xx_hal_rtc_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rtc_ex.c</FilePath></File><File><FileName>stm32g0xx_hal_spi.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_spi.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>stm32g0xx_hal_spi_ex.c</FileName><FileType>1</FileType><FilePath>../Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_spi_ex.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>Line truncated
<Group> <Group>
<GroupName>Board</GroupName> <GroupName>Board</GroupName>
</Group> </Group>
<Group><GroupName>Middlewares/FreeRTOS</GroupName><GroupOption><CommonProperty><UseCPPCompiler>0</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>2</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><GroupArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>4</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads><Aads><interw>2</interw><Ropi>2</Ropi><Rwpi>2</Rwpi><thumb>2</thumb><SplitLS>2</SplitLS><SwStkChk>2</SwStkChk><NoWarn>2</NoWarn><uSurpInc>2</uSurpInc><useXO>2</useXO><ClangAsOpt>0</ClangAsOpt></Aads></GroupArmAds></GroupOption><Files><File><FileName>croutine.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/FreeRTOS/Source/croutine.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>event_groups.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>list.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/FreeRTOS/Source/list.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads></FileArmAds></FileOption></File><File><FileName>queue.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/FreeRTOS/Source/queue.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainLine truncated
<Group> <Group>
<GroupName>::CMSIS</GroupName> <GroupName>::CMSIS</GroupName>
</Group> </Group>
</Groups>
<Group><GroupName>Middlewares/RT-Thread/RTOS/kernel</GroupName><GroupOption><CommonProperty><UseCPPCompiler>0</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>2</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><GroupArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>4</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads><Aads><interw>2</interw><Ropi>2</Ropi><Rwpi>2</Rwpi><thumb>2</thumb><SplitLS>2</SplitLS><SwStkChk>2</SwStkChk><NoWarn>2</NoWarn><uSurpInc>2</uSurpInc><useXO>2</useXO><ClangAsOpt>1</ClangAsOpt></Aads></GroupArmAds></GroupOption><Files><File><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads><Aads><interw>2</interw><Ropi>2</Ropi><Rwpi>2</Rwpi><thumb>2</thumb><SplitLS>2</SplitLS><SwStkChk>2</SwStkChk><NoWarn>2</NoWarn><uSurpInc>2</uSurpInc><useXO>2</useXO><ClangAsOpt>1</ClangAsOpt></Aads></FileArmAds></FileOption></File><File><FileName>context_rvds.S</FileName><FileType>2</FileType><FilePath>../Middlewares/Third_Party/RealThread_RTOS/libcpu/arm/cortex-m0/context_rvds.S</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads><Aads><interw>2</interw><Ropi>2</Ropi><Rwpi>2</Rwpi><thumb>2</thumb><SplitLS>2</SplitLS><SwStkChk>2</SwStkChk><NoWarn>2</NoWarn><uSurpInc>2</uSurpInc><useXO>2</useXO><ClangAsOpt>1</ClangAsOpt></Aads></FileArmAds></FileOption></File><File><FileName>clock.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/RealThread_RTOS/src/clock.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCTCodeConst>0</RVCTCodeConst><RVCTZI>0</RVCTZI><RVCTOtherData>0</RVCTOtherData><ModuleSelection>0</ModuleSelection><IncludeInBuild>1</IncludeInBuild><AlwaysBuild>2</AlwaysBuild><GenerateAssemblyFile>2</GenerateAssemblyFile><AssembleAssemblyFile>2</AssembleAssemblyFile><PublicsOnly>2</PublicsOnly><StopOnExitCode>11</StopOnExitCode><ComprImg>1</ComprImg></CommonProperty><FileArmAds><Cads><interw>2</interw><Optim>0</Optim><oTime>2</oTime><SplitLS>2</SplitLS><OneElfS>2</OneElfS><Strict>2</Strict><EnumInt>2</EnumInt><PlainCh>2</PlainCh><Ropi>2</Ropi><Rwpi>2</Rwpi><wLevel>0</wLevel><uThumb>2</uThumb><uSurpInc>2</uSurpInc><uC99>2</uC99><uGnu>2</uGnu><useXO>2</useXO><v6Lang>0</v6Lang><v6LangP>0</v6LangP><vShortEn>2</vShortEn><vShortWch>2</vShortWch><v6Lto>2</v6Lto><v6WtE>2</v6WtE><v6Rtti>2</v6Rtti></Cads><Aads><interw>2</interw><Ropi>2</Ropi><Rwpi>2</Rwpi><thumb>2</thumb><SplitLS>2</SplitLS><SwStkChk>2</SwStkChk><NoWarn>2</NoWarn><uSurpInc>2</uSurpInc><useXO>2</useXO><ClangAsOpt>1</ClangAsOpt></Aads></FileArmAds></FileOption></File><File><FileName>components.c</FileName><FileType>1</FileType><FilePath>../Middlewares/Third_Party/RealThread_RTOS/src/components.c</FilePath><FileOption><CommonProperty><UseCPPCompiler>2</UseCPPCompiler><RVCLine truncated
</Target> </Target>
</Targets> </Targets>
+6025 -12798
View File
File diff suppressed because it is too large. Load diff
+21 -21
View File
@@ -1,21 +1,21 @@
␍
/*␍ /*
* Auto generated Run-Time-Environment Configuration File␍ * Auto generated Run-Time-Environment Configuration File
* *** Do not modify ! ***␍ * *** Do not modify ! ***
*␍ *
* Project: 'GB01VETx' ␍ * Project: 'GB01VETx'
* Target: 'GB01VETx' ␍ * Target: 'GB01VETx'
*/␍ */
␍
#ifndef RTE_COMPONENTS_H␍ #ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H␍ #define RTE_COMPONENTS_H
␍
␍
/*␍ /*
* Define the Device Header File: ␍ * Define the Device Header File:
*/␍ */
#define CMSIS_device_header "stm32g0xx.h"␍ #define CMSIS_device_header "stm32g0xx.h"
␍
␍
␍
#endif /* RTE_COMPONENTS_H */␍ #endif /* RTE_COMPONENTS_H */
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-05-24 the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "main.h"
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
* Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
*/
#define RT_HEAP_SIZE (15*1024)
static rt_uint8_t rt_heap[RT_HEAP_SIZE];
RT_WEAK void *rt_heap_begin_get(void)
{
return rt_heap;
}
RT_WEAK void *rt_heap_end_get(void)
{
return rt_heap + RT_HEAP_SIZE;
}
#endif
void SysTick_Handler(void)
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
/**
* This function will initial your board.
*/
void rt_hw_board_init(void)
{
extern void SystemClock_Config(void);
HAL_Init();
SystemClock_Config();
SystemCoreClockUpdate();
/*
* 1: OS Tick Configuration
* Enable the hardware timer and call the rt_os_tick_callback function
* periodically with the frequency RT_TICK_PER_SECOND.
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
#ifdef RT_USING_CONSOLE
static UART_HandleTypeDef UartHandle;
static int uart_init(void)
{
/* TODO: Please modify the UART port number according to your needs */
UartHandle.Instance = USART2;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
while (1);
}
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
rt_size_t i = 0, size = 0;
char a = '\r';
__HAL_UNLOCK(&UartHandle);
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == '\n')
{
HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1, 1);
}
HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1, 1);
}
}
#endif
#ifdef RT_USING_FINSH
char rt_hw_console_getchar(void)
{
/* Note: the initial value of ch must < 0 */
int ch = -1;
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET)
{
ch = UartHandle.Instance->DR & 0xff;
}
else
{
rt_thread_mdelay(10);
}
return ch;
}
#endif
@@ -0,0 +1,139 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
// <i>Default: 32
#define RT_THREAD_PRIORITY_MAX 32
// <o>OS tick per second
// <i>Default: 1000 (1ms)
#define RT_TICK_PER_SECOND 1000
// <o>Alignment size for CPU architecture data access
// <i>Default: 4
#define RT_ALIGN_SIZE 4
// <o>the max length of object name<2-16>
// <i>Default: 8
#define RT_NAME_MAX 8
// <c1>Using RT-Thread components initialization
// <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>
#define RT_USING_USER_MAIN
// <o>the stack size of main thread<1-4086>
// <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE 256
// </h>
// <h>Debug Configuration
// <c1>enable kernel debug configuration
// <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
// <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
// <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>
// <h>Hook Configuration
// <c1>using hook
// <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
// <i>using idle hook
//#define RT_USING_IDLE_HOOK
// </c>
// </h>
// <e>Software timers Configuration
// <i> Enables user timers
#define RT_USING_TIMER_SOFT 0
#if RT_USING_TIMER_SOFT == 0
#undef RT_USING_TIMER_SOFT
#endif
// <o>The priority level of timer thread <0-31>
// <i>Default: 4
#define RT_TIMER_THREAD_PRIO 4
// <o>The stack size of timer thread <0-8192>
// <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE 512
// </e>
// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
// <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>
// <c1>Using Mutex
// <i>Using Mutex
//#define RT_USING_MUTEX
// </c>
// <c1>Using Event
// <i>Using Event
//#define RT_USING_EVENT
// </c>
// <c1>Using MailBox
// <i>Using MailBox
#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
// <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>
// <h>Memory Management Configuration
// <c1>Memory Pool Management
// <i>Memory Pool Management
//#define RT_USING_MEMPOOL
// </c>
// <c1>Dynamic Heap Management(Algorithm: small memory )
// <i>Dynamic Heap Management
#define RT_USING_HEAP
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
// <i>using tiny size of memory
//#define RT_USING_TINY_SIZE
// </c>
// </h>
// <h>Console Configuration
// <c1>Using console
// <i>Using console
//#define RT_USING_CONSOLE
// </c>
// <o>the buffer size of console <1-1024>
// <i>the buffer size of console
// <i>Default: 128 (128Byte)
#define RT_CONSOLEBUF_SIZE 256
// </h>
// <h>FinSH Configuration
// <c1>include finsh config
// <i>Select this choice if you using FinSH
//#include "finsh_config.h"
// </c>
// </h>
// <h>Device Configuration
// <c1>using device framework
// <i>using device framework
//#define RT_USING_DEVICE
// </c>
// </h>
// <<< end of configuration section >>>
#endif
@@ -0,0 +1,437 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2007-01-21 Bernard the first version
* 2010-05-04 Bernard add rt_device_init implementation
* 2012-10-20 Bernard add device check in register function,
* provided by Rob <rdent@iinet.net.au>
* 2012-12-25 Bernard return RT_EOK if the device interface not exist.
* 2013-07-09 Grissiom add ref_count support
* 2016-04-02 Bernard fix the open_flag initialization issue.
*/
#include <rtthread.h>
#if defined(RT_USING_POSIX)
#include <rtdevice.h> /* for wqueue_init */
#endif
#ifdef RT_USING_DEVICE
#ifdef RT_USING_DEVICE_OPS
#define device_init (dev->ops->init)
#define device_open (dev->ops->open)
#define device_close (dev->ops->close)
#define device_read (dev->ops->read)
#define device_write (dev->ops->write)
#define device_control (dev->ops->control)
#else
#define device_init (dev->init)
#define device_open (dev->open)
#define device_close (dev->close)
#define device_read (dev->read)
#define device_write (dev->write)
#define device_control (dev->control)
#endif
/**
* This function registers a device driver with specified name.
*
* @param dev the pointer of device driver structure
* @param name the device driver's name
* @param flags the capabilities flag of device
*
* @return the error code, RT_EOK on initialization successfully.
*/
rt_err_t rt_device_register(rt_device_t dev,
const char *name,
rt_uint16_t flags)
{
if (dev == RT_NULL)
return -RT_ERROR;
if (rt_device_find(name) != RT_NULL)
return -RT_ERROR;
rt_object_init(&(dev->parent), RT_Object_Class_Device, name);
dev->flag = flags;
dev->ref_count = 0;
dev->open_flag = 0;
#if defined(RT_USING_POSIX)
dev->fops = RT_NULL;
rt_wqueue_init(&(dev->wait_queue));
#endif
return RT_EOK;
}
/**
* This function removes a previously registered device driver
*
* @param dev the pointer of device driver structure
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_device_unregister(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
RT_ASSERT(rt_object_is_systemobject(&dev->parent));
rt_object_detach(&(dev->parent));
return RT_EOK;
}
/**
* This function initializes all registered device driver
*
* @return the error code, RT_EOK on successfully.
*
* @deprecated since 1.2.x, this function is not needed because the initialization
* of a device is performed when application opens it.
*/
rt_err_t rt_device_init_all(void)
{
return RT_EOK;
}
/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
*
* @return the registered device driver on successful, or RT_NULL on failure.
*/
rt_device_t rt_device_find(const char *name)
{
return (rt_device_t)rt_object_find(name, RT_Object_Class_Device);
}
#ifdef RT_USING_HEAP
/**
* This function creates a device object with user data size.
*
* @param type, the kind type of this device object.
* @param attach_size, the size of user data.
*
* @return the allocated device object, or RT_NULL when failed.
*/
rt_device_t rt_device_create(int type, int attach_size)
{
int size;
rt_device_t device;
size = RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);
attach_size = RT_ALIGN(attach_size, RT_ALIGN_SIZE);
/* use the total size */
size += attach_size;
device = (rt_device_t)rt_malloc(size);
if (device)
{
rt_memset(device, 0x0, sizeof(struct rt_device));
device->type = (enum rt_device_class_type)type;
}
return device;
}
/**
* This function destroy the specific device object.
*
* @param dev, the specific device object.
*/
void rt_device_destroy(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
RT_ASSERT(rt_object_is_systemobject(&dev->parent) == RT_FALSE);
rt_object_detach(&(dev->parent));
/* release this device object */
rt_free(dev);
}
#endif
/**
* This function will initialize the specified device
*
* @param dev the pointer of device driver structure
*
* @return the result
*/
rt_err_t rt_device_init(rt_device_t dev)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
/* get device_init handler */
if (device_init != RT_NULL)
{
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
result = device_init(dev);
if (result != RT_EOK)
{
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
dev->parent.name, result);
}
else
{
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
}
}
return result;
}
/**
* This function will open a device
*
* @param dev the pointer of device driver structure
* @param oflag the flags for device open
*
* @return the result
*/
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
/* if device is not initialized, initialize it. */
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
if (device_init != RT_NULL)
{
result = device_init(dev);
if (result != RT_EOK)
{
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
dev->parent.name, result);
return result;
}
}
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
/* device is a stand alone device and opened */
if ((dev->flag & RT_DEVICE_FLAG_STANDALONE) &&
(dev->open_flag & RT_DEVICE_OFLAG_OPEN))
{
return -RT_EBUSY;
}
/* call device_open interface */
if (device_open != RT_NULL)
{
result = device_open(dev, oflag);
}
else
{
/* set open flag */
dev->open_flag = (oflag & RT_DEVICE_OFLAG_MASK);
}
/* set open flag */
if (result == RT_EOK || result == -RT_ENOSYS)
{
dev->open_flag |= RT_DEVICE_OFLAG_OPEN;
dev->ref_count++;
/* don't let bad things happen silently. If you are bitten by this assert,
* please set the ref_count to a bigger type. */
RT_ASSERT(dev->ref_count != 0);
}
return result;
}
/**
* This function will close a device
*
* @param dev the pointer of device driver structure
*
* @return the result
*/
rt_err_t rt_device_close(rt_device_t dev)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
return -RT_ERROR;
dev->ref_count--;
if (dev->ref_count != 0)
return RT_EOK;
/* call device_close interface */
if (device_close != RT_NULL)
{
result = device_close(dev);
}
/* set open flag */
if (result == RT_EOK || result == -RT_ENOSYS)
dev->open_flag = RT_DEVICE_OFLAG_CLOSE;
return result;
}
/**
* This function will read some data from a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of reading
* @param buffer the data buffer to save read data
* @param size the size of buffer
*
* @return the actually read size on successful, otherwise negative returned.
*
* @note since 0.4.0, the unit of size/pos is a block for block device.
*/
rt_size_t rt_device_read(rt_device_t dev,
rt_off_t pos,
void *buffer,
rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
{
rt_set_errno(-RT_ERROR);
return 0;
}
/* call device_read interface */
if (device_read != RT_NULL)
{
return device_read(dev, pos, buffer, size);
}
/* set error code */
rt_set_errno(-RT_ENOSYS);
return 0;
}
/**
* This function will write some data to a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of written
* @param buffer the data buffer to be written to device
* @param size the size of buffer
*
* @return the actually written size on successful, otherwise negative returned.
*
* @note since 0.4.0, the unit of size/pos is a block for block device.
*/
rt_size_t rt_device_write(rt_device_t dev,
rt_off_t pos,
const void *buffer,
rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
{
rt_set_errno(-RT_ERROR);
return 0;
}
/* call device_write interface */
if (device_write != RT_NULL)
{
return device_write(dev, pos, buffer, size);
}
/* set error code */
rt_set_errno(-RT_ENOSYS);
return 0;
}
/**
* This function will perform a variety of control functions on devices.
*
* @param dev the pointer of device driver structure
* @param cmd the command sent to device
* @param arg the argument of command
*
* @return the result
*/
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
/* call device_write interface */
if (device_control != RT_NULL)
{
return device_control(dev, cmd, arg);
}
return -RT_ENOSYS;
}
/**
* This function will set the reception indication callback function. This callback function
* is invoked when this device receives data.
*
* @param dev the pointer of device driver structure
* @param rx_ind the indication callback function
*
* @return RT_EOK
*/
rt_err_t
rt_device_set_rx_indicate(rt_device_t dev,
rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size))
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
dev->rx_indicate = rx_ind;
return RT_EOK;
}
/**
* This function will set the indication callback function when device has
* written data to physical hardware.
*
* @param dev the pointer of device driver structure
* @param tx_done the indication callback function
*
* @return RT_EOK
*/
rt_err_t
rt_device_set_tx_complete(rt_device_t dev,
rt_err_t (*tx_done)(rt_device_t dev, void *buffer))
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
dev->tx_complete = tx_done;
return RT_EOK;
}
#endif
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,249 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_H__
#define __FINSH_H__
#include <rtthread.h>
#include "finsh_api.h"
/* -- the beginning of option -- */
#define FINSH_NAME_MAX 16 /* max length of identifier */
#define FINSH_NODE_MAX 16 /* max number of node */
#define FINSH_HEAP_MAX 128 /* max length of heap */
#define FINSH_STRING_MAX 128 /* max length of string */
#define FINSH_VARIABLE_MAX 8 /* max number of variable */
#define FINSH_STACK_MAX 64 /* max stack size */
#define FINSH_TEXT_MAX 128 /* max text segment size */
#define HEAP_ALIGNMENT 4 /* heap alignment */
#define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
#define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
#define FINSH_SET16(x, v) \
do \
{ \
*(x) = (v) & 0x00ff; \
(*((x)+1)) = (v) >> 8; \
} while ( 0 )
#define FINSH_SET32(x, v) \
do \
{ \
*(x) = (rt_uint32_t)(v) & 0x000000ff; \
(*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
(*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
(*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
} while ( 0 )
/* -- the end of option -- */
/* std header file */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define FINSH_VERSION_MAJOR 1
#define FINSH_VERSION_MINOR 0
/**
* @addtogroup finsh
*/
/*@{*/
#define FINSH_ERROR_OK 0 /**< No error */
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */
/*@}*/
/* system call item */
struct finsh_syscall_item
{
struct finsh_syscall_item* next; /* next item */
struct finsh_syscall syscall; /* syscall */
};
extern struct finsh_syscall_item *global_syscall_list;
/* system variable table */
struct finsh_sysvar
{
const char* name; /* the name of variable */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system variable */
#endif
uint8_t type; /* the type of variable */
void* var ; /* the address of variable */
};
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
#else
#define FINSH_NEXT_SYSCALL(index) index++
#define FINSH_NEXT_SYSVAR(index) index++
#endif
/* system variable item */
struct finsh_sysvar_item
{
struct finsh_sysvar_item *next; /* next item */
struct finsh_sysvar sysvar; /* system variable */
};
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
extern struct finsh_sysvar_item* global_sysvar_list;
/* find out system variable, which should be implemented in user program */
struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
struct finsh_token
{
char eof;
char replay;
int position;
uint8_t current_token;
union {
char char_value;
int int_value;
long long_value;
} value;
uint8_t string[FINSH_STRING_MAX];
uint8_t* line;
};
#define FINSH_IDTYPE_VAR 0x01
#define FINSH_IDTYPE_SYSVAR 0x02
#define FINSH_IDTYPE_SYSCALL 0x04
#define FINSH_IDTYPE_ADDRESS 0x08
struct finsh_node
{
uint8_t node_type; /* node node_type */
uint8_t data_type; /* node data node_type */
uint8_t idtype; /* id node information */
union { /* value node */
char char_value;
short short_value;
int int_value;
long long_value;
void* ptr;
} value;
union
{
/* point to variable identifier or function identifier */
struct finsh_var *var;
struct finsh_sysvar *sysvar;
struct finsh_syscall*syscall;
}id;
/* sibling and child node */
struct finsh_node *sibling, *child;
};
struct finsh_parser
{
uint8_t* parser_string;
struct finsh_token token;
struct finsh_node* root;
};
/**
* @ingroup finsh
*
* The basic data type in finsh shell
*/
enum finsh_type {
finsh_type_unknown = 0, /**< unknown data type */
finsh_type_void, /**< void */
finsh_type_voidp, /**< void pointer */
finsh_type_char, /**< char */
finsh_type_uchar, /**< unsigned char */
finsh_type_charp, /**< char pointer */
finsh_type_short, /**< short */
finsh_type_ushort, /**< unsigned short */
finsh_type_shortp, /**< short pointer */
finsh_type_int, /**< int */
finsh_type_uint, /**< unsigned int */
finsh_type_intp, /**< int pointer */
finsh_type_long, /**< long */
finsh_type_ulong, /**< unsigned long */
finsh_type_longp /**< long pointer */
};
/* init finsh environment */
int finsh_init(struct finsh_parser* parser);
/* flush finsh node, text segment */
int finsh_flush(struct finsh_parser* parser);
/* reset all of finsh */
int finsh_reset(struct finsh_parser* parser);
#ifdef RT_USING_DEVICE
void finsh_set_device(const char* device_name);
#endif
/* run finsh parser to generate abstract synatx tree */
void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
/* run compiler to compile abstract syntax tree */
int finsh_compiler_run(struct finsh_node* node);
/* run finsh virtual machine */
void finsh_vm_run(void);
/* get variable value */
struct finsh_var* finsh_var_lookup(const char* name);
/* get bottom value of stack */
long finsh_stack_bottom(void);
/* get error number of finsh */
uint8_t finsh_errno(void);
/* get error string */
const char* finsh_error_string(uint8_t type);
#ifdef RT_USING_HEAP
/**
* @ingroup finsh
*
* This function appends a system call to finsh runtime environment
* @param name the name of system call
* @param func the function pointer of system call
*/
void finsh_syscall_append(const char* name, syscall_func func);
/**
* @ingroup finsh
*
* This function appends a system variable to finsh runtime environment
* @param name the name of system variable
* @param type the data type of system variable
* @param addr the address of system variable
*/
void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
#endif
#endif
@@ -0,0 +1,220 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef FINSH_API_H__
#define FINSH_API_H__
#include "finsh_config.h"
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#pragma section("VSymTab",read)
#endif
typedef long (*syscall_func)(void);
/* system call table */
struct finsh_syscall
{
const char* name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system call */
#endif
syscall_func func; /* the function address of system call */
};
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
#endif
#ifdef FINSH_USING_DESCRIPTION
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
__declspec(allocate("VSymTab")) \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#endif
#else
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#endif
#endif /* end of FINSH_USING_DESCRIPTION */
#endif /* end of FINSH_USING_SYMTAB */
/**
* @ingroup finsh
*
* This macro exports a system function to finsh shell.
*
* @param name the name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT(name, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
/**
* @ingroup finsh
*
* This macro exports a system function with an alias name to finsh shell.
*
* @param name the name of function.
* @param alias the alias name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
/**
* @ingroup finsh
*
* This macro exports a command to module shell.
*
* @param command the name of command.
* @param desc the description of command, which will show in help.
*/
#ifdef FINSH_USING_MSH
#define MSH_CMD_EXPORT(command, desc) \
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
#else
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
#endif
#endif
@@ -0,0 +1,29 @@
/* FinSH config file */
#ifndef __MSH_CFG_H__
#define __MSH_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
// <h>FinSH Configuration
// <o>the priority of finsh thread <1-30>
// <i>the priority of finsh thread
// <i>Default: 21
#define FINSH_THREAD_PRIORITY 21
// <o>the stack of finsh thread <1-4096>
// <i>the stack of finsh thread
// <i>Default: 4096 (4096Byte)
#define FINSH_THREAD_STACK_SIZE 1024
#define FINSH_USING_SYMTAB
// <c1>Enable command description
// <i>Enable command description
#define FINSH_USING_DESCRIPTION
// </c>
// </h>
// <<< end of configuration section >>>
#endif
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtconfig.h>
#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#endif
@@ -0,0 +1,648 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for finsh
* 2014-01-03 Bernard msh can execute module.
* 2017-07-19 Aubr.Cool limit argc to RT_FINSH_ARG_MAX
*/
#include <rtthread.h>
#include <finsh_config.h>
#ifdef FINSH_USING_MSH
#include "msh.h"
#include <finsh.h>
#include <shell.h>
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#endif
#ifdef RT_USING_MODULE
#include <dlmodule.h>
#endif
#ifndef FINSH_ARG_MAX
#define FINSH_ARG_MAX 8
#endif
typedef int (*cmd_function_t)(int argc, char **argv);
#ifdef FINSH_USING_MSH
#ifdef FINSH_USING_MSH_ONLY
rt_bool_t msh_is_used(void)
{
return RT_TRUE;
}
#else
#ifdef FINSH_USING_MSH_DEFAULT
static rt_bool_t __msh_state = RT_TRUE;
#else
static rt_bool_t __msh_state = RT_FALSE;
#endif
rt_bool_t msh_is_used(void)
{
return __msh_state;
}
static int msh_exit(int argc, char **argv)
{
/* return to finsh shell mode */
__msh_state = RT_FALSE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_exit, __cmd_exit, return to RT-Thread shell mode.);
static int msh_enter(void)
{
/* enter module shell mode */
__msh_state = RT_TRUE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_enter, msh, use module shell);
#endif
int msh_help(int argc, char **argv)
{
rt_kprintf("RT-Thread shell commands:\n");
{
struct finsh_syscall *index;
for (index = _syscall_table_begin;
index < _syscall_table_end;
FINSH_NEXT_SYSCALL(index))
{
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
rt_kprintf("%-16s - %s\n", &index->name[6], index->desc);
#else
rt_kprintf("%s ", &index->name[6]);
#endif
}
}
rt_kprintf("\n");
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.);
int cmd_ps(int argc, char **argv)
{
extern long list_thread(void);
extern int list_module(void);
#ifdef RT_USING_MODULE
if ((argc == 2) && (strcmp(argv[1], "-m") == 0))
list_module();
else
#endif
list_thread();
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
#ifdef RT_USING_HEAP
int cmd_free(int argc, char **argv)
{
extern void list_mem(void);
extern void list_memheap(void);
#ifdef RT_USING_MEMHEAP_AS_HEAP
list_memheap();
#else
list_mem();
#endif
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
#endif
static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
{
char *ptr;
rt_size_t position;
rt_size_t argc;
rt_size_t i;
ptr = cmd;
position = 0; argc = 0;
while (position < length)
{
/* strip bank and tab */
while ((*ptr == ' ' || *ptr == '\t') && position < length)
{
*ptr = '\0';
ptr ++; position ++;
}
if(argc >= FINSH_ARG_MAX)
{
rt_kprintf("Too many args ! We only Use:\n");
for(i = 0; i < argc; i++)
{
rt_kprintf("%s ", argv[i]);
}
rt_kprintf("\n");
break;
}
if (position >= length) break;
/* handle string */
if (*ptr == '"')
{
ptr ++; position ++;
argv[argc] = ptr; argc ++;
/* skip this string */
while (*ptr != '"' && position < length)
{
if (*ptr == '\\')
{
if (*(ptr + 1) == '"')
{
ptr ++; position ++;
}
}
ptr ++; position ++;
}
if (position >= length) break;
/* skip '"' */
*ptr = '\0'; ptr ++; position ++;
}
else
{
argv[argc] = ptr;
argc ++;
while ((*ptr != ' ' && *ptr != '\t') && position < length)
{
ptr ++; position ++;
}
if (position >= length) break;
}
}
return argc;
}
static cmd_function_t msh_get_cmd(char *cmd, int size)
{
struct finsh_syscall *index;
cmd_function_t cmd_func = RT_NULL;
for (index = _syscall_table_begin;
index < _syscall_table_end;
FINSH_NEXT_SYSCALL(index))
{
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
if (strncmp(&index->name[6], cmd, size) == 0 &&
index->name[6 + size] == '\0')
{
cmd_func = (cmd_function_t)index->func;
break;
}
}
return cmd_func;
}
#if defined(RT_USING_MODULE) && defined(RT_USING_DFS)
/* Return 0 on module executed. Other value indicate error.
*/
int msh_exec_module(const char *cmd_line, int size)
{
int ret;
int fd = -1;
char *pg_name;
int length, cmd_length = 0;
if (size == 0)
return -RT_ERROR;
/* get the length of command0 */
while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size)
cmd_length ++;
/* get name length */
length = cmd_length + 32;
/* allocate program name memory */
pg_name = (char *) rt_malloc(length);
if (pg_name == RT_NULL)
return -RT_ENOMEM;
/* copy command0 */
memcpy(pg_name, cmd_line, cmd_length);
pg_name[cmd_length] = '\0';
if (strstr(pg_name, ".mo") != RT_NULL || strstr(pg_name, ".MO") != RT_NULL)
{
/* try to open program */
fd = open(pg_name, O_RDONLY, 0);
/* search in /bin path */
if (fd < 0)
{
rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
fd = open(pg_name, O_RDONLY, 0);
}
}
else
{
/* add .mo and open program */
/* try to open program */
strcat(pg_name, ".mo");
fd = open(pg_name, O_RDONLY, 0);
/* search in /bin path */
if (fd < 0)
{
rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line);
fd = open(pg_name, O_RDONLY, 0);
}
}
if (fd >= 0)
{
/* found program */
close(fd);
dlmodule_exec(pg_name, cmd_line, size);
ret = 0;
}
else
{
ret = -1;
}
rt_free(pg_name);
return ret;
}
int system(const char *command)
{
int ret = -RT_ENOMEM;
char *cmd = rt_strdup(command);
if (cmd)
{
ret = msh_exec(cmd, rt_strlen(cmd));
rt_free(cmd);
}
return ret;
}
#endif
static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp)
{
int argc;
rt_size_t cmd0_size = 0;
cmd_function_t cmd_func;
char *argv[FINSH_ARG_MAX];
RT_ASSERT(cmd);
RT_ASSERT(retp);
/* find the size of first command */
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
cmd0_size ++;
if (cmd0_size == 0)
return -RT_ERROR;
cmd_func = msh_get_cmd(cmd, cmd0_size);
if (cmd_func == RT_NULL)
return -RT_ERROR;
/* split arguments */
memset(argv, 0x00, sizeof(argv));
argc = msh_split(cmd, length, argv);
if (argc == 0)
return -RT_ERROR;
/* exec this command */
*retp = cmd_func(argc, argv);
return 0;
}
#if defined(RT_USING_LWP) && defined(RT_USING_DFS)
static int _msh_exec_lwp(char *cmd, rt_size_t length)
{
int argc;
int cmd0_size = 0;
char *argv[FINSH_ARG_MAX];
int fd = -1;
char *pg_name;
extern int exec(char*, int, char**);
/* find the size of first command */
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
cmd0_size ++;
if (cmd0_size == 0)
return -1;
/* split arguments */
rt_memset(argv, 0x00, sizeof(argv));
argc = msh_split(cmd, length, argv);
if (argc == 0)
return -1;
pg_name = argv[0];
/* try to open program */
fd = open(pg_name, O_RDONLY, 0);
if (fd < 0)
return -1;
/* found program */
close(fd);
exec(pg_name, argc, argv);
return 0;
}
#endif
int msh_exec(char *cmd, rt_size_t length)
{
int cmd_ret;
/* strim the beginning of command */
while ((length > 0) && (*cmd == ' ' || *cmd == '\t'))
{
cmd++;
length--;
}
if (length == 0)
return 0;
/* Exec sequence:
* 1. built-in command
* 2. module(if enabled)
*/
if (_msh_exec_cmd(cmd, length, &cmd_ret) == 0)
{
return cmd_ret;
}
#ifdef RT_USING_DFS
#ifdef DFS_USING_WORKDIR
if (msh_exec_script(cmd, length) == 0)
{
return 0;
}
#endif
#ifdef RT_USING_MODULE
if (msh_exec_module(cmd, length) == 0)
{
return 0;
}
#endif
#ifdef RT_USING_LWP
if (_msh_exec_lwp(cmd, length) == 0)
{
return 0;
}
#endif
#endif
/* truncate the cmd at the first space. */
{
char *tcmd;
tcmd = cmd;
while (*tcmd != ' ' && *tcmd != '\0')
{
tcmd++;
}
*tcmd = '\0';
}
rt_kprintf("%s: command not found.\n", cmd);
return -1;
}
static int str_common(const char *str1, const char *str2)
{
const char *str = str1;
while ((*str != 0) && (*str2 != 0) && (*str == *str2))
{
str ++;
str2 ++;
}
return (str - str1);
}
#ifdef RT_USING_DFS
void msh_auto_complete_path(char *path)
{
DIR *dir = RT_NULL;
struct dirent *dirent = RT_NULL;
char *full_path, *ptr, *index;
if (!path)
return;
full_path = (char *)rt_malloc(256);
if (full_path == RT_NULL) return; /* out of memory */
if (*path != '/')
{
getcwd(full_path, 256);
if (full_path[rt_strlen(full_path) - 1] != '/')
strcat(full_path, "/");
}
else *full_path = '\0';
index = RT_NULL;
ptr = path;
for (;;)
{
if (*ptr == '/') index = ptr + 1;
if (!*ptr) break;
ptr ++;
}
if (index == RT_NULL) index = path;
if (index != RT_NULL)
{
char *dest = index;
/* fill the parent path */
ptr = full_path;
while (*ptr) ptr ++;
for (index = path; index != dest;)
*ptr++ = *index++;
*ptr = '\0';
dir = opendir(full_path);
if (dir == RT_NULL) /* open directory failed! */
{
rt_free(full_path);
return;
}
/* restore the index position */
index = dest;
}
/* auto complete the file or directory name */
if (*index == '\0') /* display all of files and directories */
{
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_kprintf("%s\n", dirent->d_name);
}
}
else
{
rt_size_t length, min_length;
min_length = 0;
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
/* matched the prefix string */
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
{
if (min_length == 0)
{
min_length = rt_strlen(dirent->d_name);
/* save dirent name */
strcpy(full_path, dirent->d_name);
}
length = str_common(dirent->d_name, full_path);
if (length < min_length)
{
min_length = length;
}
}
}
if (min_length)
{
if (min_length < rt_strlen(full_path))
{
/* list the candidate */
rewinddir(dir);
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
rt_kprintf("%s\n", dirent->d_name);
}
}
length = index - path;
memcpy(index, full_path, min_length);
path[length + min_length] = '\0';
}
}
closedir(dir);
rt_free(full_path);
}
#endif
void msh_auto_complete(char *prefix)
{
int length, min_length;
const char *name_ptr, *cmd_name;
struct finsh_syscall *index;
min_length = 0;
name_ptr = RT_NULL;
if (*prefix == '\0')
{
msh_help(0, RT_NULL);
return;
}
#ifdef RT_USING_DFS
/* check whether a spare in the command */
{
char *ptr;
ptr = prefix + rt_strlen(prefix);
while (ptr != prefix)
{
if (*ptr == ' ')
{
msh_auto_complete_path(ptr + 1);
break;
}
ptr --;
}
#ifdef RT_USING_MODULE
/* There is a chance that the user want to run the module directly. So
* try to complete the file names. If the completed path is not a
* module, the system won't crash anyway. */
if (ptr == prefix)
{
msh_auto_complete_path(ptr);
}
#endif
}
#endif
/* checks in internal command */
{
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* skip finsh shell function */
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
cmd_name = (const char *) &index->name[6];
if (strncmp(prefix, cmd_name, strlen(prefix)) == 0)
{
if (min_length == 0)
{
/* set name_ptr */
name_ptr = cmd_name;
/* set initial length */
min_length = strlen(name_ptr);
}
length = str_common(name_ptr, cmd_name);
if (length < min_length)
min_length = length;
rt_kprintf("%s\n", cmd_name);
}
}
}
/* auto complete string */
if (name_ptr != NULL)
{
rt_strncpy(prefix, name_ptr, min_length);
}
return ;
}
#endif
#endif /* FINSH_USING_MSH */
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for FinSH
*/
#ifndef __M_SHELL__
#define __M_SHELL__
#include <rtthread.h>
rt_bool_t msh_is_used(void);
int msh_exec(char *cmd, rt_size_t length);
void msh_auto_complete(char *prefix);
int msh_exec_module(const char *cmd_line, int size);
int msh_exec_script(const char *cmd_line, int size);
#endif
@@ -0,0 +1,904 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-04-30 Bernard the first version for FinSH
* 2006-05-08 Bernard change finsh thread stack to 2048
* 2006-06-03 Bernard add support for skyeye
* 2006-09-24 Bernard remove the code related with hardware
* 2010-01-18 Bernard fix down then up key bug.
* 2010-03-19 Bernard fix backspace issue and fix device read in shell.
* 2010-04-01 Bernard add prompt output when start and remove the empty history
* 2011-02-23 Bernard fix variable section end issue of finsh shell
* initialization when use GNU GCC compiler.
* 2016-11-26 armink add password authentication
* 2018-07-02 aozima add custome prompt support.
*/
#include <rthw.h>
#include <finsh_config.h>
#ifdef RT_USING_FINSH
#include "finsh.h"
#include "shell.h"
#ifdef FINSH_USING_MSH
#include "msh.h"
#endif
#ifdef _WIN32
#include <stdio.h> /* for putchar */
#endif
/* finsh thread */
#ifndef RT_USING_HEAP
static struct rt_thread finsh_thread;
ALIGN(RT_ALIGN_SIZE)
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
struct finsh_shell _shell;
#endif
/* finsh symtab */
#ifdef FINSH_USING_SYMTAB
struct finsh_syscall *_syscall_table_begin = NULL;
struct finsh_syscall *_syscall_table_end = NULL;
struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL;
#endif
struct finsh_shell *shell;
static char *finsh_prompt_custom = RT_NULL;
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
ptr ++;
return (struct finsh_syscall*)ptr;
}
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
ptr ++;
return (struct finsh_sysvar*)ptr;
}
#endif /* defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) */
#ifdef RT_USING_HEAP
int finsh_set_prompt(const char * prompt)
{
if(finsh_prompt_custom)
{
rt_free(finsh_prompt_custom);
finsh_prompt_custom = RT_NULL;
}
/* strdup */
if(prompt)
{
finsh_prompt_custom = (char *)rt_malloc(strlen(prompt)+1);
if(finsh_prompt_custom)
{
strcpy(finsh_prompt_custom, prompt);
}
}
return 0;
}
#endif /* RT_USING_HEAP */
#if defined(RT_USING_DFS)
#include <dfs_posix.h>
#endif /* RT_USING_DFS */
const char *finsh_get_prompt()
{
#define _MSH_PROMPT "msh "
#define _PROMPT "finsh "
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
/* check prompt mode */
if (!shell->prompt_mode)
{
finsh_prompt[0] = '\0';
return finsh_prompt;
}
if(finsh_prompt_custom)
{
strncpy(finsh_prompt, finsh_prompt_custom, sizeof(finsh_prompt)-1);
return finsh_prompt;
}
#ifdef FINSH_USING_MSH
if (msh_is_used()) strcpy(finsh_prompt, _MSH_PROMPT);
else
#endif
strcpy(finsh_prompt, _PROMPT);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
/* get current working directory */
getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
#endif
strcat(finsh_prompt, ">");
return finsh_prompt;
}
/**
* @ingroup finsh
*
* This function get the prompt mode of finsh shell.
*
* @return prompt the prompt mode, 0 disable prompt mode, other values enable prompt mode.
*/
rt_uint32_t finsh_get_prompt_mode(void)
{
RT_ASSERT(shell != RT_NULL);
return shell->prompt_mode;
}
/**
* @ingroup finsh
*
* This function set the prompt mode of finsh shell.
*
* The parameter 0 disable prompt mode, other values enable prompt mode.
*
* @param prompt the prompt mode
*/
void finsh_set_prompt_mode(rt_uint32_t prompt_mode)
{
RT_ASSERT(shell != RT_NULL);
shell->prompt_mode = prompt_mode;
}
static int finsh_getchar(void)
{
#ifdef RT_USING_DEVICE
#ifdef RT_USING_POSIX
return getchar();
#else
char ch = 0;
RT_ASSERT(shell != RT_NULL);
if(shell->device)
{
while (rt_device_read(shell->device, -1, &ch, 1) != 1)
rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER);
return (int)ch;
}
else
#endif
#endif
{
extern char rt_hw_console_getchar(void);
return rt_hw_console_getchar();
}
}
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
{
RT_ASSERT(shell != RT_NULL);
/* release semaphore to let finsh thread rx data */
rt_sem_release(&shell->rx_sem);
return RT_EOK;
}
/**
* @ingroup finsh
*
* This function sets the input device of finsh shell.
*
* @param device_name the name of new input device.
*/
void finsh_set_device(const char *device_name)
{
rt_device_t dev = RT_NULL;
RT_ASSERT(shell != RT_NULL);
dev = rt_device_find(device_name);
if (dev == RT_NULL)
{
rt_kprintf("finsh: can not find device: %s\n", device_name);
return;
}
/* check whether it's a same device */
if (dev == shell->device) return;
/* open this device and set the new device in finsh shell */
if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | \
RT_DEVICE_FLAG_STREAM) == RT_EOK)
{
if (shell->device != RT_NULL)
{
/* close old finsh device */
rt_device_close(shell->device);
rt_device_set_rx_indicate(shell->device, RT_NULL);
}
/* clear line buffer before switch to new device */
memset(shell->line, 0, sizeof(shell->line));
shell->line_curpos = shell->line_position = 0;
shell->device = dev;
rt_device_set_rx_indicate(dev, finsh_rx_ind);
}
}
/**
* @ingroup finsh
*
* This function returns current finsh shell input device.
*
* @return the finsh shell input device name is returned.
*/
const char *finsh_get_device()
{
RT_ASSERT(shell != RT_NULL);
return shell->device->parent.name;
}
#endif
/**
* @ingroup finsh
*
* This function set the echo mode of finsh shell.
*
* FINSH_OPTION_ECHO=0x01 is echo mode, other values are none-echo mode.
*
* @param echo the echo mode
*/
void finsh_set_echo(rt_uint32_t echo)
{
RT_ASSERT(shell != RT_NULL);
shell->echo_mode = (rt_uint8_t)echo;
}
/**
* @ingroup finsh
*
* This function gets the echo mode of finsh shell.
*
* @return the echo mode
*/
rt_uint32_t finsh_get_echo()
{
RT_ASSERT(shell != RT_NULL);
return shell->echo_mode;
}
#ifdef FINSH_USING_AUTH
/**
* set a new password for finsh
*
* @param password new password
*
* @return result, RT_EOK on OK, -RT_ERROR on the new password length is less than
* FINSH_PASSWORD_MIN or greater than FINSH_PASSWORD_MAX
*/
rt_err_t finsh_set_password(const char *password) {
rt_ubase_t level;
rt_size_t pw_len = rt_strlen(password);
if (pw_len < FINSH_PASSWORD_MIN || pw_len > FINSH_PASSWORD_MAX)
return -RT_ERROR;
level = rt_hw_interrupt_disable();
rt_strncpy(shell->password, password, FINSH_PASSWORD_MAX);
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* get the finsh password
*
* @return password
*/
const char *finsh_get_password(void)
{
return shell->password;
}
static void finsh_wait_auth(void)
{
int ch;
rt_bool_t input_finish = RT_FALSE;
char password[FINSH_PASSWORD_MAX] = { 0 };
rt_size_t cur_pos = 0;
/* password not set */
if (rt_strlen(finsh_get_password()) == 0) return;
while (1)
{
rt_kprintf("Password for login: ");
while (!input_finish)
{
while (1)
{
/* read one character from device */
ch = finsh_getchar();
if (ch < 0)
{
continue;
}
if (ch >= ' ' && ch <= '~' && cur_pos < FINSH_PASSWORD_MAX)
{
/* change the printable characters to '*' */
rt_kprintf("*");
password[cur_pos++] = ch;
}
else if (ch == '\b' && cur_pos > 0)
{
/* backspace */
cur_pos--;
password[cur_pos] = '\0';
rt_kprintf("\b \b");
}
else if (ch == '\r' || ch == '\n')
{
rt_kprintf("\n");
input_finish = RT_TRUE;
break;
}
}
}
if (!rt_strncmp(shell->password, password, FINSH_PASSWORD_MAX)) return;
else
{
/* authentication failed, delay 2S for retry */
rt_thread_delay(2 * RT_TICK_PER_SECOND);
rt_kprintf("Sorry, try again.\n");
cur_pos = 0;
input_finish = RT_FALSE;
rt_memset(password, '\0', FINSH_PASSWORD_MAX);
}
}
}
#endif /* FINSH_USING_AUTH */
static void shell_auto_complete(char *prefix)
{
rt_kprintf("\n");
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
msh_auto_complete(prefix);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
extern void list_prefix(char * prefix);
list_prefix(prefix);
#endif
}
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
}
#ifndef FINSH_USING_MSH_ONLY
void finsh_run_line(struct finsh_parser *parser, const char *line)
{
const char *err_str;
if(shell->echo_mode)
rt_kprintf("\n");
finsh_parser_run(parser, (unsigned char *)line);
/* compile node root */
if (finsh_errno() == 0)
{
finsh_compiler_run(parser->root);
}
else
{
err_str = finsh_error_string(finsh_errno());
rt_kprintf("%s\n", err_str);
}
/* run virtual machine */
if (finsh_errno() == 0)
{
char ch;
finsh_vm_run();
ch = (unsigned char)finsh_stack_bottom();
if (ch > 0x20 && ch < 0x7e)
{
rt_kprintf("\t'%c', %d, 0x%08x\n",
(unsigned char)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
else
{
rt_kprintf("\t%d, 0x%08x\n",
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
}
finsh_flush(parser);
}
#endif
#ifdef FINSH_USING_HISTORY
static rt_bool_t shell_handle_history(struct finsh_shell *shell)
{
#if defined(_WIN32)
int i;
rt_kprintf("\r");
for (i = 0; i <= 60; i++)
putchar(' ');
rt_kprintf("\r");
#else
rt_kprintf("\033[2K\r");
#endif
rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
return RT_FALSE;
}
static void shell_push_history(struct finsh_shell *shell)
{
if (shell->line_position != 0)
{
/* push history */
if (shell->history_count >= FINSH_HISTORY_LINES)
{
/* if current cmd is same as last cmd, don't push */
if (memcmp(&shell->cmd_history[FINSH_HISTORY_LINES - 1], shell->line, FINSH_CMD_SIZE))
{
/* move history */
int index;
for (index = 0; index < FINSH_HISTORY_LINES - 1; index ++)
{
memcpy(&shell->cmd_history[index][0],
&shell->cmd_history[index + 1][0], FINSH_CMD_SIZE);
}
memset(&shell->cmd_history[index][0], 0, FINSH_CMD_SIZE);
memcpy(&shell->cmd_history[index][0], shell->line, shell->line_position);
/* it's the maximum history */
shell->history_count = FINSH_HISTORY_LINES;
}
}
else
{
/* if current cmd is same as last cmd, don't push */
if (shell->history_count == 0 || memcmp(&shell->cmd_history[shell->history_count - 1], shell->line, FINSH_CMD_SIZE))
{
shell->current_history = shell->history_count;
memset(&shell->cmd_history[shell->history_count][0], 0, FINSH_CMD_SIZE);
memcpy(&shell->cmd_history[shell->history_count][0], shell->line, shell->line_position);
/* increase count and set current history position */
shell->history_count ++;
}
}
}
shell->current_history = shell->history_count;
}
#endif
void finsh_thread_entry(void *parameter)
{
int ch;
/* normal is echo mode */
#ifndef FINSH_ECHO_DISABLE_DEFAULT
shell->echo_mode = 1;
#else
shell->echo_mode = 0;
#endif
#ifndef FINSH_USING_MSH_ONLY
finsh_init(&shell->parser);
#endif
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
/* set console device as shell device */
if (shell->device == RT_NULL)
{
rt_device_t console = rt_console_get_device();
if (console)
{
finsh_set_device(console->parent.name);
}
}
#endif
#ifdef FINSH_USING_AUTH
/* set the default password when the password isn't setting */
if (rt_strlen(finsh_get_password()) == 0)
{
if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK)
{
rt_kprintf("Finsh password set failed.\n");
}
}
/* waiting authenticate success */
finsh_wait_auth();
#endif
rt_kprintf(FINSH_PROMPT);
while (1)
{
ch = finsh_getchar();
if (ch < 0)
{
continue;
}
/*
* handle control key
* up key : 0x1b 0x5b 0x41
* down key: 0x1b 0x5b 0x42
* right key:0x1b 0x5b 0x43
* left key: 0x1b 0x5b 0x44
*/
if (ch == 0x1b)
{
shell->stat = WAIT_SPEC_KEY;
continue;
}
else if (shell->stat == WAIT_SPEC_KEY)
{
if (ch == 0x5b)
{
shell->stat = WAIT_FUNC_KEY;
continue;
}
shell->stat = WAIT_NORMAL;
}
else if (shell->stat == WAIT_FUNC_KEY)
{
shell->stat = WAIT_NORMAL;
if (ch == 0x41) /* up key */
{
#ifdef FINSH_USING_HISTORY
/* prev history */
if (shell->current_history > 0)
shell->current_history --;
else
{
shell->current_history = 0;
continue;
}
/* copy the history command */
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x42) /* down key */
{
#ifdef FINSH_USING_HISTORY
/* next history */
if (shell->current_history < shell->history_count - 1)
shell->current_history ++;
else
{
/* set to the end of history */
if (shell->history_count != 0)
shell->current_history = shell->history_count - 1;
else
continue;
}
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x44) /* left key */
{
if (shell->line_curpos)
{
rt_kprintf("\b");
shell->line_curpos --;
}
continue;
}
else if (ch == 0x43) /* right key */
{
if (shell->line_curpos < shell->line_position)
{
rt_kprintf("%c", shell->line[shell->line_curpos]);
shell->line_curpos ++;
}
continue;
}
}
/* received null or error */
if (ch == '\0' || ch == 0xFF) continue;
/* handle tab key */
else if (ch == '\t')
{
int i;
/* move the cursor to the beginning of line */
for (i = 0; i < shell->line_curpos; i++)
rt_kprintf("\b");
/* auto complete */
shell_auto_complete(&shell->line[0]);
/* re-calculate position */
shell->line_curpos = shell->line_position = strlen(shell->line);
continue;
}
/* handle backspace key */
else if (ch == 0x7f || ch == 0x08)
{
/* note that shell->line_curpos >= 0 */
if (shell->line_curpos == 0)
continue;
shell->line_position--;
shell->line_curpos--;
if (shell->line_position > shell->line_curpos)
{
int i;
rt_memmove(&shell->line[shell->line_curpos],
&shell->line[shell->line_curpos + 1],
shell->line_position - shell->line_curpos);
shell->line[shell->line_position] = 0;
rt_kprintf("\b%s \b", &shell->line[shell->line_curpos]);
/* move the cursor to the origin position */
for (i = shell->line_curpos; i <= shell->line_position; i++)
rt_kprintf("\b");
}
else
{
rt_kprintf("\b \b");
shell->line[shell->line_position] = 0;
}
continue;
}
/* handle end of line, break */
if (ch == '\r' || ch == '\n')
{
#ifdef FINSH_USING_HISTORY
shell_push_history(shell);
#endif
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
if (shell->echo_mode)
rt_kprintf("\n");
msh_exec(shell->line, shell->line_position);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
/* add ';' and run the command line */
shell->line[shell->line_position] = ';';
if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
else
if (shell->echo_mode) rt_kprintf("\n");
#endif
}
rt_kprintf(FINSH_PROMPT);
memset(shell->line, 0, sizeof(shell->line));
shell->line_curpos = shell->line_position = 0;
continue;
}
/* it's a large line, discard it */
if (shell->line_position >= FINSH_CMD_SIZE)
shell->line_position = 0;
/* normal character */
if (shell->line_curpos < shell->line_position)
{
int i;
rt_memmove(&shell->line[shell->line_curpos + 1],
&shell->line[shell->line_curpos],
shell->line_position - shell->line_curpos);
shell->line[shell->line_curpos] = ch;
if (shell->echo_mode)
rt_kprintf("%s", &shell->line[shell->line_curpos]);
/* move the cursor to new position */
for (i = shell->line_curpos; i < shell->line_position; i++)
rt_kprintf("\b");
}
else
{
shell->line[shell->line_position] = ch;
if (shell->echo_mode)
rt_kprintf("%c", ch);
}
ch = 0;
shell->line_position ++;
shell->line_curpos++;
if (shell->line_position >= FINSH_CMD_SIZE)
{
/* clear command line */
shell->line_position = 0;
shell->line_curpos = 0;
}
} /* end of device read */
}
void finsh_system_function_init(const void *begin, const void *end)
{
_syscall_table_begin = (struct finsh_syscall *) begin;
_syscall_table_end = (struct finsh_syscall *) end;
}
void finsh_system_var_init(const void *begin, const void *end)
{
_sysvar_table_begin = (struct finsh_sysvar *) begin;
_sysvar_table_end = (struct finsh_sysvar *) end;
}
#if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
#ifdef FINSH_USING_SYMTAB
#pragma section="FSymTab"
#pragma section="VSymTab"
#endif
#elif defined(__ADSPBLACKFIN__) /* for VisaulDSP++ Compiler*/
#ifdef FINSH_USING_SYMTAB
extern "asm" int __fsymtab_start;
extern "asm" int __fsymtab_end;
extern "asm" int __vsymtab_start;
extern "asm" int __vsymtab_end;
#endif
#elif defined(_MSC_VER)
#pragma section("FSymTab$a", read)
const char __fsym_begin_name[] = "__start";
const char __fsym_begin_desc[] = "begin of finsh";
__declspec(allocate("FSymTab$a")) const struct finsh_syscall __fsym_begin =
{
__fsym_begin_name,
__fsym_begin_desc,
NULL
};
#pragma section("FSymTab$z", read)
const char __fsym_end_name[] = "__end";
const char __fsym_end_desc[] = "end of finsh";
__declspec(allocate("FSymTab$z")) const struct finsh_syscall __fsym_end =
{
__fsym_end_name,
__fsym_end_desc,
NULL
};
#endif
/*
* @ingroup finsh
*
* This function will initialize finsh shell
*/
int finsh_system_init(void)
{
rt_err_t result = RT_EOK;
rt_thread_t tid;
#ifdef FINSH_USING_SYMTAB
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */
extern const int FSymTab$$Base;
extern const int FSymTab$$Limit;
extern const int VSymTab$$Base;
extern const int VSymTab$$Limit;
finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
#ifndef FINSH_USING_MSH_ONLY
finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
#endif
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
finsh_system_function_init(__section_begin("FSymTab"),
__section_end("FSymTab"));
finsh_system_var_init(__section_begin("VSymTab"),
__section_end("VSymTab"));
#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__)
/* GNU GCC Compiler and TI CCS */
extern const int __fsymtab_start;
extern const int __fsymtab_end;
extern const int __vsymtab_start;
extern const int __vsymtab_end;
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(_MSC_VER)
unsigned int *ptr_begin, *ptr_end;
if(shell)
{
rt_kprintf("finsh shell already init.\n");
return RT_EOK;
}
ptr_begin = (unsigned int *)&__fsym_begin;
ptr_begin += (sizeof(struct finsh_syscall) / sizeof(unsigned int));
while (*ptr_begin == 0) ptr_begin ++;
ptr_end = (unsigned int *) &__fsym_end;
ptr_end --;
while (*ptr_end == 0) ptr_end --;
finsh_system_function_init(ptr_begin, ptr_end);
#endif
#endif
#ifdef RT_USING_HEAP
/* create or set shell structure */
shell = (struct finsh_shell *)rt_calloc(1, sizeof(struct finsh_shell));
if (shell == RT_NULL)
{
rt_kprintf("no memory for shell\n");
return -1;
}
tid = rt_thread_create(FINSH_THREAD_NAME,
finsh_thread_entry, RT_NULL,
FINSH_THREAD_STACK_SIZE, FINSH_THREAD_PRIORITY, 10);
#else
shell = &_shell;
tid = &finsh_thread;
result = rt_thread_init(&finsh_thread,
FINSH_THREAD_NAME,
finsh_thread_entry, RT_NULL,
&finsh_thread_stack[0], sizeof(finsh_thread_stack),
FINSH_THREAD_PRIORITY, 10);
#endif /* RT_USING_HEAP */
rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
finsh_set_prompt_mode(1);
if (tid != NULL && result == RT_EOK)
rt_thread_startup(tid);
return 0;
}
INIT_APP_EXPORT(finsh_system_init);
#endif /* RT_USING_FINSH */
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard Add finsh_get_prompt function declaration
*/
#ifndef __SHELL_H__
#define __SHELL_H__
#include <rtthread.h>
#include "finsh.h"
#ifndef FINSH_THREAD_PRIORITY
#define FINSH_THREAD_PRIORITY 20
#endif
#ifndef FINSH_THREAD_STACK_SIZE
#define FINSH_THREAD_STACK_SIZE 2048
#endif
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE 80
#endif
#define FINSH_OPTION_ECHO 0x01
#define FINSH_PROMPT finsh_get_prompt()
const char* finsh_get_prompt(void);
int finsh_set_prompt(const char * prompt);
#ifdef FINSH_USING_HISTORY
#ifndef FINSH_HISTORY_LINES
#define FINSH_HISTORY_LINES 5
#endif
#endif
#ifdef FINSH_USING_AUTH
#ifndef FINSH_PASSWORD_MAX
#define FINSH_PASSWORD_MAX RT_NAME_MAX
#endif
#ifndef FINSH_PASSWORD_MIN
#define FINSH_PASSWORD_MIN 6
#endif
#ifndef FINSH_DEFAULT_PASSWORD
#define FINSH_DEFAULT_PASSWORD "rtthread"
#endif
#endif /* FINSH_USING_AUTH */
#ifndef FINSH_THREAD_NAME
#define FINSH_THREAD_NAME "tshell"
#endif
enum input_stat
{
WAIT_NORMAL,
WAIT_SPEC_KEY,
WAIT_FUNC_KEY,
};
struct finsh_shell
{
struct rt_semaphore rx_sem;
enum input_stat stat;
rt_uint8_t echo_mode:1;
rt_uint8_t prompt_mode: 1;
#ifdef FINSH_USING_HISTORY
rt_uint16_t current_history;
rt_uint16_t history_count;
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
#endif
#ifndef FINSH_USING_MSH_ONLY
struct finsh_parser parser;
#endif
char line[FINSH_CMD_SIZE];
rt_uint16_t line_position;
rt_uint16_t line_curpos;
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
rt_device_t device;
#endif
#ifdef FINSH_USING_AUTH
char password[FINSH_PASSWORD_MAX];
#endif
};
void finsh_set_echo(rt_uint32_t echo);
rt_uint32_t finsh_get_echo(void);
int finsh_system_init(void);
void finsh_set_device(const char* device_name);
const char* finsh_get_device(void);
rt_uint32_t finsh_get_prompt_mode(void);
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
#ifdef FINSH_USING_AUTH
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
#endif
#endif
+249
View File
@@ -0,0 +1,249 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_H__
#define __FINSH_H__
#include <rtthread.h>
#include "finsh_api.h"
/* -- the beginning of option -- */
#define FINSH_NAME_MAX 16 /* max length of identifier */
#define FINSH_NODE_MAX 16 /* max number of node */
#define FINSH_HEAP_MAX 128 /* max length of heap */
#define FINSH_STRING_MAX 128 /* max length of string */
#define FINSH_VARIABLE_MAX 8 /* max number of variable */
#define FINSH_STACK_MAX 64 /* max stack size */
#define FINSH_TEXT_MAX 128 /* max text segment size */
#define HEAP_ALIGNMENT 4 /* heap alignment */
#define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
#define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
#define FINSH_SET16(x, v) \
do \
{ \
*(x) = (v) & 0x00ff; \
(*((x)+1)) = (v) >> 8; \
} while ( 0 )
#define FINSH_SET32(x, v) \
do \
{ \
*(x) = (rt_uint32_t)(v) & 0x000000ff; \
(*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
(*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
(*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
} while ( 0 )
/* -- the end of option -- */
/* std header file */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define FINSH_VERSION_MAJOR 1
#define FINSH_VERSION_MINOR 0
/**
* @addtogroup finsh
*/
/*@{*/
#define FINSH_ERROR_OK 0 /**< No error */
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */
/*@}*/
/* system call item */
struct finsh_syscall_item
{
struct finsh_syscall_item* next; /* next item */
struct finsh_syscall syscall; /* syscall */
};
extern struct finsh_syscall_item *global_syscall_list;
/* system variable table */
struct finsh_sysvar
{
const char* name; /* the name of variable */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system variable */
#endif
uint8_t type; /* the type of variable */
void* var ; /* the address of variable */
};
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
#else
#define FINSH_NEXT_SYSCALL(index) index++
#define FINSH_NEXT_SYSVAR(index) index++
#endif
/* system variable item */
struct finsh_sysvar_item
{
struct finsh_sysvar_item *next; /* next item */
struct finsh_sysvar sysvar; /* system variable */
};
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
extern struct finsh_sysvar_item* global_sysvar_list;
/* find out system variable, which should be implemented in user program */
struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
struct finsh_token
{
char eof;
char replay;
int position;
uint8_t current_token;
union {
char char_value;
int int_value;
long long_value;
} value;
uint8_t string[FINSH_STRING_MAX];
uint8_t* line;
};
#define FINSH_IDTYPE_VAR 0x01
#define FINSH_IDTYPE_SYSVAR 0x02
#define FINSH_IDTYPE_SYSCALL 0x04
#define FINSH_IDTYPE_ADDRESS 0x08
struct finsh_node
{
uint8_t node_type; /* node node_type */
uint8_t data_type; /* node data node_type */
uint8_t idtype; /* id node information */
union { /* value node */
char char_value;
short short_value;
int int_value;
long long_value;
void* ptr;
} value;
union
{
/* point to variable identifier or function identifier */
struct finsh_var *var;
struct finsh_sysvar *sysvar;
struct finsh_syscall*syscall;
}id;
/* sibling and child node */
struct finsh_node *sibling, *child;
};
struct finsh_parser
{
uint8_t* parser_string;
struct finsh_token token;
struct finsh_node* root;
};
/**
* @ingroup finsh
*
* The basic data type in finsh shell
*/
enum finsh_type {
finsh_type_unknown = 0, /**< unknown data type */
finsh_type_void, /**< void */
finsh_type_voidp, /**< void pointer */
finsh_type_char, /**< char */
finsh_type_uchar, /**< unsigned char */
finsh_type_charp, /**< char pointer */
finsh_type_short, /**< short */
finsh_type_ushort, /**< unsigned short */
finsh_type_shortp, /**< short pointer */
finsh_type_int, /**< int */
finsh_type_uint, /**< unsigned int */
finsh_type_intp, /**< int pointer */
finsh_type_long, /**< long */
finsh_type_ulong, /**< unsigned long */
finsh_type_longp /**< long pointer */
};
/* init finsh environment */
int finsh_init(struct finsh_parser* parser);
/* flush finsh node, text segment */
int finsh_flush(struct finsh_parser* parser);
/* reset all of finsh */
int finsh_reset(struct finsh_parser* parser);
#ifdef RT_USING_DEVICE
void finsh_set_device(const char* device_name);
#endif
/* run finsh parser to generate abstract synatx tree */
void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
/* run compiler to compile abstract syntax tree */
int finsh_compiler_run(struct finsh_node* node);
/* run finsh virtual machine */
void finsh_vm_run(void);
/* get variable value */
struct finsh_var* finsh_var_lookup(const char* name);
/* get bottom value of stack */
long finsh_stack_bottom(void);
/* get error number of finsh */
uint8_t finsh_errno(void);
/* get error string */
const char* finsh_error_string(uint8_t type);
#ifdef RT_USING_HEAP
/**
* @ingroup finsh
*
* This function appends a system call to finsh runtime environment
* @param name the name of system call
* @param func the function pointer of system call
*/
void finsh_syscall_append(const char* name, syscall_func func);
/**
* @ingroup finsh
*
* This function appends a system variable to finsh runtime environment
* @param name the name of system variable
* @param type the data type of system variable
* @param addr the address of system variable
*/
void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
#endif
#endif
@@ -0,0 +1,220 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef FINSH_API_H__
#define FINSH_API_H__
#include "finsh_config.h"
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#pragma section("VSymTab",read)
#endif
typedef long (*syscall_func)(void);
/* system call table */
struct finsh_syscall
{
const char* name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system call */
#endif
syscall_func func; /* the function address of system call */
};
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
#endif
#ifdef FINSH_USING_DESCRIPTION
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
__declspec(allocate("VSymTab")) \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#endif
#else
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#endif
#endif /* end of FINSH_USING_DESCRIPTION */
#endif /* end of FINSH_USING_SYMTAB */
/**
* @ingroup finsh
*
* This macro exports a system function to finsh shell.
*
* @param name the name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT(name, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
/**
* @ingroup finsh
*
* This macro exports a system function with an alias name to finsh shell.
*
* @param name the name of function.
* @param alias the alias name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
/**
* @ingroup finsh
*
* This macro exports a command to module shell.
*
* @param command the name of command.
* @param desc the description of command, which will show in help.
*/
#ifdef FINSH_USING_MSH
#define MSH_CMD_EXPORT(command, desc) \
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
#else
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
#endif
#endif
@@ -0,0 +1,29 @@
/* FinSH config file */
#ifndef __MSH_CFG_H__
#define __MSH_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
// <h>FinSH Configuration
// <o>the priority of finsh thread <1-30>
// <i>the priority of finsh thread
// <i>Default: 21
#define FINSH_THREAD_PRIORITY 21
// <o>the stack of finsh thread <1-4096>
// <i>the stack of finsh thread
// <i>Default: 4096 (4096Byte)
#define FINSH_THREAD_STACK_SIZE 1024
#define FINSH_USING_SYMTAB
// <c1>Enable command description
// <i>Enable command description
#define FINSH_USING_DESCRIPTION
// </c>
// </h>
// <<< end of configuration section >>>
#endif
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for FinSH
*/
#ifndef __M_SHELL__
#define __M_SHELL__
#include <rtthread.h>
rt_bool_t msh_is_used(void);
int msh_exec(char *cmd, rt_size_t length);
void msh_auto_complete(char *prefix);
int msh_exec_module(const char *cmd_line, int size);
int msh_exec_script(const char *cmd_line, int size);
#endif
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard Add finsh_get_prompt function declaration
*/
#ifndef __SHELL_H__
#define __SHELL_H__
#include <rtthread.h>
#include "finsh.h"
#ifndef FINSH_THREAD_PRIORITY
#define FINSH_THREAD_PRIORITY 20
#endif
#ifndef FINSH_THREAD_STACK_SIZE
#define FINSH_THREAD_STACK_SIZE 2048
#endif
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE 80
#endif
#define FINSH_OPTION_ECHO 0x01
#define FINSH_PROMPT finsh_get_prompt()
const char* finsh_get_prompt(void);
int finsh_set_prompt(const char * prompt);
#ifdef FINSH_USING_HISTORY
#ifndef FINSH_HISTORY_LINES
#define FINSH_HISTORY_LINES 5
#endif
#endif
#ifdef FINSH_USING_AUTH
#ifndef FINSH_PASSWORD_MAX
#define FINSH_PASSWORD_MAX RT_NAME_MAX
#endif
#ifndef FINSH_PASSWORD_MIN
#define FINSH_PASSWORD_MIN 6
#endif
#ifndef FINSH_DEFAULT_PASSWORD
#define FINSH_DEFAULT_PASSWORD "rtthread"
#endif
#endif /* FINSH_USING_AUTH */
#ifndef FINSH_THREAD_NAME
#define FINSH_THREAD_NAME "tshell"
#endif
enum input_stat
{
WAIT_NORMAL,
WAIT_SPEC_KEY,
WAIT_FUNC_KEY,
};
struct finsh_shell
{
struct rt_semaphore rx_sem;
enum input_stat stat;
rt_uint8_t echo_mode:1;
rt_uint8_t prompt_mode: 1;
#ifdef FINSH_USING_HISTORY
rt_uint16_t current_history;
rt_uint16_t history_count;
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
#endif
#ifndef FINSH_USING_MSH_ONLY
struct finsh_parser parser;
#endif
char line[FINSH_CMD_SIZE];
rt_uint16_t line_position;
rt_uint16_t line_curpos;
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
rt_device_t device;
#endif
#ifdef FINSH_USING_AUTH
char password[FINSH_PASSWORD_MAX];
#endif
};
void finsh_set_echo(rt_uint32_t echo);
rt_uint32_t finsh_get_echo(void);
int finsh_system_init(void);
void finsh_set_device(const char* device_name);
const char* finsh_get_device(void);
rt_uint32_t finsh_get_prompt_mode(void);
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
#ifdef FINSH_USING_AUTH
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
#endif
#endif
+187
View File
@@ -0,0 +1,187 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016-11-12 Bernard The first version
* 2018-05-25 armink Add simple API, such as LOG_D, LOG_E
*/
/*
* The macro definitions for debug
*
* These macros are defined in static. If you want to use debug macro, you can
* use as following code:
*
* In your C/C++ file, enable/disable DEBUG_ENABLE macro, and then include this
* header file.
*
* #define DBG_TAG "MOD_TAG"
* #define DBG_LVL DBG_INFO
* #include <rtdbg.h> // must after of DBG_LVL, DBG_TAG or other options
*
* Then in your C/C++ file, you can use LOG_X macro to print out logs:
* LOG_D("this is a debug log!");
* LOG_E("this is a error log!");
*/
#ifndef RT_DBG_H__
#define RT_DBG_H__
#include <rtconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* the debug log will force enable when RT_DEBUG macro is defined */
#if defined(RT_DEBUG) && !defined(DBG_ENABLE)
#define DBG_ENABLE
#endif
/* it will force output color log when RT_DEBUG_COLOR macro is defined */
#if defined(RT_DEBUG_COLOR) && !defined(DBG_COLOR)
#define DBG_COLOR
#endif
#if defined(RT_USING_ULOG)
/* using ulog compatible with rtdbg */
#include <ulog.h>
#else
/* DEBUG level */
#define DBG_ERROR 0
#define DBG_WARNING 1
#define DBG_INFO 2
#define DBG_LOG 3
#ifdef DBG_TAG
#ifndef DBG_SECTION_NAME
#define DBG_SECTION_NAME DBG_TAG
#endif
#else
/* compatible with old version */
#ifndef DBG_SECTION_NAME
#define DBG_SECTION_NAME "DBG"
#endif
#endif /* DBG_TAG */
#ifdef DBG_ENABLE
#ifdef DBG_LVL
#ifndef DBG_LEVEL
#define DBG_LEVEL DBG_LVL
#endif
#else
/* compatible with old version */
#ifndef DBG_LEVEL
#define DBG_LEVEL DBG_WARNING
#endif
#endif /* DBG_LVL */
/*
* The color for terminal (foreground)
* BLACK 30
* RED 31
* GREEN 32
* YELLOW 33
* BLUE 34
* PURPLE 35
* CYAN 36
* WHITE 37
*/
#ifdef DBG_COLOR
#define _DBG_COLOR(n) rt_kprintf("\033["#n"m")
#define _DBG_LOG_HDR(lvl_name, color_n) \
rt_kprintf("\033["#color_n"m[" lvl_name "/" DBG_SECTION_NAME "] ")
#define _DBG_LOG_X_END \
rt_kprintf("\033[0m\n")
#else
#define _DBG_COLOR(n)
#define _DBG_LOG_HDR(lvl_name, color_n) \
rt_kprintf("[" lvl_name "/" DBG_SECTION_NAME "] ")
#define _DBG_LOG_X_END \
rt_kprintf("\n")
#endif /* DBG_COLOR */
/*
* static debug routine
* NOTE: This is a NOT RECOMMENDED API. Please using LOG_X API.
* It will be DISCARDED later. Because it will take up more resources.
*/
#define dbg_log(level, fmt, ...) \
if ((level) <= DBG_LEVEL) \
{ \
switch(level) \
{ \
case DBG_ERROR: _DBG_LOG_HDR("E", 31); break; \
case DBG_WARNING: _DBG_LOG_HDR("W", 33); break; \
case DBG_INFO: _DBG_LOG_HDR("I", 32); break; \
case DBG_LOG: _DBG_LOG_HDR("D", 0); break; \
default: break; \
} \
rt_kprintf(fmt, ##__VA_ARGS__); \
_DBG_COLOR(0); \
}
#define dbg_here \
if ((DBG_LEVEL) <= DBG_LOG){ \
rt_kprintf(DBG_SECTION_NAME " Here %s:%d\n", \
__FUNCTION__, __LINE__); \
}
#define dbg_log_line(lvl, color_n, fmt, ...) \
do \
{ \
_DBG_LOG_HDR(lvl, color_n); \
rt_kprintf(fmt, ##__VA_ARGS__); \
_DBG_LOG_X_END; \
} \
while (0)
#define dbg_raw(...) rt_kprintf(__VA_ARGS__);
#else
#define dbg_log(level, fmt, ...)
#define dbg_here
#define dbg_enter
#define dbg_exit
#define dbg_log_line(lvl, color_n, fmt, ...)
#define dbg_raw(...)
#endif /* DBG_ENABLE */
#if (DBG_LEVEL >= DBG_LOG)
#define LOG_D(fmt, ...) dbg_log_line("D", 0, fmt, ##__VA_ARGS__)
#else
#define LOG_D(...)
#endif
#if (DBG_LEVEL >= DBG_INFO)
#define LOG_I(fmt, ...) dbg_log_line("I", 32, fmt, ##__VA_ARGS__)
#else
#define LOG_I(...)
#endif
#if (DBG_LEVEL >= DBG_WARNING)
#define LOG_W(fmt, ...) dbg_log_line("W", 33, fmt, ##__VA_ARGS__)
#else
#define LOG_W(...)
#endif
#if (DBG_LEVEL >= DBG_ERROR)
#define LOG_E(fmt, ...) dbg_log_line("E", 31, fmt, ##__VA_ARGS__)
#else
#define LOG_E(...)
#endif
#define LOG_RAW(...) dbg_raw(__VA_ARGS__)
#endif /* defined(RT_USING_ULOG) && define(DBG_ENABLE) */
#ifdef __cplusplus
}
#endif
#endif /* RT_DBG_H__ */
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __RTDEBUG_H__
#define __RTDEBUG_H__
#include <rtconfig.h>
/* settings depend check */
/* Using this macro to control all kernel debug features. */
#ifdef RT_DEBUG
/* Turn on some of these (set to non-zero) to debug kernel */
#ifndef RT_DEBUG_MEM
#define RT_DEBUG_MEM 0
#endif
#ifndef RT_DEBUG_MEMHEAP
#define RT_DEBUG_MEMHEAP 0
#endif
#ifndef RT_DEBUG_MODULE
#define RT_DEBUG_MODULE 0
#endif
#ifndef RT_DEBUG_SCHEDULER
#define RT_DEBUG_SCHEDULER 0
#endif
#ifndef RT_DEBUG_SLAB
#define RT_DEBUG_SLAB 0
#endif
#ifndef RT_DEBUG_THREAD
#define RT_DEBUG_THREAD 0
#endif
#ifndef RT_DEBUG_TIMER
#define RT_DEBUG_TIMER 0
#endif
#ifndef RT_DEBUG_IRQ
#define RT_DEBUG_IRQ 0
#endif
#ifndef RT_DEBUG_IPC
#define RT_DEBUG_IPC 0
#endif
#ifndef RT_DEBUG_INIT
#define RT_DEBUG_INIT 0
#endif
/* Turn on this to enable context check */
#ifndef RT_DEBUG_CONTEXT_CHECK
#define RT_DEBUG_CONTEXT_CHECK 1
#endif
#define RT_DEBUG_LOG(type, message) \
do \
{ \
if (type) \
rt_kprintf message; \
} \
while (0)
#define RT_ASSERT(EX) \
if (!(EX)) \
{ \
rt_assert_handler(#EX, __FUNCTION__, __LINE__); \
}
/* Macro to check current context */
#if RT_DEBUG_CONTEXT_CHECK
#define RT_DEBUG_NOT_IN_INTERRUPT \
do \
{ \
rt_base_t level; \
level = rt_hw_interrupt_disable(); \
if (rt_interrupt_get_nest() != 0) \
{ \
rt_kprintf("Function[%s] shall not be used in ISR\n", __FUNCTION__); \
RT_ASSERT(0) \
} \
rt_hw_interrupt_enable(level); \
} \
while (0)
/* "In thread context" means:
* 1) the scheduler has been started
* 2) not in interrupt context.
*/
#define RT_DEBUG_IN_THREAD_CONTEXT \
do \
{ \
rt_base_t level; \
level = rt_hw_interrupt_disable(); \
if (rt_thread_self() == RT_NULL) \
{ \
rt_kprintf("Function[%s] shall not be used before scheduler start\n", \
__FUNCTION__); \
RT_ASSERT(0) \
} \
RT_DEBUG_NOT_IN_INTERRUPT; \
rt_hw_interrupt_enable(level); \
} \
while (0)
#else
#define RT_DEBUG_NOT_IN_INTERRUPT
#define RT_DEBUG_IN_THREAD_CONTEXT
#endif
#else /* RT_DEBUG */
#define RT_ASSERT(EX)
#define RT_DEBUG_LOG(type, message)
#define RT_DEBUG_NOT_IN_INTERRUPT
#define RT_DEBUG_IN_THREAD_CONTEXT
#endif /* RT_DEBUG */
#endif /* __RTDEBUG_H__ */
+875
View File
@@ -0,0 +1,875 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2007-01-10 Bernard the first version
* 2008-07-12 Bernard remove all rt_int8, rt_uint32_t etc typedef
* 2010-10-26 yi.qiu add module support
* 2010-11-10 Bernard add cleanup callback function in thread exit.
* 2011-05-09 Bernard use builtin va_arg in GCC 4.x
* 2012-11-16 Bernard change RT_NULL from ((void*)0) to 0.
* 2012-12-29 Bernard change the RT_USING_MEMPOOL location and add
* RT_USING_MEMHEAP condition.
* 2012-12-30 Bernard add more control command for graphic.
* 2013-01-09 Bernard change version number.
* 2015-02-01 Bernard change version number to v2.1.0
* 2017-08-31 Bernard change version number to v3.0.0
* 2017-11-30 Bernard change version number to v3.0.1
* 2017-12-27 Bernard change version number to v3.0.2
* 2018-02-24 Bernard change version number to v3.0.3
* 2018-04-25 Bernard change version number to v3.0.4
* 2018-05-31 Bernard change version number to v3.1.0
* 2018-09-04 Bernard change version number to v3.1.1
* 2018-09-14 Bernard apply Apache License v2.0 to RT-Thread Kernel
* 2018-12-28 armink change version number to v3.1.2
* 2019-03-14 armink change version number to v3.1.3
* 2019-06-12 armink change version number to v3.1.4
* 2020-05-14 armink change version number to v3.1.5
*/
#ifndef __RT_DEF_H__
#define __RT_DEF_H__
/* include rtconfig header to import configuration */
#include <rtconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup BasicDef
*/
/*@{*/
/* RT-Thread version information */
#define RT_VERSION 3L /**< major version number */
#define RT_SUBVERSION 1L /**< minor version number */
#define RT_REVISION 5L /**< revise version number */
/* RT-Thread version */
#define RTTHREAD_VERSION ((RT_VERSION * 10000) + \
(RT_SUBVERSION * 100) + RT_REVISION)
/* RT-Thread basic data type definitions */
#ifndef RT_USING_ARCH_DATA_TYPE
typedef signed char rt_int8_t; /**< 8bit integer type */
typedef signed short rt_int16_t; /**< 16bit integer type */
typedef signed int rt_int32_t; /**< 32bit integer type */
typedef unsigned char rt_uint8_t; /**< 8bit unsigned integer type */
typedef unsigned short rt_uint16_t; /**< 16bit unsigned integer type */
typedef unsigned int rt_uint32_t; /**< 32bit unsigned integer type */
#ifdef ARCH_CPU_64BIT
typedef signed long rt_int64_t; /**< 64bit integer type */
typedef unsigned long rt_uint64_t; /**< 64bit unsigned integer type */
#else
typedef signed long long rt_int64_t; /**< 64bit integer type */
typedef unsigned long long rt_uint64_t; /**< 64bit unsigned integer type */
#endif
#endif
typedef int rt_bool_t; /**< boolean type */
typedef long rt_base_t; /**< Nbit CPU related date type */
typedef unsigned long rt_ubase_t; /**< Nbit unsigned CPU related data type */
typedef rt_base_t rt_err_t; /**< Type for error number */
typedef rt_uint32_t rt_time_t; /**< Type for time stamp */
typedef rt_uint32_t rt_tick_t; /**< Type for tick count */
typedef rt_base_t rt_flag_t; /**< Type for flags */
typedef rt_ubase_t rt_size_t; /**< Type for size number */
typedef rt_ubase_t rt_dev_t; /**< Type for device */
typedef rt_base_t rt_off_t; /**< Type for offset */
/* boolean type definitions */
#define RT_TRUE 1 /**< boolean true */
#define RT_FALSE 0 /**< boolean fails */
/**@}*/
/* maximum value of base type */
#define RT_UINT8_MAX 0xff /**< Maxium number of UINT8 */
#define RT_UINT16_MAX 0xffff /**< Maxium number of UINT16 */
#define RT_UINT32_MAX 0xffffffff /**< Maxium number of UINT32 */
#define RT_TICK_MAX RT_UINT32_MAX /**< Maxium number of tick */
/* maximum value of ipc type */
#define RT_SEM_VALUE_MAX RT_UINT16_MAX /**< Maxium number of semaphore .value */
#define RT_MUTEX_VALUE_MAX RT_UINT16_MAX /**< Maxium number of mutex .value */
#define RT_MUTEX_HOLD_MAX RT_UINT8_MAX /**< Maxium number of mutex .hold */
#define RT_MB_ENTRY_MAX RT_UINT16_MAX /**< Maxium number of mailbox .entry */
#define RT_MQ_ENTRY_MAX RT_UINT16_MAX /**< Maxium number of message queue .entry */
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __CLANG_ARM
#endif
/* Compiler Related Definitions */
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */
#include <stdarg.h>
#define SECTION(x) __attribute__((section(x)))
#define RT_UNUSED __attribute__((unused))
#define RT_USED __attribute__((used))
#define ALIGN(n) __attribute__((aligned(n)))
#define RT_WEAK __attribute__((weak))
#define rt_inline static __inline
#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
#include <stdarg.h>
#define SECTION(x) @ x
#define RT_UNUSED
#define RT_USED __root
#define PRAGMA(x) _Pragma(#x)
#define ALIGN(n) PRAGMA(data_alignment=n)
#define RT_WEAK __weak
#define rt_inline static inline
#elif defined (__GNUC__) /* GNU GCC Compiler */
#ifdef RT_USING_NEWLIB
#include <stdarg.h>
#else
/* the version of GNU GCC must be greater than 4.x */
typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#endif
#define SECTION(x) __attribute__((section(x)))
#define RT_UNUSED __attribute__((unused))
#define RT_USED __attribute__((used))
#define ALIGN(n) __attribute__((aligned(n)))
#define RT_WEAK __attribute__((weak))
#define rt_inline static __inline
#elif defined (__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
#include <stdarg.h>
#define SECTION(x) __attribute__((section(x)))
#define RT_UNUSED __attribute__((unused))
#define RT_USED __attribute__((used))
#define ALIGN(n) __attribute__((aligned(n)))
#define RT_WEAK __attribute__((weak))
#define rt_inline static inline
#elif defined (_MSC_VER)
#include <stdarg.h>
#define SECTION(x)
#define RT_UNUSED
#define RT_USED
#define ALIGN(n) __declspec(align(n))
#define RT_WEAK
#define rt_inline static __inline
#elif defined (__TI_COMPILER_VERSION__)
#include <stdarg.h>
/* The way that TI compiler set section is different from other(at least
* GCC and MDK) compilers. See ARM Optimizing C/C++ Compiler 5.9.3 for more
* details. */
#define SECTION(x)
#define RT_UNUSED
#define RT_USED
#define PRAGMA(x) _Pragma(#x)
#define ALIGN(n)
#define RT_WEAK
#define rt_inline static inline
#else
#error not supported tool chain
#endif
/* initialization export */
#ifdef RT_USING_COMPONENTS_INIT
typedef int (*init_fn_t)(void);
#ifdef _MSC_VER /* we do not support MS VC++ compiler */
#define INIT_EXPORT(fn, level)
#else
#if RT_DEBUG_INIT
struct rt_init_desc
{
const char* fn_name;
const init_fn_t fn;
};
#define INIT_EXPORT(fn, level) \
const char __rti_##fn##_name[] = #fn; \
RT_USED const struct rt_init_desc __rt_init_desc_##fn SECTION(".rti_fn." level) = \
{ __rti_##fn##_name, fn};
#else
#define INIT_EXPORT(fn, level) \
RT_USED const init_fn_t __rt_init_##fn SECTION(".rti_fn." level) = fn
#endif
#endif
#else
#define INIT_EXPORT(fn, level)
#endif
/* board init routines will be called in board_init() function */
#define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
/* pre/device/component/env/app init routines will be called in init_thread */
/* components pre-initialization (pure software initilization) */
#define INIT_PREV_EXPORT(fn) INIT_EXPORT(fn, "2")
/* device initialization */
#define INIT_DEVICE_EXPORT(fn) INIT_EXPORT(fn, "3")
/* components initialization (dfs, lwip, ...) */
#define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "4")
/* environment initialization (mount disk, ...) */
#define INIT_ENV_EXPORT(fn) INIT_EXPORT(fn, "5")
/* appliation initialization (rtgui application etc ...) */
#define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")
#if !defined(RT_USING_FINSH)
/* define these to empty, even if not include finsh.h file */
#define FINSH_FUNCTION_EXPORT(name, desc)
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
#define FINSH_VAR_EXPORT(name, type, desc)
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
#elif !defined(FINSH_USING_SYMTAB)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc)
#endif
/* event length */
#define RT_EVENT_LENGTH 32
/* memory management option */
#define RT_MM_PAGE_SIZE 4096
#define RT_MM_PAGE_MASK (RT_MM_PAGE_SIZE - 1)
#define RT_MM_PAGE_BITS 12
/* kernel malloc definitions */
#ifndef RT_KERNEL_MALLOC
#define RT_KERNEL_MALLOC(sz) rt_malloc(sz)
#endif
#ifndef RT_KERNEL_FREE
#define RT_KERNEL_FREE(ptr) rt_free(ptr)
#endif
#ifndef RT_KERNEL_REALLOC
#define RT_KERNEL_REALLOC(ptr, size) rt_realloc(ptr, size)
#endif
/**
* @addtogroup Error
*/
/**@{*/
/* RT-Thread error code definitions */
#define RT_EOK 0 /**< There is no error */
#define RT_ERROR 1 /**< A generic error happens */
#define RT_ETIMEOUT 2 /**< Timed out */
#define RT_EFULL 3 /**< The resource is full */
#define RT_EEMPTY 4 /**< The resource is empty */
#define RT_ENOMEM 5 /**< No memory */
#define RT_ENOSYS 6 /**< No system */
#define RT_EBUSY 7 /**< Busy */
#define RT_EIO 8 /**< IO error */
#define RT_EINTR 9 /**< Interrupted system call */
#define RT_EINVAL 10 /**< Invalid argument */
/**@}*/
/**
* @ingroup BasicDef
*
* @def RT_ALIGN(size, align)
* Return the most contiguous size aligned at specified width. RT_ALIGN(13, 4)
* would return 16.
*/
#define RT_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1))
/**
* @ingroup BasicDef
*
* @def RT_ALIGN_DOWN(size, align)
* Return the down number of aligned at specified width. RT_ALIGN_DOWN(13, 4)
* would return 12.
*/
#define RT_ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
/**
* @ingroup BasicDef
*
* @def RT_NULL
* Similar as the \c NULL in C library.
*/
#define RT_NULL (0)
/**
* Double List structure
*/
struct rt_list_node
{
struct rt_list_node *next; /**< point to next node. */
struct rt_list_node *prev; /**< point to prev node. */
};
typedef struct rt_list_node rt_list_t; /**< Type for lists. */
/**
* Single List structure
*/
struct rt_slist_node
{
struct rt_slist_node *next; /**< point to next node. */
};
typedef struct rt_slist_node rt_slist_t; /**< Type for single list. */
/**
* @addtogroup KernelObject
*/
/**@{*/
/*
* kernel object macros
*/
/**
* Base structure of Kernel object
*/
struct rt_object
{
char name[RT_NAME_MAX]; /**< name of kernel object */
rt_uint8_t type; /**< type of kernel object */
rt_uint8_t flag; /**< flag of kernel object */
rt_list_t list; /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
/**
* The object type can be one of the follows with specific
* macros enabled:
* - Thread
* - Semaphore
* - Mutex
* - Event
* - MailBox
* - MessageQueue
* - MemHeap
* - MemPool
* - Device
* - Timer
* - Unknown
* - Static
*/
enum rt_object_class_type
{
RT_Object_Class_Null = 0x00, /**< The object is not used. */
RT_Object_Class_Thread = 0x01, /**< The object is a thread. */
RT_Object_Class_Semaphore = 0x02, /**< The object is a semaphore. */
RT_Object_Class_Mutex = 0x03, /**< The object is a mutex. */
RT_Object_Class_Event = 0x04, /**< The object is a event. */
RT_Object_Class_MailBox = 0x05, /**< The object is a mail box. */
RT_Object_Class_MessageQueue = 0x06, /**< The object is a message queue. */
RT_Object_Class_MemHeap = 0x07, /**< The object is a memory heap. */
RT_Object_Class_MemPool = 0x08, /**< The object is a memory pool. */
RT_Object_Class_Device = 0x09, /**< The object is a device. */
RT_Object_Class_Timer = 0x0a, /**< The object is a timer. */
RT_Object_Class_Unknown = 0x0c, /**< The object is unknown. */
RT_Object_Class_Static = 0x80 /**< The object is a static object. */
};
/**
* The information of the kernel object
*/
struct rt_object_information
{
enum rt_object_class_type type; /**< object class type */
rt_list_t object_list; /**< object list */
rt_size_t object_size; /**< object size */
};
/**
* The hook function call macro
*/
#ifdef RT_USING_HOOK
#define RT_OBJECT_HOOK_CALL(func, argv) \
do { if ((func) != RT_NULL) func argv; } while (0)
#else
#define RT_OBJECT_HOOK_CALL(func, argv)
#endif
/**@}*/
/**
* @addtogroup Clock
*/
/**@{*/
/**
* clock & timer macros
*/
#define RT_TIMER_FLAG_DEACTIVATED 0x0 /**< timer is deactive */
#define RT_TIMER_FLAG_ACTIVATED 0x1 /**< timer is active */
#define RT_TIMER_FLAG_ONE_SHOT 0x0 /**< one shot timer */
#define RT_TIMER_FLAG_PERIODIC 0x2 /**< periodic timer */
#define RT_TIMER_FLAG_HARD_TIMER 0x0 /**< hard timer,the timer's callback function will be called in tick isr. */
#define RT_TIMER_FLAG_SOFT_TIMER 0x4 /**< soft timer,the timer's callback function will be called in timer thread. */
#define RT_TIMER_CTRL_SET_TIME 0x0 /**< set timer control command */
#define RT_TIMER_CTRL_GET_TIME 0x1 /**< get timer control command */
#define RT_TIMER_CTRL_SET_ONESHOT 0x2 /**< change timer to one shot */
#define RT_TIMER_CTRL_SET_PERIODIC 0x3 /**< change timer to periodic */
#define RT_TIMER_CTRL_GET_STATE 0x4 /**< get timer run state active or deactive*/
#ifndef RT_TIMER_SKIP_LIST_LEVEL
#define RT_TIMER_SKIP_LIST_LEVEL 1
#endif
/* 1 or 3 */
#ifndef RT_TIMER_SKIP_LIST_MASK
#define RT_TIMER_SKIP_LIST_MASK 0x3
#endif
/**
* timer structure
*/
struct rt_timer
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL];
void (*timeout_func)(void *parameter); /**< timeout function */
void *parameter; /**< timeout function's parameter */
rt_tick_t init_tick; /**< timer timeout tick */
rt_tick_t timeout_tick; /**< timeout tick */
};
typedef struct rt_timer *rt_timer_t;
/**@}*/
/**
* @addtogroup Thread
*/
/**@{*/
/*
* Thread
*/
/*
* thread state definitions
*/
#define RT_THREAD_INIT 0x00 /**< Initialized status */
#define RT_THREAD_READY 0x01 /**< Ready status */
#define RT_THREAD_SUSPEND 0x02 /**< Suspend status */
#define RT_THREAD_RUNNING 0x03 /**< Running status */
#define RT_THREAD_BLOCK RT_THREAD_SUSPEND /**< Blocked status */
#define RT_THREAD_CLOSE 0x04 /**< Closed status */
#define RT_THREAD_STAT_MASK 0x0f
/**
* thread control command definitions
*/
#define RT_THREAD_CTRL_STARTUP 0x00 /**< Startup thread. */
#define RT_THREAD_CTRL_CLOSE 0x01 /**< Close thread. */
#define RT_THREAD_CTRL_CHANGE_PRIORITY 0x02 /**< Change thread priority. */
#define RT_THREAD_CTRL_INFO 0x03 /**< Get thread information. */
/**
* Thread structure
*/
struct rt_thread
{
/* rt object */
char name[RT_NAME_MAX]; /**< the name of thread */
rt_uint8_t type; /**< type of object */
rt_uint8_t flags; /**< thread's flags */
rt_list_t list; /**< the object list */
rt_list_t tlist; /**< the thread list */
/* stack point and entry */
void *sp; /**< stack point */
void *entry; /**< entry */
void *parameter; /**< parameter */
void *stack_addr; /**< stack address */
rt_uint32_t stack_size; /**< stack size */
/* error code */
rt_err_t error; /**< error code */
rt_uint8_t stat; /**< thread status */
/* priority */
rt_uint8_t current_priority; /**< current priority */
rt_uint8_t init_priority; /**< initialized priority */
#if RT_THREAD_PRIORITY_MAX > 32
rt_uint8_t number;
rt_uint8_t high_mask;
#endif
rt_uint32_t number_mask;
#if defined(RT_USING_EVENT)
/* thread event */
rt_uint32_t event_set;
rt_uint8_t event_info;
#endif
rt_ubase_t init_tick; /**< thread's initialized tick */
rt_ubase_t remaining_tick; /**< remaining tick */
struct rt_timer thread_timer; /**< built-in thread timer */
void (*cleanup)(struct rt_thread *tid); /**< cleanup function when thread exit */
rt_uint32_t user_data; /**< private user data beyond this thread */
};
typedef struct rt_thread *rt_thread_t;
/**@}*/
/**
* @addtogroup IPC
*/
/**@{*/
/**
* IPC flags and control command definitions
*/
#define RT_IPC_FLAG_FIFO 0x00 /**< FIFOed IPC. @ref IPC. */
#define RT_IPC_FLAG_PRIO 0x01 /**< PRIOed IPC. @ref IPC. */
#define RT_IPC_CMD_UNKNOWN 0x00 /**< unknown IPC command */
#define RT_IPC_CMD_RESET 0x01 /**< reset IPC object */
#define RT_WAITING_FOREVER -1 /**< Block forever until get resource. */
#define RT_WAITING_NO 0 /**< Non-block. */
/**
* Base structure of IPC object
*/
struct rt_ipc_object
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t suspend_thread; /**< threads pended on this resource */
};
#ifdef RT_USING_SEMAPHORE
/**
* Semaphore structure
*/
struct rt_semaphore
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_uint16_t value; /**< value of semaphore. */
rt_uint16_t reserved; /**< reserved field */
};
typedef struct rt_semaphore *rt_sem_t;
#endif
#ifdef RT_USING_MUTEX
/**
* Mutual exclusion (mutex) structure
*/
struct rt_mutex
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_uint16_t value; /**< value of mutex */
rt_uint8_t original_priority; /**< priority of last thread hold the mutex */
rt_uint8_t hold; /**< numbers of thread hold the mutex */
struct rt_thread *owner; /**< current owner of mutex */
};
typedef struct rt_mutex *rt_mutex_t;
#endif
#ifdef RT_USING_EVENT
/**
* flag defintions in event
*/
#define RT_EVENT_FLAG_AND 0x01 /**< logic and */
#define RT_EVENT_FLAG_OR 0x02 /**< logic or */
#define RT_EVENT_FLAG_CLEAR 0x04 /**< clear flag */
/*
* event structure
*/
struct rt_event
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_uint32_t set; /**< event set */
};
typedef struct rt_event *rt_event_t;
#endif
#ifdef RT_USING_MAILBOX
/**
* mailbox structure
*/
struct rt_mailbox
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_ubase_t *msg_pool; /**< start address of message buffer */
rt_uint16_t size; /**< size of message pool */
rt_uint16_t entry; /**< index of messages in msg_pool */
rt_uint16_t in_offset; /**< input offset of the message buffer */
rt_uint16_t out_offset; /**< output offset of the message buffer */
rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */
};
typedef struct rt_mailbox *rt_mailbox_t;
#endif
#ifdef RT_USING_MESSAGEQUEUE
/**
* message queue structure
*/
struct rt_messagequeue
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
void *msg_pool; /**< start address of message queue */
rt_uint16_t msg_size; /**< message size of each message */
rt_uint16_t max_msgs; /**< max number of messages */
rt_uint16_t entry; /**< index of messages in the queue */
void *msg_queue_head; /**< list head */
void *msg_queue_tail; /**< list tail */
void *msg_queue_free; /**< pointer indicated the free node of queue */
rt_list_t suspend_sender_thread; /**< sender thread suspended on this message queue */
};
typedef struct rt_messagequeue *rt_mq_t;
#endif
/**@}*/
/**
* @addtogroup MM
*/
/**@{*/
/*
* memory management
* heap & partition
*/
#ifdef RT_USING_MEMHEAP
/**
* memory item on the heap
*/
struct rt_memheap_item
{
rt_uint32_t magic; /**< magic number for memheap */
struct rt_memheap *pool_ptr; /**< point of pool */
struct rt_memheap_item *next; /**< next memheap item */
struct rt_memheap_item *prev; /**< prev memheap item */
struct rt_memheap_item *next_free; /**< next free memheap item */
struct rt_memheap_item *prev_free; /**< prev free memheap item */
};
/**
* Base structure of memory heap object
*/
struct rt_memheap
{
struct rt_object parent; /**< inherit from rt_object */
void *start_addr; /**< pool start address and size */
rt_uint32_t pool_size; /**< pool size */
rt_uint32_t available_size; /**< available size */
rt_uint32_t max_used_size; /**< maximum allocated size */
struct rt_memheap_item *block_list; /**< used block list */
struct rt_memheap_item *free_list; /**< free block list */
struct rt_memheap_item free_header; /**< free block list header */
struct rt_semaphore lock; /**< semaphore lock */
};
#endif
#ifdef RT_USING_MEMPOOL
/**
* Base structure of Memory pool object
*/
struct rt_mempool
{
struct rt_object parent; /**< inherit from rt_object */
void *start_address; /**< memory pool start */
rt_size_t size; /**< size of memory pool */
rt_size_t block_size; /**< size of memory blocks */
rt_uint8_t *block_list; /**< memory blocks list */
rt_size_t block_total_count; /**< numbers of memory block */
rt_size_t block_free_count; /**< numbers of free memory block */
rt_list_t suspend_thread; /**< threads pended on this resource */
};
typedef struct rt_mempool *rt_mp_t;
#endif
/**@}*/
#ifdef RT_USING_DEVICE
/**
* @addtogroup Device
*/
/**@{*/
/**
* device (I/O) class type
*/
enum rt_device_class_type
{
RT_Device_Class_Char = 0, /**< character device */
RT_Device_Class_Block, /**< block device */
RT_Device_Class_NetIf, /**< net interface */
RT_Device_Class_MTD, /**< memory device */
RT_Device_Class_CAN, /**< CAN device */
RT_Device_Class_RTC, /**< RTC device */
RT_Device_Class_Sound, /**< Sound device */
RT_Device_Class_Graphic, /**< Graphic device */
RT_Device_Class_I2CBUS, /**< I2C bus device */
RT_Device_Class_USBDevice, /**< USB slave device */
RT_Device_Class_USBHost, /**< USB host bus */
RT_Device_Class_SPIBUS, /**< SPI bus device */
RT_Device_Class_SPIDevice, /**< SPI device */
RT_Device_Class_SDIO, /**< SDIO bus device */
RT_Device_Class_PM, /**< PM pseudo device */
RT_Device_Class_Pipe, /**< Pipe device */
RT_Device_Class_Portal, /**< Portal device */
RT_Device_Class_Timer, /**< Timer device */
RT_Device_Class_Miscellaneous, /**< Miscellaneous device */
RT_Device_Class_Sensor, /**< Sensor device */
RT_Device_Class_Touch, /**< Touch device */
RT_Device_Class_Unknown /**< unknown device */
};
/**
* device flags defitions
*/
#define RT_DEVICE_FLAG_DEACTIVATE 0x000 /**< device is not not initialized */
#define RT_DEVICE_FLAG_RDONLY 0x001 /**< read only */
#define RT_DEVICE_FLAG_WRONLY 0x002 /**< write only */
#define RT_DEVICE_FLAG_RDWR 0x003 /**< read and write */
#define RT_DEVICE_FLAG_REMOVABLE 0x004 /**< removable device */
#define RT_DEVICE_FLAG_STANDALONE 0x008 /**< standalone device */
#define RT_DEVICE_FLAG_ACTIVATED 0x010 /**< device is activated */
#define RT_DEVICE_FLAG_SUSPENDED 0x020 /**< device is suspended */
#define RT_DEVICE_FLAG_STREAM 0x040 /**< stream mode */
#define RT_DEVICE_FLAG_INT_RX 0x100 /**< INT mode on Rx */
#define RT_DEVICE_FLAG_DMA_RX 0x200 /**< DMA mode on Rx */
#define RT_DEVICE_FLAG_INT_TX 0x400 /**< INT mode on Tx */
#define RT_DEVICE_FLAG_DMA_TX 0x800 /**< DMA mode on Tx */
#define RT_DEVICE_OFLAG_CLOSE 0x000 /**< device is closed */
#define RT_DEVICE_OFLAG_RDONLY 0x001 /**< read only access */
#define RT_DEVICE_OFLAG_WRONLY 0x002 /**< write only access */
#define RT_DEVICE_OFLAG_RDWR 0x003 /**< read and write */
#define RT_DEVICE_OFLAG_OPEN 0x008 /**< device is opened */
#define RT_DEVICE_OFLAG_MASK 0xf0f /**< mask of open flag */
/**
* general device commands
*/
#define RT_DEVICE_CTRL_RESUME 0x01 /**< resume device */
#define RT_DEVICE_CTRL_SUSPEND 0x02 /**< suspend device */
#define RT_DEVICE_CTRL_CONFIG 0x03 /**< configure device */
#define RT_DEVICE_CTRL_CLOSE 0x04 /**< close device */
#define RT_DEVICE_CTRL_SET_INT 0x10 /**< set interrupt */
#define RT_DEVICE_CTRL_CLR_INT 0x11 /**< clear interrupt */
#define RT_DEVICE_CTRL_GET_INT 0x12 /**< get interrupt status */
typedef struct rt_device *rt_device_t;
/**
* operations set for device object
*/
struct rt_device_ops
{
/* common device interface */
rt_err_t (*init) (rt_device_t dev);
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close) (rt_device_t dev);
rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
};
/**
* Device structure
*/
struct rt_device
{
struct rt_object parent; /**< inherit from rt_object */
enum rt_device_class_type type; /**< device type */
rt_uint16_t flag; /**< device flag */
rt_uint16_t open_flag; /**< device open flag */
rt_uint8_t ref_count; /**< reference count */
rt_uint8_t device_id; /**< 0 - 255 */
/* device call back */
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
#ifdef RT_USING_DEVICE_OPS
const struct rt_device_ops *ops;
#else
/* common device interface */
rt_err_t (*init) (rt_device_t dev);
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close) (rt_device_t dev);
rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
#endif
void *user_data; /**< device private data */
};
/**@}*/
#endif
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
/* RT-Thread definitions for C++ */
namespace rtthread {
enum TICK_WAIT {
WAIT_NONE = 0,
WAIT_FOREVER = -1,
};
}
#endif /* end of __cplusplus */
#endif
+130
View File
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-25 Bernard add rt_hw_context_switch_interrupt declaration
* 2006-09-24 Bernard add rt_hw_context_switch_to declaration
* 2012-12-29 Bernard add rt_hw_exception_install declaration
* 2017-10-17 Hichard add some micros
*/
#ifndef __RT_HW_H__
#define __RT_HW_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Some macros define
*/
#ifndef HWREG32
#define HWREG32(x) (*((volatile rt_uint32_t *)(x)))
#endif
#ifndef HWREG16
#define HWREG16(x) (*((volatile rt_uint16_t *)(x)))
#endif
#ifndef HWREG8
#define HWREG8(x) (*((volatile rt_uint8_t *)(x)))
#endif
#ifndef RT_CPU_CACHE_LINE_SZ
#define RT_CPU_CACHE_LINE_SZ 32
#endif
enum RT_HW_CACHE_OPS
{
RT_HW_CACHE_FLUSH = 0x01,
RT_HW_CACHE_INVALIDATE = 0x02,
};
/*
* CPU interfaces
*/
void rt_hw_cpu_icache_enable(void);
void rt_hw_cpu_icache_disable(void);
rt_base_t rt_hw_cpu_icache_status(void);
void rt_hw_cpu_icache_ops(int ops, void* addr, int size);
void rt_hw_cpu_dcache_enable(void);
void rt_hw_cpu_dcache_disable(void);
rt_base_t rt_hw_cpu_dcache_status(void);
void rt_hw_cpu_dcache_ops(int ops, void* addr, int size);
void rt_hw_cpu_reset(void);
void rt_hw_cpu_shutdown(void);
rt_uint8_t *rt_hw_stack_init(void *entry,
void *parameter,
rt_uint8_t *stack_addr,
void *exit);
/*
* Interrupt handler definition
*/
typedef void (*rt_isr_handler_t)(int vector, void *param);
struct rt_irq_desc
{
rt_isr_handler_t handler;
void *param;
#ifdef RT_USING_INTERRUPT_INFO
char name[RT_NAME_MAX];
rt_uint32_t counter;
#endif
};
/*
* Interrupt interfaces
*/
void rt_hw_interrupt_init(void);
void rt_hw_interrupt_mask(int vector);
void rt_hw_interrupt_umask(int vector);
rt_isr_handler_t rt_hw_interrupt_install(int vector,
rt_isr_handler_t handler,
void *param,
const char *name);
rt_base_t rt_hw_interrupt_disable(void);
void rt_hw_interrupt_enable(rt_base_t level);
/*
* Context interfaces
*/
void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
void rt_hw_context_switch_to(rt_ubase_t to);
void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to);
void rt_hw_console_output(const char *str);
void rt_hw_backtrace(rt_uint32_t *fp, rt_ubase_t thread_entry);
void rt_hw_show_memory(rt_uint32_t addr, rt_size_t size);
/*
* Exception interfaces
*/
void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context));
/*
* delay interfaces
*/
void rt_hw_us_delay(rt_uint32_t us);
#define RT_DEFINE_SPINLOCK(x)
#define RT_DECLARE_SPINLOCK(x) rt_ubase_t x
#define rt_hw_spin_lock(lock) *(lock) = rt_hw_interrupt_disable()
#define rt_hw_spin_unlock(lock) rt_hw_interrupt_enable(*(lock))
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,315 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-16 Bernard the first version
* 2006-09-07 Bernard move the kservice APIs to rtthread.h
* 2007-06-27 Bernard fix the rt_list_remove bug
* 2012-03-22 Bernard rename kservice.h to rtservice.h
* 2017-11-15 JasonJia Modify rt_slist_foreach to rt_slist_for_each_entry.
* Make code cleanup.
*/
#ifndef __RT_SERVICE_H__
#define __RT_SERVICE_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup KernelService
*/
/**@{*/
/**
* rt_container_of - return the member address of ptr, if the type of ptr is the
* struct type.
*/
#define rt_container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/**
* @brief initialize a list object
*/
#define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
/**
* @brief initialize a list
*
* @param l list to be initialized
*/
rt_inline void rt_list_init(rt_list_t *l)
{
l->next = l->prev = l;
}
/**
* @brief insert a node after a list
*
* @param l list to insert it
* @param n new node to be inserted
*/
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
{
l->next->prev = n;
n->next = l->next;
l->next = n;
n->prev = l;
}
/**
* @brief insert a node before a list
*
* @param n new node to be inserted
* @param l list to insert it
*/
rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
{
l->prev->next = n;
n->prev = l->prev;
l->prev = n;
n->next = l;
}
/**
* @brief remove node from list.
* @param n the node to remove from the list.
*/
rt_inline void rt_list_remove(rt_list_t *n)
{
n->next->prev = n->prev;
n->prev->next = n->next;
n->next = n->prev = n;
}
/**
* @brief tests whether a list is empty
* @param l the list to test.
*/
rt_inline int rt_list_isempty(const rt_list_t *l)
{
return l->next == l;
}
/**
* @brief get the list length
* @param l the list to get.
*/
rt_inline unsigned int rt_list_len(const rt_list_t *l)
{
unsigned int len = 0;
const rt_list_t *p = l;
while (p->next != l)
{
p = p->next;
len ++;
}
return len;
}
/**
* @brief get the struct for this entry
* @param node the entry point
* @param type the type of structure
* @param member the name of list in structure
*/
#define rt_list_entry(node, type, member) \
rt_container_of(node, type, member)
/**
* rt_list_for_each - iterate over a list
* @pos: the rt_list_t * to use as a loop cursor.
* @head: the head for your list.
*/
#define rt_list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* rt_list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the rt_list_t * to use as a loop cursor.
* @n: another rt_list_t * to use as temporary storage
* @head: the head for your list.
*/
#define rt_list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* rt_list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define rt_list_for_each_entry(pos, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = rt_list_entry(pos->member.next, typeof(*pos), member))
/**
* rt_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define rt_list_for_each_entry_safe(pos, n, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
n = rt_list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
/**
* rt_list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define rt_list_first_entry(ptr, type, member) \
rt_list_entry((ptr)->next, type, member)
#define RT_SLIST_OBJECT_INIT(object) { RT_NULL }
/**
* @brief initialize a single list
*
* @param l the single list to be initialized
*/
rt_inline void rt_slist_init(rt_slist_t *l)
{
l->next = RT_NULL;
}
rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
{
struct rt_slist_node *node;
node = l;
while (node->next) node = node->next;
/* append the node to the tail */
node->next = n;
n->next = RT_NULL;
}
rt_inline void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
{
n->next = l->next;
l->next = n;
}
rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
{
unsigned int len = 0;
const rt_slist_t *list = l->next;
while (list != RT_NULL)
{
list = list->next;
len ++;
}
return len;
}
rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
{
/* remove slist head */
struct rt_slist_node *node = l;
while (node->next && node->next != n) node = node->next;
/* remove node */
if (node->next != (rt_slist_t *)0) node->next = node->next->next;
return l;
}
rt_inline rt_slist_t *rt_slist_first(rt_slist_t *l)
{
return l->next;
}
rt_inline rt_slist_t *rt_slist_tail(rt_slist_t *l)
{
while (l->next) l = l->next;
return l;
}
rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
{
return n->next;
}
rt_inline int rt_slist_isempty(rt_slist_t *l)
{
return l->next == RT_NULL;
}
/**
* @brief get the struct for this single list node
* @param node the entry point
* @param type the type of structure
* @param member the name of list in structure
*/
#define rt_slist_entry(node, type, member) \
rt_container_of(node, type, member)
/**
* rt_slist_for_each - iterate over a single list
* @pos: the rt_slist_t * to use as a loop cursor.
* @head: the head for your single list.
*/
#define rt_slist_for_each(pos, head) \
for (pos = (head)->next; pos != RT_NULL; pos = pos->next)
/**
* rt_slist_for_each_entry - iterate over single list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your single list.
* @member: the name of the list_struct within the struct.
*/
#define rt_slist_for_each_entry(pos, head, member) \
for (pos = rt_slist_entry((head)->next, typeof(*pos), member); \
&pos->member != (RT_NULL); \
pos = rt_slist_entry(pos->member.next, typeof(*pos), member))
/**
* rt_slist_first_entry - get the first element from a slist
* @ptr: the slist head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the slist_struct within the struct.
*
* Note, that slist is expected to be not empty.
*/
#define rt_slist_first_entry(ptr, type, member) \
rt_slist_entry((ptr)->next, type, member)
/**
* rt_slist_tail_entry - get the tail element from a slist
* @ptr: the slist head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the slist_struct within the struct.
*
* Note, that slist is expected to be not empty.
*/
#define rt_slist_tail_entry(ptr, type, member) \
rt_slist_entry(rt_slist_tail(ptr), type, member)
/**@}*/
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,520 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-26 Bernard add semaphore APIs
* 2006-08-10 Bernard add version information
* 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
* 2007-03-03 Bernard clean up the definitions to rtdef.h
* 2010-04-11 yi.qiu add module feature
* 2013-06-24 Bernard add rt_kprintf re-define when not use RT_USING_CONSOLE.
* 2016-08-09 ArdaFu add new thread and interrupt hook.
*/
#ifndef __RT_THREAD_H__
#define __RT_THREAD_H__
#include <rtconfig.h>
#include <rtdebug.h>
#include <rtdef.h>
#include <rtservice.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup KernelObject
*/
/**@{*/
/*
* kernel object interface
*/
void rt_system_object_init(void);
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type);
int rt_object_get_length(enum rt_object_class_type type);
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen);
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name);
void rt_object_detach(rt_object_t object);
rt_object_t rt_object_allocate(enum rt_object_class_type type,
const char *name);
void rt_object_delete(rt_object_t object);
rt_bool_t rt_object_is_systemobject(rt_object_t object);
rt_uint8_t rt_object_get_type(rt_object_t object);
rt_object_t rt_object_find(const char *name, rt_uint8_t type);
#ifdef RT_USING_HOOK
void rt_object_attach_sethook(void (*hook)(struct rt_object *object));
void rt_object_detach_sethook(void (*hook)(struct rt_object *object));
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object));
void rt_object_take_sethook(void (*hook)(struct rt_object *object));
void rt_object_put_sethook(void (*hook)(struct rt_object *object));
#endif
/**@}*/
/**
* @addtogroup Clock
*/
/**@{*/
/*
* clock & timer interface
*/
void rt_system_tick_init(void);
rt_tick_t rt_tick_get(void);
void rt_tick_set(rt_tick_t tick);
void rt_tick_increase(void);
rt_tick_t rt_tick_from_millisecond(rt_int32_t ms);
void rt_system_timer_init(void);
void rt_system_timer_thread_init(void);
void rt_timer_init(rt_timer_t timer,
const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag);
rt_err_t rt_timer_detach(rt_timer_t timer);
rt_timer_t rt_timer_create(const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg);
rt_tick_t rt_timer_next_timeout_tick(void);
void rt_timer_check(void);
#ifdef RT_USING_HOOK
void rt_timer_enter_sethook(void (*hook)(struct rt_timer *timer));
void rt_timer_exit_sethook(void (*hook)(struct rt_timer *timer));
#endif
/**@}*/
/**
* @addtogroup Thread
*/
/**@{*/
/*
* thread interface
*/
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick);
rt_err_t rt_thread_detach(rt_thread_t thread);
rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick);
rt_thread_t rt_thread_self(void);
rt_thread_t rt_thread_find(char *name);
rt_err_t rt_thread_startup(rt_thread_t thread);
rt_err_t rt_thread_delete(rt_thread_t thread);
rt_err_t rt_thread_yield(void);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg);
rt_err_t rt_thread_suspend(rt_thread_t thread);
rt_err_t rt_thread_resume(rt_thread_t thread);
void rt_thread_timeout(void *parameter);
#ifdef RT_USING_HOOK
void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread));
void rt_thread_resume_sethook (void (*hook)(rt_thread_t thread));
void rt_thread_inited_sethook (void (*hook)(rt_thread_t thread));
#endif
/*
* idle thread interface
*/
void rt_thread_idle_init(void);
#if defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK)
rt_err_t rt_thread_idle_sethook(void (*hook)(void));
rt_err_t rt_thread_idle_delhook(void (*hook)(void));
#endif
void rt_thread_idle_excute(void);
rt_thread_t rt_thread_idle_gethandler(void);
/*
* schedule service
*/
void rt_system_scheduler_init(void);
void rt_system_scheduler_start(void);
void rt_schedule(void);
void rt_schedule_insert_thread(struct rt_thread *thread);
void rt_schedule_remove_thread(struct rt_thread *thread);
void rt_enter_critical(void);
void rt_exit_critical(void);
rt_uint16_t rt_critical_level(void);
#ifdef RT_USING_HOOK
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
#endif
/**@}*/
/**
* @addtogroup MM
*/
/**@{*/
/*
* memory management interface
*/
#ifdef RT_USING_MEMPOOL
/*
* memory pool interface
*/
rt_err_t rt_mp_init(struct rt_mempool *mp,
const char *name,
void *start,
rt_size_t size,
rt_size_t block_size);
rt_err_t rt_mp_detach(struct rt_mempool *mp);
rt_mp_t rt_mp_create(const char *name,
rt_size_t block_count,
rt_size_t block_size);
rt_err_t rt_mp_delete(rt_mp_t mp);
void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time);
void rt_mp_free(void *block);
#ifdef RT_USING_HOOK
void rt_mp_alloc_sethook(void (*hook)(struct rt_mempool *mp, void *block));
void rt_mp_free_sethook(void (*hook)(struct rt_mempool *mp, void *block));
#endif
#endif
#ifdef RT_USING_HEAP
/*
* heap memory interface
*/
void rt_system_heap_init(void *begin_addr, void *end_addr);
void *rt_malloc(rt_size_t nbytes);
void rt_free(void *ptr);
void *rt_realloc(void *ptr, rt_size_t nbytes);
void *rt_calloc(rt_size_t count, rt_size_t size);
void *rt_malloc_align(rt_size_t size, rt_size_t align);
void rt_free_align(void *ptr);
void rt_memory_info(rt_uint32_t *total,
rt_uint32_t *used,
rt_uint32_t *max_used);
#ifdef RT_USING_SLAB
void *rt_page_alloc(rt_size_t npages);
void rt_page_free(void *addr, rt_size_t npages);
#endif
#ifdef RT_USING_HOOK
void rt_malloc_sethook(void (*hook)(void *ptr, rt_size_t size));
void rt_free_sethook(void (*hook)(void *ptr));
#endif
#endif
#ifdef RT_USING_MEMHEAP
/**
* memory heap object interface
*/
rt_err_t rt_memheap_init(struct rt_memheap *memheap,
const char *name,
void *start_addr,
rt_size_t size);
rt_err_t rt_memheap_detach(struct rt_memheap *heap);
void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size);
void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize);
void rt_memheap_free(void *ptr);
#endif
/**@}*/
/**
* @addtogroup IPC
*/
/**@{*/
#ifdef RT_USING_SEMAPHORE
/*
* semaphore interface
*/
rt_err_t rt_sem_init(rt_sem_t sem,
const char *name,
rt_uint32_t value,
rt_uint8_t flag);
rt_err_t rt_sem_detach(rt_sem_t sem);
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag);
rt_err_t rt_sem_delete(rt_sem_t sem);
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time);
rt_err_t rt_sem_trytake(rt_sem_t sem);
rt_err_t rt_sem_release(rt_sem_t sem);
rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg);
#endif
#ifdef RT_USING_MUTEX
/*
* mutex interface
*/
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag);
rt_err_t rt_mutex_detach(rt_mutex_t mutex);
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag);
rt_err_t rt_mutex_delete(rt_mutex_t mutex);
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time);
rt_err_t rt_mutex_release(rt_mutex_t mutex);
rt_err_t rt_mutex_control(rt_mutex_t mutex, int cmd, void *arg);
#endif
#ifdef RT_USING_EVENT
/*
* event interface
*/
rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag);
rt_err_t rt_event_detach(rt_event_t event);
rt_event_t rt_event_create(const char *name, rt_uint8_t flag);
rt_err_t rt_event_delete(rt_event_t event);
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);
rt_err_t rt_event_recv(rt_event_t event,
rt_uint32_t set,
rt_uint8_t opt,
rt_int32_t timeout,
rt_uint32_t *recved);
rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg);
#endif
#ifdef RT_USING_MAILBOX
/*
* mailbox interface
*/
rt_err_t rt_mb_init(rt_mailbox_t mb,
const char *name,
void *msgpool,
rt_size_t size,
rt_uint8_t flag);
rt_err_t rt_mb_detach(rt_mailbox_t mb);
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag);
rt_err_t rt_mb_delete(rt_mailbox_t mb);
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value);
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_ubase_t value,
rt_int32_t timeout);
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout);
rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg);
#endif
#ifdef RT_USING_MESSAGEQUEUE
/*
* message queue interface
*/
rt_err_t rt_mq_init(rt_mq_t mq,
const char *name,
void *msgpool,
rt_size_t msg_size,
rt_size_t pool_size,
rt_uint8_t flag);
rt_err_t rt_mq_detach(rt_mq_t mq);
rt_mq_t rt_mq_create(const char *name,
rt_size_t msg_size,
rt_size_t max_msgs,
rt_uint8_t flag);
rt_err_t rt_mq_delete(rt_mq_t mq);
rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size);
rt_err_t rt_mq_send_wait(rt_mq_t mq,
const void *buffer,
rt_size_t size,
rt_int32_t timeout);
rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size);
rt_err_t rt_mq_recv(rt_mq_t mq,
void *buffer,
rt_size_t size,
rt_int32_t timeout);
rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg);
#endif
/**@}*/
#ifdef RT_USING_DEVICE
/**
* @addtogroup Device
*/
/**@{*/
/*
* device (I/O) system interface
*/
rt_device_t rt_device_find(const char *name);
rt_err_t rt_device_register(rt_device_t dev,
const char *name,
rt_uint16_t flags);
rt_err_t rt_device_unregister(rt_device_t dev);
rt_device_t rt_device_create(int type, int attach_size);
void rt_device_destroy(rt_device_t device);
rt_err_t rt_device_init_all(void);
rt_err_t
rt_device_set_rx_indicate(rt_device_t dev,
rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size));
rt_err_t
rt_device_set_tx_complete(rt_device_t dev,
rt_err_t (*tx_done)(rt_device_t dev, void *buffer));
rt_err_t rt_device_init (rt_device_t dev);
rt_err_t rt_device_open (rt_device_t dev, rt_uint16_t oflag);
rt_err_t rt_device_close(rt_device_t dev);
rt_size_t rt_device_read (rt_device_t dev,
rt_off_t pos,
void *buffer,
rt_size_t size);
rt_size_t rt_device_write(rt_device_t dev,
rt_off_t pos,
const void *buffer,
rt_size_t size);
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg);
/**@}*/
#endif
/*
* interrupt service
*/
/*
* rt_interrupt_enter and rt_interrupt_leave only can be called by BSP
*/
void rt_interrupt_enter(void);
void rt_interrupt_leave(void);
/*
* the number of nested interrupts.
*/
rt_uint8_t rt_interrupt_get_nest(void);
#ifdef RT_USING_HOOK
void rt_interrupt_enter_sethook(void (*hook)(void));
void rt_interrupt_leave_sethook(void (*hook)(void));
#endif
#ifdef RT_USING_COMPONENTS_INIT
void rt_components_init(void);
void rt_components_board_init(void);
#endif
/**
* @addtogroup KernelService
*/
/**@{*/
/*
* general kernel service
*/
#ifndef RT_USING_CONSOLE
#define rt_kprintf(...)
#define rt_kputs(str)
#else
void rt_kprintf(const char *fmt, ...);
void rt_kputs(const char *str);
#endif
rt_int32_t rt_vsprintf(char *dest, const char *format, va_list arg_ptr);
rt_int32_t rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args);
rt_int32_t rt_sprintf(char *buf, const char *format, ...);
rt_int32_t rt_snprintf(char *buf, rt_size_t size, const char *format, ...);
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
rt_device_t rt_console_set_device(const char *name);
rt_device_t rt_console_get_device(void);
#endif
rt_err_t rt_get_errno(void);
void rt_set_errno(rt_err_t no);
int *_rt_errno(void);
#if !defined(RT_USING_NEWLIB) && !defined(_WIN32)
#ifndef errno
#define errno *_rt_errno()
#endif
#endif
int __rt_ffs(int value);
void *rt_memset(void *src, int c, rt_ubase_t n);
void *rt_memcpy(void *dest, const void *src, rt_ubase_t n);
rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_ubase_t count);
rt_int32_t rt_strcmp(const char *cs, const char *ct);
rt_size_t rt_strlen(const char *src);
rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen);
char *rt_strdup(const char *s);
#if defined(__CC_ARM) || defined(__CLANG_ARM)
/* leak strdup interface */
char* strdup(const char* str);
#endif
char *rt_strstr(const char *str1, const char *str2);
rt_int32_t rt_sscanf(const char *buf, const char *fmt, ...);
char *rt_strncpy(char *dest, const char *src, rt_ubase_t n);
void *rt_memmove(void *dest, const void *src, rt_ubase_t n);
rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_ubase_t count);
rt_int32_t rt_strcasecmp(const char *a, const char *b);
void rt_show_version(void);
#ifdef RT_DEBUG
extern void (*rt_assert_hook)(const char *ex, const char *func, rt_size_t line);
void rt_assert_set_hook(void (*hook)(const char *ex, const char *func, rt_size_t line));
void rt_assert_handler(const char *ex, const char *func, rt_size_t line);
#endif /* RT_DEBUG */
#ifdef RT_USING_FINSH
#include <finsh_api.h>
#endif
/**@}*/
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,210 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-01-25 Bernard first version
* 2012-06-01 aozima set pendsv priority to 0xFF.
* 2012-08-17 aozima fixed bug: store r8 - r11.
* 2013-02-20 aozima port to gcc.
* 2013-06-18 aozima add restore MSP feature.
* 2013-11-04 bright fixed hardfault bug for gcc.
*/
.cpu cortex-m0
.fpu softvfp
.syntax unified
.thumb
.text
.equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */
.equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
MRS R0, PRIMASK
CPSID I
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
MSR PRIMASK, R0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* R0 --> from
* R1 --> to
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
/* set rt_thread_switch_interrupt_flag to 1 */
LDR R2, =rt_thread_switch_interrupt_flag
LDR R3, [R2]
CMP R3, #1
BEQ _reswitch
MOVS R3, #1
STR R3, [R2]
LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
STR R0, [R2]
_reswitch:
LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
STR R1, [R2]
LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
BX LR
/* R0 --> switch from thread stack
* R1 --> switch to thread stack
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS R2, PRIMASK
CPSID I
/* get rt_thread_switch_interrupt_flag */
LDR R0, =rt_thread_switch_interrupt_flag
LDR R1, [R0]
CMP R1, #0x00
BEQ pendsv_exit /* pendsv aLReady handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
MOVS R1, #0
STR R1, [R0]
LDR R0, =rt_interrupt_from_thread
LDR R1, [R0]
CMP R1, #0x00
BEQ switch_to_thread /* skip register save at the first time */
MRS R1, PSP /* get from thread stack pointer */
SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */
LDR R0, [R0]
STR R1, [R0] /* update from thread stack pointer */
STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */
MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */
MOV R5, R9
MOV R6, R10
MOV R7, R11
STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */
switch_to_thread:
LDR R1, =rt_interrupt_to_thread
LDR R1, [R1]
LDR R1, [R1] /* load thread stack pointer */
LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */
PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */
LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */
MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */
MOV R9, R5
MOV R10, R6
MOV R11, R7
POP {R4 - R7} /* pop {R4 - R7} from MSP */
MSR PSP, R1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, R2
MOVS R0, #0x04
RSBS R0, R0, #0x00
BX R0
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* R0 --> to
*/
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR R1, =rt_interrupt_to_thread
STR R0, [R1]
/* set from thread to 0 */
LDR R1, =rt_interrupt_from_thread
MOVS R0, #0
STR R0, [R1]
/* set interrupt flag to 1 */
LDR R1, =rt_thread_switch_interrupt_flag
MOVS R0, #1
STR R0, [R1]
/* set the PendSV and SysTick exception priority */
LDR R0, =NVIC_SHPR3
LDR R1, =NVIC_PENDSV_PRI
LDR R2, [R0,#0x00] /* read */
ORRS R1, R1, R2 /* modify */
STR R1, [R0] /* write-back */
LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
NOP
/* restore MSP */
LDR R0, =SCB_VTOR
LDR R0, [R0]
LDR R0, [R0]
NOP
MSR MSP, R0
/* enable interrupts at processor level */
CPSIE I
/* never reach here! */
/* compatible with old version */
.global rt_hw_interrupt_thread_switch
.type rt_hw_interrupt_thread_switch, %function
rt_hw_interrupt_thread_switch:
BX LR
NOP
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
MRS R0, PSP /* get fault thread stack pointer */
PUSH {LR}
BL rt_hw_hard_fault_exception
POP {PC}
/*
* rt_uint32_t rt_hw_interrupt_check(void);
* R0 --> state
*/
.global rt_hw_interrupt_check
.type rt_hw_interrupt_check, %function
rt_hw_interrupt_check:
MRS R0, IPSR
BX LR
@@ -0,0 +1,206 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2010-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; * 2013-06-18 aozima add restore MSP feature.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
EXPORT rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
EXPORT rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
EXPORT rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
; r0 --> switch from thread stack
; r1 --> switch to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
EXPORT PendSV_Handler
PendSV_Handler:
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ switch_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
switch_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
EXPORT rt_hw_context_switch_to
rt_hw_context_switch_to:
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
NOP
; restore MSP
LDR r0, =SCB_VTOR
LDR r0, [r0]
LDR r0, [r0]
NOP
MSR msp, r0
; enable interrupts at processor level
CPSIE I
; never reach here!
; compatible with old version
EXPORT rt_hw_interrupt_thread_switch
rt_hw_interrupt_thread_switch:
BX lr
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler:
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
END
@@ -0,0 +1,215 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2010-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; * 2013-06-18 aozima add restore MSP feature.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x01
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> switch from thread stack
; r1 --> switch to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ switch_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
switch_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
; restore MSP
LDR r0, =SCB_VTOR
LDR r0, [r0]
LDR r0, [r0]
MSR msp, r0
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
ENDP
IMPORT rt_hw_hard_fault_exception
HardFault_Handler PROC
EXPORT HardFault_Handler
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
ENDP
ALIGN 4
END
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-01-25 Bernard first version
* 2012-05-31 aozima Merge all of the C source code into cpuport.c
* 2012-08-17 aozima fixed bug: store r8 - r11.
* 2012-12-23 aozima stack addr align to 8byte.
*/
#include <rtthread.h>
struct exception_stack_frame
{
rt_uint32_t r0;
rt_uint32_t r1;
rt_uint32_t r2;
rt_uint32_t r3;
rt_uint32_t r12;
rt_uint32_t lr;
rt_uint32_t pc;
rt_uint32_t psr;
};
struct stack_frame
{
/* r4 ~ r7 low register */
rt_uint32_t r4;
rt_uint32_t r5;
rt_uint32_t r6;
rt_uint32_t r7;
/* r8 ~ r11 high register */
rt_uint32_t r8;
rt_uint32_t r9;
rt_uint32_t r10;
rt_uint32_t r11;
struct exception_stack_frame exception_stack_frame;
};
/* flag in interrupt handling */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry,
void *parameter,
rt_uint8_t *stack_addr,
void *texit)
{
struct stack_frame *stack_frame;
rt_uint8_t *stk;
unsigned long i;
stk = stack_addr + sizeof(rt_uint32_t);
stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
stk -= sizeof(struct stack_frame);
stack_frame = (struct stack_frame *)stk;
/* init all register */
for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
{
((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
}
stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */
stack_frame->exception_stack_frame.r1 = 0; /* r1 */
stack_frame->exception_stack_frame.r2 = 0; /* r2 */
stack_frame->exception_stack_frame.r3 = 0; /* r3 */
stack_frame->exception_stack_frame.r12 = 0; /* r12 */
stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
/* return task's current stack address */
return stk;
}
extern long list_thread(void);
extern rt_thread_t rt_current_thread;
/**
* fault exception handling
*/
void rt_hw_hard_fault_exception(struct exception_stack_frame *contex)
{
rt_kprintf("psr: 0x%08x\n", contex->psr);
rt_kprintf(" pc: 0x%08x\n", contex->pc);
rt_kprintf(" lr: 0x%08x\n", contex->lr);
rt_kprintf("r12: 0x%08x\n", contex->r12);
rt_kprintf("r03: 0x%08x\n", contex->r3);
rt_kprintf("r02: 0x%08x\n", contex->r2);
rt_kprintf("r01: 0x%08x\n", contex->r1);
rt_kprintf("r00: 0x%08x\n", contex->r0);
rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
while (1);
}
#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
/**
* reset CPU
*/
RT_WEAK void rt_hw_cpu_reset(void)
{
SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk);
}
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-12 Bernard first version
* 2006-05-27 Bernard add support for same priority thread schedule
* 2006-08-10 Bernard remove the last rt_schedule in rt_tick_increase
* 2010-03-08 Bernard remove rt_passed_second
* 2010-05-20 Bernard fix the tick exceeds the maximum limits
* 2010-07-13 Bernard fix rt_tick_from_millisecond issue found by kuronca
* 2011-06-26 Bernard add rt_tick_set function.
* 2018-11-22 Jesven add per cpu tick
*/
#include <rthw.h>
#include <rtthread.h>
static rt_tick_t rt_tick = 0;
/**
* This function will initialize system tick and set it to zero.
* @ingroup SystemInit
*
* @deprecated since 1.1.0, this function does not need to be invoked
* in the system initialization.
*/
void rt_system_tick_init(void)
{
}
/**
* @addtogroup Clock
*/
/**@{*/
/**
* This function will return current tick from operating system startup
*
* @return current tick
*/
rt_tick_t rt_tick_get(void)
{
/* return the global tick */
return rt_tick;
}
/**
* This function will set current tick
*/
void rt_tick_set(rt_tick_t tick)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
rt_tick = tick;
rt_hw_interrupt_enable(level);
}
/**
* This function will notify kernel there is one tick passed. Normally,
* this function is invoked by clock ISR.
*/
void rt_tick_increase(void)
{
struct rt_thread *thread;
/* increase the global tick */
++ rt_tick;
/* check time slice */
thread = rt_thread_self();
-- thread->remaining_tick;
if (thread->remaining_tick == 0)
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;
/* yield */
rt_thread_yield();
}
/* check timer */
rt_timer_check();
}
/**
* This function will calculate the tick from millisecond.
*
* @param ms the specified millisecond
* - Negative Number wait forever
* - Zero not wait
* - Max 0x7fffffff
*
* @return the calculated tick
*/
rt_tick_t rt_tick_from_millisecond(rt_int32_t ms)
{
rt_tick_t tick;
if (ms < 0)
{
tick = (rt_tick_t)RT_WAITING_FOREVER;
}
else
{
tick = RT_TICK_PER_SECOND * (ms / 1000);
tick += (RT_TICK_PER_SECOND * (ms % 1000) + 999) / 1000;
}
/* return the calculated tick */
return tick;
}
/**@}*/
+246
View File
@@ -0,0 +1,246 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-09-20 Bernard Change the name to components.c
* And all components related header files.
* 2012-12-23 Bernard fix the pthread initialization issue.
* 2013-06-23 Bernard Add the init_call for components initialization.
* 2013-07-05 Bernard Remove initialization feature for MS VC++ compiler
* 2015-02-06 Bernard Remove the MS VC++ support and move to the kernel
* 2015-05-04 Bernard Rename it to components.c because compiling issue
* in some IDEs.
* 2015-07-29 Arda.Fu Add support to use RT_USING_USER_MAIN with IAR
* 2018-11-22 Jesven Add secondary cpu boot up
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_USER_MAIN
#ifndef RT_MAIN_THREAD_STACK_SIZE
#define RT_MAIN_THREAD_STACK_SIZE 2048
#endif
#ifndef RT_MAIN_THREAD_PRIORITY
#define RT_MAIN_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 3)
#endif
#endif
#ifdef RT_USING_COMPONENTS_INIT
/*
* Components Initialization will initialize some driver and components as following
* order:
* rti_start --> 0
* BOARD_EXPORT --> 1
* rti_board_end --> 1.end
*
* DEVICE_EXPORT --> 2
* COMPONENT_EXPORT --> 3
* FS_EXPORT --> 4
* ENV_EXPORT --> 5
* APP_EXPORT --> 6
*
* rti_end --> 6.end
*
* These automatically initialization, the driver or component initial function must
* be defined with:
* INIT_BOARD_EXPORT(fn);
* INIT_DEVICE_EXPORT(fn);
* ...
* INIT_APP_EXPORT(fn);
* etc.
*/
static int rti_start(void)
{
return 0;
}
INIT_EXPORT(rti_start, "0");
static int rti_board_start(void)
{
return 0;
}
INIT_EXPORT(rti_board_start, "0.end");
static int rti_board_end(void)
{
return 0;
}
INIT_EXPORT(rti_board_end, "1.end");
static int rti_end(void)
{
return 0;
}
INIT_EXPORT(rti_end, "6.end");
/**
* RT-Thread Components Initialization for board
*/
void rt_components_board_init(void)
{
#if RT_DEBUG_INIT
int result;
const struct rt_init_desc *desc;
for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d done\n", result);
}
#else
volatile const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
{
(*fn_ptr)();
}
#endif
}
/**
* RT-Thread Components Initialization
*/
void rt_components_init(void)
{
#if RT_DEBUG_INIT
int result;
const struct rt_init_desc *desc;
rt_kprintf("do components initialization.\n");
for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d done\n", result);
}
#else
volatile const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
(*fn_ptr)();
}
#endif
}
#endif /* RT_USING_COMPONENTS_INIT */
#ifdef RT_USING_USER_MAIN
void rt_application_init(void);
void rt_hw_board_init(void);
int rtthread_startup(void);
#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int $Super$$main(void);
/* re-define main function */
int $Sub$$main(void)
{
rtthread_startup();
return 0;
}
#elif defined(__ICCARM__)
extern int main(void);
/* __low_level_init will auto called by IAR cstartup */
extern void __iar_data_init3(void);
int __low_level_init(void)
{
// call IAR table copy function.
__iar_data_init3();
rtthread_startup();
return 0;
}
#elif defined(__GNUC__)
/* Add -eentry to arm-none-eabi-gcc argument */
int entry(void)
{
rtthread_startup();
return 0;
}
#endif
#ifndef RT_USING_HEAP
/* if there is not enable heap, we should use static thread and stack. */
ALIGN(8)
static rt_uint8_t main_stack[RT_MAIN_THREAD_STACK_SIZE];
struct rt_thread main_thread;
#endif
/* the system main thread */
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
#ifdef RT_USING_COMPONENTS_INIT
/* RT-Thread components initialization */
rt_components_init();
#endif
/* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
$Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
main();
#endif
}
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif
rt_thread_startup(tid);
}
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initialization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
#endif
+14
View File
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-10-30 Bernard The first version
*/
#include <rtthread.h>
#include <rthw.h>
/* nothing on non-smp version */
+235
View File
@@ -0,0 +1,235 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-23 Bernard the first version
* 2010-11-10 Bernard add cleanup callback function in thread exit.
* 2012-12-29 Bernard fix compiling warning.
* 2013-12-21 Grissiom let rt_thread_idle_excute loop until there is no
* dead thread.
* 2016-08-09 ArdaFu add method to get the handler of the idle thread.
* 2018-02-07 Bernard lock scheduler to protect tid->cleanup.
* 2018-07-14 armink add idle hook list
* 2018-11-22 Jesven add per cpu idle task
* combine the code of primary and secondary cpu
*/
#include <rthw.h>
#include <rtthread.h>
#if defined (RT_USING_HOOK)
#ifndef RT_USING_IDLE_HOOK
#define RT_USING_IDLE_HOOK
#endif
#endif
#ifndef IDLE_THREAD_STACK_SIZE
#if defined (RT_USING_IDLE_HOOK) || defined(RT_USING_HEAP)
#define IDLE_THREAD_STACK_SIZE 256
#else
#define IDLE_THREAD_STACK_SIZE 128
#endif
#endif
extern rt_list_t rt_thread_defunct;
static struct rt_thread idle;
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE];
#ifdef RT_USING_IDLE_HOOK
#ifndef RT_IDLE_HOOK_LIST_SIZE
#define RT_IDLE_HOOK_LIST_SIZE 4
#endif
static void (*idle_hook_list[RT_IDLE_HOOK_LIST_SIZE])(void);
/**
* @ingroup Hook
* This function sets a hook function to idle thread loop. When the system performs
* idle loop, this hook function should be invoked.
*
* @param hook the specified hook function
*
* @return RT_EOK: set OK
* -RT_EFULL: hook list is full
*
* @note the hook function must be simple and never be blocked or suspend.
*/
rt_err_t rt_thread_idle_sethook(void (*hook)(void))
{
rt_size_t i;
rt_base_t level;
rt_err_t ret = -RT_EFULL;
/* disable interrupt */
level = rt_hw_interrupt_disable();
for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] == RT_NULL)
{
idle_hook_list[i] = hook;
ret = RT_EOK;
break;
}
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
return ret;
}
/**
* delete the idle hook on hook list
*
* @param hook the specified hook function
*
* @return RT_EOK: delete OK
* -RT_ENOSYS: hook was not found
*/
rt_err_t rt_thread_idle_delhook(void (*hook)(void))
{
rt_size_t i;
rt_base_t level;
rt_err_t ret = -RT_ENOSYS;
/* disable interrupt */
level = rt_hw_interrupt_disable();
for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] == hook)
{
idle_hook_list[i] = RT_NULL;
ret = RT_EOK;
break;
}
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
return ret;
}
#endif
#ifdef RT_USING_HEAP
/* Return whether there is defunctional thread to be deleted. */
rt_inline int _has_defunct_thread(void)
{
/* The rt_list_isempty has prototype of "int rt_list_isempty(const rt_list_t *l)".
* So the compiler has a good reason that the rt_thread_defunct list does
* not change within rt_thread_idle_excute thus optimize the "while" loop
* into a "if".
*
* So add the volatile qualifier here. */
const volatile rt_list_t *l = (const volatile rt_list_t *)&rt_thread_defunct;
return l->next != l;
}
#endif
/**
* @ingroup Thread
*
* This function will perform system background job when system idle.
*/
void rt_thread_idle_excute(void)
{
/* Loop until there is no dead thread. So one call to rt_thread_idle_excute
* will do all the cleanups. */
/* disable interrupt */
RT_DEBUG_NOT_IN_INTERRUPT;
#ifdef RT_USING_HEAP
while (1)
{
rt_base_t lock;
rt_thread_t thread;
lock = rt_hw_interrupt_disable();
/* check whether list is empty */
if (!_has_defunct_thread())
{
rt_hw_interrupt_enable(lock);
break;
}
/* get defunct thread */
thread = rt_list_entry(rt_thread_defunct.next,
struct rt_thread,
tlist);
/* remove defunct thread */
rt_list_remove(&(thread->tlist));
/* release thread's stack */
RT_KERNEL_FREE(thread->stack_addr);
/* delete thread object */
rt_object_delete((rt_object_t)thread);
rt_hw_interrupt_enable(lock);
}
#endif
}
extern void rt_system_power_manager(void);
static void rt_thread_idle_entry(void *parameter)
{
while (1)
{
#ifdef RT_USING_IDLE_HOOK
rt_size_t i;
for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] != RT_NULL)
{
idle_hook_list[i]();
}
}
#endif
rt_thread_idle_excute();
#ifdef RT_USING_PM
rt_system_power_manager();
#endif
}
}
/**
* @ingroup SystemInit
*
* This function will initialize idle thread, then start it.
*
* @note this function must be invoked when system init.
*/
void rt_thread_idle_init(void)
{
/* initialize thread */
rt_thread_init(&idle,
"tidle",
rt_thread_idle_entry,
RT_NULL,
&rt_thread_stack[0],
sizeof(rt_thread_stack),
RT_THREAD_PRIORITY_MAX - 1,
32);
/* startup */
rt_thread_startup(&idle);
}
/**
* @ingroup Thread
*
* This function will get the handler of the idle thread.
*
*/
rt_thread_t rt_thread_idle_gethandler(void)
{
return (rt_thread_t)(&idle);
}
File diff suppressed because it is too large. Load diff
+113
View File
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-02-24 Bernard first version
* 2006-05-03 Bernard add IRQ_DEBUG
* 2016-08-09 ArdaFu add interrupt enter and leave hook.
* 2018-11-22 Jesven rt_interrupt_get_nest function add disable irq
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_HOOK
static void (*rt_interrupt_enter_hook)(void);
static void (*rt_interrupt_leave_hook)(void);
/**
* @ingroup Hook
* This function set a hook function when the system enter a interrupt
*
* @note the hook function must be simple and never be blocked or suspend.
*/
void rt_interrupt_enter_sethook(void (*hook)(void))
{
rt_interrupt_enter_hook = hook;
}
/**
* @ingroup Hook
* This function set a hook function when the system exit a interrupt.
*
* @note the hook function must be simple and never be blocked or suspend.
*/
void rt_interrupt_leave_sethook(void (*hook)(void))
{
rt_interrupt_leave_hook = hook;
}
#endif
/* #define IRQ_DEBUG */
/**
* @addtogroup Kernel
*/
/**@{*/
volatile rt_uint8_t rt_interrupt_nest;
/**
* This function will be invoked by BSP, when enter interrupt service routine
*
* @note please don't invoke this routine in application
*
* @see rt_interrupt_leave
*/
void rt_interrupt_enter(void)
{
rt_base_t level;
RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq coming..., irq nest:%d\n",
rt_interrupt_nest));
level = rt_hw_interrupt_disable();
rt_interrupt_nest ++;
RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());
rt_hw_interrupt_enable(level);
}
/**
* This function will be invoked by BSP, when leave interrupt service routine
*
* @note please don't invoke this routine in application
*
* @see rt_interrupt_enter
*/
void rt_interrupt_leave(void)
{
rt_base_t level;
RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq leave, irq nest:%d\n",
rt_interrupt_nest));
level = rt_hw_interrupt_disable();
rt_interrupt_nest --;
RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
rt_hw_interrupt_enable(level);
}
/**
* This function will return the nest of interrupt.
*
* User application can invoke this function to get whether current
* context is interrupt context.
*
* @return the number of nested interrupts.
*/
RT_WEAK rt_uint8_t rt_interrupt_get_nest(void)
{
rt_uint8_t ret;
rt_base_t level;
level = rt_hw_interrupt_disable();
ret = rt_interrupt_nest;
rt_hw_interrupt_enable(level);
return ret;
}
/**@}*/
File diff suppressed because it is too large. Load diff
+713
View File
@@ -0,0 +1,713 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2008-7-12 Bernard the first version
* 2010-06-09 Bernard fix the end stub of heap
* fix memory check in rt_realloc function
* 2010-07-13 Bernard fix RT_ALIGN issue found by kuronca
* 2010-10-14 Bernard fix rt_realloc issue when realloc a NULL pointer.
* 2017-07-14 armink fix rt_realloc issue when new size is 0
* 2018-10-02 Bernard Add 64bit support
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Simon Goldschmidt
*
*/
#include <rthw.h>
#include <rtthread.h>
#ifndef RT_USING_MEMHEAP_AS_HEAP
/* #define RT_MEM_DEBUG */
#define RT_MEM_STATS
#if defined (RT_USING_HEAP) && defined (RT_USING_SMALL_MEM)
#ifdef RT_USING_HOOK
static void (*rt_malloc_hook)(void *ptr, rt_size_t size);
static void (*rt_free_hook)(void *ptr);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when a memory
* block is allocated from heap memory.
*
* @param hook the hook function
*/
void rt_malloc_sethook(void (*hook)(void *ptr, rt_size_t size))
{
rt_malloc_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when a memory
* block is released to heap memory.
*
* @param hook the hook function
*/
void rt_free_sethook(void (*hook)(void *ptr))
{
rt_free_hook = hook;
}
/**@}*/
#endif
#define HEAP_MAGIC 0x1ea0
struct heap_mem
{
/* magic and used flag */
rt_uint16_t magic;
rt_uint16_t used;
#ifdef ARCH_CPU_64BIT
rt_uint32_t resv;
#endif
rt_size_t next, prev;
#ifdef RT_USING_MEMTRACE
#ifdef ARCH_CPU_64BIT
rt_uint8_t thread[8];
#else
rt_uint8_t thread[4]; /* thread name */
#endif
#endif
};
/** pointer to the heap: for alignment, heap_ptr is now a pointer instead of an array */
static rt_uint8_t *heap_ptr;
/** the last entry, always unused! */
static struct heap_mem *heap_end;
#ifdef ARCH_CPU_64BIT
#define MIN_SIZE 24
#else
#define MIN_SIZE 12
#endif
#define MIN_SIZE_ALIGNED RT_ALIGN(MIN_SIZE, RT_ALIGN_SIZE)
#define SIZEOF_STRUCT_MEM RT_ALIGN(sizeof(struct heap_mem), RT_ALIGN_SIZE)
static struct heap_mem *lfree; /* pointer to the lowest free block */
static struct rt_semaphore heap_sem;
static rt_size_t mem_size_aligned;
#ifdef RT_MEM_STATS
static rt_size_t used_mem, max_mem;
#endif
#ifdef RT_USING_MEMTRACE
rt_inline void rt_mem_setname(struct heap_mem *mem, const char *name)
{
int index;
for (index = 0; index < sizeof(mem->thread); index ++)
{
if (name[index] == '\0') break;
mem->thread[index] = name[index];
}
for (; index < sizeof(mem->thread); index ++)
{
mem->thread[index] = ' ';
}
}
#endif
static void plug_holes(struct heap_mem *mem)
{
struct heap_mem *nmem;
struct heap_mem *pmem;
RT_ASSERT((rt_uint8_t *)mem >= heap_ptr);
RT_ASSERT((rt_uint8_t *)mem < (rt_uint8_t *)heap_end);
RT_ASSERT(mem->used == 0);
/* plug hole forward */
nmem = (struct heap_mem *)&heap_ptr[mem->next];
if (mem != nmem &&
nmem->used == 0 &&
(rt_uint8_t *)nmem != (rt_uint8_t *)heap_end)
{
/* if mem->next is unused and not end of heap_ptr,
* combine mem and mem->next
*/
if (lfree == nmem)
{
lfree = mem;
}
mem->next = nmem->next;
((struct heap_mem *)&heap_ptr[nmem->next])->prev = (rt_uint8_t *)mem - heap_ptr;
}
/* plug hole backward */
pmem = (struct heap_mem *)&heap_ptr[mem->prev];
if (pmem != mem && pmem->used == 0)
{
/* if mem->prev is unused, combine mem and mem->prev */
if (lfree == mem)
{
lfree = pmem;
}
pmem->next = mem->next;
((struct heap_mem *)&heap_ptr[mem->next])->prev = (rt_uint8_t *)pmem - heap_ptr;
}
}
/**
* @ingroup SystemInit
*
* This function will initialize system heap memory.
*
* @param begin_addr the beginning address of system heap memory.
* @param end_addr the end address of system heap memory.
*/
void rt_system_heap_init(void *begin_addr, void *end_addr)
{
struct heap_mem *mem;
rt_ubase_t begin_align = RT_ALIGN((rt_ubase_t)begin_addr, RT_ALIGN_SIZE);
rt_ubase_t end_align = RT_ALIGN_DOWN((rt_ubase_t)end_addr, RT_ALIGN_SIZE);
RT_DEBUG_NOT_IN_INTERRUPT;
/* alignment addr */
if ((end_align > (2 * SIZEOF_STRUCT_MEM)) &&
((end_align - 2 * SIZEOF_STRUCT_MEM) >= begin_align))
{
/* calculate the aligned memory size */
mem_size_aligned = end_align - begin_align - 2 * SIZEOF_STRUCT_MEM;
}
else
{
rt_kprintf("mem init, error begin address 0x%x, and end address 0x%x\n",
(rt_ubase_t)begin_addr, (rt_ubase_t)end_addr);
return;
}
/* point to begin address of heap */
heap_ptr = (rt_uint8_t *)begin_align;
RT_DEBUG_LOG(RT_DEBUG_MEM, ("mem init, heap begin address 0x%x, size %d\n",
(rt_ubase_t)heap_ptr, mem_size_aligned));
/* initialize the start of the heap */
mem = (struct heap_mem *)heap_ptr;
mem->magic = HEAP_MAGIC;
mem->next = mem_size_aligned + SIZEOF_STRUCT_MEM;
mem->prev = 0;
mem->used = 0;
#ifdef RT_USING_MEMTRACE
rt_mem_setname(mem, "INIT");
#endif
/* initialize the end of the heap */
heap_end = (struct heap_mem *)&heap_ptr[mem->next];
heap_end->magic = HEAP_MAGIC;
heap_end->used = 1;
heap_end->next = mem_size_aligned + SIZEOF_STRUCT_MEM;
heap_end->prev = mem_size_aligned + SIZEOF_STRUCT_MEM;
#ifdef RT_USING_MEMTRACE
rt_mem_setname(heap_end, "INIT");
#endif
rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO);
/* initialize the lowest-free pointer to the start of the heap */
lfree = (struct heap_mem *)heap_ptr;
}
/**
* @addtogroup MM
*/
/**@{*/
/**
* Allocate a block of memory with a minimum of 'size' bytes.
*
* @param size is the minimum size of the requested block in bytes.
*
* @return pointer to allocated memory or NULL if no free memory was found.
*/
void *rt_malloc(rt_size_t size)
{
rt_size_t ptr, ptr2;
struct heap_mem *mem, *mem2;
if (size == 0)
return RT_NULL;
RT_DEBUG_NOT_IN_INTERRUPT;
if (size != RT_ALIGN(size, RT_ALIGN_SIZE))
RT_DEBUG_LOG(RT_DEBUG_MEM, ("malloc size %d, but align to %d\n",
size, RT_ALIGN(size, RT_ALIGN_SIZE)));
else
RT_DEBUG_LOG(RT_DEBUG_MEM, ("malloc size %d\n", size));
/* alignment size */
size = RT_ALIGN(size, RT_ALIGN_SIZE);
if (size > mem_size_aligned)
{
RT_DEBUG_LOG(RT_DEBUG_MEM, ("no memory\n"));
return RT_NULL;
}
/* every data block must be at least MIN_SIZE_ALIGNED long */
if (size < MIN_SIZE_ALIGNED)
size = MIN_SIZE_ALIGNED;
/* take memory semaphore */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
for (ptr = (rt_uint8_t *)lfree - heap_ptr;
ptr < mem_size_aligned - size;
ptr = ((struct heap_mem *)&heap_ptr[ptr])->next)
{
mem = (struct heap_mem *)&heap_ptr[ptr];
if ((!mem->used) && (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size)
{
/* mem is not used and at least perfect fit is possible:
* mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >=
(size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED))
{
/* (in addition to the above, we test if another struct heap_mem (SIZEOF_STRUCT_MEM) containing
* at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
* -> split large block, create empty remainder,
* remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
* mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
* struct heap_mem would fit in but no data between mem2 and mem2->next
* @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
* region that couldn't hold data, but when mem->next gets freed,
* the 2 regions would be combined, resulting in more free memory
*/
ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
/* create mem2 struct */
mem2 = (struct heap_mem *)&heap_ptr[ptr2];
mem2->magic = HEAP_MAGIC;
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
#ifdef RT_USING_MEMTRACE
rt_mem_setname(mem2, " ");
#endif
/* and insert it between mem and mem->next */
mem->next = ptr2;
mem->used = 1;
if (mem2->next != mem_size_aligned + SIZEOF_STRUCT_MEM)
{
((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2;
}
#ifdef RT_MEM_STATS
used_mem += (size + SIZEOF_STRUCT_MEM);
if (max_mem < used_mem)
max_mem = used_mem;
#endif
}
else
{
/* (a mem2 struct does no fit into the user data space of mem and mem->next will always
* be used at this point: if not we have 2 unused structs in a row, plug_holes should have
* take care of this).
* -> near fit or excact fit: do not split, no mem2 creation
* also can't move mem->next directly behind mem, since mem->next
* will always be used at this point!
*/
mem->used = 1;
#ifdef RT_MEM_STATS
used_mem += mem->next - ((rt_uint8_t *)mem - heap_ptr);
if (max_mem < used_mem)
max_mem = used_mem;
#endif
}
/* set memory block magic */
mem->magic = HEAP_MAGIC;
#ifdef RT_USING_MEMTRACE
if (rt_thread_self())
rt_mem_setname(mem, rt_thread_self()->name);
else
rt_mem_setname(mem, "NONE");
#endif
if (mem == lfree)
{
/* Find next free block after mem and update lowest free pointer */
while (lfree->used && lfree != heap_end)
lfree = (struct heap_mem *)&heap_ptr[lfree->next];
RT_ASSERT(((lfree == heap_end) || (!lfree->used)));
}
rt_sem_release(&heap_sem);
RT_ASSERT((rt_ubase_t)mem + SIZEOF_STRUCT_MEM + size <= (rt_ubase_t)heap_end);
RT_ASSERT((rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM) % RT_ALIGN_SIZE == 0);
RT_ASSERT((((rt_ubase_t)mem) & (RT_ALIGN_SIZE - 1)) == 0);
RT_DEBUG_LOG(RT_DEBUG_MEM,
("allocate memory at 0x%x, size: %d\n",
(rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM),
(rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - heap_ptr))));
RT_OBJECT_HOOK_CALL(rt_malloc_hook,
(((void *)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM)), size));
/* return the memory data except mem struct */
return (rt_uint8_t *)mem + SIZEOF_STRUCT_MEM;
}
}
rt_sem_release(&heap_sem);
return RT_NULL;
}
/**
* This function will change the previously allocated memory block.
*
* @param rmem pointer to memory allocated by rt_malloc
* @param newsize the required new size
*
* @return the changed memory block address
*/
void *rt_realloc(void *rmem, rt_size_t newsize)
{
rt_size_t size;
rt_size_t ptr, ptr2;
struct heap_mem *mem, *mem2;
void *nmem;
RT_DEBUG_NOT_IN_INTERRUPT;
/* alignment size */
newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
if (newsize > mem_size_aligned)
{
RT_DEBUG_LOG(RT_DEBUG_MEM, ("realloc: out of memory\n"));
return RT_NULL;
}
else if (newsize == 0)
{
rt_free(rmem);
return RT_NULL;
}
/* allocate a new memory block */
if (rmem == RT_NULL)
return rt_malloc(newsize);
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
if ((rt_uint8_t *)rmem < (rt_uint8_t *)heap_ptr ||
(rt_uint8_t *)rmem >= (rt_uint8_t *)heap_end)
{
/* illegal memory */
rt_sem_release(&heap_sem);
return rmem;
}
mem = (struct heap_mem *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM);
ptr = (rt_uint8_t *)mem - heap_ptr;
size = mem->next - ptr - SIZEOF_STRUCT_MEM;
if (size == newsize)
{
/* the size is the same as */
rt_sem_release(&heap_sem);
return rmem;
}
if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size)
{
/* split memory block */
#ifdef RT_MEM_STATS
used_mem -= (size - newsize);
#endif
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
mem2 = (struct heap_mem *)&heap_ptr[ptr2];
mem2->magic = HEAP_MAGIC;
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
#ifdef RT_USING_MEMTRACE
rt_mem_setname(mem2, " ");
#endif
mem->next = ptr2;
if (mem2->next != mem_size_aligned + SIZEOF_STRUCT_MEM)
{
((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2;
}
if (mem2 < lfree)
{
/* the splited struct is now the lowest */
lfree = mem2;
}
plug_holes(mem2);
rt_sem_release(&heap_sem);
return rmem;
}
rt_sem_release(&heap_sem);
/* expand memory */
nmem = rt_malloc(newsize);
if (nmem != RT_NULL) /* check memory */
{
rt_memcpy(nmem, rmem, size < newsize ? size : newsize);
rt_free(rmem);
}
return nmem;
}
/**
* This function will contiguously allocate enough space for count objects
* that are size bytes of memory each and returns a pointer to the allocated
* memory.
*
* The allocated memory is filled with bytes of value zero.
*
* @param count number of objects to allocate
* @param size size of the objects to allocate
*
* @return pointer to allocated memory / NULL pointer if there is an error
*/
void *rt_calloc(rt_size_t count, rt_size_t size)
{
void *p;
/* allocate 'count' objects of size 'size' */
p = rt_malloc(count * size);
/* zero the memory */
if (p)
rt_memset(p, 0, count * size);
return p;
}
/**
* This function will release the previously allocated memory block by
* rt_malloc. The released memory block is taken back to system heap.
*
* @param rmem the address of memory which will be released
*/
void rt_free(void *rmem)
{
struct heap_mem *mem;
if (rmem == RT_NULL)
return;
RT_DEBUG_NOT_IN_INTERRUPT;
RT_ASSERT((((rt_ubase_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0);
RT_ASSERT((rt_uint8_t *)rmem >= (rt_uint8_t *)heap_ptr &&
(rt_uint8_t *)rmem < (rt_uint8_t *)heap_end);
RT_OBJECT_HOOK_CALL(rt_free_hook, (rmem));
if ((rt_uint8_t *)rmem < (rt_uint8_t *)heap_ptr ||
(rt_uint8_t *)rmem >= (rt_uint8_t *)heap_end)
{
RT_DEBUG_LOG(RT_DEBUG_MEM, ("illegal memory\n"));
return;
}
/* Get the corresponding struct heap_mem ... */
mem = (struct heap_mem *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM);
RT_DEBUG_LOG(RT_DEBUG_MEM,
("release memory 0x%x, size: %d\n",
(rt_ubase_t)rmem,
(rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - heap_ptr))));
/* protect the heap from concurrent access */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
/* ... which has to be in a used state ... */
if (!mem->used || mem->magic != HEAP_MAGIC)
{
rt_kprintf("to free a bad data block:\n");
rt_kprintf("mem: 0x%08x, used flag: %d, magic code: 0x%04x\n", mem, mem->used, mem->magic);
}
RT_ASSERT(mem->used);
RT_ASSERT(mem->magic == HEAP_MAGIC);
/* ... and is now unused. */
mem->used = 0;
mem->magic = HEAP_MAGIC;
#ifdef RT_USING_MEMTRACE
rt_mem_setname(mem, " ");
#endif
if (mem < lfree)
{
/* the newly freed struct is now the lowest */
lfree = mem;
}
#ifdef RT_MEM_STATS
used_mem -= (mem->next - ((rt_uint8_t *)mem - heap_ptr));
#endif
/* finally, see if prev or next are free also */
plug_holes(mem);
rt_sem_release(&heap_sem);
}
#ifdef RT_MEM_STATS
void rt_memory_info(rt_uint32_t *total,
rt_uint32_t *used,
rt_uint32_t *max_used)
{
if (total != RT_NULL)
*total = mem_size_aligned;
if (used != RT_NULL)
*used = used_mem;
if (max_used != RT_NULL)
*max_used = max_mem;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
void list_mem(void)
{
rt_kprintf("total memory: %d\n", mem_size_aligned);
rt_kprintf("used memory : %d\n", used_mem);
rt_kprintf("maximum allocated memory: %d\n", max_mem);
}
FINSH_FUNCTION_EXPORT(list_mem, list memory usage information)
#ifdef RT_USING_MEMTRACE
int memcheck(void)
{
int position;
rt_ubase_t level;
struct heap_mem *mem;
level = rt_hw_interrupt_disable();
for (mem = (struct heap_mem *)heap_ptr; mem != heap_end; mem = (struct heap_mem *)&heap_ptr[mem->next])
{
position = (rt_ubase_t)mem - (rt_ubase_t)heap_ptr;
if (position < 0) goto __exit;
if (position > (int)mem_size_aligned) goto __exit;
if (mem->magic != HEAP_MAGIC) goto __exit;
if (mem->used != 0 && mem->used != 1) goto __exit;
}
rt_hw_interrupt_enable(level);
return 0;
__exit:
rt_kprintf("Memory block wrong:\n");
rt_kprintf("address: 0x%08x\n", mem);
rt_kprintf(" magic: 0x%04x\n", mem->magic);
rt_kprintf(" used: %d\n", mem->used);
rt_kprintf(" size: %d\n", mem->next - position - SIZEOF_STRUCT_MEM);
rt_hw_interrupt_enable(level);
return 0;
}
MSH_CMD_EXPORT(memcheck, check memory data);
int memtrace(int argc, char **argv)
{
struct heap_mem *mem;
list_mem();
rt_kprintf("\nmemory heap address:\n");
rt_kprintf("heap_ptr: 0x%08x\n", heap_ptr);
rt_kprintf("lfree : 0x%08x\n", lfree);
rt_kprintf("heap_end: 0x%08x\n", heap_end);
rt_kprintf("\n--memory item information --\n");
for (mem = (struct heap_mem *)heap_ptr; mem != heap_end; mem = (struct heap_mem *)&heap_ptr[mem->next])
{
int position = (rt_ubase_t)mem - (rt_ubase_t)heap_ptr;
int size;
rt_kprintf("[0x%08x - ", mem);
size = mem->next - position - SIZEOF_STRUCT_MEM;
if (size < 1024)
rt_kprintf("%5d", size);
else if (size < 1024 * 1024)
rt_kprintf("%4dK", size / 1024);
else
rt_kprintf("%4dM", size / (1024 * 1024));
rt_kprintf("] %c%c%c%c", mem->thread[0], mem->thread[1], mem->thread[2], mem->thread[3]);
if (mem->magic != HEAP_MAGIC)
rt_kprintf(": ***\n");
else
rt_kprintf("\n");
}
return 0;
}
MSH_CMD_EXPORT(memtrace, dump memory trace information);
#endif /* end of RT_USING_MEMTRACE */
#endif /* end of RT_USING_FINSH */
#endif
/**@}*/
#endif /* end of RT_USING_HEAP */
#endif /* end of RT_USING_MEMHEAP_AS_HEAP */
+722
View File
@@ -0,0 +1,722 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* File : memheap.c
*
* Change Logs:
* Date Author Notes
* 2012-04-10 Bernard first implementation
* 2012-10-16 Bernard add the mutex lock for heap object.
* 2012-12-29 Bernard memheap can be used as system heap.
* change mutex lock to semaphore lock.
* 2013-04-10 Bernard add rt_memheap_realloc function.
* 2013-05-24 Bernard fix the rt_memheap_realloc issue.
* 2013-07-11 Grissiom fix the memory block splitting issue.
* 2013-07-15 Grissiom optimize rt_memheap_realloc
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_MEMHEAP
/* dynamic pool magic and mask */
#define RT_MEMHEAP_MAGIC 0x1ea01ea0
#define RT_MEMHEAP_MASK 0xfffffffe
#define RT_MEMHEAP_USED 0x01
#define RT_MEMHEAP_FREED 0x00
#define RT_MEMHEAP_IS_USED(i) ((i)->magic & RT_MEMHEAP_USED)
#define RT_MEMHEAP_MINIALLOC 12
#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
#define MEMITEM_SIZE(item) ((rt_ubase_t)item->next - (rt_ubase_t)item - RT_MEMHEAP_SIZE)
/*
* The initialized memory pool will be:
* +-----------------------------------+--------------------------+
* | whole freed memory block | Used Memory Block Tailer |
* +-----------------------------------+--------------------------+
*
* block_list --> whole freed memory block
*
* The length of Used Memory Block Tailer is 0,
* which is prevents block merging across list
*/
rt_err_t rt_memheap_init(struct rt_memheap *memheap,
const char *name,
void *start_addr,
rt_size_t size)
{
struct rt_memheap_item *item;
RT_ASSERT(memheap != RT_NULL);
/* initialize pool object */
rt_object_init(&(memheap->parent), RT_Object_Class_MemHeap, name);
memheap->start_addr = start_addr;
memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE);
memheap->max_used_size = memheap->pool_size - memheap->available_size;
/* initialize the free list header */
item = &(memheap->free_header);
item->magic = RT_MEMHEAP_MAGIC;
item->pool_ptr = memheap;
item->next = RT_NULL;
item->prev = RT_NULL;
item->next_free = item;
item->prev_free = item;
/* set the free list to free list header */
memheap->free_list = item;
/* initialize the first big memory block */
item = (struct rt_memheap_item *)start_addr;
item->magic = RT_MEMHEAP_MAGIC;
item->pool_ptr = memheap;
item->next = RT_NULL;
item->prev = RT_NULL;
item->next_free = item;
item->prev_free = item;
item->next = (struct rt_memheap_item *)
((rt_uint8_t *)item + memheap->available_size + RT_MEMHEAP_SIZE);
item->prev = item->next;
/* block list header */
memheap->block_list = item;
/* place the big memory block to free list */
item->next_free = memheap->free_list->next_free;
item->prev_free = memheap->free_list;
memheap->free_list->next_free->prev_free = item;
memheap->free_list->next_free = item;
/* move to the end of memory pool to build a small tailer block,
* which prevents block merging
*/
item = item->next;
/* it's a used memory block */
item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
item->pool_ptr = memheap;
item->next = (struct rt_memheap_item *)start_addr;
item->prev = (struct rt_memheap_item *)start_addr;
/* not in free list */
item->next_free = item->prev_free = RT_NULL;
/* initialize semaphore lock */
rt_sem_init(&(memheap->lock), name, 1, RT_IPC_FLAG_FIFO);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("memory heap: start addr 0x%08x, size %d, free list header 0x%08x\n",
start_addr, size, &(memheap->free_header)));
return RT_EOK;
}
rt_err_t rt_memheap_detach(struct rt_memheap *heap)
{
RT_ASSERT(heap);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
RT_ASSERT(rt_object_is_systemobject(&heap->parent));
rt_sem_detach(&heap->lock);
rt_object_detach(&(heap->parent));
/* Return a successful completion. */
return RT_EOK;
}
void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
{
rt_err_t result;
rt_uint32_t free_size;
struct rt_memheap_item *header_ptr;
RT_ASSERT(heap != RT_NULL);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
/* align allocated size */
size = RT_ALIGN(size, RT_ALIGN_SIZE);
if (size < RT_MEMHEAP_MINIALLOC)
size = RT_MEMHEAP_MINIALLOC;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d on heap:%8.*s",
size, RT_NAME_MAX, heap->parent.name));
if (size < heap->available_size)
{
/* search on free list */
free_size = 0;
/* lock memheap */
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_set_errno(result);
return RT_NULL;
}
/* get the first free memory block */
header_ptr = heap->free_list->next_free;
while (header_ptr != heap->free_list && free_size < size)
{
/* get current freed memory block size */
free_size = MEMITEM_SIZE(header_ptr);
if (free_size < size)
{
/* move to next free memory block */
header_ptr = header_ptr->next_free;
}
}
/* determine if the memory is available. */
if (free_size >= size)
{
/* a block that satisfies the request has been found. */
/* determine if the block needs to be split. */
if (free_size >= (size + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC))
{
struct rt_memheap_item *new_ptr;
/* split the block. */
new_ptr = (struct rt_memheap_item *)
(((rt_uint8_t *)header_ptr) + size + RT_MEMHEAP_SIZE);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
header_ptr,
header_ptr->next,
header_ptr->prev,
new_ptr));
/* mark the new block as a memory block and freed. */
new_ptr->magic = RT_MEMHEAP_MAGIC;
/* put the pool pointer into the new block. */
new_ptr->pool_ptr = heap;
/* break down the block list */
new_ptr->prev = header_ptr;
new_ptr->next = header_ptr->next;
header_ptr->next->prev = new_ptr;
header_ptr->next = new_ptr;
/* remove header ptr from free list */
header_ptr->next_free->prev_free = header_ptr->prev_free;
header_ptr->prev_free->next_free = header_ptr->next_free;
header_ptr->next_free = RT_NULL;
header_ptr->prev_free = RT_NULL;
/* insert new_ptr to free list */
new_ptr->next_free = heap->free_list->next_free;
new_ptr->prev_free = heap->free_list;
heap->free_list->next_free->prev_free = new_ptr;
heap->free_list->next_free = new_ptr;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x\n",
new_ptr->next_free,
new_ptr->prev_free));
/* decrement the available byte count. */
heap->available_size = heap->available_size -
size -
RT_MEMHEAP_SIZE;
if (heap->pool_size - heap->available_size > heap->max_used_size)
heap->max_used_size = heap->pool_size - heap->available_size;
}
else
{
/* decrement the entire free size from the available bytes count. */
heap->available_size = heap->available_size - free_size;
if (heap->pool_size - heap->available_size > heap->max_used_size)
heap->max_used_size = heap->pool_size - heap->available_size;
/* remove header_ptr from free list */
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("one block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x\n",
header_ptr,
header_ptr->next_free,
header_ptr->prev_free));
header_ptr->next_free->prev_free = header_ptr->prev_free;
header_ptr->prev_free->next_free = header_ptr->next_free;
header_ptr->next_free = RT_NULL;
header_ptr->prev_free = RT_NULL;
}
/* Mark the allocated block as not available. */
header_ptr->magic |= RT_MEMHEAP_USED;
/* release lock */
rt_sem_release(&(heap->lock));
/* Return a memory address to the caller. */
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("alloc mem: memory[0x%08x], heap[0x%08x], size: %d\n",
(void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE),
header_ptr,
size));
return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE);
}
/* release lock */
rt_sem_release(&(heap->lock));
}
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
/* Return the completion status. */
return RT_NULL;
}
void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
{
rt_err_t result;
rt_size_t oldsize;
struct rt_memheap_item *header_ptr;
struct rt_memheap_item *new_ptr;
RT_ASSERT(heap);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
if (newsize == 0)
{
rt_memheap_free(ptr);
return RT_NULL;
}
/* align allocated size */
newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
if (newsize < RT_MEMHEAP_MINIALLOC)
newsize = RT_MEMHEAP_MINIALLOC;
if (ptr == RT_NULL)
{
return rt_memheap_alloc(heap, newsize);
}
/* get memory block header and get the size of memory block */
header_ptr = (struct rt_memheap_item *)
((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
oldsize = MEMITEM_SIZE(header_ptr);
/* re-allocate memory */
if (newsize > oldsize)
{
void *new_ptr;
struct rt_memheap_item *next_ptr;
/* lock memheap */
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_set_errno(result);
return RT_NULL;
}
next_ptr = header_ptr->next;
/* header_ptr should not be the tail */
RT_ASSERT(next_ptr > header_ptr);
/* check whether the following free space is enough to expand */
if (!RT_MEMHEAP_IS_USED(next_ptr))
{
rt_int32_t nextsize;
nextsize = MEMITEM_SIZE(next_ptr);
RT_ASSERT(next_ptr > 0);
/* Here is the ASCII art of the situation that we can make use of
* the next free node without alloc/memcpy, |*| is the control
* block:
*
* oldsize free node
* |*|-----------|*|----------------------|*|
* newsize >= minialloc
* |*|----------------|*|-----------------|*|
*/
if (nextsize + oldsize > newsize + RT_MEMHEAP_MINIALLOC)
{
/* decrement the entire free size from the available bytes count. */
heap->available_size = heap->available_size - (newsize - oldsize);
if (heap->pool_size - heap->available_size > heap->max_used_size)
heap->max_used_size = heap->pool_size - heap->available_size;
/* remove next_ptr from free list */
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("remove block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x",
next_ptr,
next_ptr->next_free,
next_ptr->prev_free));
next_ptr->next_free->prev_free = next_ptr->prev_free;
next_ptr->prev_free->next_free = next_ptr->next_free;
next_ptr->next->prev = next_ptr->prev;
next_ptr->prev->next = next_ptr->next;
/* build a new one on the right place */
next_ptr = (struct rt_memheap_item *)((char *)ptr + newsize);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("new free block: block[0x%08x] nextm[0x%08x] prevm[0x%08x]",
next_ptr,
next_ptr->next,
next_ptr->prev));
/* mark the new block as a memory block and freed. */
next_ptr->magic = RT_MEMHEAP_MAGIC;
/* put the pool pointer into the new block. */
next_ptr->pool_ptr = heap;
next_ptr->prev = header_ptr;
next_ptr->next = header_ptr->next;
header_ptr->next->prev = next_ptr;
header_ptr->next = next_ptr;
/* insert next_ptr to free list */
next_ptr->next_free = heap->free_list->next_free;
next_ptr->prev_free = heap->free_list;
heap->free_list->next_free->prev_free = next_ptr;
heap->free_list->next_free = next_ptr;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x",
next_ptr->next_free,
next_ptr->prev_free));
/* release lock */
rt_sem_release(&(heap->lock));
return ptr;
}
}
/* release lock */
rt_sem_release(&(heap->lock));
/* re-allocate a memory block */
new_ptr = (void *)rt_memheap_alloc(heap, newsize);
if (new_ptr != RT_NULL)
{
rt_memcpy(new_ptr, ptr, oldsize < newsize ? oldsize : newsize);
rt_memheap_free(ptr);
}
return new_ptr;
}
/* don't split when there is less than one node space left */
if (newsize + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC >= oldsize)
return ptr;
/* lock memheap */
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_set_errno(result);
return RT_NULL;
}
/* split the block. */
new_ptr = (struct rt_memheap_item *)
(((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
header_ptr,
header_ptr->next,
header_ptr->prev,
new_ptr));
/* mark the new block as a memory block and freed. */
new_ptr->magic = RT_MEMHEAP_MAGIC;
/* put the pool pointer into the new block. */
new_ptr->pool_ptr = heap;
/* break down the block list */
new_ptr->prev = header_ptr;
new_ptr->next = header_ptr->next;
header_ptr->next->prev = new_ptr;
header_ptr->next = new_ptr;
/* determine if the block can be merged with the next neighbor. */
if (!RT_MEMHEAP_IS_USED(new_ptr->next))
{
struct rt_memheap_item *free_ptr;
/* merge block with next neighbor. */
free_ptr = new_ptr->next;
heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
header_ptr, header_ptr->next_free, header_ptr->prev_free));
free_ptr->next->prev = new_ptr;
new_ptr->next = free_ptr->next;
/* remove free ptr from free list */
free_ptr->next_free->prev_free = free_ptr->prev_free;
free_ptr->prev_free->next_free = free_ptr->next_free;
}
/* insert the split block to free list */
new_ptr->next_free = heap->free_list->next_free;
new_ptr->prev_free = heap->free_list;
heap->free_list->next_free->prev_free = new_ptr;
heap->free_list->next_free = new_ptr;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x\n",
new_ptr->next_free,
new_ptr->prev_free));
/* increment the available byte count. */
heap->available_size = heap->available_size + MEMITEM_SIZE(new_ptr);
/* release lock */
rt_sem_release(&(heap->lock));
/* return the old memory block */
return ptr;
}
void rt_memheap_free(void *ptr)
{
rt_err_t result;
struct rt_memheap *heap;
struct rt_memheap_item *header_ptr, *new_ptr;
rt_uint32_t insert_header;
/* NULL check */
if (ptr == RT_NULL) return;
/* set initial status as OK */
insert_header = 1;
new_ptr = RT_NULL;
header_ptr = (struct rt_memheap_item *)
((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]\n",
ptr, header_ptr));
/* check magic */
RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
RT_ASSERT(header_ptr->magic & RT_MEMHEAP_USED);
/* check whether this block of memory has been over-written. */
RT_ASSERT((header_ptr->next->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
/* get pool ptr */
heap = header_ptr->pool_ptr;
RT_ASSERT(heap);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
/* lock memheap */
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_set_errno(result);
return ;
}
/* Mark the memory as available. */
header_ptr->magic &= ~RT_MEMHEAP_USED;
/* Adjust the available number of bytes. */
heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr);
/* Determine if the block can be merged with the previous neighbor. */
if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
{
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x\n",
header_ptr->prev));
/* adjust the available number of bytes. */
heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
/* yes, merge block with previous neighbor. */
(header_ptr->prev)->next = header_ptr->next;
(header_ptr->next)->prev = header_ptr->prev;
/* move header pointer to previous. */
header_ptr = header_ptr->prev;
/* don't insert header to free list */
insert_header = 0;
}
/* determine if the block can be merged with the next neighbor. */
if (!RT_MEMHEAP_IS_USED(header_ptr->next))
{
/* adjust the available number of bytes. */
heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
/* merge block with next neighbor. */
new_ptr = header_ptr->next;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
new_ptr, new_ptr->next_free, new_ptr->prev_free));
new_ptr->next->prev = header_ptr;
header_ptr->next = new_ptr->next;
/* remove new ptr from free list */
new_ptr->next_free->prev_free = new_ptr->prev_free;
new_ptr->prev_free->next_free = new_ptr->next_free;
}
if (insert_header)
{
/* no left merge, insert to free list */
header_ptr->next_free = heap->free_list->next_free;
header_ptr->prev_free = heap->free_list;
heap->free_list->next_free->prev_free = header_ptr;
heap->free_list->next_free = header_ptr;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
("insert to free list: next_free 0x%08x, prev_free 0x%08x\n",
header_ptr->next_free, header_ptr->prev_free));
}
/* release lock */
rt_sem_release(&(heap->lock));
}
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap _heap;
void rt_system_heap_init(void *begin_addr, void *end_addr)
{
/* initialize a default heap in the system */
rt_memheap_init(&_heap,
"heap",
begin_addr,
(rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
}
void *rt_malloc(rt_size_t size)
{
void *ptr;
/* try to allocate in system heap */
ptr = rt_memheap_alloc(&_heap, size);
if (ptr == RT_NULL)
{
struct rt_object *object;
struct rt_list_node *node;
struct rt_memheap *heap;
struct rt_object_information *information;
/* try to allocate on other memory heap */
information = rt_object_get_information(RT_Object_Class_MemHeap);
RT_ASSERT(information != RT_NULL);
for (node = information->object_list.next;
node != &(information->object_list);
node = node->next)
{
object = rt_list_entry(node, struct rt_object, list);
heap = (struct rt_memheap *)object;
RT_ASSERT(heap);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
/* not allocate in the default system heap */
if (heap == &_heap)
continue;
ptr = rt_memheap_alloc(heap, size);
if (ptr != RT_NULL)
break;
}
}
return ptr;
}
void rt_free(void *rmem)
{
rt_memheap_free(rmem);
}
void *rt_realloc(void *rmem, rt_size_t newsize)
{
void *new_ptr;
struct rt_memheap_item *header_ptr;
if (rmem == RT_NULL)
return rt_malloc(newsize);
if (newsize == 0)
{
rt_free(rmem);
return RT_NULL;
}
/* get old memory item */
header_ptr = (struct rt_memheap_item *)
((rt_uint8_t *)rmem - RT_MEMHEAP_SIZE);
new_ptr = rt_memheap_realloc(header_ptr->pool_ptr, rmem, newsize);
if (new_ptr == RT_NULL && newsize != 0)
{
/* allocate memory block from other memheap */
new_ptr = rt_malloc(newsize);
if (new_ptr != RT_NULL && rmem != RT_NULL)
{
rt_size_t oldsize;
/* get the size of old memory block */
oldsize = MEMITEM_SIZE(header_ptr);
if (newsize > oldsize)
rt_memcpy(new_ptr, rmem, oldsize);
else
rt_memcpy(new_ptr, rmem, newsize);
rt_free(rmem);
}
}
return new_ptr;
}
void *rt_calloc(rt_size_t count, rt_size_t size)
{
void *ptr;
rt_size_t total_size;
total_size = count * size;
ptr = rt_malloc(total_size);
if (ptr != RT_NULL)
{
/* clean memory */
rt_memset(ptr, 0, total_size);
}
return ptr;
}
void rt_memory_info(rt_uint32_t *total,
rt_uint32_t *used,
rt_uint32_t *max_used)
{
if (total != RT_NULL)
*total = _heap.pool_size;
if (used != RT_NULL)
*used = _heap.pool_size - _heap.available_size;
if (max_used != RT_NULL)
*max_used = _heap.max_used_size;
}
#endif
#endif
+449
View File
@@ -0,0 +1,449 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-05-27 Bernard implement memory pool
* 2006-06-03 Bernard fix the thread timer init bug
* 2006-06-30 Bernard fix the allocate/free block bug
* 2006-08-04 Bernard add hook support
* 2006-08-10 Bernard fix interrupt bug in rt_mp_alloc
* 2010-07-13 Bernard fix RT_ALIGN issue found by kuronca
* 2010-10-26 yi.qiu add module support in rt_mp_delete
* 2011-01-24 Bernard add object allocation check.
* 2012-03-22 Bernard fix align issue in rt_mp_init and rt_mp_create.
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_MEMPOOL
#ifdef RT_USING_HOOK
static void (*rt_mp_alloc_hook)(struct rt_mempool *mp, void *block);
static void (*rt_mp_free_hook)(struct rt_mempool *mp, void *block);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when a memory
* block is allocated from memory pool.
*
* @param hook the hook function
*/
void rt_mp_alloc_sethook(void (*hook)(struct rt_mempool *mp, void *block))
{
rt_mp_alloc_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when a memory
* block is released to memory pool.
*
* @param hook the hook function
*/
void rt_mp_free_sethook(void (*hook)(struct rt_mempool *mp, void *block))
{
rt_mp_free_hook = hook;
}
/**@}*/
#endif
/**
* @addtogroup MM
*/
/**@{*/
/**
* This function will initialize a memory pool object, normally which is used
* for static object.
*
* @param mp the memory pool object
* @param name the name of memory pool
* @param start the star address of memory pool
* @param size the total size of memory pool
* @param block_size the size for each block
*
* @return RT_EOK
*/
rt_err_t rt_mp_init(struct rt_mempool *mp,
const char *name,
void *start,
rt_size_t size,
rt_size_t block_size)
{
rt_uint8_t *block_ptr;
register rt_size_t offset;
/* parameter check */
RT_ASSERT(mp != RT_NULL);
RT_ASSERT(name != RT_NULL);
RT_ASSERT(start != RT_NULL);
RT_ASSERT(size > 0 && block_size > 0);
/* initialize object */
rt_object_init(&(mp->parent), RT_Object_Class_MemPool, name);
/* initialize memory pool */
mp->start_address = start;
mp->size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
/* align the block size */
block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE);
mp->block_size = block_size;
/* align to align size byte */
mp->block_total_count = mp->size / (mp->block_size + sizeof(rt_uint8_t *));
mp->block_free_count = mp->block_total_count;
/* initialize suspended thread list */
rt_list_init(&(mp->suspend_thread));
/* initialize free block list */
block_ptr = (rt_uint8_t *)mp->start_address;
for (offset = 0; offset < mp->block_total_count; offset ++)
{
*(rt_uint8_t **)(block_ptr + offset * (block_size + sizeof(rt_uint8_t *))) =
(rt_uint8_t *)(block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8_t *)));
}
*(rt_uint8_t **)(block_ptr + (offset - 1) * (block_size + sizeof(rt_uint8_t *))) =
RT_NULL;
mp->block_list = block_ptr;
return RT_EOK;
}
/**
* This function will detach a memory pool from system object management.
*
* @param mp the memory pool object
*
* @return RT_EOK
*/
rt_err_t rt_mp_detach(struct rt_mempool *mp)
{
struct rt_thread *thread;
register rt_ubase_t level;
/* parameter check */
RT_ASSERT(mp != RT_NULL);
RT_ASSERT(rt_object_get_type(&mp->parent) == RT_Object_Class_MemPool);
RT_ASSERT(rt_object_is_systemobject(&mp->parent));
/* wake up all suspended threads */
while (!rt_list_isempty(&(mp->suspend_thread)))
{
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(mp->suspend_thread.next, struct rt_thread, tlist);
/* set error code to RT_ERROR */
thread->error = -RT_ERROR;
/*
* resume thread
* In rt_thread_resume function, it will remove current thread from
* suspend list
*/
rt_thread_resume(thread);
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/* detach object */
rt_object_detach(&(mp->parent));
return RT_EOK;
}
#ifdef RT_USING_HEAP
/**
* This function will create a mempool object and allocate the memory pool from
* heap.
*
* @param name the name of memory pool
* @param block_count the count of blocks in memory pool
* @param block_size the size for each block
*
* @return the created mempool object
*/
rt_mp_t rt_mp_create(const char *name,
rt_size_t block_count,
rt_size_t block_size)
{
rt_uint8_t *block_ptr;
struct rt_mempool *mp;
register rt_size_t offset;
RT_DEBUG_NOT_IN_INTERRUPT;
/* parameter check */
RT_ASSERT(name != RT_NULL);
RT_ASSERT(block_count > 0 && block_size > 0);
/* allocate object */
mp = (struct rt_mempool *)rt_object_allocate(RT_Object_Class_MemPool, name);
/* allocate object failed */
if (mp == RT_NULL)
return RT_NULL;
/* initialize memory pool */
block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE);
mp->block_size = block_size;
mp->size = (block_size + sizeof(rt_uint8_t *)) * block_count;
/* allocate memory */
mp->start_address = rt_malloc((block_size + sizeof(rt_uint8_t *)) *
block_count);
if (mp->start_address == RT_NULL)
{
/* no memory, delete memory pool object */
rt_object_delete(&(mp->parent));
return RT_NULL;
}
mp->block_total_count = block_count;
mp->block_free_count = mp->block_total_count;
/* initialize suspended thread list */
rt_list_init(&(mp->suspend_thread));
/* initialize free block list */
block_ptr = (rt_uint8_t *)mp->start_address;
for (offset = 0; offset < mp->block_total_count; offset ++)
{
*(rt_uint8_t **)(block_ptr + offset * (block_size + sizeof(rt_uint8_t *)))
= block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8_t *));
}
*(rt_uint8_t **)(block_ptr + (offset - 1) * (block_size + sizeof(rt_uint8_t *)))
= RT_NULL;
mp->block_list = block_ptr;
return mp;
}
/**
* This function will delete a memory pool and release the object memory.
*
* @param mp the memory pool object
*
* @return RT_EOK
*/
rt_err_t rt_mp_delete(rt_mp_t mp)
{
struct rt_thread *thread;
register rt_ubase_t level;
RT_DEBUG_NOT_IN_INTERRUPT;
/* parameter check */
RT_ASSERT(mp != RT_NULL);
RT_ASSERT(rt_object_get_type(&mp->parent) == RT_Object_Class_MemPool);
RT_ASSERT(rt_object_is_systemobject(&mp->parent) == RT_FALSE);
/* wake up all suspended threads */
while (!rt_list_isempty(&(mp->suspend_thread)))
{
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(mp->suspend_thread.next, struct rt_thread, tlist);
/* set error code to RT_ERROR */
thread->error = -RT_ERROR;
/*
* resume thread
* In rt_thread_resume function, it will remove current thread from
* suspend list
*/
rt_thread_resume(thread);
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/* release allocated room */
rt_free(mp->start_address);
/* detach object */
rt_object_delete(&(mp->parent));
return RT_EOK;
}
#endif
/**
* This function will allocate a block from memory pool
*
* @param mp the memory pool object
* @param time the waiting time
*
* @return the allocated memory block or RT_NULL on allocated failed
*/
void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time)
{
rt_uint8_t *block_ptr;
register rt_base_t level;
struct rt_thread *thread;
rt_uint32_t before_sleep = 0;
/* parameter check */
RT_ASSERT(mp != RT_NULL);
/* get current thread */
thread = rt_thread_self();
/* disable interrupt */
level = rt_hw_interrupt_disable();
while (mp->block_free_count == 0)
{
/* memory block is unavailable. */
if (time == 0)
{
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_set_errno(-RT_ETIMEOUT);
return RT_NULL;
}
RT_DEBUG_NOT_IN_INTERRUPT;
thread->error = RT_EOK;
/* need suspend thread */
rt_thread_suspend(thread);
rt_list_insert_after(&(mp->suspend_thread), &(thread->tlist));
if (time > 0)
{
/* get the start tick of timer */
before_sleep = rt_tick_get();
/* init thread timer and start it */
rt_timer_control(&(thread->thread_timer),
RT_TIMER_CTRL_SET_TIME,
&time);
rt_timer_start(&(thread->thread_timer));
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* do a schedule */
rt_schedule();
if (thread->error != RT_EOK)
return RT_NULL;
if (time > 0)
{
time -= rt_tick_get() - before_sleep;
if (time < 0)
time = 0;
}
/* disable interrupt */
level = rt_hw_interrupt_disable();
}
/* memory block is available. decrease the free block counter */
mp->block_free_count--;
/* get block from block list */
block_ptr = mp->block_list;
RT_ASSERT(block_ptr != RT_NULL);
/* Setup the next free node. */
mp->block_list = *(rt_uint8_t **)block_ptr;
/* point to memory pool */
*(rt_uint8_t **)block_ptr = (rt_uint8_t *)mp;
/* enable interrupt */
rt_hw_interrupt_enable(level);
RT_OBJECT_HOOK_CALL(rt_mp_alloc_hook,
(mp, (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *))));
return (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *));
}
/**
* This function will release a memory block
*
* @param block the address of memory block to be released
*/
void rt_mp_free(void *block)
{
rt_uint8_t **block_ptr;
struct rt_mempool *mp;
struct rt_thread *thread;
register rt_base_t level;
/* parameter check */
if (block == RT_NULL) return;
/* get the control block of pool which the block belongs to */
block_ptr = (rt_uint8_t **)((rt_uint8_t *)block - sizeof(rt_uint8_t *));
mp = (struct rt_mempool *)*block_ptr;
RT_OBJECT_HOOK_CALL(rt_mp_free_hook, (mp, block));
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* increase the free block count */
mp->block_free_count ++;
/* link the block into the block list */
*block_ptr = mp->block_list;
mp->block_list = (rt_uint8_t *)block_ptr;
if (!rt_list_isempty(&(mp->suspend_thread)))
{
/* get the suspended thread */
thread = rt_list_entry(mp->suspend_thread.next,
struct rt_thread,
tlist);
/* set error */
thread->error = RT_EOK;
/* resume thread */
rt_thread_resume(thread);
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* do a schedule */
rt_schedule();
return;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/**@}*/
#endif
+548
View File
@@ -0,0 +1,548 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-14 Bernard the first version
* 2006-04-21 Bernard change the scheduler lock to interrupt lock
* 2006-05-18 Bernard fix the object init bug
* 2006-08-03 Bernard add hook support
* 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
* 2010-10-26 yi.qiu add module support in rt_object_allocate and rt_object_free
* 2017-12-10 Bernard Add object_info enum.
* 2018-01-25 Bernard Fix the object find issue when enable MODULE.
*/
#include <rtthread.h>
#include <rthw.h>
/*
* define object_info for the number of rt_object_container items.
*/
enum rt_object_info_type
{
RT_Object_Info_Thread = 0, /**< The object is a thread. */
#ifdef RT_USING_SEMAPHORE
RT_Object_Info_Semaphore, /**< The object is a semaphore. */
#endif
#ifdef RT_USING_MUTEX
RT_Object_Info_Mutex, /**< The object is a mutex. */
#endif
#ifdef RT_USING_EVENT
RT_Object_Info_Event, /**< The object is a event. */
#endif
#ifdef RT_USING_MAILBOX
RT_Object_Info_MailBox, /**< The object is a mail box. */
#endif
#ifdef RT_USING_MESSAGEQUEUE
RT_Object_Info_MessageQueue, /**< The object is a message queue. */
#endif
#ifdef RT_USING_MEMHEAP
RT_Object_Info_MemHeap, /**< The object is a memory heap */
#endif
#ifdef RT_USING_MEMPOOL
RT_Object_Info_MemPool, /**< The object is a memory pool. */
#endif
#ifdef RT_USING_DEVICE
RT_Object_Info_Device, /**< The object is a device */
#endif
RT_Object_Info_Timer, /**< The object is a timer. */
RT_Object_Info_Unknown, /**< The object is unknown. */
};
#define _OBJ_CONTAINER_LIST_INIT(c) \
{&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
/* initialize object container - thread */
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},
#ifdef RT_USING_SEMAPHORE
/* initialize object container - semaphore */
{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX
/* initialize object container - mutex */
{RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
/* initialize object container - event */
{RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
/* initialize object container - mailbox */
{RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MailBox), sizeof(struct rt_mailbox)},
#endif
#ifdef RT_USING_MESSAGEQUEUE
/* initialize object container - message queue */
{RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MessageQueue), sizeof(struct rt_messagequeue)},
#endif
#ifdef RT_USING_MEMHEAP
/* initialize object container - memory heap */
{RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemHeap), sizeof(struct rt_memheap)},
#endif
#ifdef RT_USING_MEMPOOL
/* initialize object container - memory pool */
{RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE
/* initialize object container - device */
{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif
/* initialize object container - timer */
{RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer)},
};
#ifdef RT_USING_HOOK
static void (*rt_object_attach_hook)(struct rt_object *object);
static void (*rt_object_detach_hook)(struct rt_object *object);
void (*rt_object_trytake_hook)(struct rt_object *object);
void (*rt_object_take_hook)(struct rt_object *object);
void (*rt_object_put_hook)(struct rt_object *object);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when object
* attaches to kernel object system.
*
* @param hook the hook function
*/
void rt_object_attach_sethook(void (*hook)(struct rt_object *object))
{
rt_object_attach_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when object
* detaches from kernel object system.
*
* @param hook the hook function
*/
void rt_object_detach_sethook(void (*hook)(struct rt_object *object))
{
rt_object_detach_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when object
* is taken from kernel object system.
*
* The object is taken means:
* semaphore - semaphore is taken by thread
* mutex - mutex is taken by thread
* event - event is received by thread
* mailbox - mail is received by thread
* message queue - message is received by thread
*
* @param hook the hook function
*/
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object))
{
rt_object_trytake_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when object
* have been taken from kernel object system.
*
* The object have been taken means:
* semaphore - semaphore have been taken by thread
* mutex - mutex have been taken by thread
* event - event have been received by thread
* mailbox - mail have been received by thread
* message queue - message have been received by thread
* timer - timer is started
*
* @param hook the hook function
*/
void rt_object_take_sethook(void (*hook)(struct rt_object *object))
{
rt_object_take_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when object
* is put to kernel object system.
*
* @param hook the hook function
*/
void rt_object_put_sethook(void (*hook)(struct rt_object *object))
{
rt_object_put_hook = hook;
}
/**@}*/
#endif
/**
* @ingroup SystemInit
*
* This function will initialize system object management.
*
* @deprecated since 0.3.0, this function does not need to be invoked
* in the system initialization.
*/
void rt_system_object_init(void)
{
}
/**
* @addtogroup KernelObject
*/
/**@{*/
/**
* This function will return the specified type of object information.
*
* @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
*
* @return the object type information or RT_NULL
*/
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type)
{
int index;
for (index = 0; index < RT_Object_Info_Unknown; index ++)
if (rt_object_container[index].type == type) return &rt_object_container[index];
return RT_NULL;
}
/**
* This function will return the length of object list in object container.
*
* @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
* @return the length of object list
*/
int rt_object_get_length(enum rt_object_class_type type)
{
int count = 0;
rt_ubase_t level;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
information = rt_object_get_information((enum rt_object_class_type)type);
if (information == RT_NULL) return 0;
level = rt_hw_interrupt_disable();
/* get the count of objects */
rt_list_for_each(node, &(information->object_list))
{
count ++;
}
rt_hw_interrupt_enable(level);
return count;
}
/**
* This function will copy the object pointer of the specified type,
* with the maximum size specified by maxlen.
*
* @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
* @param pointers the pointers will be saved to
* @param maxlen the maximum number of pointers can be saved
*
* @return the copied number of object pointers
*/
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
{
int index = 0;
rt_ubase_t level;
struct rt_object *object;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
if (maxlen <= 0) return 0;
information = rt_object_get_information((enum rt_object_class_type)type);
if (information == RT_NULL) return 0;
level = rt_hw_interrupt_disable();
/* retrieve pointer of object */
rt_list_for_each(node, &(information->object_list))
{
object = rt_list_entry(node, struct rt_object, list);
pointers[index] = object;
index ++;
if (index >= maxlen) break;
}
rt_hw_interrupt_enable(level);
return index;
}
/**
* This function will initialize an object and add it to object system
* management.
*
* @param object the specified object to be initialized.
* @param type the object type.
* @param name the object name. In system, the object's name must be unique.
*/
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name)
{
register rt_base_t temp;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information;
/* get object information */
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
/* check object type to avoid re-initialization */
/* enter critical */
rt_enter_critical();
/* try to find object */
for (node = information->object_list.next;
node != &(information->object_list);
node = node->next)
{
struct rt_object *obj;
obj = rt_list_entry(node, struct rt_object, list);
if (obj) /* skip warning when disable debug */
{
RT_ASSERT(obj != object);
}
}
/* leave critical */
rt_exit_critical();
/* initialize object's parameters */
/* set object type to static */
object->type = type | RT_Object_Class_Static;
/* copy name */
rt_strncpy(object->name, name, RT_NAME_MAX);
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
/* lock interrupt */
temp = rt_hw_interrupt_disable();
/* insert object into information object list */
rt_list_insert_after(&(information->object_list), &(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
}
/**
* This function will detach a static object from object system,
* and the memory of static object is not freed.
*
* @param object the specified object to be detached.
*/
void rt_object_detach(rt_object_t object)
{
register rt_base_t temp;
/* object check */
RT_ASSERT(object != RT_NULL);
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
/* reset object type */
object->type = 0;
/* lock interrupt */
temp = rt_hw_interrupt_disable();
/* remove from old list */
rt_list_remove(&(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
}
#ifdef RT_USING_HEAP
/**
* This function will allocate an object from object system
*
* @param type the type of object
* @param name the object name. In system, the object's name must be unique.
*
* @return object
*/
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
struct rt_object *object;
register rt_base_t temp;
struct rt_object_information *information;
RT_DEBUG_NOT_IN_INTERRUPT;
/* get object information */
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
if (object == RT_NULL)
{
/* no memory can be allocated */
return RT_NULL;
}
/* clean memory data of object */
rt_memset(object, 0x0, information->object_size);
/* initialize object's parameters */
/* set object type */
object->type = type;
/* set object flag */
object->flag = 0;
/* copy name */
rt_strncpy(object->name, name, RT_NAME_MAX);
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
/* lock interrupt */
temp = rt_hw_interrupt_disable();
/* insert object into information object list */
rt_list_insert_after(&(information->object_list), &(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
/* return object */
return object;
}
/**
* This function will delete an object and release object memory.
*
* @param object the specified object to be deleted.
*/
void rt_object_delete(rt_object_t object)
{
register rt_base_t temp;
/* object check */
RT_ASSERT(object != RT_NULL);
RT_ASSERT(!(object->type & RT_Object_Class_Static));
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
/* reset object type */
object->type = RT_Object_Class_Null;
/* lock interrupt */
temp = rt_hw_interrupt_disable();
/* remove from old list */
rt_list_remove(&(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
/* free the memory of object */
RT_KERNEL_FREE(object);
}
#endif
/**
* This function will judge the object is system object or not.
* Normally, the system object is a static object and the type
* of object set to RT_Object_Class_Static.
*
* @param object the specified object to be judged.
*
* @return RT_TRUE if a system object, RT_FALSE for others.
*/
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{
/* object check */
RT_ASSERT(object != RT_NULL);
if (object->type & RT_Object_Class_Static)
return RT_TRUE;
return RT_FALSE;
}
/**
* This function will return the type of object without
* RT_Object_Class_Static flag.
*
* @param object the specified object to be get type.
*
* @return the type of object.
*/
rt_uint8_t rt_object_get_type(rt_object_t object)
{
/* object check */
RT_ASSERT(object != RT_NULL);
return object->type & ~RT_Object_Class_Static;
}
/**
* This function will find specified name object from object
* container.
*
* @param name the specified name of object.
* @param type the type of object
*
* @return the found object or RT_NULL if there is no this object
* in object container.
*
* @note this function shall not be invoked in interrupt status.
*/
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{
struct rt_object *object = RT_NULL;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
information = rt_object_get_information((enum rt_object_class_type)type);
/* parameter check */
if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
/* which is invoke in interrupt status */
RT_DEBUG_NOT_IN_INTERRUPT;
/* enter critical */
rt_enter_critical();
/* try to find object */
rt_list_for_each(node, &(information->object_list))
{
object = rt_list_entry(node, struct rt_object, list);
if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
{
/* leave critical */
rt_exit_critical();
return object;
}
}
/* leave critical */
rt_exit_critical();
return RT_NULL;
}
/**@}*/
+423
View File
@@ -0,0 +1,423 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-17 Bernard the first version
* 2006-04-28 Bernard fix the scheduler algorthm
* 2006-04-30 Bernard add SCHEDULER_DEBUG
* 2006-05-27 Bernard fix the scheduler algorthm for same priority
* thread schedule
* 2006-06-04 Bernard rewrite the scheduler algorithm
* 2006-08-03 Bernard add hook support
* 2006-09-05 Bernard add 32 priority level support
* 2006-09-24 Bernard add rt_system_scheduler_start function
* 2009-09-16 Bernard fix _rt_scheduler_stack_check
* 2010-04-11 yi.qiu add module feature
* 2010-07-13 Bernard fix the maximal number of rt_scheduler_lock_nest
* issue found by kuronca
* 2010-12-13 Bernard add defunct list initialization even if not use heap.
* 2011-05-10 Bernard clean scheduler debug log.
* 2013-12-21 Grissiom add rt_critical_level
* 2018-11-22 Jesven remove the current task from ready queue
* add per cpu ready queue
* add _get_highest_priority_thread to find highest priority task
* rt_schedule_insert_thread won't insert current task to ready queue
* in smp version, rt_hw_context_switch_interrupt maybe switch to
* new task directly
*
*/
#include <rtthread.h>
#include <rthw.h>
rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
rt_uint32_t rt_thread_ready_priority_group;
#if RT_THREAD_PRIORITY_MAX > 32
/* Maximum priority level, 256 */
rt_uint8_t rt_thread_ready_table[32];
#endif
extern volatile rt_uint8_t rt_interrupt_nest;
static rt_int16_t rt_scheduler_lock_nest;
struct rt_thread *rt_current_thread = RT_NULL;
rt_uint8_t rt_current_priority;
rt_list_t rt_thread_defunct;
#ifdef RT_USING_HOOK
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when thread
* switch happens.
*
* @param hook the hook function
*/
void
rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))
{
rt_scheduler_hook = hook;
}
/**@}*/
#endif
#ifdef RT_USING_OVERFLOW_CHECK
static void _rt_scheduler_stack_check(struct rt_thread *thread)
{
RT_ASSERT(thread != RT_NULL);
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
#else
if (*((rt_uint8_t *)thread->stack_addr) != '#' ||
#endif
(rt_ubase_t)thread->sp <= (rt_ubase_t)thread->stack_addr ||
(rt_ubase_t)thread->sp >
(rt_ubase_t)thread->stack_addr + (rt_ubase_t)thread->stack_size)
{
rt_ubase_t level;
rt_kprintf("thread:%s stack overflow\n", thread->name);
#ifdef RT_USING_FINSH
{
extern long list_thread(void);
list_thread();
}
#endif
level = rt_hw_interrupt_disable();
while (level);
}
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
else if ((rt_ubase_t)thread->sp > ((rt_ubase_t)thread->stack_addr + thread->stack_size))
{
rt_kprintf("warning: %s stack is close to the top of stack address.\n",
thread->name);
}
#else
else if ((rt_ubase_t)thread->sp <= ((rt_ubase_t)thread->stack_addr + 32))
{
rt_kprintf("warning: %s stack is close to end of stack address.\n",
thread->name);
}
#endif
}
#endif
/**
* @ingroup SystemInit
* This function will initialize the system scheduler
*/
void rt_system_scheduler_init(void)
{
register rt_base_t offset;
rt_scheduler_lock_nest = 0;
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("start scheduler: max priority 0x%02x\n",
RT_THREAD_PRIORITY_MAX));
for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++)
{
rt_list_init(&rt_thread_priority_table[offset]);
}
rt_current_priority = RT_THREAD_PRIORITY_MAX - 1;
rt_current_thread = RT_NULL;
/* initialize ready priority group */
rt_thread_ready_priority_group = 0;
#if RT_THREAD_PRIORITY_MAX > 32
/* initialize ready table */
rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table));
#endif
/* initialize thread defunct */
rt_list_init(&rt_thread_defunct);
}
/**
* @ingroup SystemInit
* This function will startup scheduler. It will select one thread
* with the highest priority level, then switch to it.
*/
void rt_system_scheduler_start(void)
{
register struct rt_thread *to_thread;
register rt_ubase_t highest_ready_priority;
#if RT_THREAD_PRIORITY_MAX > 32
register rt_ubase_t number;
number = __rt_ffs(rt_thread_ready_priority_group) - 1;
highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#else
highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#endif
/* get switch to thread */
to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,
struct rt_thread,
tlist);
rt_current_thread = to_thread;
/* switch to new thread */
rt_hw_context_switch_to((rt_uint32_t)&to_thread->sp);
/* never come back */
}
/**
* @addtogroup Thread
*/
/**@{*/
/**
* This function will perform one schedule. It will select one thread
* with the highest priority level, then switch to it.
*/
void rt_schedule(void)
{
rt_base_t level;
struct rt_thread *to_thread;
struct rt_thread *from_thread;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* check the scheduler is enabled or not */
if (rt_scheduler_lock_nest == 0)
{
register rt_ubase_t highest_ready_priority;
#if RT_THREAD_PRIORITY_MAX <= 32
highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#else
register rt_ubase_t number;
number = __rt_ffs(rt_thread_ready_priority_group) - 1;
highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#endif
/* get switch to thread */
to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,
struct rt_thread,
tlist);
/* if the destination thread is not the same as current thread */
if (to_thread != rt_current_thread)
{
rt_current_priority = (rt_uint8_t)highest_ready_priority;
from_thread = rt_current_thread;
rt_current_thread = to_thread;
RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));
/* switch to new thread */
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
("[%d]switch to priority#%d "
"thread:%.*s(sp:0x%p), "
"from thread:%.*s(sp: 0x%p)\n",
rt_interrupt_nest, highest_ready_priority,
RT_NAME_MAX, to_thread->name, to_thread->sp,
RT_NAME_MAX, from_thread->name, from_thread->sp));
#ifdef RT_USING_OVERFLOW_CHECK
_rt_scheduler_stack_check(to_thread);
#endif
if (rt_interrupt_nest == 0)
{
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
/* enable interrupt */
rt_hw_interrupt_enable(level);
return ;
}
else
{
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));
rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
}
}
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/*
* This function will insert a thread to system ready queue. The state of
* thread will be set as READY and remove from suspend queue.
*
* @param thread the thread to be inserted
* @note Please do not invoke this function in user application.
*/
void rt_schedule_insert_thread(struct rt_thread *thread)
{
register rt_base_t temp;
RT_ASSERT(thread != RT_NULL);
/* disable interrupt */
temp = rt_hw_interrupt_disable();
/* change stat */
thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK);
/* insert thread to ready list */
rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
&(thread->tlist));
/* set priority mask */
#if RT_THREAD_PRIORITY_MAX <= 32
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("insert thread[%.*s], the priority: %d\n",
RT_NAME_MAX, thread->name, thread->current_priority));
#else
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
("insert thread[%.*s], the priority: %d 0x%x %d\n",
RT_NAME_MAX,
thread->name,
thread->number,
thread->number_mask,
thread->high_mask));
#endif
#if RT_THREAD_PRIORITY_MAX > 32
rt_thread_ready_table[thread->number] |= thread->high_mask;
#endif
rt_thread_ready_priority_group |= thread->number_mask;
/* enable interrupt */
rt_hw_interrupt_enable(temp);
}
/*
* This function will remove a thread from system ready queue.
*
* @param thread the thread to be removed
*
* @note Please do not invoke this function in user application.
*/
void rt_schedule_remove_thread(struct rt_thread *thread)
{
register rt_base_t temp;
RT_ASSERT(thread != RT_NULL);
/* disable interrupt */
temp = rt_hw_interrupt_disable();
#if RT_THREAD_PRIORITY_MAX <= 32
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("remove thread[%.*s], the priority: %d\n",
RT_NAME_MAX, thread->name,
thread->current_priority));
#else
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
("remove thread[%.*s], the priority: %d 0x%x %d\n",
RT_NAME_MAX,
thread->name,
thread->number,
thread->number_mask,
thread->high_mask));
#endif
/* remove thread from ready list */
rt_list_remove(&(thread->tlist));
if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority])))
{
#if RT_THREAD_PRIORITY_MAX > 32
rt_thread_ready_table[thread->number] &= ~thread->high_mask;
if (rt_thread_ready_table[thread->number] == 0)
{
rt_thread_ready_priority_group &= ~thread->number_mask;
}
#else
rt_thread_ready_priority_group &= ~thread->number_mask;
#endif
}
/* enable interrupt */
rt_hw_interrupt_enable(temp);
}
/**
* This function will lock the thread scheduler.
*/
void rt_enter_critical(void)
{
register rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/*
* the maximal number of nest is RT_UINT16_MAX, which is big
* enough and does not check here
*/
rt_scheduler_lock_nest ++;
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/**
* This function will unlock the thread scheduler.
*/
void rt_exit_critical(void)
{
register rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
rt_scheduler_lock_nest --;
if (rt_scheduler_lock_nest <= 0)
{
rt_scheduler_lock_nest = 0;
/* enable interrupt */
rt_hw_interrupt_enable(level);
if (rt_current_thread)
{
/* if scheduler is started, do a schedule */
rt_schedule();
}
}
else
{
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
}
/**
* Get the scheduler lock level
*
* @return the level of the scheduler lock. 0 means unlocked.
*/
rt_uint16_t rt_critical_level(void)
{
return rt_scheduler_lock_nest;
}
/**@}*/
+931
View File
@@ -0,0 +1,931 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* File : slab.c
*
* Change Logs:
* Date Author Notes
* 2008-07-12 Bernard the first version
* 2010-07-13 Bernard fix RT_ALIGN issue found by kuronca
* 2010-10-23 yi.qiu add module memory allocator
* 2010-12-18 yi.qiu fix zone release bug
*/
/*
* KERN_SLABALLOC.C - Kernel SLAB memory allocator
*
* Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
*
* This code is derived from software contributed to The DragonFly Project
* by Matthew Dillon <dillon@backplane.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of The DragonFly Project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific, prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <rthw.h>
#include <rtthread.h>
#define RT_MEM_STATS
#if defined (RT_USING_HEAP) && defined (RT_USING_SLAB)
/* some statistical variable */
#ifdef RT_MEM_STATS
static rt_size_t used_mem, max_mem;
#endif
#ifdef RT_USING_HOOK
static void (*rt_malloc_hook)(void *ptr, rt_size_t size);
static void (*rt_free_hook)(void *ptr);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when a memory
* block is allocated from heap memory.
*
* @param hook the hook function
*/
void rt_malloc_sethook(void (*hook)(void *ptr, rt_size_t size))
{
rt_malloc_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when a memory
* block is released to heap memory.
*
* @param hook the hook function
*/
void rt_free_sethook(void (*hook)(void *ptr))
{
rt_free_hook = hook;
}
/**@}*/
#endif
/*
* slab allocator implementation
*
* A slab allocator reserves a ZONE for each chunk size, then lays the
* chunks out in an array within the zone. Allocation and deallocation
* is nearly instantanious, and fragmentation/overhead losses are limited
* to a fixed worst-case amount.
*
* The downside of this slab implementation is in the chunk size
* multiplied by the number of zones. ~80 zones * 128K = 10MB of VM per cpu.
* In a kernel implementation all this memory will be physical so
* the zone size is adjusted downward on machines with less physical
* memory. The upside is that overhead is bounded... this is the *worst*
* case overhead.
*
* Slab management is done on a per-cpu basis and no locking or mutexes
* are required, only a critical section. When one cpu frees memory
* belonging to another cpu's slab manager an asynchronous IPI message
* will be queued to execute the operation. In addition, both the
* high level slab allocator and the low level zone allocator optimize
* M_ZERO requests, and the slab allocator does not have to pre initialize
* the linked list of chunks.
*
* XXX Balancing is needed between cpus. Balance will be handled through
* asynchronous IPIs primarily by reassigning the z_Cpu ownership of chunks.
*
* XXX If we have to allocate a new zone and M_USE_RESERVE is set, use of
* the new zone should be restricted to M_USE_RESERVE requests only.
*
* Alloc Size Chunking Number of zones
* 0-127 8 16
* 128-255 16 8
* 256-511 32 8
* 512-1023 64 8
* 1024-2047 128 8
* 2048-4095 256 8
* 4096-8191 512 8
* 8192-16383 1024 8
* 16384-32767 2048 8
* (if RT_MM_PAGE_SIZE is 4K the maximum zone allocation is 16383)
*
* Allocations >= zone_limit go directly to kmem.
*
* API REQUIREMENTS AND SIDE EFFECTS
*
* To operate as a drop-in replacement to the FreeBSD-4.x malloc() we
* have remained compatible with the following API requirements:
*
* + small power-of-2 sized allocations are power-of-2 aligned (kern_tty)
* + all power-of-2 sized allocations are power-of-2 aligned (twe)
* + malloc(0) is allowed and returns non-RT_NULL (ahc driver)
* + ability to allocate arbitrarily large chunks of memory
*/
/*
* Chunk structure for free elements
*/
typedef struct slab_chunk
{
struct slab_chunk *c_next;
} slab_chunk;
/*
* The IN-BAND zone header is placed at the beginning of each zone.
*/
typedef struct slab_zone
{
rt_int32_t z_magic; /* magic number for sanity check */
rt_int32_t z_nfree; /* total free chunks / ualloc space in zone */
rt_int32_t z_nmax; /* maximum free chunks */
struct slab_zone *z_next; /* zoneary[] link if z_nfree non-zero */
rt_uint8_t *z_baseptr; /* pointer to start of chunk array */
rt_int32_t z_uindex; /* current initial allocation index */
rt_int32_t z_chunksize; /* chunk size for validation */
rt_int32_t z_zoneindex; /* zone index */
slab_chunk *z_freechunk; /* free chunk list */
} slab_zone;
#define ZALLOC_SLAB_MAGIC 0x51ab51ab
#define ZALLOC_ZONE_LIMIT (16 * 1024) /* max slab-managed alloc */
#define ZALLOC_MIN_ZONE_SIZE (32 * 1024) /* minimum zone size */
#define ZALLOC_MAX_ZONE_SIZE (128 * 1024) /* maximum zone size */
#define NZONES 72 /* number of zones */
#define ZONE_RELEASE_THRESH 2 /* threshold number of zones */
static slab_zone *zone_array[NZONES]; /* linked list of zones NFree > 0 */
static slab_zone *zone_free; /* whole zones that have become free */
static int zone_free_cnt;
static int zone_size;
static int zone_limit;
static int zone_page_cnt;
/*
* Misc constants. Note that allocations that are exact multiples of
* RT_MM_PAGE_SIZE, or exceed the zone limit, fall through to the kmem module.
*/
#define MIN_CHUNK_SIZE 8 /* in bytes */
#define MIN_CHUNK_MASK (MIN_CHUNK_SIZE - 1)
/*
* Array of descriptors that describe the contents of each page
*/
#define PAGE_TYPE_FREE 0x00
#define PAGE_TYPE_SMALL 0x01
#define PAGE_TYPE_LARGE 0x02
struct memusage
{
rt_uint32_t type: 2 ; /* page type */
rt_uint32_t size: 30; /* pages allocated or offset from zone */
};
static struct memusage *memusage = RT_NULL;
#define btokup(addr) \
(&memusage[((rt_ubase_t)(addr) - heap_start) >> RT_MM_PAGE_BITS])
static rt_ubase_t heap_start, heap_end;
/* page allocator */
struct rt_page_head
{
struct rt_page_head *next; /* next valid page */
rt_size_t page; /* number of page */
/* dummy */
char dummy[RT_MM_PAGE_SIZE - (sizeof(struct rt_page_head *) + sizeof(rt_size_t))];
};
static struct rt_page_head *rt_page_list;
static struct rt_semaphore heap_sem;
void *rt_page_alloc(rt_size_t npages)
{
struct rt_page_head *b, *n;
struct rt_page_head **prev;
if (npages == 0)
return RT_NULL;
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
for (prev = &rt_page_list; (b = *prev) != RT_NULL; prev = &(b->next))
{
if (b->page > npages)
{
/* splite pages */
n = b + npages;
n->next = b->next;
n->page = b->page - npages;
*prev = n;
break;
}
if (b->page == npages)
{
/* this node fit, remove this node */
*prev = b->next;
break;
}
}
/* unlock heap */
rt_sem_release(&heap_sem);
return b;
}
void rt_page_free(void *addr, rt_size_t npages)
{
struct rt_page_head *b, *n;
struct rt_page_head **prev;
RT_ASSERT(addr != RT_NULL);
RT_ASSERT((rt_ubase_t)addr % RT_MM_PAGE_SIZE == 0);
RT_ASSERT(npages != 0);
n = (struct rt_page_head *)addr;
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
for (prev = &rt_page_list; (b = *prev) != RT_NULL; prev = &(b->next))
{
RT_ASSERT(b->page > 0);
RT_ASSERT(b > n || b + b->page <= n);
if (b + b->page == n)
{
if (b + (b->page += npages) == b->next)
{
b->page += b->next->page;
b->next = b->next->next;
}
goto _return;
}
if (b == n + npages)
{
n->page = b->page + npages;
n->next = b->next;
*prev = n;
goto _return;
}
if (b > n + npages)
break;
}
n->page = npages;
n->next = b;
*prev = n;
_return:
/* unlock heap */
rt_sem_release(&heap_sem);
}
/*
* Initialize the page allocator
*/
static void rt_page_init(void *addr, rt_size_t npages)
{
RT_ASSERT(addr != RT_NULL);
RT_ASSERT(npages != 0);
rt_page_list = RT_NULL;
rt_page_free(addr, npages);
}
/**
* @ingroup SystemInit
*
* This function will init system heap
*
* @param begin_addr the beginning address of system page
* @param end_addr the end address of system page
*/
void rt_system_heap_init(void *begin_addr, void *end_addr)
{
rt_uint32_t limsize, npages;
RT_DEBUG_NOT_IN_INTERRUPT;
/* align begin and end addr to page */
heap_start = RT_ALIGN((rt_ubase_t)begin_addr, RT_MM_PAGE_SIZE);
heap_end = RT_ALIGN_DOWN((rt_ubase_t)end_addr, RT_MM_PAGE_SIZE);
if (heap_start >= heap_end)
{
rt_kprintf("rt_system_heap_init, wrong address[0x%x - 0x%x]\n",
(rt_ubase_t)begin_addr, (rt_ubase_t)end_addr);
return;
}
limsize = heap_end - heap_start;
npages = limsize / RT_MM_PAGE_SIZE;
/* initialize heap semaphore */
rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO);
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("heap[0x%x - 0x%x], size 0x%x, 0x%x pages\n",
heap_start, heap_end, limsize, npages));
/* init pages */
rt_page_init((void *)heap_start, npages);
/* calculate zone size */
zone_size = ZALLOC_MIN_ZONE_SIZE;
while (zone_size < ZALLOC_MAX_ZONE_SIZE && (zone_size << 1) < (limsize / 1024))
zone_size <<= 1;
zone_limit = zone_size / 4;
if (zone_limit > ZALLOC_ZONE_LIMIT)
zone_limit = ZALLOC_ZONE_LIMIT;
zone_page_cnt = zone_size / RT_MM_PAGE_SIZE;
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("zone size 0x%x, zone page count 0x%x\n",
zone_size, zone_page_cnt));
/* allocate memusage array */
limsize = npages * sizeof(struct memusage);
limsize = RT_ALIGN(limsize, RT_MM_PAGE_SIZE);
memusage = rt_page_alloc(limsize / RT_MM_PAGE_SIZE);
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("memusage 0x%x, size 0x%x\n",
(rt_ubase_t)memusage, limsize));
}
/*
* Calculate the zone index for the allocation request size and set the
* allocation request size to that particular zone's chunk size.
*/
rt_inline int zoneindex(rt_size_t *bytes)
{
/* unsigned for shift opt */
rt_ubase_t n = (rt_ubase_t)(*bytes);
if (n < 128)
{
*bytes = n = (n + 7) & ~7;
/* 8 byte chunks, 16 zones */
return (n / 8 - 1);
}
if (n < 256)
{
*bytes = n = (n + 15) & ~15;
return (n / 16 + 7);
}
if (n < 8192)
{
if (n < 512)
{
*bytes = n = (n + 31) & ~31;
return (n / 32 + 15);
}
if (n < 1024)
{
*bytes = n = (n + 63) & ~63;
return (n / 64 + 23);
}
if (n < 2048)
{
*bytes = n = (n + 127) & ~127;
return (n / 128 + 31);
}
if (n < 4096)
{
*bytes = n = (n + 255) & ~255;
return (n / 256 + 39);
}
*bytes = n = (n + 511) & ~511;
return (n / 512 + 47);
}
if (n < 16384)
{
*bytes = n = (n + 1023) & ~1023;
return (n / 1024 + 55);
}
rt_kprintf("Unexpected byte count %d", n);
return 0;
}
/**
* @addtogroup MM
*/
/**@{*/
/**
* This function will allocate a block from system heap memory.
* - If the nbytes is less than zero,
* or
* - If there is no nbytes sized memory valid in system,
* the RT_NULL is returned.
*
* @param size the size of memory to be allocated
*
* @return the allocated memory
*/
void *rt_malloc(rt_size_t size)
{
slab_zone *z;
rt_int32_t zi;
slab_chunk *chunk;
struct memusage *kup;
/* zero size, return RT_NULL */
if (size == 0)
return RT_NULL;
/*
* Handle large allocations directly. There should not be very many of
* these so performance is not a big issue.
*/
if (size >= zone_limit)
{
size = RT_ALIGN(size, RT_MM_PAGE_SIZE);
chunk = rt_page_alloc(size >> RT_MM_PAGE_BITS);
if (chunk == RT_NULL)
return RT_NULL;
/* set kup */
kup = btokup(chunk);
kup->type = PAGE_TYPE_LARGE;
kup->size = size >> RT_MM_PAGE_BITS;
RT_DEBUG_LOG(RT_DEBUG_SLAB,
("malloc a large memory 0x%x, page cnt %d, kup %d\n",
size,
size >> RT_MM_PAGE_BITS,
((rt_ubase_t)chunk - heap_start) >> RT_MM_PAGE_BITS));
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
#ifdef RT_MEM_STATS
used_mem += size;
if (used_mem > max_mem)
max_mem = used_mem;
#endif
goto done;
}
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
/*
* Attempt to allocate out of an existing zone. First try the free list,
* then allocate out of unallocated space. If we find a good zone move
* it to the head of the list so later allocations find it quickly
* (we might have thousands of zones in the list).
*
* Note: zoneindex() will panic of size is too large.
*/
zi = zoneindex(&size);
RT_ASSERT(zi < NZONES);
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("try to malloc 0x%x on zone: %d\n", size, zi));
if ((z = zone_array[zi]) != RT_NULL)
{
RT_ASSERT(z->z_nfree > 0);
/* Remove us from the zone_array[] when we become empty */
if (--z->z_nfree == 0)
{
zone_array[zi] = z->z_next;
z->z_next = RT_NULL;
}
/*
* No chunks are available but nfree said we had some memory, so
* it must be available in the never-before-used-memory area
* governed by uindex. The consequences are very serious if our zone
* got corrupted so we use an explicit rt_kprintf rather then a KASSERT.
*/
if (z->z_uindex + 1 != z->z_nmax)
{
z->z_uindex = z->z_uindex + 1;
chunk = (slab_chunk *)(z->z_baseptr + z->z_uindex * size);
}
else
{
/* find on free chunk list */
chunk = z->z_freechunk;
/* remove this chunk from list */
z->z_freechunk = z->z_freechunk->c_next;
}
#ifdef RT_MEM_STATS
used_mem += z->z_chunksize;
if (used_mem > max_mem)
max_mem = used_mem;
#endif
goto done;
}
/*
* If all zones are exhausted we need to allocate a new zone for this
* index.
*
* At least one subsystem, the tty code (see CROUND) expects power-of-2
* allocations to be power-of-2 aligned. We maintain compatibility by
* adjusting the base offset below.
*/
{
rt_int32_t off;
if ((z = zone_free) != RT_NULL)
{
/* remove zone from free zone list */
zone_free = z->z_next;
-- zone_free_cnt;
}
else
{
/* unlock heap, since page allocator will think about lock */
rt_sem_release(&heap_sem);
/* allocate a zone from page */
z = rt_page_alloc(zone_size / RT_MM_PAGE_SIZE);
if (z == RT_NULL)
{
chunk = RT_NULL;
goto __exit;
}
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("alloc a new zone: 0x%x\n",
(rt_ubase_t)z));
/* set message usage */
for (off = 0, kup = btokup(z); off < zone_page_cnt; off ++)
{
kup->type = PAGE_TYPE_SMALL;
kup->size = off;
kup ++;
}
}
/* clear to zero */
rt_memset(z, 0, sizeof(slab_zone));
/* offset of slab zone struct in zone */
off = sizeof(slab_zone);
/*
* Guarentee power-of-2 alignment for power-of-2-sized chunks.
* Otherwise just 8-byte align the data.
*/
if ((size | (size - 1)) + 1 == (size << 1))
off = (off + size - 1) & ~(size - 1);
else
off = (off + MIN_CHUNK_MASK) & ~MIN_CHUNK_MASK;
z->z_magic = ZALLOC_SLAB_MAGIC;
z->z_zoneindex = zi;
z->z_nmax = (zone_size - off) / size;
z->z_nfree = z->z_nmax - 1;
z->z_baseptr = (rt_uint8_t *)z + off;
z->z_uindex = 0;
z->z_chunksize = size;
chunk = (slab_chunk *)(z->z_baseptr + z->z_uindex * size);
/* link to zone array */
z->z_next = zone_array[zi];
zone_array[zi] = z;
#ifdef RT_MEM_STATS
used_mem += z->z_chunksize;
if (used_mem > max_mem)
max_mem = used_mem;
#endif
}
done:
rt_sem_release(&heap_sem);
RT_OBJECT_HOOK_CALL(rt_malloc_hook, ((char *)chunk, size));
__exit:
return chunk;
}
/**
* This function will change the size of previously allocated memory block.
*
* @param ptr the previously allocated memory block
* @param size the new size of memory block
*
* @return the allocated memory
*/
void *rt_realloc(void *ptr, rt_size_t size)
{
void *nptr;
slab_zone *z;
struct memusage *kup;
if (ptr == RT_NULL)
return rt_malloc(size);
if (size == 0)
{
rt_free(ptr);
return RT_NULL;
}
/*
* Get the original allocation's zone. If the new request winds up
* using the same chunk size we do not have to do anything.
*/
kup = btokup((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK);
if (kup->type == PAGE_TYPE_LARGE)
{
rt_size_t osize;
osize = kup->size << RT_MM_PAGE_BITS;
if ((nptr = rt_malloc(size)) == RT_NULL)
return RT_NULL;
rt_memcpy(nptr, ptr, size > osize ? osize : size);
rt_free(ptr);
return nptr;
}
else if (kup->type == PAGE_TYPE_SMALL)
{
z = (slab_zone *)(((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK) -
kup->size * RT_MM_PAGE_SIZE);
RT_ASSERT(z->z_magic == ZALLOC_SLAB_MAGIC);
zoneindex(&size);
if (z->z_chunksize == size)
return (ptr); /* same chunk */
/*
* Allocate memory for the new request size. Note that zoneindex has
* already adjusted the request size to the appropriate chunk size, which
* should optimize our bcopy(). Then copy and return the new pointer.
*/
if ((nptr = rt_malloc(size)) == RT_NULL)
return RT_NULL;
rt_memcpy(nptr, ptr, size > z->z_chunksize ? z->z_chunksize : size);
rt_free(ptr);
return nptr;
}
return RT_NULL;
}
/**
* This function will contiguously allocate enough space for count objects
* that are size bytes of memory each and returns a pointer to the allocated
* memory.
*
* The allocated memory is filled with bytes of value zero.
*
* @param count number of objects to allocate
* @param size size of the objects to allocate
*
* @return pointer to allocated memory / NULL pointer if there is an error
*/
void *rt_calloc(rt_size_t count, rt_size_t size)
{
void *p;
/* allocate 'count' objects of size 'size' */
p = rt_malloc(count * size);
/* zero the memory */
if (p)
rt_memset(p, 0, count * size);
return p;
}
/**
* This function will release the previous allocated memory block by rt_malloc.
* The released memory block is taken back to system heap.
*
* @param ptr the address of memory which will be released
*/
void rt_free(void *ptr)
{
slab_zone *z;
slab_chunk *chunk;
struct memusage *kup;
/* free a RT_NULL pointer */
if (ptr == RT_NULL)
return ;
RT_OBJECT_HOOK_CALL(rt_free_hook, (ptr));
/* get memory usage */
#if RT_DEBUG_SLAB
{
rt_ubase_t addr = ((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK);
RT_DEBUG_LOG(RT_DEBUG_SLAB,
("free a memory 0x%x and align to 0x%x, kup index %d\n",
(rt_ubase_t)ptr,
(rt_ubase_t)addr,
((rt_ubase_t)(addr) - heap_start) >> RT_MM_PAGE_BITS));
}
#endif
kup = btokup((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK);
/* release large allocation */
if (kup->type == PAGE_TYPE_LARGE)
{
rt_ubase_t size;
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
/* clear page counter */
size = kup->size;
kup->size = 0;
#ifdef RT_MEM_STATS
used_mem -= size * RT_MM_PAGE_SIZE;
#endif
rt_sem_release(&heap_sem);
RT_DEBUG_LOG(RT_DEBUG_SLAB,
("free large memory block 0x%x, page count %d\n",
(rt_ubase_t)ptr, size));
/* free this page */
rt_page_free(ptr, size);
return;
}
/* lock heap */
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
/* zone case. get out zone. */
z = (slab_zone *)(((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK) -
kup->size * RT_MM_PAGE_SIZE);
RT_ASSERT(z->z_magic == ZALLOC_SLAB_MAGIC);
chunk = (slab_chunk *)ptr;
chunk->c_next = z->z_freechunk;
z->z_freechunk = chunk;
#ifdef RT_MEM_STATS
used_mem -= z->z_chunksize;
#endif
/*
* Bump the number of free chunks. If it becomes non-zero the zone
* must be added back onto the appropriate list.
*/
if (z->z_nfree++ == 0)
{
z->z_next = zone_array[z->z_zoneindex];
zone_array[z->z_zoneindex] = z;
}
/*
* If the zone becomes totally free, and there are other zones we
* can allocate from, move this zone to the FreeZones list. Since
* this code can be called from an IPI callback, do *NOT* try to mess
* with kernel_map here. Hysteresis will be performed at malloc() time.
*/
if (z->z_nfree == z->z_nmax &&
(z->z_next || zone_array[z->z_zoneindex] != z))
{
slab_zone **pz;
RT_DEBUG_LOG(RT_DEBUG_SLAB, ("free zone 0x%x\n",
(rt_ubase_t)z, z->z_zoneindex));
/* remove zone from zone array list */
for (pz = &zone_array[z->z_zoneindex]; z != *pz; pz = &(*pz)->z_next)
;
*pz = z->z_next;
/* reset zone */
z->z_magic = -1;
/* insert to free zone list */
z->z_next = zone_free;
zone_free = z;
++ zone_free_cnt;
/* release zone to page allocator */
if (zone_free_cnt > ZONE_RELEASE_THRESH)
{
register rt_base_t i;
z = zone_free;
zone_free = z->z_next;
-- zone_free_cnt;
/* set message usage */
for (i = 0, kup = btokup(z); i < zone_page_cnt; i ++)
{
kup->type = PAGE_TYPE_FREE;
kup->size = 0;
kup ++;
}
/* unlock heap */
rt_sem_release(&heap_sem);
/* release pages */
rt_page_free(z, zone_size / RT_MM_PAGE_SIZE);
return;
}
}
/* unlock heap */
rt_sem_release(&heap_sem);
}
#ifdef RT_MEM_STATS
void rt_memory_info(rt_uint32_t *total,
rt_uint32_t *used,
rt_uint32_t *max_used)
{
if (total != RT_NULL)
*total = heap_end - heap_start;
if (used != RT_NULL)
*used = used_mem;
if (max_used != RT_NULL)
*max_used = max_mem;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
void list_mem(void)
{
rt_kprintf("total memory: %d\n", heap_end - heap_start);
rt_kprintf("used memory : %d\n", used_mem);
rt_kprintf("maximum allocated memory: %d\n", max_mem);
}
FINSH_FUNCTION_EXPORT(list_mem, list memory usage information)
#endif
#endif
/**@}*/
#endif
+834
View File
@@ -0,0 +1,834 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-28 Bernard first version
* 2006-04-29 Bernard implement thread timer
* 2006-04-30 Bernard added THREAD_DEBUG
* 2006-05-27 Bernard fixed the rt_thread_yield bug
* 2006-06-03 Bernard fixed the thread timer init bug
* 2006-08-10 Bernard fixed the timer bug in thread_sleep
* 2006-09-03 Bernard changed rt_timer_delete to rt_timer_detach
* 2006-09-03 Bernard implement rt_thread_detach
* 2008-02-16 Bernard fixed the rt_thread_timeout bug
* 2010-03-21 Bernard change the errno of rt_thread_delay/sleep to
* RT_EOK.
* 2010-11-10 Bernard add cleanup callback function in thread exit.
* 2011-09-01 Bernard fixed rt_thread_exit issue when the current
* thread preempted, which reported by Jiaxing Lee.
* 2011-09-08 Bernard fixed the scheduling issue in rt_thread_startup.
* 2012-12-29 Bernard fixed compiling warning.
* 2016-08-09 ArdaFu add thread suspend and resume hook.
* 2017-04-10 armink fixed the rt_thread_delete and rt_thread_detach
bug when thread has not startup.
* 2018-11-22 Jesven yield is same to rt_schedule
* add support for tasks bound to cpu
*/
#include <rthw.h>
#include <rtthread.h>
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
extern struct rt_thread *rt_current_thread;
extern rt_list_t rt_thread_defunct;
#ifdef RT_USING_HOOK
static void (*rt_thread_suspend_hook)(rt_thread_t thread);
static void (*rt_thread_resume_hook) (rt_thread_t thread);
static void (*rt_thread_inited_hook) (rt_thread_t thread);
/**
* @ingroup Hook
* This function sets a hook function when the system suspend a thread.
*
* @param hook the specified hook function
*
* @note the hook function must be simple and never be blocked or suspend.
*/
void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread))
{
rt_thread_suspend_hook = hook;
}
/**
* @ingroup Hook
* This function sets a hook function when the system resume a thread.
*
* @param hook the specified hook function
*
* @note the hook function must be simple and never be blocked or suspend.
*/
void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread))
{
rt_thread_resume_hook = hook;
}
/**
* @ingroup Hook
* This function sets a hook function when a thread is initialized.
*
* @param hook the specified hook function
*/
void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
{
rt_thread_inited_hook = hook;
}
#endif
/* must be invoke witch rt_hw_interrupt_disable */
static void _thread_cleanup_execute(rt_thread_t thread)
{
register rt_base_t level;
level = rt_hw_interrupt_disable();
/* invoke thread cleanup */
if (thread->cleanup != RT_NULL)
thread->cleanup(thread);
rt_hw_interrupt_enable(level);
}
void rt_thread_exit(void)
{
struct rt_thread *thread;
register rt_base_t level;
/* get current thread */
thread = rt_current_thread;
/* disable interrupt */
level = rt_hw_interrupt_disable();
_thread_cleanup_execute(thread);
/* remove from schedule */
rt_schedule_remove_thread(thread);
/* change stat */
thread->stat = RT_THREAD_CLOSE;
/* remove it from timer list */
rt_timer_detach(&thread->thread_timer);
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
{
rt_object_detach((rt_object_t)thread);
}
else
{
/* insert to defunct thread list */
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
}
/* switch to next task */
rt_schedule();
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
static rt_err_t _rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
{
/* init thread list */
rt_list_init(&(thread->tlist));
thread->entry = (void *)entry;
thread->parameter = parameter;
/* stack init */
thread->stack_addr = stack_start;
thread->stack_size = stack_size;
/* init thread stack */
rt_memset(thread->stack_addr, '#', thread->stack_size);
#ifdef ARCH_CPU_STACK_GROWS_UPWARD
thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
(void *)((char *)thread->stack_addr),
(void *)rt_thread_exit);
#else
thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
(rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)),
(void *)rt_thread_exit);
#endif
/* priority init */
RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
thread->init_priority = priority;
thread->current_priority = priority;
thread->number_mask = 0;
#if RT_THREAD_PRIORITY_MAX > 32
thread->number = 0;
thread->high_mask = 0;
#endif
/* tick init */
thread->init_tick = tick;
thread->remaining_tick = tick;
/* error and flags */
thread->error = RT_EOK;
thread->stat = RT_THREAD_INIT;
/* initialize cleanup function and user data */
thread->cleanup = 0;
thread->user_data = 0;
/* initialize thread timer */
rt_timer_init(&(thread->thread_timer),
thread->name,
rt_thread_timeout,
thread,
0,
RT_TIMER_FLAG_ONE_SHOT);
RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
return RT_EOK;
}
/**
* @addtogroup Thread
*/
/**@{*/
/**
* This function will initialize a thread, normally it's used to initialize a
* static thread object.
*
* @param thread the static thread object
* @param name the name of thread, which shall be unique
* @param entry the entry function of thread
* @param parameter the parameter of thread enter function
* @param stack_start the start address of thread stack
* @param stack_size the size of thread stack
* @param priority the priority of thread
* @param tick the time slice if there are same priority thread
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
{
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(stack_start != RT_NULL);
/* initialize thread object */
rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
return _rt_thread_init(thread,
name,
entry,
parameter,
stack_start,
stack_size,
priority,
tick);
}
/**
* This function will return self thread object
*
* @return the self thread object
*/
rt_thread_t rt_thread_self(void)
{
return rt_current_thread;
}
/**
* This function will start a thread and put it to system ready queue
*
* @param thread the thread to be started
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_startup(rt_thread_t thread)
{
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* set current priority to initialize priority */
thread->current_priority = thread->init_priority;
/* calculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32
thread->number = thread->current_priority >> 3; /* 5bit */
thread->number_mask = 1L << thread->number;
thread->high_mask = 1L << (thread->current_priority & 0x07); /* 3bit */
#else
thread->number_mask = 1L << thread->current_priority;
#endif
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",
thread->name, thread->init_priority));
/* change thread stat */
thread->stat = RT_THREAD_SUSPEND;
/* then resume it */
rt_thread_resume(thread);
if (rt_thread_self() != RT_NULL)
{
/* do a scheduling */
rt_schedule();
}
return RT_EOK;
}
/**
* This function will detach a thread. The thread object will be removed from
* thread queue and detached/deleted from system object management.
*
* @param thread the thread to be deleted
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_detach(rt_thread_t thread)
{
rt_base_t lock;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
RT_ASSERT(rt_object_is_systemobject((rt_object_t)thread));
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
return RT_EOK;
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
{
/* remove from schedule */
rt_schedule_remove_thread(thread);
}
_thread_cleanup_execute(thread);
/* release thread timer */
rt_timer_detach(&(thread->thread_timer));
/* change stat */
thread->stat = RT_THREAD_CLOSE;
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
{
rt_object_detach((rt_object_t)thread);
}
else
{
/* disable interrupt */
lock = rt_hw_interrupt_disable();
/* insert to defunct thread list */
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
/* enable interrupt */
rt_hw_interrupt_enable(lock);
}
return RT_EOK;
}
#ifdef RT_USING_HEAP
/**
* This function will create a thread object and allocate thread object memory
* and stack.
*
* @param name the name of thread, which shall be unique
* @param entry the entry function of thread
* @param parameter the parameter of thread enter function
* @param stack_size the size of thread stack
* @param priority the priority of thread
* @param tick the time slice if there are same priority thread
*
* @return the created thread object
*/
rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
{
struct rt_thread *thread;
void *stack_start;
thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread,
name);
if (thread == RT_NULL)
return RT_NULL;
stack_start = (void *)RT_KERNEL_MALLOC(stack_size);
if (stack_start == RT_NULL)
{
/* allocate stack failure */
rt_object_delete((rt_object_t)thread);
return RT_NULL;
}
_rt_thread_init(thread,
name,
entry,
parameter,
stack_start,
stack_size,
priority,
tick);
return thread;
}
/**
* This function will delete a thread. The thread object will be removed from
* thread queue and deleted from system object management in the idle thread.
*
* @param thread the thread to be deleted
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_delete(rt_thread_t thread)
{
rt_base_t lock;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
RT_ASSERT(rt_object_is_systemobject((rt_object_t)thread) == RT_FALSE);
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
return RT_EOK;
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
{
/* remove from schedule */
rt_schedule_remove_thread(thread);
}
_thread_cleanup_execute(thread);
/* release thread timer */
rt_timer_detach(&(thread->thread_timer));
/* disable interrupt */
lock = rt_hw_interrupt_disable();
/* change stat */
thread->stat = RT_THREAD_CLOSE;
/* insert to defunct thread list */
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
/* enable interrupt */
rt_hw_interrupt_enable(lock);
return RT_EOK;
}
#endif
/**
* This function will let current thread yield processor, and scheduler will
* choose a highest thread to run. After yield processor, the current thread
* is still in READY state.
*
* @return RT_EOK
*/
rt_err_t rt_thread_yield(void)
{
register rt_base_t level;
struct rt_thread *thread;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* set to current thread */
thread = rt_current_thread;
/* if the thread stat is READY and on ready queue list */
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY &&
thread->tlist.next != thread->tlist.prev)
{
/* remove thread from thread list */
rt_list_remove(&(thread->tlist));
/* put thread to end of ready queue */
rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
&(thread->tlist));
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_schedule();
return RT_EOK;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* This function will let current thread sleep for some ticks.
*
* @param tick the sleep ticks
*
* @return RT_EOK
*/
rt_err_t rt_thread_sleep(rt_tick_t tick)
{
register rt_base_t temp;
struct rt_thread *thread;
/* disable interrupt */
temp = rt_hw_interrupt_disable();
/* set to current thread */
thread = rt_current_thread;
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* suspend thread */
rt_thread_suspend(thread);
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
rt_timer_start(&(thread->thread_timer));
/* enable interrupt */
rt_hw_interrupt_enable(temp);
rt_schedule();
/* clear error number of this thread to RT_EOK */
if (thread->error == -RT_ETIMEOUT)
thread->error = RT_EOK;
return RT_EOK;
}
/**
* This function will let current thread delay for some ticks.
*
* @param tick the delay ticks
*
* @return RT_EOK
*/
rt_err_t rt_thread_delay(rt_tick_t tick)
{
return rt_thread_sleep(tick);
}
/**
* This function will let current thread delay until (*tick + inc_tick).
*
* @param tick the tick of last wakeup.
* @param inc_tick the increment tick
*
* @return RT_EOK
*/
rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick)
{
register rt_base_t level;
struct rt_thread *thread;
RT_ASSERT(tick != RT_NULL);
/* set to current thread */
thread = rt_thread_self();
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (rt_tick_get() - *tick < inc_tick)
{
*tick = *tick + inc_tick - rt_tick_get();
/* suspend thread */
rt_thread_suspend(thread);
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, tick);
rt_timer_start(&(thread->thread_timer));
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_schedule();
/* clear error number of this thread to RT_EOK */
if (thread->error == -RT_ETIMEOUT)
{
thread->error = RT_EOK;
}
}
else
{
rt_hw_interrupt_enable(level);
}
/* get the wakeup tick */
*tick = rt_tick_get();
return RT_EOK;
}
/**
* This function will let current thread delay for some milliseconds.
*
* @param ms the delay ms time
*
* @return RT_EOK
*/
rt_err_t rt_thread_mdelay(rt_int32_t ms)
{
rt_tick_t tick;
tick = rt_tick_from_millisecond(ms);
return rt_thread_sleep(tick);
}
/**
* This function will control thread behaviors according to control command.
*
* @param thread the specified thread to be controlled
* @param cmd the control command, which includes
* RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread;
* RT_THREAD_CTRL_STARTUP for starting a thread;
* RT_THREAD_CTRL_CLOSE for delete a thread;
* RT_THREAD_CTRL_BIND_CPU for bind the thread to a CPU.
* @param arg the argument of control command
*
* @return RT_EOK
*/
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
{
register rt_base_t temp;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
switch (cmd)
{
case RT_THREAD_CTRL_CHANGE_PRIORITY:
/* disable interrupt */
temp = rt_hw_interrupt_disable();
/* for ready thread, change queue */
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY)
{
/* remove thread from schedule queue first */
rt_schedule_remove_thread(thread);
/* change thread priority */
thread->current_priority = *(rt_uint8_t *)arg;
/* recalculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32
thread->number = thread->current_priority >> 3; /* 5bit */
thread->number_mask = 1 << thread->number;
thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
#else
thread->number_mask = 1 << thread->current_priority;
#endif
/* insert thread to schedule queue again */
rt_schedule_insert_thread(thread);
}
else
{
thread->current_priority = *(rt_uint8_t *)arg;
/* recalculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32
thread->number = thread->current_priority >> 3; /* 5bit */
thread->number_mask = 1 << thread->number;
thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
#else
thread->number_mask = 1 << thread->current_priority;
#endif
}
/* enable interrupt */
rt_hw_interrupt_enable(temp);
break;
case RT_THREAD_CTRL_STARTUP:
return rt_thread_startup(thread);
case RT_THREAD_CTRL_CLOSE:
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
{
return rt_thread_detach(thread);
}
#ifdef RT_USING_HEAP
else
{
return rt_thread_delete(thread);
}
#endif
default:
break;
}
return RT_EOK;
}
/**
* This function will suspend the specified thread.
*
* @param thread the thread to be suspended
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*
* @note if suspend self thread, after this function call, the
* rt_schedule() must be invoked.
*/
rt_err_t rt_thread_suspend(rt_thread_t thread)
{
register rt_base_t temp;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: %s\n", thread->name));
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_READY)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, 0x%2x\n",
thread->stat));
return -RT_ERROR;
}
/* disable interrupt */
temp = rt_hw_interrupt_disable();
/* change thread stat */
rt_schedule_remove_thread(thread);
thread->stat = RT_THREAD_SUSPEND | (thread->stat & ~RT_THREAD_STAT_MASK);
/* stop thread timer anyway */
rt_timer_stop(&(thread->thread_timer));
/* enable interrupt */
rt_hw_interrupt_enable(temp);
RT_OBJECT_HOOK_CALL(rt_thread_suspend_hook, (thread));
return RT_EOK;
}
/**
* This function will resume a thread and put it to system ready queue.
*
* @param thread the thread to be resumed
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_resume(rt_thread_t thread)
{
register rt_base_t temp;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: %s\n", thread->name));
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_SUSPEND)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",
thread->stat));
return -RT_ERROR;
}
/* disable interrupt */
temp = rt_hw_interrupt_disable();
/* remove from suspend list */
rt_list_remove(&(thread->tlist));
rt_timer_stop(&thread->thread_timer);
/* enable interrupt */
rt_hw_interrupt_enable(temp);
/* insert to schedule ready list */
rt_schedule_insert_thread(thread);
RT_OBJECT_HOOK_CALL(rt_thread_resume_hook, (thread));
return RT_EOK;
}
/**
* This function is the timeout function for thread, normally which is invoked
* when thread is timeout to wait some resource.
*
* @param parameter the parameter of thread timeout function
*/
void rt_thread_timeout(void *parameter)
{
struct rt_thread *thread;
thread = (struct rt_thread *)parameter;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* set error number */
thread->error = -RT_ETIMEOUT;
/* remove from suspend list */
rt_list_remove(&(thread->tlist));
/* insert to schedule ready list */
rt_schedule_insert_thread(thread);
/* do schedule */
rt_schedule();
}
/**
* This function will find the specified thread.
*
* @param name the name of thread finding
*
* @return the found thread
*
* @note please don't invoke this function in interrupt status.
*/
rt_thread_t rt_thread_find(char *name)
{
return (rt_thread_t)rt_object_find(name, RT_Object_Class_Thread);
}
/**@}*/
+763
View File
@@ -0,0 +1,763 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-12 Bernard first version
* 2006-04-29 Bernard implement thread timer
* 2006-06-04 Bernard implement rt_timer_control
* 2006-08-10 Bernard fix the periodic timer bug
* 2006-09-03 Bernard implement rt_timer_detach
* 2009-11-11 LiJin add soft timer
* 2010-05-12 Bernard fix the timer check bug.
* 2010-11-02 Charlie re-implement tick overflow issue
* 2012-12-15 Bernard fix the next timeout issue in soft timer
* 2014-07-12 Bernard does not lock scheduler when invoking soft-timer
* timeout function.
*/
#include <rtthread.h>
#include <rthw.h>
/* hard timer list */
static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
#ifdef RT_USING_TIMER_SOFT
#define RT_SOFT_TIMER_IDLE 1
#define RT_SOFT_TIMER_BUSY 0
#ifndef RT_TIMER_THREAD_STACK_SIZE
#define RT_TIMER_THREAD_STACK_SIZE 512
#endif
#ifndef RT_TIMER_THREAD_PRIO
#define RT_TIMER_THREAD_PRIO 0
#endif
/* soft timer status */
static rt_uint8_t soft_timer_status = RT_SOFT_TIMER_IDLE;
/* soft timer list */
static rt_list_t rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
static struct rt_thread timer_thread;
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t timer_thread_stack[RT_TIMER_THREAD_STACK_SIZE];
#endif
#ifdef RT_USING_HOOK
extern void (*rt_object_take_hook)(struct rt_object *object);
extern void (*rt_object_put_hook)(struct rt_object *object);
static void (*rt_timer_enter_hook)(struct rt_timer *timer);
static void (*rt_timer_exit_hook)(struct rt_timer *timer);
/**
* @addtogroup Hook
*/
/**@{*/
/**
* This function will set a hook function, which will be invoked when enter
* timer timeout callback function.
*
* @param hook the hook function
*/
void rt_timer_enter_sethook(void (*hook)(struct rt_timer *timer))
{
rt_timer_enter_hook = hook;
}
/**
* This function will set a hook function, which will be invoked when exit
* timer timeout callback function.
*
* @param hook the hook function
*/
void rt_timer_exit_sethook(void (*hook)(struct rt_timer *timer))
{
rt_timer_exit_hook = hook;
}
/**@}*/
#endif
static void _rt_timer_init(rt_timer_t timer,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag)
{
int i;
/* set flag */
timer->parent.flag = flag;
/* set deactivated */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
timer->timeout_func = timeout;
timer->parameter = parameter;
timer->timeout_tick = 0;
timer->init_tick = time;
/* initialize timer list */
for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
{
rt_list_init(&(timer->row[i]));
}
}
/* the fist timer always in the last row */
static rt_tick_t rt_timer_list_next_timeout(rt_list_t timer_list[])
{
struct rt_timer *timer;
register rt_base_t level;
rt_tick_t timeout_tick = RT_TICK_MAX;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]))
{
timer = rt_list_entry(timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
timeout_tick = timer->timeout_tick;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
return timeout_tick;
}
rt_inline void _rt_timer_remove(rt_timer_t timer)
{
int i;
for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
{
rt_list_remove(&timer->row[i]);
}
}
#if RT_DEBUG_TIMER
static int rt_timer_count_height(struct rt_timer *timer)
{
int i, cnt = 0;
for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
{
if (!rt_list_isempty(&timer->row[i]))
cnt++;
}
return cnt;
}
void rt_timer_dump(rt_list_t timer_heads[])
{
rt_list_t *list;
for (list = timer_heads[RT_TIMER_SKIP_LIST_LEVEL - 1].next;
list != &timer_heads[RT_TIMER_SKIP_LIST_LEVEL - 1];
list = list->next)
{
struct rt_timer *timer = rt_list_entry(list,
struct rt_timer,
row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
rt_kprintf("%d", rt_timer_count_height(timer));
}
rt_kprintf("\n");
}
#endif
/**
* @addtogroup Clock
*/
/**@{*/
/**
* This function will initialize a timer, normally this function is used to
* initialize a static timer object.
*
* @param timer the static timer object
* @param name the name of timer
* @param timeout the timeout function
* @param parameter the parameter of timeout function
* @param time the tick of timer
* @param flag the flag of timer
*/
void rt_timer_init(rt_timer_t timer,
const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag)
{
/* timer check */
RT_ASSERT(timer != RT_NULL);
/* timer object initialization */
rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
_rt_timer_init(timer, timeout, parameter, time, flag);
}
/**
* This function will detach a timer from timer management.
*
* @param timer the static timer object
*
* @return the operation status, RT_EOK on OK; RT_ERROR on error
*/
rt_err_t rt_timer_detach(rt_timer_t timer)
{
register rt_base_t level;
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
RT_ASSERT(rt_object_is_systemobject(&timer->parent));
/* disable interrupt */
level = rt_hw_interrupt_disable();
_rt_timer_remove(timer);
/* stop timer */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_object_detach((rt_object_t)timer);
return RT_EOK;
}
#ifdef RT_USING_HEAP
/**
* This function will create a timer
*
* @param name the name of timer
* @param timeout the timeout function
* @param parameter the parameter of timeout function
* @param time the tick of timer
* @param flag the flag of timer
*
* @return the created timer object
*/
rt_timer_t rt_timer_create(const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag)
{
struct rt_timer *timer;
/* allocate a object */
timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);
if (timer == RT_NULL)
{
return RT_NULL;
}
_rt_timer_init(timer, timeout, parameter, time, flag);
return timer;
}
/**
* This function will delete a timer and release timer memory
*
* @param timer the timer to be deleted
*
* @return the operation status, RT_EOK on OK; RT_ERROR on error
*/
rt_err_t rt_timer_delete(rt_timer_t timer)
{
register rt_base_t level;
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
RT_ASSERT(rt_object_is_systemobject(&timer->parent) == RT_FALSE);
/* disable interrupt */
level = rt_hw_interrupt_disable();
_rt_timer_remove(timer);
/* stop timer */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_object_delete((rt_object_t)timer);
return RT_EOK;
}
#endif
/**
* This function will start the timer
*
* @param timer the timer to be started
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_timer_start(rt_timer_t timer)
{
unsigned int row_lvl;
rt_list_t *timer_list;
register rt_base_t level;
rt_list_t *row_head[RT_TIMER_SKIP_LIST_LEVEL];
unsigned int tst_nr;
static unsigned int random_nr;
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
/* stop timer firstly */
level = rt_hw_interrupt_disable();
/* remove timer from list */
_rt_timer_remove(timer);
/* change status of timer */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
/*
* get timeout tick,
* the max timeout tick shall not great than RT_TICK_MAX/2
*/
RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);
timer->timeout_tick = rt_tick_get() + timer->init_tick;
#ifdef RT_USING_TIMER_SOFT
if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
{
/* insert timer to soft timer list */
timer_list = rt_soft_timer_list;
}
else
#endif
{
/* insert timer to system timer list */
timer_list = rt_timer_list;
}
row_head[0] = &timer_list[0];
for (row_lvl = 0; row_lvl < RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
{
for (; row_head[row_lvl] != timer_list[row_lvl].prev;
row_head[row_lvl] = row_head[row_lvl]->next)
{
struct rt_timer *t;
rt_list_t *p = row_head[row_lvl]->next;
/* fix up the entry pointer */
t = rt_list_entry(p, struct rt_timer, row[row_lvl]);
/* If we have two timers that timeout at the same time, it's
* preferred that the timer inserted early get called early.
* So insert the new timer to the end the the some-timeout timer
* list.
*/
if ((t->timeout_tick - timer->timeout_tick) == 0)
{
continue;
}
else if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX / 2)
{
break;
}
}
if (row_lvl != RT_TIMER_SKIP_LIST_LEVEL - 1)
row_head[row_lvl + 1] = row_head[row_lvl] + 1;
}
/* Interestingly, this super simple timer insert counter works very very
* well on distributing the list height uniformly. By means of "very very
* well", I mean it beats the randomness of timer->timeout_tick very easily
* (actually, the timeout_tick is not random and easy to be attacked). */
random_nr++;
tst_nr = random_nr;
rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL - 1],
&(timer->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
for (row_lvl = 2; row_lvl <= RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
{
if (!(tst_nr & RT_TIMER_SKIP_LIST_MASK))
rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL - row_lvl],
&(timer->row[RT_TIMER_SKIP_LIST_LEVEL - row_lvl]));
else
break;
/* Shift over the bits we have tested. Works well with 1 bit and 2
* bits. */
tst_nr >>= (RT_TIMER_SKIP_LIST_MASK + 1) >> 1;
}
timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
/* enable interrupt */
rt_hw_interrupt_enable(level);
#ifdef RT_USING_TIMER_SOFT
if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
{
/* check whether timer thread is ready */
if ((soft_timer_status == RT_SOFT_TIMER_IDLE) &&
((timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND))
{
/* resume timer thread to check soft timer */
rt_thread_resume(&timer_thread);
rt_schedule();
}
}
#endif
return RT_EOK;
}
/**
* This function will stop the timer
*
* @param timer the timer to be stopped
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_timer_stop(rt_timer_t timer)
{
register rt_base_t level;
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
return -RT_ERROR;
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));
/* disable interrupt */
level = rt_hw_interrupt_disable();
_rt_timer_remove(timer);
/* change status */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
/* enable interrupt */
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* This function will get or set some options of the timer
*
* @param timer the timer to be get or set
* @param cmd the control command
* @param arg the argument
*
* @return RT_EOK
*/
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
{
register rt_base_t level;
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
level = rt_hw_interrupt_disable();
switch (cmd)
{
case RT_TIMER_CTRL_GET_TIME:
*(rt_tick_t *)arg = timer->init_tick;
break;
case RT_TIMER_CTRL_SET_TIME:
timer->init_tick = *(rt_tick_t *)arg;
break;
case RT_TIMER_CTRL_SET_ONESHOT:
timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
break;
case RT_TIMER_CTRL_SET_PERIODIC:
timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
break;
case RT_TIMER_CTRL_GET_STATE:
if(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
{
/*timer is start and run*/
*(rt_tick_t *)arg = RT_TIMER_FLAG_ACTIVATED;
}
else
{
/*timer is stop*/
*(rt_tick_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
}
break;
default:
break;
}
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* This function will check timer list, if a timeout event happens, the
* corresponding timeout function will be invoked.
*
* @note this function shall be invoked in operating system timer interrupt.
*/
void rt_timer_check(void)
{
struct rt_timer *t;
rt_tick_t current_tick;
register rt_base_t level;
rt_list_t list;
rt_list_init(&list);
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));
current_tick = rt_tick_get();
/* disable interrupt */
level = rt_hw_interrupt_disable();
while (!rt_list_isempty(&rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]))
{
t = rt_list_entry(rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
/*
* It supposes that the new tick shall less than the half duration of
* tick max.
*/
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
{
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
/* remove timer from timer list firstly */
_rt_timer_remove(t);
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
{
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
}
/* add timer to temporary list */
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
/* call timeout function */
t->timeout_func(t->parameter);
/* re-get tick */
current_tick = rt_tick_get();
RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
/* Check whether the timer object is detached or started again */
if (rt_list_isempty(&list))
{
continue;
}
rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
{
/* start it */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
rt_timer_start(t);
}
}
else break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));
}
/**
* This function will return the next timeout tick in the system.
*
* @return the next timeout tick in the system
*/
rt_tick_t rt_timer_next_timeout_tick(void)
{
return rt_timer_list_next_timeout(rt_timer_list);
}
#ifdef RT_USING_TIMER_SOFT
/**
* This function will check software-timer list, if a timeout event happens, the
* corresponding timeout function will be invoked.
*/
void rt_soft_timer_check(void)
{
rt_tick_t current_tick;
struct rt_timer *t;
register rt_base_t level;
rt_list_t list;
rt_list_init(&list);
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));
/* disable interrupt */
level = rt_hw_interrupt_disable();
while (!rt_list_isempty(&rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]))
{
t = rt_list_entry(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
current_tick = rt_tick_get();
/*
* It supposes that the new tick shall less than the half duration of
* tick max.
*/
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
{
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
/* remove timer from timer list firstly */
_rt_timer_remove(t);
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
{
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
}
/* add timer to temporary list */
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
soft_timer_status = RT_SOFT_TIMER_BUSY;
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* call timeout function */
t->timeout_func(t->parameter);
RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
/* disable interrupt */
level = rt_hw_interrupt_disable();
soft_timer_status = RT_SOFT_TIMER_IDLE;
/* Check whether the timer object is detached or started again */
if (rt_list_isempty(&list))
{
continue;
}
rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
{
/* start it */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
rt_timer_start(t);
}
}
else break; /* not check anymore */
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
}
/* system timer thread entry */
static void rt_thread_timer_entry(void *parameter)
{
rt_tick_t next_timeout;
while (1)
{
/* get the next timeout tick */
next_timeout = rt_timer_list_next_timeout(rt_soft_timer_list);
if (next_timeout == RT_TICK_MAX)
{
/* no software timer exist, suspend self. */
rt_thread_suspend(rt_thread_self());
rt_schedule();
}
else
{
rt_tick_t current_tick;
/* get current tick */
current_tick = rt_tick_get();
if ((next_timeout - current_tick) < RT_TICK_MAX / 2)
{
/* get the delta timeout tick */
next_timeout = next_timeout - current_tick;
rt_thread_delay(next_timeout);
}
}
/* check software timer */
rt_soft_timer_check();
}
}
#endif
/**
* @ingroup SystemInit
*
* This function will initialize system timer
*/
void rt_system_timer_init(void)
{
int i;
for (i = 0; i < sizeof(rt_timer_list) / sizeof(rt_timer_list[0]); i++)
{
rt_list_init(rt_timer_list + i);
}
}
/**
* @ingroup SystemInit
*
* This function will initialize system timer thread
*/
void rt_system_timer_thread_init(void)
{
#ifdef RT_USING_TIMER_SOFT
int i;
for (i = 0;
i < sizeof(rt_soft_timer_list) / sizeof(rt_soft_timer_list[0]);
i++)
{
rt_list_init(rt_soft_timer_list + i);
}
/* start software timer thread */
rt_thread_init(&timer_thread,
"timer",
rt_thread_timer_entry,
RT_NULL,
&timer_thread_stack[0],
sizeof(timer_thread_stack),
RT_TIMER_THREAD_PRIO,
10);
/* startup */
rt_thread_startup(&timer_thread);
#endif
}
/**@}*/
+1
Submodule Project/Example added at 1f36287996.
+159
View File
@@ -0,0 +1,159 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
// <i>Default: 32
#define RT_THREAD_PRIORITY_MAX 32
// <o>OS tick per second
// <i>Default: 1000 (1ms)
#define RT_TICK_PER_SECOND 1000
// <o>Alignment size for CPU architecture data access
// <i>Default: 4
#define RT_ALIGN_SIZE 4
// <o>the max length of object name<2-16>
// <i>Default: 8
#define RT_NAME_MAX 8
// <c1>Using RT-Thread components initialization
// <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>
// <c1>Using user main
// <i>Using user main
#define RT_USING_USER_MAIN
// </c>
// <o>the size of main thread<1-4086>
// <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE 4096
// </h>
// <h>Debug Configuration
// <c1>enable kernel debug configuration
// <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
// <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
// <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>
// <h>Hook Configuration
// <c1>using hook
// <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
// <i>using idle hook
//#define RT_USING_IDLE_HOOK
// </c>
// </h>
// <h>Software timers Configuration
// <c1> Enables user timers
// <i> Enables user timers
//#define RT_USING_TIMER_SOFT
// </c>
// <o>The priority level of timer thread <0-31>
// <i>Default: 4
#define RT_TIMER_THREAD_PRIO 4
// <o>The stack size of timer thread <0-8192>
// <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE 512
// </h>
// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
// <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>
// <c1>Using Mutex
// <i>Using Mutex
//#define RT_USING_MUTEX
// </c>
// <c1>Using Event
// <i>Using Event
//#define RT_USING_EVENT
// </c>
// <c1>Using MailBox
// <i>Using MailBox
//#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
// <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>
// <h>Memory Management Configuration
// <c1>Using Mempool Management
// <i>Using Mempool Management
//#define RT_USING_MEMPOOL
// </c>
// <c1>Dynamic Heap Management
// <i>Dynamic Heap Management
//#define RT_USING_HEAP
// </c>
// <c1>using small memory
// <i>using small memory
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
// <i>using tiny size of memory
//#define RT_USING_TINY_SIZE
// </c>
// </h>
// <h>Console Configuration
// <c1>Using console
// <i>Using console
#define RT_USING_CONSOLE
// </c>
// <o>the buffer size of console <1-1024>
// <i>the buffer size of console
// <i>Default: 128 (128Byte)
#define RT_CONSOLEBUF_SIZE 128
// </h>
// <h>Enable FinSH Configuration
// <c1>include shell config
// <i> Select this choice if you using FinSH
//#include "finsh_config.h"
// </c>
// </h>
// <h>Device Configuration
// <c1>using device framework
// <i>using device framework
//#define RT_USING_DEVICE
// </c>
// </h>
// <<< end of configuration section >>>
#endif
+5 -3
View File
@@ -29,7 +29,7 @@
#include <easyflash.h> #include <easyflash.h>
#include <stdarg.h> #include <stdarg.h>
#include <sfud.h> #include <sfud.h>
#include "FreeRTOS.h" #include <rtthread.h>
@@ -197,7 +197,8 @@ EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) {
* lock the ENV ram cache * lock the ENV ram cache
*/ */
void ef_port_env_lock(void) { void ef_port_env_lock(void) {
portENTER_CRITICAL(); rt_enter_critical();
// portENTER_CRITICAL();
/* You can add your code under here. */ /* You can add your code under here. */
//__disable_irq(); //__disable_irq();
@@ -207,7 +208,8 @@ void ef_port_env_lock(void) {
* unlock the ENV ram cache * unlock the ENV ram cache
*/ */
void ef_port_env_unlock(void) { void ef_port_env_unlock(void) {
portEXIT_CRITICAL(); rt_exit_critical();
// portEXIT_CRITICAL();
/* You can add your code under here. */ /* You can add your code under here. */
// __enable_irq(); // __enable_irq();
} }
+6 -7
View File
@@ -3,13 +3,6 @@
#include<stdint.h> #include<stdint.h>
#include "crc.h" #include "crc.h"
//static uint8_t s_tx_buffer[512];
//static uint16_t s_tx_length;
//static uint8_t rx_buffer[512];
// 读取保持寄存器的值 // 读取保持寄存器的值
// addr 寄存器地址 // addr 寄存器地址
// id 丛机地址 // id 丛机地址
@@ -29,5 +22,11 @@ int modbus_m_read_regist(uint8_t id,uint16_t addr,uint16_t length,uint8_t * data
return index; return index;
} }
//// 解析通过03 命令读取回来额寄存器数据
//int modbus_m_read_regist_ack(uint)
//{
//
//}
+4 -1
View File
@@ -5,4 +5,7 @@
int modbus_m_read_regist(uint8_t id,uint16_t addr,uint16_t length,uint8_t * data); int modbus_m_read_regist(uint8_t id,uint16_t addr,uint16_t length,uint8_t * data);
#endif #endif
+4 -5
View File
@@ -31,7 +31,8 @@
#include <stdio.h> #include <stdio.h>
#include "main.h" #include "main.h"
#include <string.h> #include <string.h>
#include "FreeRTOS.h" #include <rtthread.h>
//#include "FreeRTOS.h"
void sfud_log_info (const char *format, ...); void sfud_log_info (const char *format, ...);
sfud_err qspi_send_then_recv (const void *send_buf, size_t send_length, void *recv_buf, size_t recv_length); sfud_err qspi_send_then_recv (const void *send_buf, size_t send_length, void *recv_buf, size_t recv_length);
@@ -50,14 +51,12 @@ void sfud_log_debug (const char *file, const long line, const char *format, ...)
static void spi_lock (const sfud_spi *spi) static void spi_lock (const sfud_spi *spi)
{ {
portENTER_CRITICAL(); rt_enter_critical();
//__disable_irq();
} }
static void spi_unlock (const sfud_spi *spi) static void spi_unlock (const sfud_spi *spi)
{ {
portEXIT_CRITICAL(); rt_exit_critical();
//__enable_irq();
} }
/** /**