diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7b7617c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "if_pwm.h": "c" + } +} \ No newline at end of file diff --git a/RTE/_app/RTE_Components.h b/RTE/_app/RTE_Components.h index d91c46f..15c73f4 100644 --- a/RTE/_app/RTE_Components.h +++ b/RTE/_app/RTE_Components.h @@ -17,6 +17,6 @@ #define CMSIS_device_header "stm32mp157dxx_cm4.h" #define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ - #define RTE_Compiler_IO_STDOUT_BKPT /* Compiler I/O: STDOUT Breakpoint */ + #define RTE_Compiler_IO_STDOUT_User /* Compiler I/O: STDOUT Breakpoint */ #endif /* RTE_COMPONENTS_H */ diff --git a/ReadMe.txt b/ReadMe.txt index daebc0e..70ae6ec 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,3 +1,5 @@ 2023.6.21 建立工程,成功创建两个虚拟串口与主机通信 - \ No newline at end of file +2023.6.25 + 使用rt-thread + 电机控制、按键、ADC在M4上实现 \ No newline at end of file diff --git a/checker_m4.uvoptx b/checker_m4.uvoptx index 6fa438d..717bfbe 100644 --- a/checker_m4.uvoptx +++ b/checker_m4.uvoptx @@ -314,21 +314,249 @@ rtthread - 0 + 1 0 0 0 + + 3 + 11 + 1 + 0 + 0 + 0 + .\source\rt_thread\libcpu\arm\cortex-m4\cpuport.c + cpuport.c + 0 + 0 + + + 3 + 12 + 2 + 0 + 0 + 0 + .\source\rt_thread\libcpu\arm\cortex-m4\context_rvds.S + context_rvds.S + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\clock.c + clock.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\components.c + components.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\cpu.c + cpu.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\idle.c + idle.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\ipc.c + ipc.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\irq.c + irq.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\kservice.c + kservice.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\mem.c + mem.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\memheap.c + memheap.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\mempool.c + mempool.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\object.c + object.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\scheduler.c + scheduler.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\slab.c + slab.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\thread.c + thread.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + .\source\rt_thread\src\timer.c + timer.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + .\source\rt_thread\board.c + board.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + .\source\rt_thread\core_delay.c + core_delay.c + 0 + 0 + stm32lib - 0 + 1 0 0 0 4 - 11 + 30 1 0 0 @@ -340,7 +568,7 @@ 4 - 12 + 31 1 0 0 @@ -352,7 +580,7 @@ 4 - 13 + 32 1 0 0 @@ -364,7 +592,7 @@ 4 - 14 + 33 1 0 0 @@ -376,7 +604,7 @@ 4 - 15 + 34 1 0 0 @@ -388,7 +616,7 @@ 4 - 16 + 35 1 0 0 @@ -400,7 +628,7 @@ 4 - 17 + 36 1 0 0 @@ -412,7 +640,7 @@ 4 - 18 + 37 1 0 0 @@ -424,7 +652,7 @@ 4 - 19 + 38 1 0 0 @@ -436,7 +664,7 @@ 4 - 20 + 39 1 0 0 @@ -448,7 +676,7 @@ 4 - 21 + 40 1 0 0 @@ -460,7 +688,7 @@ 4 - 22 + 41 1 0 0 @@ -472,7 +700,7 @@ 4 - 23 + 42 1 0 0 @@ -482,6 +710,18 @@ 0 0 + + 4 + 43 + 1 + 0 + 0 + 0 + .\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c + stm32mp1xx_hal_tim.c + 0 + 0 + @@ -492,7 +732,7 @@ 0 5 - 24 + 44 1 0 0 @@ -504,7 +744,7 @@ 5 - 25 + 45 1 0 0 @@ -516,7 +756,7 @@ 5 - 26 + 46 1 0 0 @@ -528,7 +768,7 @@ 5 - 27 + 47 1 0 0 @@ -540,7 +780,7 @@ 5 - 28 + 48 1 0 0 @@ -552,7 +792,7 @@ 5 - 29 + 49 1 0 0 @@ -564,7 +804,7 @@ 5 - 30 + 50 1 0 0 @@ -576,7 +816,7 @@ 5 - 31 + 51 1 0 0 @@ -588,7 +828,7 @@ 5 - 32 + 52 1 0 0 @@ -600,7 +840,7 @@ 5 - 33 + 53 1 0 0 @@ -612,7 +852,7 @@ 5 - 34 + 54 1 0 0 @@ -624,7 +864,7 @@ 5 - 35 + 55 1 0 0 @@ -636,7 +876,7 @@ 5 - 36 + 56 1 0 0 @@ -648,7 +888,7 @@ 5 - 37 + 57 1 0 0 @@ -660,7 +900,7 @@ 5 - 38 + 58 1 0 0 @@ -672,7 +912,7 @@ 5 - 39 + 59 1 0 0 @@ -684,7 +924,7 @@ 5 - 40 + 60 1 0 0 @@ -696,7 +936,7 @@ 5 - 41 + 61 1 0 0 @@ -708,7 +948,7 @@ 5 - 42 + 62 1 0 0 @@ -720,6 +960,166 @@ + + interface + 1 + 0 + 0 + 0 + + 6 + 63 + 1 + 0 + 0 + 0 + .\source\interface\if_pwm.c + if_pwm.c + 0 + 0 + + + + + soft + 1 + 0 + 0 + 0 + + 7 + 64 + 1 + 0 + 0 + 0 + .\source\soft\buff.c + buff.c + 0 + 0 + + + 7 + 65 + 1 + 0 + 0 + 0 + .\source\soft\bytearray.c + bytearray.c + 0 + 0 + + + 7 + 66 + 1 + 0 + 0 + 0 + .\source\soft\cJSON.c + cJSON.c + 0 + 0 + + + 7 + 67 + 1 + 0 + 0 + 0 + .\source\soft\crc.c + crc.c + 0 + 0 + + + 7 + 68 + 1 + 0 + 0 + 0 + .\source\soft\debug.c + debug.c + 0 + 0 + + + 7 + 69 + 1 + 0 + 0 + 0 + .\source\soft\list.c + list.c + 0 + 0 + + + 7 + 70 + 1 + 0 + 0 + 0 + .\source\soft\mymisc.c + mymisc.c + 0 + 0 + + + 7 + 71 + 1 + 0 + 0 + 0 + .\source\soft\mystdlib.c + mystdlib.c + 0 + 0 + + + 7 + 72 + 1 + 0 + 0 + 0 + .\source\soft\mystring.c + mystring.c + 0 + 0 + + + 7 + 73 + 1 + 0 + 0 + 0 + .\source\soft\signal.c + signal.c + 0 + 0 + + + 7 + 74 + 1 + 0 + 0 + 0 + .\source\soft\sort.c + sort.c + 0 + 0 + + + ::CMSIS 0 diff --git a/checker_m4.uvprojx b/checker_m4.uvprojx index b809bb4..35b99df 100644 --- a/checker_m4.uvprojx +++ b/checker_m4.uvprojx @@ -54,7 +54,7 @@ 0 0 1 - 0 + 1 .\Listings\ 1 0 @@ -336,9 +336,9 @@ 0 - CORE_CM4,NO_ATOMIC_64_SUPPORT,USE_HAL_DRIVER,STM32MP157Dxx,METAL_INTERNAL,METAL_MAX_DEVICE_REGIONS=2,METAL_INTERNAL,VIRTIO_SLAVE_ONLY,__LOG_TRACE_IO_ + CORE_CM4,NO_ATOMIC_64_SUPPORT,USE_HAL_DRIVER,STM32MP157Dxx,METAL_INTERNAL,METAL_MAX_DEVICE_REGIONS=2,METAL_INTERNAL,VIRTIO_SLAVE_ONLY,__LOG_TRACE_IO_,RT_THREAD - .\source\core;.\source\main;.\source\rt_thread;.\source\rt_thread\include;.\source\stm32lib\STM32MP1xx_HAL_Driver\Inc;.\source\stm32lib\CMSIS\Include;.\source\OpenAMP\open-amp\lib\include;.\source\OpenAMP\libmetal\lib\include;.\source\OpenAMP\virtual_driver + .\source\core;.\source\main;.\source\rt_thread;.\source\rt_thread\include;.\source\stm32lib\STM32MP1xx_HAL_Driver\Inc;.\source\stm32lib\CMSIS\Include;.\source\OpenAMP\open-amp\lib\include;.\source\OpenAMP\libmetal\lib\include;.\source\OpenAMP\virtual_driver;.\source\soft @@ -441,6 +441,103 @@ rtthread + + + cpuport.c + 1 + .\source\rt_thread\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + .\source\rt_thread\libcpu\arm\cortex-m4\context_rvds.S + + + clock.c + 1 + .\source\rt_thread\src\clock.c + + + components.c + 1 + .\source\rt_thread\src\components.c + + + cpu.c + 1 + .\source\rt_thread\src\cpu.c + + + idle.c + 1 + .\source\rt_thread\src\idle.c + + + ipc.c + 1 + .\source\rt_thread\src\ipc.c + + + irq.c + 1 + .\source\rt_thread\src\irq.c + + + kservice.c + 1 + .\source\rt_thread\src\kservice.c + + + mem.c + 1 + .\source\rt_thread\src\mem.c + + + memheap.c + 1 + .\source\rt_thread\src\memheap.c + + + mempool.c + 1 + .\source\rt_thread\src\mempool.c + + + object.c + 1 + .\source\rt_thread\src\object.c + + + scheduler.c + 1 + .\source\rt_thread\src\scheduler.c + + + slab.c + 1 + .\source\rt_thread\src\slab.c + + + thread.c + 1 + .\source\rt_thread\src\thread.c + + + timer.c + 1 + .\source\rt_thread\src\timer.c + + + board.c + 1 + .\source\rt_thread\board.c + + + core_delay.c + 1 + .\source\rt_thread\core_delay.c + + stm32lib @@ -561,6 +658,11 @@ + + stm32mp1xx_hal_tim.c + 1 + .\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c + @@ -663,6 +765,280 @@ + + interface + + + if_pwm.c + 1 + .\source\interface\if_pwm.c + + + + + soft + + + buff.c + 1 + .\source\soft\buff.c + + + bytearray.c + 1 + .\source\soft\bytearray.c + + + cJSON.c + 1 + .\source\soft\cJSON.c + + + crc.c + 1 + .\source\soft\crc.c + + + debug.c + 1 + .\source\soft\debug.c + + + list.c + 1 + .\source\soft\list.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + mymisc.c + 1 + .\source\soft\mymisc.c + + + mystdlib.c + 1 + .\source\soft\mystdlib.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + mystring.c + 1 + .\source\soft\mystring.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + signal.c + 1 + .\source\soft\signal.c + + + sort.c + 1 + .\source\soft\sort.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + ::CMSIS diff --git a/source/interface/if_pwm.c b/source/interface/if_pwm.c new file mode 100644 index 0000000..b92073b --- /dev/null +++ b/source/interface/if_pwm.c @@ -0,0 +1,55 @@ +#include "board.h" +#include "debug.h" + +// 使用定时器14 + +// PF7,8,9 是输出口 + +typedef struct{ + TIM_HandleTypeDef htim; +}self_def; + + +static self_def g_self; + + +static int init(pwm_def *p) +{ + self_def *s=&g_self; + if(p->private_data) return 0; + p->private_data=s; + + s->htim.Instance = TIM14; + s->htim.Init.Prescaler = 209-1; + s->htim.Init.CounterMode = TIM_COUNTERMODE_UP; + s->htim.Init.Period = 65535; + s->htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + s->htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&s->htim) != HAL_OK) + { + DBG_ERR("time init failed."); + return -1; + } + return 0; +} + + + + + + + + + + + + + +void TIM14_IRQHandler(void) +{ + self_def *s=&g_self; + HAL_TIM_IRQHandler(&s->htim); +} + + + diff --git a/source/interface/if_pwm.h b/source/interface/if_pwm.h new file mode 100644 index 0000000..6bd1ac5 --- /dev/null +++ b/source/interface/if_pwm.h @@ -0,0 +1,17 @@ + +#ifndef if_pwm_h__ +#define if_pwm_h__ + + + + + + + + + + + +#endif + + diff --git a/source/main/main.c b/source/main/main.c index 0abca8a..f67cee9 100644 --- a/source/main/main.c +++ b/source/main/main.c @@ -24,7 +24,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ - +#include "debug.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -78,17 +78,17 @@ void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart); int main(void) { /* USER CODE BEGIN 1 */ + debug_init(); /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ - log_info("ssss"); + DBG_LOG("mcu start."); /* Reset of all peripherals, Initialize the Systick. */ HAL_Init(); - log_info("aaaa"); /* USER CODE BEGIN Init */ - if(IS_ENGINEERING_BOOT_MODE()) + if(IS_ENGINEERING_BOOT_MODE()) { /* Configure the system clock */ SystemClock_Config(); diff --git a/source/main/stm32mp1xx_hal_conf.h b/source/main/stm32mp1xx_hal_conf.h index 3a43fa4..7588d6d 100644 --- a/source/main/stm32mp1xx_hal_conf.h +++ b/source/main/stm32mp1xx_hal_conf.h @@ -70,7 +70,7 @@ /*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_SRAM_MODULE_ENABLED */ /*#define HAL_TAMP_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED /*#define HAL_TMPSENS_MODULE_ENABLED */ /*#define HAL_UART_MODULE_ENABLED */ /*#define HAL_USART_MODULE_ENABLED */ diff --git a/source/main/stm32mp1xx_hal_msp.c b/source/main/stm32mp1xx_hal_msp.c index cb86705..4f0c431 100644 --- a/source/main/stm32mp1xx_hal_msp.c +++ b/source/main/stm32mp1xx_hal_msp.c @@ -128,6 +128,66 @@ void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef* hipcc) } + + + + +/** +* @brief TIM_Base MSP Initialization +* This function configures the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspInit 0 */ + + /* USER CODE END TIM14_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM14_CLK_ENABLE(); + /* TIM14 interrupt Init */ + HAL_NVIC_SetPriority(TIM14_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(TIM14_IRQn); + /* USER CODE BEGIN TIM14_MspInit 1 */ + + /* USER CODE END TIM14_MspInit 1 */ + } + +} + +/** +* @brief TIM_Base MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspDeInit 0 */ + + /* USER CODE END TIM14_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM14_CLK_DISABLE(); + + /* TIM14 interrupt DeInit */ + HAL_NVIC_DisableIRQ(TIM14_IRQn); + /* USER CODE BEGIN TIM14_MspDeInit 1 */ + + /* USER CODE END TIM14_MspDeInit 1 */ + } + +} + + + + + + + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/source/main/stm32mp1xx_it.c b/source/main/stm32mp1xx_it.c index 6eedf6c..55be38e 100644 --- a/source/main/stm32mp1xx_it.c +++ b/source/main/stm32mp1xx_it.c @@ -83,17 +83,17 @@ void NMI_Handler(void) /** * @brief This function handles Hard fault interrupt. */ -void HardFault_Handler(void) -{ - /* USER CODE BEGIN HardFault_IRQn 0 */ +//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 */ - } -} +// /* USER CODE END HardFault_IRQn 0 */ +// while (1) +// { +// /* USER CODE BEGIN W1_HardFault_IRQn 0 */ +// /* USER CODE END W1_HardFault_IRQn 0 */ +// } +//} /** * @brief This function handles Memory management fault. @@ -169,29 +169,29 @@ void DebugMon_Handler(void) /** * @brief This function handles Pendable request for system service. */ -void PendSV_Handler(void) -{ - /* USER CODE BEGIN PendSV_IRQn 0 */ +//void PendSV_Handler(void) +//{ +// /* USER CODE BEGIN PendSV_IRQn 0 */ - /* USER CODE END PendSV_IRQn 0 */ - /* USER CODE BEGIN PendSV_IRQn 1 */ +// /* USER CODE END PendSV_IRQn 0 */ +// /* USER CODE BEGIN PendSV_IRQn 1 */ - /* USER CODE END PendSV_IRQn 1 */ -} +// /* USER CODE END PendSV_IRQn 1 */ +//} /** * @brief This function handles System tick timer. */ -void SysTick_Handler(void) -{ - /* USER CODE BEGIN SysTick_IRQn 0 */ +//void SysTick_Handler(void) +//{ +// /* USER CODE BEGIN SysTick_IRQn 0 */ - /* USER CODE END SysTick_IRQn 0 */ - HAL_IncTick(); - /* USER CODE BEGIN SysTick_IRQn 1 */ +// /* USER CODE END SysTick_IRQn 0 */ +// HAL_IncTick(); +// /* USER CODE BEGIN SysTick_IRQn 1 */ - /* USER CODE END SysTick_IRQn 1 */ -} +// /* USER CODE END SysTick_IRQn 1 */ +//} /******************************************************************************/ /* STM32MP1xx Peripheral Interrupt Handlers */ diff --git a/source/rt_thread/board.c b/source/rt_thread/board.c index 2e7f7c0..448f9f6 100644 --- a/source/rt_thread/board.c +++ b/source/rt_thread/board.c @@ -1,5 +1,5 @@ -#include "stm32h7xx.h" +#include "stm32mp1xx.h" #include #include #include "board.h" @@ -36,7 +36,7 @@ static uint32_t _SysTick_Config(rt_uint32_t ticks) } #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP) -static uint32_t g_heap[64*1024/4]; +static uint32_t g_heap[32*1024/4]; RT_WEAK void *rt_heap_begin_get(void) { return (void *)g_heap; @@ -44,7 +44,7 @@ RT_WEAK void *rt_heap_begin_get(void) RT_WEAK void *rt_heap_end_get(void) { - return (void *)(g_heap+(64*1024/4)); + return (void *)(g_heap+(32*1024/4)); } #endif @@ -57,10 +57,10 @@ void rt_hw_board_init() { //NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x20000); // 1msһtick - _SysTick_Config (400000000/1000); + _SysTick_Config (HAL_RCC_GetMCUFreq()/1000); rt_system_heap_init(rt_heap_begin_get(),rt_heap_end_get()); - mem_init(); - tempptr_init(); + //mem_init(); + //tempptr_init(); delay_init(); signal_init(); @@ -75,6 +75,23 @@ void SysTick_Handler(void) } +uint32_t HAL_GetTick(void) +{ + return rt_tick_get(); +} + + +void HAL_Delay(uint32_t Delay) +{ + rt_thread_mdelay(Delay); +} + +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + return HAL_OK; +} + + #endif void *dev_get(const char *name) @@ -223,25 +240,25 @@ void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) -#pragma import(__use_no_semihosting) +//#pragma import(__use_no_semihosting) -struct __FILE -{ - int handle; -}; +//struct __FILE +//{ +// int handle; +//}; -FILE __stdout; +//FILE __stdout; -void _sys_exit(int x) -{ - x = x; -} +//void _sys_exit(int x) +//{ +// x = x; +//} -int fputc(int ch, FILE *f) -{ -// SEGGER_RTT_PutChar(0,ch); - return ch; -} +//int fputc(int ch, FILE *f) +//{ +//// SEGGER_RTT_PutChar(0,ch); +// return ch; +//} diff --git a/source/rt_thread/board.h b/source/rt_thread/board.h index 4f5bc25..dc5d0b3 100644 --- a/source/rt_thread/board.h +++ b/source/rt_thread/board.h @@ -5,7 +5,7 @@ #include "rtthread.h" #include #include "string.h" -#include "stm32h7xx.h" +#include "stm32mp1xx.h" struct dev_struct{ diff --git a/source/rt_thread/core_delay.c b/source/rt_thread/core_delay.c index 6aca9de..9dd2f58 100644 --- a/source/rt_thread/core_delay.c +++ b/source/rt_thread/core_delay.c @@ -1,4 +1,4 @@ -#include "stm32h7xx.h" +#include "stm32mp1xx.h" #include "core_delay.h" #include "rtthread.h" #include @@ -17,7 +17,7 @@ //ȡϵͳƵ static uint32_t get_sys_clocks_freq (void) { - return HAL_RCC_GetSysClockFreq(); + return HAL_RCC_GetMCUFreq(); } diff --git a/source/rt_thread/libcpu/arm/cortex-m4/context_rvds.S b/source/rt_thread/libcpu/arm/cortex-m4/context_rvds.S index 9414ace..da0e1c7 100644 --- a/source/rt_thread/libcpu/arm/cortex-m4/context_rvds.S +++ b/source/rt_thread/libcpu/arm/cortex-m4/context_rvds.S @@ -217,13 +217,13 @@ rt_hw_interrupt_thread_switch PROC BX lr ENDP - IMPORT bk_reboot_hard_err + ;IMPORT bk_reboot_hard_err IMPORT rt_hw_hard_fault_exception EXPORT HardFault_Handler HardFault_Handler PROC ; get current context - BL bk_reboot_hard_err + ;BL bk_reboot_hard_err B . TST lr, #0x04 ; if(!EXC_RETURN[2]) ITE EQ diff --git a/source/soft/buff.c b/source/soft/buff.c new file mode 100644 index 0000000..2ca3c7f --- /dev/null +++ b/source/soft/buff.c @@ -0,0 +1,180 @@ +#include "buff.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" + + + +#ifdef RT_THREAD + #include "rthw.h" + #define IRQ_DISABLE() rt_base_t irq_stat=rt_hw_interrupt_disable( ) + #define IRQ_ENABLE() rt_hw_interrupt_enable (irq_stat) + #define MUTEX_INIT(buff,name) buff->mutex=rt_mutex_create(name,RT_IPC_FLAG_FIFO) + #define MUTEX_TAKE(buff) rt_mutex_take(buff->mutex,RT_WAITING_FOREVER) + #define MUTEX_RELEASE(buff) rt_mutex_release(buff->mutex); +#else + #define IRQ_DISABLE() { } + #define IRQ_ENABLE() { } + #define MUTEX_INIT(buff,name) {} + #define MUTEX_TAKE(buff) {} + #define MUTEX_RELEASE(buff) {} +#endif + + + +static int g_buff_num=0; + + +int buff_init(data_buff *buff,int size,int use_frame,int frame_start,int frame_end) +{ + int buff_index; + char str[20]; + if(buff==0) return -1; + if(buff->buff==0) + { + IRQ_DISABLE(); + buff_index=g_buff_num; + g_buff_num++; + IRQ_ENABLE(); + buff->buff=malloc(size); + if(buff->buff==0) return -1; + memset(buff->buff,0,sizeof(size)); + buff->buff_len= size; + buff->use_frame=use_frame; + buff->frame_start=frame_start; + buff->frame_end=frame_end; + sprintf(str,"buff_#%d",buff_index); + MUTEX_INIT(buff,str); + } + buff_clear(buff); + return 0; +} + + +int buff_deinit(data_buff *buff) +{ + if(buff==0) return -1; + if(buff->buff) + { + free(buff->buff); + buff->buff=0; + buff->buff_len=0; + } + return 0; +} + + +int buff_get_used(data_buff *buff) +{ + int ret=-1; + IRQ_DISABLE(); + ret=buff->buff_used; + IRQ_ENABLE(); + return ret; +} + + + + +int buff_save_byte(data_buff *buff,uint8_t data) +{ + if(buff==0) return -1; + int ret=-1; + IRQ_DISABLE(); + if((!buff->use_frame)||(data==buff->frame_start)) buff->active=1; + if((buff->buff_usedbuff_len)&&buff->active) + { + buff->buff[buff->save_ptr]=data; + buff->buff_used++; + if((buff->use_frame)&&(data==buff->frame_end)) { + buff->frame_num++; + buff->active=0; + } + buff->save_ptr++; + if (buff->save_ptr>=buff->buff_len) + buff->save_ptr=0; + ret= 0; + } + IRQ_ENABLE(); + return ret; +} + + +int buff_save_bytes(data_buff *buff,const uint8_t *data,int len) +{ + if(buff==0) return -1; + int ret=-1; + MUTEX_TAKE(buff); + if (buff->buff_used+len<=buff->buff_len) + { + while(len--) + { + ret=buff_save_byte(buff,*data);data++; + if(ret!=0) break; + } + } + MUTEX_RELEASE(buff); + return ret; +} + + + +int buff_read_byte(data_buff *buff,uint8_t *data) +{ + if(buff==0) return -1; + int ret=-1; + IRQ_DISABLE(); + if (((buff->frame_num)&&(buff->buff_used))||((!buff->use_frame)&&(buff->buff_used))) + { + *data=buff->buff[buff->read_ptr]; + buff->buff_used--; + if((buff->use_frame)&&(*data==buff->frame_end)) buff->frame_num--; + buff->read_ptr++; + if (buff->read_ptr>=buff->buff_len) + buff->read_ptr=0; + ret= 0; + } + IRQ_ENABLE(); + return ret; +} + + + +int buff_read_bytes(data_buff *buff,uint8_t *data,int len) +{ + if(buff==0) return -1; + int ret=-1; + MUTEX_TAKE(buff); + if (buff->buff_used>=len) + { + while(len--) + { + ret=buff_read_byte(buff,data);data++; + if(ret!=0) break; + } + } + MUTEX_RELEASE(buff); + return ret; +} + + + + +int buff_clear(data_buff *buff) +{ + if(buff==0) return -1; + IRQ_DISABLE(); + buff->buff_used=0; + buff->read_ptr=0; + buff->save_ptr=0; + buff->frame_num=0; + buff->active=0; + IRQ_ENABLE(); + return 0; +} + + + + + + diff --git a/source/soft/buff.h b/source/soft/buff.h new file mode 100644 index 0000000..6bc4883 --- /dev/null +++ b/source/soft/buff.h @@ -0,0 +1,60 @@ + +#ifndef BUFF_H__ +#define BUFF_H__ + + +#include + + + + +typedef struct +{ + int buff_len; + int buff_used; + int read_ptr; + int save_ptr; + int use_frame; //使用帧 + int frame_start; //帧开始 + int frame_end; //帧结束 + int frame_num; //完整帧数 + int active; //在接收到帧开始之后进入活跃状态 + uint8_t *buff; + void *mutex; +} data_buff; + + +// 初始化一个指定长度的缓冲区,返回0成功 +int buff_init(data_buff *buff,int size,int use_frame,int frame_start,int frame_end); + +// 去初始化一个指定长度的缓冲区,返回0成功 +int buff_deinit(data_buff *buff); + +// 获取buff的使用量 +int buff_get_used(data_buff *buff); + +// 保存一个字节数据,返回0,成功 +int buff_save_byte(data_buff *buff,uint8_t data); + +// 保存多个字节,返回0成功 +int buff_save_bytes(data_buff *buff,const uint8_t *data,int len); + +// 读取一个字节数据,返回0,成功 +int buff_read_byte(data_buff *buff,uint8_t *data); + +// 读取多个字节,返回0,成功 +int buff_read_bytes(data_buff *buff,uint8_t *data,int len); + + +// 清除缓冲区,返回0,成功 +int buff_clear(data_buff *buff); + + + + +#endif + + + + + diff --git a/source/soft/bytearray.c b/source/soft/bytearray.c new file mode 100644 index 0000000..de50686 --- /dev/null +++ b/source/soft/bytearray.c @@ -0,0 +1,208 @@ +#include "bytearray.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" +#include "board.h" +#include "mystdlib.h" +#include "debug.h" +#include "rtthread.h" + + + +#define ARR_MAX_PRINT_LEN 20 + +#define ARRAY_APPEND_SKIP 50 + + + +// 使用时保证不要在不同线程同时修改,可以不用保护以提高速度 +#define rt_mutex_create(...) 0 +#define rt_mutex_delete(...) +#define rt_mutex_take(...) +#define rt_mutex_release(...) + + + + + +struct _array_def{ + int32_t all; + int32_t used; + rt_mutex_t mutex; + uint8_t data[0]; +}; + + + + + +array_def *arr_creat(void) +{ + array_def *a; + static uint16_t count=0; + char s1[16]={0}; + sprintf(s1,"arr_mut#%d",count); + int size=0; + size+=sizeof(array_def); + size+=ARRAY_APPEND_SKIP; + a=malloc(size); + param_check(a); + a->all=ARRAY_APPEND_SKIP; + a->used=0; + a->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO); + count++; + return a; +} + + + +static array_def *arr_expend(array_def *a) +{ + array_def *r; + int size=0; + int cpysize=0; + size+=sizeof(array_def); + size+=a->all+ARRAY_APPEND_SKIP; + r=malloc(size); + param_check(r); + cpysize=sizeof(array_def)+a->used; + memcpy(r,a,cpysize); + r->all+=ARRAY_APPEND_SKIP; + free(a); + return r; +} + + + + +array_def *_arr_append(array_def **a,uint8_t d) +{ + param_check(a); + param_check(*a); + array_def *r=*a; + rt_mutex_take(r->mutex,RT_WAITING_FOREVER); + if((*a)->used>=(*a)->all) + { + r=arr_expend(*a); + } + r->data[r->used]=d; + r->used++; + rt_mutex_release(r->mutex); + *a=r; + return r; +} + + +uint8_t arr_get(array_def *a,int index) +{ + uint8_t ret=0; + param_check(a); + rt_mutex_take(a->mutex,RT_WAITING_FOREVER); + if(index<0) index=a->used+index; + if((index>=0&&indexused)==0) ret=0; + else ret=a->data[index]; + rt_mutex_release(a->mutex); + return ret; +} + + +uint8_t *arr_data(array_def *a) +{ + param_check(a); + return a->data; +} + + +int arr_length(array_def *a) +{ + param_check(a); + return a->used; +} + + +// 截取数组 +array_def *arr_mid(array_def *a,int start,int len) +{ + param_check(a); + array_def *r; + r=arr_creat(); + if(start<0) start=a->used+start; + if((start>=0&&startused)==0) + { + return r; + } + if(start+len>a->used) + { + len=a->used-start; + } + for(int i=0;idata[i+start]); + } + //return tappend(r,0); + return r; +} + +// 移除一些数据,返回实际移除的数据长度 +int arr_remove(array_def *a,int start,int len) +{ + param_check(a); + if(start<0) start=a->used+start; + if((start>=0&&startused)==0) + { + return 0; + } + if(start+len>a->used) + { + len=a->used-start; + } + int move_len=a->used-(start+len); + memcpy(&a->data[start],&a->data[start+len],move_len); + a->used-=len; + return len; +} + +// 输出打印字符串 +char *arr_string(array_def *a) +{ + param_check(a); + array_def *d=arr_creat(); + param_check(d); + // DBG_LOG("d=%08x,a=%08x",d,a); + // DBG_LOG("%s:length(a)==%d.",__func__,arr_length(a)); + int len=0; + char s[20]; + int index=0; + arr_append(d,'['); + for(int i=0;i=ARR_MAX_PRINT_LEN){ + // 超过20字节的 只打印前20字节 + sprintf(s,"...(%d)",arr_length(a)); + len=strlen(s); + arr_appends(d,s,len); + break; + } + } + arr_append(d,']'); + len=arr_length(d); + char *ptr=malloc(len+1); + param_check(ptr); + memcpy(ptr,arr_data(d),len); + arr_delete(d); + ptr[len]=0; + return ptr; +} + + + + + + diff --git a/source/soft/bytearray.h b/source/soft/bytearray.h new file mode 100644 index 0000000..0551d3b --- /dev/null +++ b/source/soft/bytearray.h @@ -0,0 +1,46 @@ +#ifndef bytearray_h__ +#define bytearray_h__ + +#include "stdint.h" + +struct _array_def; +typedef struct _array_def array_def; + + + +array_def *arr_creat(void); +uint8_t arr_get(array_def *a,int index); +array_def *arr_mid(array_def *a,int start,int len); +uint8_t *arr_data(array_def *a); +int arr_length(array_def *a); +int arr_remove(array_def *a,int start,int len); +char *arr_string(array_def *a); + + +#define arr_delete(a) {free(a);a=0;} +#define arr_append(a,d) _arr_append(&a,d) +#define arr_appends(a,d,len) for(int i=0;i +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + + +static const char *ep; + +const char *cJSON_GetErrorPtr(void) {return ep;} + +static int cJSON_strcasecmp(const char *s1,const char *s2) +{ + if (!s1) return (s1==s2)?0:1;if (!s2) return 1; + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; + return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + + len = strlen(str) + 1; + if ((copy = (char*)cJSON_malloc(len)),copy==0) return 0; + memcpy(copy,(void *)str,len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(void) +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node,0,sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (c->string) cJSON_free(c->string); + cJSON_free(c); + c=next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + if (*num=='-') sign=-1,num++; /* Has sign? */ + if (*num=='0') num++; /* is zero */ + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ + if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ + if (*num=='e' || *num=='E') /* Exponent? */ + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +#ifdef MY_NUMTOSTR + + //把数字转换成字符串 +void num_to_str (u8 *str,u8 num1,u8 num2) +{ + if (num1>9) + { + *str++=num1/10+'0'; + *str++=num1%10+'0'; + } + else + { + *str++=num1+'0'; + } + *str++='.'; + if (num2<10) + { + *str++=num2+'0'; + } + else + { + *str++=num2/10+'0'; + *str++=num2%10+'0'; + } + *str=0; +} + +#endif + + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) + { + str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str,"%d",item->valueint); + } + else + { + str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); + else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else + { +#ifndef MY_NUMTOSTR + sprintf(str,"%f",d); +#else + num_to_str((u8*)str,(u8)d,(u8)((d-(u8)d)*10)); +#endif + } + } + } + return str; +} + +static unsigned parse_hex4(const char *str) +{ + unsigned h=0; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; + if (*str!='\"') {ep=str;return 0;} /* not a string! */ + + while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': /* transcode utf16 to utf8. */ + uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ + + if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ + uc2=parse_hex4(ptr+3);ptr+=6; + if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ + uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); + } + + len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; + + switch (len) { + case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 =(uc | firstByteMark[len]); + } + ptr2+=len; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) +{ + const char *ptr;char *ptr2,*out;int len=0;unsigned char token; + + if (!str) return cJSON_strdup(""); + ptr=str;while ((token=*ptr),token && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} + + out=(char*)cJSON_malloc(len+3); + if (!out) return 0; + + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth,int fmt); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth,int fmt); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth,int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} + +/* Parse an object - create a new root, and populate. */ +cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) +{ + const char *end=0; + cJSON *c=cJSON_New_Item(); + ep=0; + if (!c) return 0; /* memory fail */ + + end=parse_value(c,skip(value)); + if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} + if (return_parse_end) *return_parse_end=end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} + +/* Render a cJSON item/entity/structure to text. */ +char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} +char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + ep=value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item,int depth,int fmt) +{ + char *out=0; + if (!item) return 0; + switch ((item->type)&255) + { + case cJSON_NULL: out=cJSON_strdup("null"); break; + case cJSON_False: out=cJSON_strdup("false");break; + case cJSON_True: out=cJSON_strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth,fmt);break; + case cJSON_Object: out=print_object(item,depth,fmt);break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') {ep=value;return 0;} /* not an array! */ + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if ((new_item=cJSON_New_Item()),new_item==0) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + if (!value) return 0; /* memory fail */ + } + + if (*value==']') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item,int depth,int fmt) +{ + char **entries; + char *out=0,*ptr,*ret;int len=5; + cJSON *child=item->child; + int numentries=0,i=0,fail=0; + + /* How many entries in the array? */ + while (child) numentries++,child=child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + out=(char*)cJSON_malloc(3); + if (out) strcpy(out,"[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + memset(entries,0,numentries*sizeof(char*)); + /* Retrieve all the results: */ + child=item->child; + while (child && !fail) + { + ret=print_value(child,depth+1,fmt); + entries[i++]=ret; + if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; + child=child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail=1; + + /* Handle failure. */ + if (fail) + { + for (i=0;itype=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; + value=skip(parse_string(child,skip(value))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if ((new_item=cJSON_New_Item()),new_item==0) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value=='}') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item,int depth,int fmt) +{ + char **entries=0,**names=0; + char *out=0,*ptr,*ret,*str;int len=7,i=0,j; + cJSON *child=item->child; + int numentries=0,fail=0; + /* Count the number of entries. */ + while (child) numentries++,child=child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + out=(char*)cJSON_malloc(fmt?depth+4:3); + if (!out) return 0; + ptr=out;*ptr++='{'; + if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; + while (child) + { + names[i]=str=print_string_ptr(child->string); + entries[i++]=ret=print_value(child,depth,fmt); + if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; + child=child->next; + } + + /* Try to allocate the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + if (!out) fail=1; + + /* Handle failure */ + if (fail) + { + for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} +void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} + +cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; + if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} +void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} +void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} + +/* Replace array/object items with new ones. */ +void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; + newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; + if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} +void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} + +/* Create basic types: */ +cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} +cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} +cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} +cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} + +/* Create Arrays: */ +cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} + +/* Duplication */ +cJSON *cJSON_Duplicate(cJSON *item,int recurse) +{ + cJSON *newitem,*cptr,*nptr=0,*newchild; + /* Bail on bad ptr */ + if (!item) return 0; + /* Create new item */ + newitem=cJSON_New_Item(); + if (!newitem) return 0; + /* Copy over all vars */ + newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; + if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} + if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} + /* If non-recursive, then we're done! */ + if (!recurse) return newitem; + /* Walk the ->next chain for the child. */ + cptr=item->child; + while (cptr) + { + newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) {cJSON_Delete(newitem);return 0;} + if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ + cptr=cptr->next; + } + return newitem; +} + +void cJSON_Minify(char *json) +{ + char *into=json; + while (*json) + { + if (*json==' ') json++; + else if (*json=='\t') json++; // Whitespace characters. + else if (*json=='\r') json++; + else if (*json=='\n') json++; + else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line. + else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments. + else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive. + else *into++=*json++; // All other characters. + } + *into=0; // and null-terminate. +} + + + + diff --git a/source/soft/cJSON.h b/source/soft/cJSON.h new file mode 100644 index 0000000..9745c5f --- /dev/null +++ b/source/soft/cJSON.h @@ -0,0 +1,146 @@ +/* + Copyright (c) 2009 Dave Gamble + + 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. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#include +#ifdef __cplusplus +extern "C" +{ +#endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + + + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks* hooks); + + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(void); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); +extern void cJSON_DeleteItemFromArray(cJSON *array,int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); + +extern void cJSON_Minify(char *json); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/soft/crc.c b/source/soft/crc.c new file mode 100644 index 0000000..366a85b --- /dev/null +++ b/source/soft/crc.c @@ -0,0 +1,109 @@ +#include "crc.h" + + + + + + + +uint8_t crc_crc8(const uint8_t *data,int num) +{ + uint8_t crc = 0; + uint16_t j,i; + for (j = 0; j < num; j++) + { + crc ^= *(data+j); + for ( i = 0; i < 8; i++) + { + if ((crc & 0x01) != 0) + { + crc >>= 1; + crc ^= 0x8c; + } + else + { + crc >>= 1; + } + } + } + return crc; +} + + + + + +void crc_crc16(const uint8_t *data, int len,uint8_t *lb,uint8_t *hb) +{ + if (len > 0) + { + uint16_t crc = 0xFFFF; + int i = 0; + for (; i < len; i++) + { + crc = (uint16_t)(crc ^ (data[i])); + for (int j = 0; j < 8; j++) + { + crc = (crc & 1) != 0 ? (uint16_t)((crc >> 1) ^ 0xA001) : (uint16_t)(crc >> 1); + } + } + uint8_t hi = (uint8_t)((crc & 0xFF00) >> 8); //高位置 + uint8_t lo = (uint8_t)(crc & 0x00FF); //低位置 + *lb=lo;*hb=hi; + } +} + + + +uint32_t crc_crc32(const uint8_t *data,int size) +{ + uint32_t temp,crc=0xffffffff; + int i=0,j=0; + if((size%4)!=0) + { + return 0; + } + while(iinit(); + //DBG_DEV->write((const uint8_t *)"\r\n",2); + g_data.inited=1; + DBG_LOG("debug inited.\r\n"); + } + return 0; +} + + +void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...) +{ + if(g_data.inited==0) return; + va_list args; + size_t length; + static char log_buf[CONSOLEBUF_SIZE]; + static const char *level_str[]={"[info] ","[log] ","[warn] ","[err] "}; + static int level_str_len[]={7,6,7,6}; + if(levelDBG_LEVEL_ERR) return; + #ifdef RT_THREAD + rt_mutex_take(&g_data.mutex,RT_WAITING_FOREVER); + #endif + memcpy(log_buf,level_str[level],level_str_len[level]); + length=level_str_len[level]; + length+=sprintf(log_buf + length,"%s|%s|%d| ",file,fun,line); + + va_start(args, fmt); + length += vsnprintf(log_buf + length, sizeof(log_buf) - length - 1, fmt, args); + if (length > CONSOLEBUF_SIZE - 1) + length = CONSOLEBUF_SIZE - 1; + va_end(args); + memcpy(&log_buf[length],"\r\n",2); + length+=2; + log_buf[length]=0;length++; + //DBG_DEV->write((const uint8_t *)log_buf,length); + printf("%s",log_buf); + #ifdef RT_THREAD + rt_mutex_release(&g_data.mutex); + #endif +} + + + + + diff --git a/source/soft/debug.h b/source/soft/debug.h new file mode 100644 index 0000000..74d6ab7 --- /dev/null +++ b/source/soft/debug.h @@ -0,0 +1,57 @@ + + + + +#include "stdint.h" +#include "stdio.h" + + + + +/*r{ 修改日志打印等级 }c*/ +#define DBG_LOG_LEVEL DBG_LEVEL_INFO + + + +/*r{ 定义打印数据等级 }c*/ +#define DBG_LEVEL_INFO 0 +#define DBG_LEVEL_LOG 1 +#define DBG_LEVEL_WARN 2 +#define DBG_LEVEL_ERR 3 + + +#if (DBG_LOG_LEVEL<=DBG_LEVEL_INFO) +#define DBG_INFO( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_INFO, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_INFO( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_LOG) +#define DBG_LOG( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_LOG, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_LOG( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_WARN) +#define DBG_WARN( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_WARN, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_WARN( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_ERR) +#define DBG_ERR( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_ERR, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_ERR( ml_msg_, ...) +#endif + + +#define DBG_LOG_(type_,msg_,...)\ + debug_log(__FILE__,__func__,__LINE__,type_,(msg_),##__VA_ARGS__) + + +int debug_init(void); + +void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...); + + diff --git a/source/soft/history/myjson-.c b/source/soft/history/myjson-.c new file mode 100644 index 0000000..7129f07 --- /dev/null +++ b/source/soft/history/myjson-.c @@ -0,0 +1,556 @@ +#include "myjson.h" +#include "board.h" +#include "debug.h" +#include "mystdlib.h" +#include "bytearray.h" + + + + + +// jsonַתΪjson,ʱָ +cJSON *json_parse(const char *jstr) +{ + cJSON *json=cJSON_Parse(jstr); + if(json){ + return tappend(json,cJSON_Delete); + } + return json; +} + + + + + + +/*r{ json תб }c*/ +list_def *jarray_to_list(cJSON *jarray,obj_def *obj) +{ + param_check(obj); + param_check(obj->to_obj_fun); + param_check(obj->obj_size); + param_check(jarray); + list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0); + void *o; + int array_size; + if(jarray->type!=cJSON_Array){ + DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null"); + goto err; + } + array_size=cJSON_GetArraySize(jarray); + for(int i=0;ito_obj_fun(cJSON_GetArrayItem(jarray,i)); + if(o==0) + { + DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null"); + goto err; + } + list_append(l,o); + if(obj->del_fun) obj->del_fun(o); + } + err: + return l; +} + + +/*r{ jsonת }c*/ +static void *json_to_int(cJSON *j) +{ + if(j->type==cJSON_Number) + { + int *ret=malloc(sizeof(int)); + param_check(ret); + *ret=j->valueint; + return ret; + } + return 0; +} + + + +static obj_def g_obj_int={ + .obj_size=sizeof(int), + .to_obj_fun=json_to_int, + .del_fun=free, + .sub=INT_SUB, + .del=INT_DEL +}; + + +obj_def *obj_int(void) +{ + return &g_obj_int; +} + + + + + + + + +/*r{ jsonתַ }c*/ +static void *json_to_str(cJSON *j) +{ + if(j->type==cJSON_String) + { + int len=strlen(j->valuestring)+1; + char *ret=malloc(len); + char **ret_ptr=malloc(sizeof(char *)); + param_check(ret); + param_check(ret_ptr); + memcpy(ret,j->valuestring,len+1); + *ret_ptr=ret; + return ret_ptr; + } + return 0; +} + + + +static obj_def g_obj_str={ + .obj_size=sizeof(char *), + .to_obj_fun=json_to_str, + .del_fun=free, + .sub=STR_SUB, + .del=STR_DEL +}; + + +obj_def *obj_str(void) +{ + return &g_obj_str; +} + + + + + +static void *json_to_range(cJSON *j) +{ + sch_range *s=malloc(sizeof(sch_range)); + param_check(s); + JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max); + JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min); + if(s->min>s->max){ + DBG_WARN("range is empty."); + } + return s; +} + + + + + +static obj_def g_obj_range={ + .obj_size=sizeof(sch_range), + .to_obj_fun=json_to_range, + .del_fun=free, + .sub=0, + .del=0 +}; + + +obj_def *obj_range(void) +{ + return &g_obj_range; +} + +// 1ڷΧ +int range_in_range(sch_range *r,int num) +{ + if(num>=r->min&&num<=r->max) + return 1; + else + return 0; +} + + + + + + + + +static void *json_to_task(cJSON *j) +{ + sch_task *task=calloc(1,sizeof(sch_range)); + JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index); + JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump); + JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry); + JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num); + JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num); + task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str()); + task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str()); + task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int()); + task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range()); + JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code); + task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int()); + return task; +} + + + + +static int _list_del_task(void *p) +{ + sch_task *t=p; + CHECK_DO(t->brief,free); + CHECK_DO(t->params_info,list_delete); + CHECK_DO(t->returns_info,list_delete); + CHECK_DO(t->params,list_delete); + CHECK_DO(t->ranges,list_delete); + CHECK_DO(t->ret_failed_code,list_delete); + CHECK_DO(t->ch_errcode,list_delete); + return 0; +} + + + +static obj_def g_obj_task={ + .obj_size=sizeof(sch_task), + .to_obj_fun=json_to_task, + .del_fun=free, + .sub=0, + .del=_list_del_task +}; + + +obj_def *obj_task(void) +{ + return &g_obj_task; +} + +// תΪ +array_def *task_to_array(sch_task *t) +{ + array_def *a=arr_creat(); + arr_append(a,(uint8_t)t->task_id); + arr_append(a,(uint8_t)t->index); + arr_append(a,(uint8_t)t->retry); + arr_append(a,(uint8_t)t->err_jump); + arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4)); + for(int i=0;iparams);i++) + { + arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff)); + arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8)); + } + if(list_length(t->params)!=t->param_num) + { + DBG_WARN("name=%s param_num!=params.size().",t->brief); + } + if(t->return_num>list_length(t->returns_info)) + { + DBG_WARN("name=%s return_num>returns_info.size().",t->brief); + } + if(list_length(t->ch_errcode)!=list_length(t->ranges)) + { + DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief); + } + return a; +} + + + +// ack==0ɹ +task_returns *task_check_returns(sch_task *t,int ack,array_def *data) +{ + int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num; + task_returns *res=malloc(size); + param_check(res); + res->size=size; + memset(res,0,size); + if(t->ch_errcode==0) t->ch_errcode=list_creat_int(); + list_clear(t->ch_errcode); + res->index=t->index; + res->id=t->task_id; + res->ack=ack; + if(res->ack==0){ + res->exe_err=0; + }else{ + res->exe_err=t->failed_code; + list_append_int(t->ch_errcode,t->failed_code); + } + if(arr_length(data)/2return_num){ + DBG_WARN("task=%s, data size too less.",t->brief); + }else{ + for(int i=0;ireturn_num;i++) + { + reurn_item *item=&res->items[i]; + int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8); + item->value=value; + if(list_length(t->ranges)>i) + { + if(range_in_range(list_get(t->ranges,i),value)) + item->err=0; + else{ + if(list_length(t->ret_failed_code)>i) + { + item->err=list_get_int(t->ret_failed_code,i); + list_append_int(t->ch_errcode,item->err); + } + } + } + } + } + return res; +} + + + + + +static void *json_to_errcode(cJSON *j) +{ + sch_errcode *e=calloc(1,sizeof(sch_errcode)); + param_check(e); + JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err); + JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info); + e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int()); + return e; +} + +static int _list_del_errcode(void *p) +{ + sch_errcode *e=p; + CHECK_DO(e->info,free); + CHECK_DO(e->suberr,list_delete); + return 0; +} + +static obj_def g_obj_errcode={ + .obj_size=sizeof(sch_errcode), + .to_obj_fun=json_to_errcode, + .del_fun=free, + .sub=0, + .del=_list_del_errcode +}; + + +obj_def *obj_errcode(void) +{ + return &g_obj_errcode; +} + +// 1ڷΧ +int errcode_in_range(sch_errcode *e,int subcode) +{ + param_check(e); + for(int i=0;isuberr);i++) + { + if(subcode==list_get_int(e->suberr,i)) + return 1; + } + return 0; +} + + + + + +static void *_json_to_scheme(cJSON *j) +{ + scheme_def *s=calloc(1,sizeof(scheme_def)); + param_check(s); + JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id); + JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief); + s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int()); + s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int()); + JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s); + JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max); + s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode()); + s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task()); + return s; +} + + + +static int _list_del_scheme(void *p) +{ + scheme_def *t=p; + CHECK_DO(t->brief,free); + CHECK_DO(t->slave_soft_versions,list_delete); + CHECK_DO(t->slave_hard_versions,list_delete); + CHECK_DO(t->errs,list_delete); + CHECK_DO(t->tasks,list_delete); + CHECK_DO(t->ch_errcode,list_delete); + return 0; +} + +static obj_def g_obj_scheme={ + .obj_size=sizeof(scheme_def), + .to_obj_fun=_json_to_scheme, + .del_fun=free, + .sub=0, + .del=_list_del_scheme +}; + + +obj_def *obj_scheme(void) +{ + return &g_obj_scheme; +} + + + +scheme_def *json_to_scheme(cJSON *j) +{ + param_check(j); + obj_def *obj=obj_scheme(); + scheme_def *s=obj->to_obj_fun(j); + return s; +} +void scheme_delete(scheme_def *s) +{ + obj_def *obj=obj_scheme(); + param_check(s); + obj->del(s); + obj->del_fun(s); +} + + +// idתΪֽ +#define TASKSID_MAX_SIZE 0x100 +static array_def *scheme_taskid_to_array(scheme_def *s) +{ + param_check(s); + array_def *res=arr_creat(); + param_check(res); + arr_append(res,s->plan_id&0xff); + arr_append(res,(s->plan_id>>8)&0xff); + arr_append(res,(s->plan_id>>16)&0xff); + arr_append(res,(s->plan_id>>24)&0xff); + for(int i=0;itasks);i++) + { + sch_task *t=list_get(s->tasks,i); + arr_append(res,t->task_id); + } + int size=arr_length(res); + if(sizetasks);i++) + { + sch_task *t=list_get(s->tasks,i); + array_def *a=task_to_array(t); + arr_appends_from(res,a); + arr_delete(a); + } + int size=arr_length(res); + if(sizetasks);i++) + { + sch_task *t=list_get(s->tasks,i); + num+=t->return_num; + } + return num; +} + +// 0ɹ1ʧ +int scheme_check_ack(array_def *data,int index) +{ + param_check(index>=0); + param_check(indexerrs);i++) + { + sch_errcode *e=list_get(s->errs,i); + if(errcode_in_range(e,subcode)) + return e->err; + } + return 0; +} + + +// ж +scheme_returns *scheme_check_returns(scheme_def *s,array_def *data) +{ + int size=0; + size+=sizeof(scheme_returns); + size+=sizeof(task_returns)*list_length(s->tasks); + size+=sizeof(reurn_item)*scheme_get_returns_num(s); + scheme_returns *res=malloc(size); + param_check(res); + memset(res,0,size); + res->size=size; + if(s->ch_errcode==0) s->ch_errcode= list_creat_int(); + list_clear(s->ch_errcode); + + int start=16; + int off=0; + for(int i=0;itasks);i++) + { + int ack=scheme_check_ack(data,i); + sch_task *t=list_get(s->tasks,i); + array_def *arr_temp=arr_mid(data,start,t->return_num*2); + task_returns *task_ret=task_check_returns(t,ack,arr_temp); + arr_delete(arr_temp); + memcpy(&res->data[off],task_ret,task_ret->size); + off+=task_ret->size; + start+=t->return_num*2; + list_append_from(s->ch_errcode,t->ch_errcode); + } + if(list_length(s->ch_errcode)>0) + { + res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0)); + }else{ + res->errcode=0; + } + return res; +} + + + + diff --git a/source/soft/history/myjson-.h b/source/soft/history/myjson-.h new file mode 100644 index 0000000..4159c1b --- /dev/null +++ b/source/soft/history/myjson-.h @@ -0,0 +1,156 @@ +#ifndef myjson_h__ +#define myjson_h__ + +#include "cjson.h" +#include "list.h" +#include "bytearray.h" + + + + + + + +#define JSON_GET_INT(j,v) {\ + if(j->type==cJSON_Number)\ + {\ + v=j->valueint;\ + }else{\ + DBG_WARN("%s not a int value.",#j);\ + }} + +// ȡַv==0ڴ +#define JSON_GET_STR(j,v) {\ + if(j->type==cJSON_String)\ + {\ + int len=strlen(j->valuestring)+1;\ + if(v==0){\ + v=malloc(len);\ + }\ + memcpy(v,j->valuestring,len);\ + }else{\ + DBG_WARN("%s not a str value.",#j);\ + }} + + + +typedef void *(*json_to_obj)(cJSON *j); +typedef void (*del_obj)(void *obj); +typedef struct { + int obj_size; + json_to_obj to_obj_fun; + del_obj del_fun; + + // ЩбĻص + sub_fun_def sub; + del_fun_def del; +}obj_def; + + +obj_def *obj_int(void); +obj_def *obj_str(void); +list_def *jarray_to_list(cJSON *jarray,obj_def *obj); +cJSON *json_parse(const char *jstr);/*temp_ptr*/ + + + + + +// Χ +typedef struct { + int max; + int min; +}sch_range; +obj_def *obj_range(void); +int range_in_range(sch_range *r,int num); + + + + +// +typedef struct{ + char *brief; + int task_id; + int index; + int param_num; + list_def *params_info;//str + list_def *params;//int + list_def *ranges;//sch_range + int return_num; + list_def *returns_info;//str + int err_jump; + int retry; + int failed_code; + list_def *ret_failed_code;//int + list_def *ch_errcode;//int +}sch_task; + +__packed +typedef struct{ + uint16_t value; + uint8_t err; +}reurn_item; +__packed +typedef struct{ + uint8_t size; + uint8_t index; + uint8_t id; + uint8_t ack; + uint8_t exe_err; + reurn_item items[0]; +}task_returns; + +obj_def *obj_task(void); +array_def *task_to_array(sch_task *t); +task_returns *task_check_returns(sch_task *t,int ack,array_def *data); + + + + +// +typedef struct{ + int err; + char *info; + list_def *suberr;//int +}sch_errcode; + +obj_def *obj_errcode(void); +int errcode_in_range(sch_errcode *e,int subcode); + + + +typedef struct{ + int plan_id; + char *brief; + list_def *slave_soft_versions;//int + list_def *slave_hard_versions;//int + int timeout_s; + int timeout_m; + int task_id_max; + list_def *errs;//sch_errcode + list_def *tasks;//sch_task + list_def *ch_errcode;//int +}scheme_def; + + + +obj_def *obj_scheme(void); +scheme_def *json_to_scheme(cJSON *j); +void scheme_delete(scheme_def *s); +array_def *scheme_to_byte_array(scheme_def *s); + + +__packed +typedef struct{ + uint16_t size; + uint8_t errcode; + uint8_t data[0]; +}scheme_returns; +scheme_returns *scheme_check_returns(scheme_def *s,array_def *data); + + + + + +#endif + diff --git a/source/soft/history/myjson.c b/source/soft/history/myjson.c new file mode 100644 index 0000000..7129f07 --- /dev/null +++ b/source/soft/history/myjson.c @@ -0,0 +1,556 @@ +#include "myjson.h" +#include "board.h" +#include "debug.h" +#include "mystdlib.h" +#include "bytearray.h" + + + + + +// jsonַתΪjson,ʱָ +cJSON *json_parse(const char *jstr) +{ + cJSON *json=cJSON_Parse(jstr); + if(json){ + return tappend(json,cJSON_Delete); + } + return json; +} + + + + + + +/*r{ json תб }c*/ +list_def *jarray_to_list(cJSON *jarray,obj_def *obj) +{ + param_check(obj); + param_check(obj->to_obj_fun); + param_check(obj->obj_size); + param_check(jarray); + list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0); + void *o; + int array_size; + if(jarray->type!=cJSON_Array){ + DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null"); + goto err; + } + array_size=cJSON_GetArraySize(jarray); + for(int i=0;ito_obj_fun(cJSON_GetArrayItem(jarray,i)); + if(o==0) + { + DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null"); + goto err; + } + list_append(l,o); + if(obj->del_fun) obj->del_fun(o); + } + err: + return l; +} + + +/*r{ jsonת }c*/ +static void *json_to_int(cJSON *j) +{ + if(j->type==cJSON_Number) + { + int *ret=malloc(sizeof(int)); + param_check(ret); + *ret=j->valueint; + return ret; + } + return 0; +} + + + +static obj_def g_obj_int={ + .obj_size=sizeof(int), + .to_obj_fun=json_to_int, + .del_fun=free, + .sub=INT_SUB, + .del=INT_DEL +}; + + +obj_def *obj_int(void) +{ + return &g_obj_int; +} + + + + + + + + +/*r{ jsonתַ }c*/ +static void *json_to_str(cJSON *j) +{ + if(j->type==cJSON_String) + { + int len=strlen(j->valuestring)+1; + char *ret=malloc(len); + char **ret_ptr=malloc(sizeof(char *)); + param_check(ret); + param_check(ret_ptr); + memcpy(ret,j->valuestring,len+1); + *ret_ptr=ret; + return ret_ptr; + } + return 0; +} + + + +static obj_def g_obj_str={ + .obj_size=sizeof(char *), + .to_obj_fun=json_to_str, + .del_fun=free, + .sub=STR_SUB, + .del=STR_DEL +}; + + +obj_def *obj_str(void) +{ + return &g_obj_str; +} + + + + + +static void *json_to_range(cJSON *j) +{ + sch_range *s=malloc(sizeof(sch_range)); + param_check(s); + JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max); + JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min); + if(s->min>s->max){ + DBG_WARN("range is empty."); + } + return s; +} + + + + + +static obj_def g_obj_range={ + .obj_size=sizeof(sch_range), + .to_obj_fun=json_to_range, + .del_fun=free, + .sub=0, + .del=0 +}; + + +obj_def *obj_range(void) +{ + return &g_obj_range; +} + +// 1ڷΧ +int range_in_range(sch_range *r,int num) +{ + if(num>=r->min&&num<=r->max) + return 1; + else + return 0; +} + + + + + + + + +static void *json_to_task(cJSON *j) +{ + sch_task *task=calloc(1,sizeof(sch_range)); + JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index); + JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump); + JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry); + JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num); + JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num); + task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str()); + task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str()); + task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int()); + task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range()); + JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code); + task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int()); + return task; +} + + + + +static int _list_del_task(void *p) +{ + sch_task *t=p; + CHECK_DO(t->brief,free); + CHECK_DO(t->params_info,list_delete); + CHECK_DO(t->returns_info,list_delete); + CHECK_DO(t->params,list_delete); + CHECK_DO(t->ranges,list_delete); + CHECK_DO(t->ret_failed_code,list_delete); + CHECK_DO(t->ch_errcode,list_delete); + return 0; +} + + + +static obj_def g_obj_task={ + .obj_size=sizeof(sch_task), + .to_obj_fun=json_to_task, + .del_fun=free, + .sub=0, + .del=_list_del_task +}; + + +obj_def *obj_task(void) +{ + return &g_obj_task; +} + +// תΪ +array_def *task_to_array(sch_task *t) +{ + array_def *a=arr_creat(); + arr_append(a,(uint8_t)t->task_id); + arr_append(a,(uint8_t)t->index); + arr_append(a,(uint8_t)t->retry); + arr_append(a,(uint8_t)t->err_jump); + arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4)); + for(int i=0;iparams);i++) + { + arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff)); + arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8)); + } + if(list_length(t->params)!=t->param_num) + { + DBG_WARN("name=%s param_num!=params.size().",t->brief); + } + if(t->return_num>list_length(t->returns_info)) + { + DBG_WARN("name=%s return_num>returns_info.size().",t->brief); + } + if(list_length(t->ch_errcode)!=list_length(t->ranges)) + { + DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief); + } + return a; +} + + + +// ack==0ɹ +task_returns *task_check_returns(sch_task *t,int ack,array_def *data) +{ + int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num; + task_returns *res=malloc(size); + param_check(res); + res->size=size; + memset(res,0,size); + if(t->ch_errcode==0) t->ch_errcode=list_creat_int(); + list_clear(t->ch_errcode); + res->index=t->index; + res->id=t->task_id; + res->ack=ack; + if(res->ack==0){ + res->exe_err=0; + }else{ + res->exe_err=t->failed_code; + list_append_int(t->ch_errcode,t->failed_code); + } + if(arr_length(data)/2return_num){ + DBG_WARN("task=%s, data size too less.",t->brief); + }else{ + for(int i=0;ireturn_num;i++) + { + reurn_item *item=&res->items[i]; + int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8); + item->value=value; + if(list_length(t->ranges)>i) + { + if(range_in_range(list_get(t->ranges,i),value)) + item->err=0; + else{ + if(list_length(t->ret_failed_code)>i) + { + item->err=list_get_int(t->ret_failed_code,i); + list_append_int(t->ch_errcode,item->err); + } + } + } + } + } + return res; +} + + + + + +static void *json_to_errcode(cJSON *j) +{ + sch_errcode *e=calloc(1,sizeof(sch_errcode)); + param_check(e); + JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err); + JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info); + e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int()); + return e; +} + +static int _list_del_errcode(void *p) +{ + sch_errcode *e=p; + CHECK_DO(e->info,free); + CHECK_DO(e->suberr,list_delete); + return 0; +} + +static obj_def g_obj_errcode={ + .obj_size=sizeof(sch_errcode), + .to_obj_fun=json_to_errcode, + .del_fun=free, + .sub=0, + .del=_list_del_errcode +}; + + +obj_def *obj_errcode(void) +{ + return &g_obj_errcode; +} + +// 1ڷΧ +int errcode_in_range(sch_errcode *e,int subcode) +{ + param_check(e); + for(int i=0;isuberr);i++) + { + if(subcode==list_get_int(e->suberr,i)) + return 1; + } + return 0; +} + + + + + +static void *_json_to_scheme(cJSON *j) +{ + scheme_def *s=calloc(1,sizeof(scheme_def)); + param_check(s); + JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id); + JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief); + s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int()); + s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int()); + JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s); + JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m); + JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max); + s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode()); + s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task()); + return s; +} + + + +static int _list_del_scheme(void *p) +{ + scheme_def *t=p; + CHECK_DO(t->brief,free); + CHECK_DO(t->slave_soft_versions,list_delete); + CHECK_DO(t->slave_hard_versions,list_delete); + CHECK_DO(t->errs,list_delete); + CHECK_DO(t->tasks,list_delete); + CHECK_DO(t->ch_errcode,list_delete); + return 0; +} + +static obj_def g_obj_scheme={ + .obj_size=sizeof(scheme_def), + .to_obj_fun=_json_to_scheme, + .del_fun=free, + .sub=0, + .del=_list_del_scheme +}; + + +obj_def *obj_scheme(void) +{ + return &g_obj_scheme; +} + + + +scheme_def *json_to_scheme(cJSON *j) +{ + param_check(j); + obj_def *obj=obj_scheme(); + scheme_def *s=obj->to_obj_fun(j); + return s; +} +void scheme_delete(scheme_def *s) +{ + obj_def *obj=obj_scheme(); + param_check(s); + obj->del(s); + obj->del_fun(s); +} + + +// idתΪֽ +#define TASKSID_MAX_SIZE 0x100 +static array_def *scheme_taskid_to_array(scheme_def *s) +{ + param_check(s); + array_def *res=arr_creat(); + param_check(res); + arr_append(res,s->plan_id&0xff); + arr_append(res,(s->plan_id>>8)&0xff); + arr_append(res,(s->plan_id>>16)&0xff); + arr_append(res,(s->plan_id>>24)&0xff); + for(int i=0;itasks);i++) + { + sch_task *t=list_get(s->tasks,i); + arr_append(res,t->task_id); + } + int size=arr_length(res); + if(sizetasks);i++) + { + sch_task *t=list_get(s->tasks,i); + array_def *a=task_to_array(t); + arr_appends_from(res,a); + arr_delete(a); + } + int size=arr_length(res); + if(sizetasks);i++) + { + sch_task *t=list_get(s->tasks,i); + num+=t->return_num; + } + return num; +} + +// 0ɹ1ʧ +int scheme_check_ack(array_def *data,int index) +{ + param_check(index>=0); + param_check(indexerrs);i++) + { + sch_errcode *e=list_get(s->errs,i); + if(errcode_in_range(e,subcode)) + return e->err; + } + return 0; +} + + +// ж +scheme_returns *scheme_check_returns(scheme_def *s,array_def *data) +{ + int size=0; + size+=sizeof(scheme_returns); + size+=sizeof(task_returns)*list_length(s->tasks); + size+=sizeof(reurn_item)*scheme_get_returns_num(s); + scheme_returns *res=malloc(size); + param_check(res); + memset(res,0,size); + res->size=size; + if(s->ch_errcode==0) s->ch_errcode= list_creat_int(); + list_clear(s->ch_errcode); + + int start=16; + int off=0; + for(int i=0;itasks);i++) + { + int ack=scheme_check_ack(data,i); + sch_task *t=list_get(s->tasks,i); + array_def *arr_temp=arr_mid(data,start,t->return_num*2); + task_returns *task_ret=task_check_returns(t,ack,arr_temp); + arr_delete(arr_temp); + memcpy(&res->data[off],task_ret,task_ret->size); + off+=task_ret->size; + start+=t->return_num*2; + list_append_from(s->ch_errcode,t->ch_errcode); + } + if(list_length(s->ch_errcode)>0) + { + res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0)); + }else{ + res->errcode=0; + } + return res; +} + + + + diff --git a/source/soft/history/myjson.h b/source/soft/history/myjson.h new file mode 100644 index 0000000..4159c1b --- /dev/null +++ b/source/soft/history/myjson.h @@ -0,0 +1,156 @@ +#ifndef myjson_h__ +#define myjson_h__ + +#include "cjson.h" +#include "list.h" +#include "bytearray.h" + + + + + + + +#define JSON_GET_INT(j,v) {\ + if(j->type==cJSON_Number)\ + {\ + v=j->valueint;\ + }else{\ + DBG_WARN("%s not a int value.",#j);\ + }} + +// ȡַv==0ڴ +#define JSON_GET_STR(j,v) {\ + if(j->type==cJSON_String)\ + {\ + int len=strlen(j->valuestring)+1;\ + if(v==0){\ + v=malloc(len);\ + }\ + memcpy(v,j->valuestring,len);\ + }else{\ + DBG_WARN("%s not a str value.",#j);\ + }} + + + +typedef void *(*json_to_obj)(cJSON *j); +typedef void (*del_obj)(void *obj); +typedef struct { + int obj_size; + json_to_obj to_obj_fun; + del_obj del_fun; + + // ЩбĻص + sub_fun_def sub; + del_fun_def del; +}obj_def; + + +obj_def *obj_int(void); +obj_def *obj_str(void); +list_def *jarray_to_list(cJSON *jarray,obj_def *obj); +cJSON *json_parse(const char *jstr);/*temp_ptr*/ + + + + + +// Χ +typedef struct { + int max; + int min; +}sch_range; +obj_def *obj_range(void); +int range_in_range(sch_range *r,int num); + + + + +// +typedef struct{ + char *brief; + int task_id; + int index; + int param_num; + list_def *params_info;//str + list_def *params;//int + list_def *ranges;//sch_range + int return_num; + list_def *returns_info;//str + int err_jump; + int retry; + int failed_code; + list_def *ret_failed_code;//int + list_def *ch_errcode;//int +}sch_task; + +__packed +typedef struct{ + uint16_t value; + uint8_t err; +}reurn_item; +__packed +typedef struct{ + uint8_t size; + uint8_t index; + uint8_t id; + uint8_t ack; + uint8_t exe_err; + reurn_item items[0]; +}task_returns; + +obj_def *obj_task(void); +array_def *task_to_array(sch_task *t); +task_returns *task_check_returns(sch_task *t,int ack,array_def *data); + + + + +// +typedef struct{ + int err; + char *info; + list_def *suberr;//int +}sch_errcode; + +obj_def *obj_errcode(void); +int errcode_in_range(sch_errcode *e,int subcode); + + + +typedef struct{ + int plan_id; + char *brief; + list_def *slave_soft_versions;//int + list_def *slave_hard_versions;//int + int timeout_s; + int timeout_m; + int task_id_max; + list_def *errs;//sch_errcode + list_def *tasks;//sch_task + list_def *ch_errcode;//int +}scheme_def; + + + +obj_def *obj_scheme(void); +scheme_def *json_to_scheme(cJSON *j); +void scheme_delete(scheme_def *s); +array_def *scheme_to_byte_array(scheme_def *s); + + +__packed +typedef struct{ + uint16_t size; + uint8_t errcode; + uint8_t data[0]; +}scheme_returns; +scheme_returns *scheme_check_returns(scheme_def *s,array_def *data); + + + + + +#endif + diff --git a/source/soft/list.c b/source/soft/list.c new file mode 100644 index 0000000..16d87cb --- /dev/null +++ b/source/soft/list.c @@ -0,0 +1,588 @@ +#include "list.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" +#include "board.h" +#include "mystdlib.h" +#include "debug.h" +#include "bytearray.h" +#include "rtthread.h" + +#define LIST_APPEND_SKIP 10 + + +typedef struct{ + int32_t next; + int32_t prev; + uint32_t data[0]; +}list_node_def; + + +struct _list_def{ + int32_t all; + int32_t used; + int32_t block_size; + int32_t block_size4; + rt_mutex_t mutex; + int32_t head; + int32_t tail; + sub_fun_def sub; + del_fun_def del; + str_fun_def str; + uint32_t data[0]; +}; + +//#define list_enter_mutex(l)\ +// rt_mutex_take((l)->mutex,RT_WAITING_FOREVER) +// +//#define list_exit_mutex(l)\ +// rt_mutex_release((l)->mutex) + +#define list_enter_mutex(l) +#define list_exit_mutex(l) +#define rt_mutex_create(...) 0 +#define rt_mutex_delete(l) + +list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str) +{ + static uint16_t count=0; + char s1[16]={0}; + sprintf(s1,"list_mut#%d",count); + int size=0; + int block_size4; + list_def *l; + size+=sizeof(list_def); + // 4字节对齐 + block_size4=((block_size+3)/4)*4; + size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP; + l=malloc(size); + param_check(l); + l->all=LIST_APPEND_SKIP; + l->used=0; + l->block_size=block_size; + l->block_size4=block_size4; + l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO); + l->head=-1; + l->tail=-1; + l->sub=sub; + l->del=del; + l->str=str; + + // 初始化列表 + list_node_def *node; + node=(list_node_def *)l->data; + for(int i=0;iall;i++) + { + node->next=-1; + node->prev=-1; + node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4); + } + count++; + return l; +} + + +// 对于数据里有指针数据的成员,需要提供del函数 +void _list_delete(list_def **l) +{ + param_check(l); + param_check(*l); + list_enter_mutex(*l); + if((*l)->del) + { + for(int i=0;i<(*l)->used;i++) + { + (*l)->del(list_get(*l,i)); + } + } + list_exit_mutex(*l); + rt_mutex_delete((*l)->mutex); + free(*l); + *l=0; +} + + + + + + +int list_block_size4(list_def *l) +{ + param_check(l); + return l->block_size4; +} + + +//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) +//{ +// for(int i=0;iblock_size4)*(l->all); + cpysize=size; + size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP); + r=malloc(size); + param_check(r); + cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4); + // 初始化列表 + list_node_def *node; + node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4)); + for(int i=0;inext=-1; + node->prev=-1; + node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4); + } + r->all+=LIST_APPEND_SKIP; + free(l); + return r; +} + +// 查找一个未使用的节点 +static list_node_def *list_unused_node(list_def *l,int *index) +{ + list_node_def *node=0; + node=(list_node_def *)l->data; + for(int i=0;iall;i++) + { + if((node->next==-1)&&(node->prev==-1)){ + if(index) *index=i; + return node; + } + node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4); + } + return node; +} + +// 取得指定序号的节点 +static list_node_def *list_node(list_def *l,int index) +{ + list_node_def *node; + param_check(index>=0&&indexall); + node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4)); + return node; +} + + +// 取得节点的物理索引 +static int list_phy_index(list_def *l,list_node_def *n) +{ + return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4); +} + + +/* +// 改为统一使用insert函数 +list_def *list_append(list_def **l,void *data) +{ + param_check(l); + param_check(*l); + list_def *r=*l; + if((*l)->used>=(*l)->all) + { + r=list_expend(*l); + } + list_node_def *node; + int index; + node=list_unused_node(r,&index); + param_check(node); + memcpy(node->data,data,r->block_size); + if(r->head==-1&&r->tail==-1) + { + r->head=index; + r->tail=index; + node->next=index; + node->prev=index; + } + else if(r->head!=-1&&r->tail!=-1) + { + node->prev=r->tail; + node->next=list_node(r,r->tail)->next; + list_node(r,r->tail)->next=index; + r->tail=index; + list_node(r,r->head)->prev=index; + } + else + { + param_check(0); + } + r->used++; + *l=r; + return r; +} +*/ + + + +// 返回指定index的已使用节点 +static list_node_def *list_used_node(list_def *l,int index) +{ + list_node_def *node=0; + if(index>l->used/2) + { + index=l->used-1-index; + node=list_node(l,l->tail); + for(int i=0;iprev); + } + } + else{ + node=list_node(l,l->head); + for(int i=0;inext); + } + } + return node; +} + + + + + +// 获取第index项数据,不删除 +// index支持负数,-1表示最后一项 +// 返回数据引用 +void *list_get(list_def *l,int index) +{ + param_check(l); + void *ret=0; + list_enter_mutex(l); + list_node_def *node; + if(index<0) index=l->used+index; + if((index>=0&&indexused)==0) + ret=0; + else{ + node=list_used_node(l,index); + param_check(node); + ret=node->data; + } + list_exit_mutex(l); + return ret; +} + + +// 删除第index项数据 +// index支持负数,-1表示最后一项 +void list_remove(list_def *l,int index) +{ + param_check(l); + list_node_def *node; + int phy_index; + if(index<0) index=l->used+index; + list_enter_mutex(l); + if((index>=0&&indexused)){ + node=list_used_node(l,index); + param_check(node); + phy_index=list_phy_index(l,node); + if(l->used==1) + { + l->head=-1; + l->tail=-1; + } + else + { + if(l->head==phy_index) + { + l->head=node->next; + } + if(l->tail==phy_index) + { + l->tail=node->prev; + } + list_node(l,node->prev)->next=node->next; + list_node(l,node->next)->prev=node->prev; + } + node->next=-1; + node->prev=-1; + if(l->del) l->del(node->data); + l->used--; + } + list_enter_mutex(l); +} + + +// 获取指定index的数据,随后删除 +// 返回数据的临时指针 +// 对于存在动态指针的对象,由于take之后会自动删除,take操作会出现野指针 +// 建议使用list_get + list_remove的方式代替list_take +void *list_take(list_def *l,int index) +{ + param_check(l); + void *p; + p=list_get(l,index); + void *t=tmalloc(l->block_size); + param_check(t); + memcpy(t,p,l->block_size); + list_remove(l,index); + return t; +} + + +// 清空 +void list_clear(list_def *l) +{ + param_check(l); + list_enter_mutex(l); + while(l->used>0) + { + list_remove(l,0); + } + list_exit_mutex(l); +} + + +int list_length(list_def *l) +{ + param_check(l); + return l->used; +} + + + + +// 在指定位置插入 +// index为节点插入之后所在的位置 +list_def *_list_insert(list_def **l,void *data,int index) +{ + param_check(l); + param_check(*l); + list_enter_mutex(*l); + if(index<0) index=(*l)->used+index+1; + if((index>=0&&index<=(*l)->used)==0){ + list_exit_mutex(*l); + return *l; + } + list_def *r=*l; + if((*l)->used>=(*l)->all) + { + r=list_expend(*l); + } + list_node_def *node; + int phy_index; + node=list_unused_node(r,&phy_index); + param_check(node); + memcpy(node->data,data,r->block_size); + if(r->head==-1&&r->tail==-1) + { + r->head=phy_index; + r->tail=phy_index; + node->next=phy_index; + node->prev=phy_index; + } + else if(r->head!=-1&&r->tail!=-1) + { + list_node_def *n; + int n_phy_index; + if(indexused) + { + n=list_used_node(r,index); + n_phy_index=list_phy_index(r,n); + list_node(r,n->prev)->next=phy_index; + node->prev=n->prev; + node->next=n_phy_index; + n->prev=phy_index; + if(index==0) + { + r->head=phy_index; + } + } + else + { + node->prev=r->tail; + node->next=list_node(r,r->tail)->next; + list_node(r,r->tail)->next=phy_index; + r->tail=index; + list_node(r,r->head)->prev=phy_index; + } + } + else + { + param_check(0); + } + r->used++; + *l=r; + list_exit_mutex(*l); + return r; +} + + +void list_sort(list_def *l) +{ + param_check(l); + list_enter_mutex(l); + if(l->sub){ + _list_sort(l,l->sub); + } + else{ + DBG_WARN("obj->sub fun is null."); + } + list_exit_mutex(l); +} + + + + +// 在列表内返回1,不在返回0 +int list_contains(list_def *l,void *d) +{ + param_check(l); + list_enter_mutex(l); + if(l->sub) + { + for(int i=0;isub(list_get(l,i),d)==0){ + list_exit_mutex(l); + return 1; + } + } + } + else{ + DBG_WARN("obj->sub fun is null."); + } + list_exit_mutex(l); + return 0; +} + + +// 交换两个位置 +void list_swap(list_def *l,int index_a,int index_b) +{ + param_check(l); + list_enter_mutex(l); + void *a_=list_get(l,index_a); + void *b_=list_get(l,index_b); + void *t_=0; + if(a_&&b_) + { + t_=calloc(1,sizeof(l->block_size4)); + cpy4byte(t_,a_,l->block_size4/4); + cpy4byte(a_,b_,l->block_size4/4); + cpy4byte(b_,t_,l->block_size4/4); + free(t_); + } + list_exit_mutex(l); +} + + +// 向后循环移动 +void list_shift(list_def *l) +{ + param_check(l); + list_enter_mutex(l); + if(l->used>0){ + l->head=list_node(l,l->head)->next; + l->tail=list_node(l,l->tail)->next; + } + list_exit_mutex(l); +} + + + + + +// 输出打印字符串 +char *list_string(list_def *l) +{ + param_check(l); + list_enter_mutex(l); + array_def *d=arr_creat(); + param_check(d); + int len=0; + char *s=0; + arr_append(d,'('); + if(l->str) + { + for(int i=0;istr(list_get(l,i)); + len=strlen(s); + arr_appends(d,s,len); + free(s); + arr_append(d,','); + arr_append(d,' '); + } + } + arr_append(d,')'); + len=arr_length(d); + s=malloc(len+1); + param_check(s); + memcpy(s,arr_data(d),len); + arr_delete(d); + s[len]=0; + list_exit_mutex(l); + return s; +} + + + + + +// int sub函数 +int _list_int_sub(void *a,void *b) +{ + return *(int *)a-*(int *)b; +} + + +// int 打印函数 +char *_list_int_str(void *a) +{ + char *s=malloc(20); + param_check(s); + sprintf(s,"%d",*(int *)a); + return s; +} + + +// str sub函数 +int _list_str_sub(void *a,void *b) +{ + char *a_=*(char **)a; + char *b_=*(char **)b; + return strcmp(a_,b_); +} + + +// str删除函数 +int _list_str_del(void *d) +{ + char **c=d; + if(*c) free(*c); + return 0; +} + +// str 打印函数 +char *_list_str_str(void *a) +{ + char *a_=*(char **)a; + int len=strlen(a_); + char *s=malloc(len+1); + param_check(s); + memcpy(s,a_,len+1); + return s; +} + + + +// 延迟删除,不需要修改指针 +void _list_delete_later(list_def *l) +{ + _list_delete(&l); +} + + + diff --git a/source/soft/list.h b/source/soft/list.h new file mode 100644 index 0000000..ed6bc7b --- /dev/null +++ b/source/soft/list.h @@ -0,0 +1,90 @@ +#ifndef list_h__ +#define list_h__ + +#include "stdint.h" +#include "stdlib.h" + + + +struct _list_def; +typedef struct _list_def list_def; + + + +typedef int (*sub_fun_def)(void *a,void *b); +typedef int (*del_fun_def)(void *p); +// 生成打印字符串指针,列表获取后会使用free释放 +typedef char *(*str_fun_def)(void *p); + +#define INT_SUB _list_int_sub +#define INT_DEL 0 +#define INT_STR _list_int_str +#define STR_SUB _list_str_sub +#define STR_DEL _list_str_del +#define STR_STR _list_str_str + + +/*r{ 基本操作函数 }c*/ +list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str); +void *list_get(list_def *l,int index); +void list_remove(list_def *l,int index); +void *list_take(list_def *l,int index);/*temp_ptr*/ +void list_clear(list_def *l); +int list_length(list_def *l); +int list_block_size4(list_def *l); +void list_sort(list_def *l); +int list_contains(list_def *l,void *d); +void list_swap(list_def *l,int index_a,int index_b); +char *list_string(list_def *l); +void list_shift(list_def *l); + + + + +/*r{ 宏函数 }c*/ +#define list_creat_int() list_creat(sizeof(int),INT_SUB,INT_DEL,INT_STR) +#define list_creat_str() list_creat(sizeof(char *),STR_SUB,STR_DEL,STR_STR) +#define list_delete(l) _list_delete(&(l)) +#define list_insert(l,data,index) _list_insert(&(l),data,index) +#define list_append(l,data) list_insert(l,data,-1) +#define list_insert_int(l,int_,index) list_insert(l,(uint32_t []){int_},index) +#define list_append_int(l,int_) list_insert_int(l,int_,-1) +#define list_append_str(l,str) list_insert_str(l,str,-1) +#define list_get_int(l,index) (*(int *)list_get(l,index)) +#define list_get_str(sl,index) (*(char **)list_get(sl,index)) +#define list_take_str(sl,index) (*(char **)list_take(sl,index)) +#define list_take_int(l,index) (*(int *)list_take(l,index)) +#define list_insert_str(l,str,index)\ + {\ + char *c=malloc(strlen(str)+1);\ + param_check(c);\ + memcpy(c,str,strlen(str)+1);\ + list_insert(l,(uint32_t []){(uint32_t)(c)},index);} +// 要保证a,b的类型相同 +#define list_append_from(a,b) \ + for(int i=0;itimer); + if(l->later_fun){ + l->later_fun(l->t); + } + free(l); +} + +// 延迟一段时间调用函数 +void later_execute(void (*fun)(void *t),void *t,int ms) +{ + static uint16_t count; + char s1[16]={0}; + sprintf(s1,"later_t#%d",count); + later_def *l=calloc(1,sizeof(later_def)); + l->later_fun=fun; + l->t=t; + l->timer=rt_timer_create(s1,later_fun_exe,l, + rt_tick_from_millisecond(ms), + RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER); + rt_timer_start(l->timer); + count++; +} + + + + + + + diff --git a/source/soft/mymisc.h b/source/soft/mymisc.h new file mode 100644 index 0000000..a6ab32b --- /dev/null +++ b/source/soft/mymisc.h @@ -0,0 +1,20 @@ +#ifndef mymisc_h__ +#define mymisc_h__ + + + + + +void later_execute(void (*fun)(void *t),void *t,int ms); + + + + + + + + + + +#endif + diff --git a/source/soft/mystdlib.c b/source/soft/mystdlib.c new file mode 100644 index 0000000..1b5b29e --- /dev/null +++ b/source/soft/mystdlib.c @@ -0,0 +1,352 @@ + +#include "stdint.h" +#include "string.h" +#include "rtthread.h" +#include "board.h" +#include "debug.h" + + +typedef struct +{ + uint8_t *membase; // 内存池 + uint8_t memrdy; // 内存管理是否就绪 + uint16_t *memmap; // 内存管理状态表 + // 内存管理参数 + uint32_t memtblsize ; // 内存表大小 + uint32_t memblksize; // 内存分块大小 + uint32_t memsize ; // 内存总大小 + void *mutex; +}mallco_dev; + + + + + +#define SRAM_USER_SIZE (64*1024) +#define MEM_BLOCK_SIZE (32) +#define MEM_MAX_SIZE (((SRAM_USER_SIZE))*MEM_BLOCK_SIZE/(MEM_BLOCK_SIZE+2)) +#define MEM_ALLOC_TABLE_SIZE ((MEM_MAX_SIZE/MEM_BLOCK_SIZE)&(~3)) +#define SRAM_USER_ADDR ((uint32_t)g_sram_mem) + +//分配的内存都是双字对齐的 +#define MEM_BASE ((uint8_t *)(SRAM_USER_ADDR+MEM_ALLOC_TABLE_SIZE*2)) +#define MEMMAP_BASE ((uint16_t *)(SRAM_USER_ADDR)) + +static uint8_t g_sram_mem[SRAM_USER_SIZE]; +//内存管理控制器 +static mallco_dev g_self; + + + + +//内存管理初始化 +void mem_init(void) +{ + mallco_dev *self=&g_self; + if(self->memrdy) return; + + self->memtblsize = MEM_ALLOC_TABLE_SIZE; + self->memblksize = MEM_BLOCK_SIZE; + self->memsize = MEM_MAX_SIZE; + self->membase=MEM_BASE; + self->memmap=MEMMAP_BASE; + + memset(self->memmap, 0,self->memtblsize*2); + memset(self->membase, 0,self->memsize); + self->mutex=rt_mutex_create("mem",RT_IPC_FLAG_FIFO); + self->memrdy=1; +} + + + +// 获取内存使用率 +// 返回值:使用率(0~100) +int mem_perused(void) +{ + mallco_dev *self=&g_self; + uint32_t used=0; + uint32_t i; + for(i=0;imemtblsize;i++) + { + if(self->memmap[i])used++; + } + //return (used*100)/(self->memtblsize); + return used; +} + + + + + + + +// 内存分配(内部调用) +// size:要分配的内存大小(字节) +// 返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址 +static uint32_t mem_malloc(uint32_t size) +{ + mallco_dev *self=&g_self; + signed long offset=0; + uint16_t nmemb; + uint16_t cmemb=0; + uint32_t i; + uint32_t ret=0xffffffff; + if(size==0)return ret; + rt_mutex_take(self->mutex,RT_WAITING_FOREVER); + nmemb=size/self->memblksize; + if(size%self->memblksize)nmemb++; + for(offset=self->memtblsize-1;offset>=0;offset--) + { + if(!self->memmap[offset])cmemb++; + else cmemb=0; + if(cmemb==nmemb) + { + for(i=0;imemmap[offset+i]=nmemb; + } + ret= (offset*self->memblksize); + break; + } + } + rt_mutex_release(self->mutex); + return ret; +} + +//释放内存(内部调用) +//offset:内存地址偏移 +//返回值:0,释放成功;1,释放失败; +static int mem_free(uint32_t offset) +{ + mallco_dev *self=&g_self; + int i; + int ret=1; + rt_mutex_take(self->mutex,RT_WAITING_FOREVER); + if(offsetmemsize) + { + int index=offset/self->memblksize; + int nmemb=self->memmap[index]; + for(i=0;imemmap[index+i]=0; + } + ret= 0; + } + rt_mutex_release(self->mutex); + return ret; +} + + + + + +void *malloc(uint32_t size) +{ + mallco_dev *self=&g_self; + uint32_t offset; + void *ret_addr=NULL; + offset=mem_malloc(size); + if (offset!=0XFFFFFFFF) + { + ret_addr=(void*)((uint32_t)self->membase+offset); + } + return ret_addr; +} + + + +static void self_free(void *ptr) +{ + mallco_dev *self=&g_self; + uint32_t offset; + if(ptr==NULL) + { + return; + } + else + { + offset=(uint32_t)ptr-(uint32_t)self->membase; + mem_free(offset); + } +} + + +void *calloc(size_t nmemb, size_t size) +{ + void *p; + p=malloc(nmemb*size); + if(p) memset(p,0,size); + return p; +} + + +void *realloc(void *p,size_t size) +{ + param_check(0); + return NULL; +} + + + +#define MEM_TEMP_PTR_NUM 400 +typedef void (*del_fun_def)(void *t); + +typedef struct{ + void *temp_ptr[MEM_TEMP_PTR_NUM]; + void *del_ptr[MEM_TEMP_PTR_NUM]; + int used; + uint32_t bitmap[(MEM_TEMP_PTR_NUM+31)/32]; + void *mutex; +}temp_def; +static temp_def g_tempptr; + + +// 在位图中找到一个0/1 +static int bitmap_find(uint32_t *bitmap,int num,int bit) +{ + for(int i=0;iusedbitmap,MEM_TEMP_PTR_NUM,0); + param_check(index>=0); + t->temp_ptr[index]=p; + t->del_ptr[index]=del_fun; + bitmap_set(t->bitmap,index); + ret= p; + t->used++; + } + else{ + param_check(0); + } + if(ret==NULL) ((del_fun_def)del_fun)(p); + return ret; +} + +// 查询指针是否已存在 +static int tempptr_find(temp_def *t,void *p) +{ + int index; + for(int i=0;ibitmap,i)) + { + if(t->temp_ptr[i]==p) + { + return 1; + } + } + } + return 0; +} + + + +static void tempptr_free(void) +{ + int index; + void *p=NULL; + del_fun_def del=NULL; + temp_def *t=&g_tempptr; + rt_mutex_take(t->mutex,RT_WAITING_FOREVER); + if(index=bitmap_find(t->bitmap,MEM_TEMP_PTR_NUM,1),index>=0) + { + // DBG_LOG("%s:free tempptr",__func__); + p=t->temp_ptr[index]; + t->temp_ptr[index]=0; + del=(del_fun_def)t->del_ptr[index]; + bitmap_clear(t->bitmap,index); + t->used--; + } + rt_mutex_release(t->mutex); + if(del) del(p); +} + + +void tempptr_init(void) +{ + temp_def *t=&g_tempptr; + t->mutex=rt_mutex_create("tempptr",RT_IPC_FLAG_FIFO); + rt_thread_idle_sethook(tempptr_free); +} + + + + +// 申请临时内存,在任务结束后自动释放 +void *tmalloc(uint32_t size) +{ + void *p; + temp_def *t=&g_tempptr; + p=malloc(size); + rt_mutex_take(t->mutex,RT_WAITING_FOREVER); + p=tempptr_append(&g_tempptr,p,NULL); + rt_mutex_release(t->mutex); + return p; +} + +// 把指针添加为临时指针 +void *tappend(void *p,void *del) +{ + mallco_dev *self=&g_self; + temp_def *t=&g_tempptr; + void *ret=NULL; + rt_mutex_take(t->mutex,RT_WAITING_FOREVER); + if(((uint32_t)p>=(uint32_t)self->membase)&& + ((uint32_t)p<(uint32_t)(self->membase+self->memsize))) + { + if(tempptr_find(t,p)==0) + { + ret= tempptr_append(t,p,del); + } + } + rt_mutex_release(t->mutex); + return ret; +} + + + +// 释放内存,如果在临时表中则退出 +void free(void *p) +{ + if(p==NULL) return; + mallco_dev *self=&g_self; + temp_def *t=&g_tempptr; + int ret=0; + rt_mutex_take(t->mutex,RT_WAITING_FOREVER); + ret=tempptr_find(t,p); + rt_mutex_release(t->mutex); + if(ret){ + return; + }else{ + self_free(p); + } +} + + + diff --git a/source/soft/mystdlib.h b/source/soft/mystdlib.h new file mode 100644 index 0000000..88935ac --- /dev/null +++ b/source/soft/mystdlib.h @@ -0,0 +1,27 @@ +#ifndef mystdlib_h__ +#define mystdlib_h__ + +#include "stdint.h" + + + +void mem_init(void); + +int mem_perused(void); + +void tempptr_init(void); + +void *tmalloc(uint32_t size); + +void *tappend(void *p,void *del); + + + + + + + + + +#endif + diff --git a/source/soft/mystring.c b/source/soft/mystring.c new file mode 100644 index 0000000..da63f8b --- /dev/null +++ b/source/soft/mystring.c @@ -0,0 +1,344 @@ + + +#include "stdlib.h" +#include "mystdlib.h" +#include "mystring.h" +#include "bytearray.h" +#include "board.h" +#include "string.h" + +/* +* +* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0 +* 例如 char *s=str_find_char_right("abcdef",'c') +* s="cdef" +* +*/ +const char *str_find_char_right(const char *s,char c) +{ + while(*s){ + if(*s==c) return s; + s++; + } + return 0; +} + + +/* +* +* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0, +* 指针p是向右检索的终点 +* 例如 char *s=str_find_char_right("abcdef",'c') +* s="cdef" +* +*/ +const char *str_find_char_right_p(const char *s, const char *const p, char c) +{ + while (*s++) + { + if (*s == c) return s; + if (s >= p) break; + } + return 0; +} + + + +/* +* +* 从右向左找到字符串s中首次出现字符c的指针,没找到返回0 +* 指针p是向左检索的终点,s检索开始 +* char *t="abcdef"; +* char *s; +* s=str_find_char_left(t,t+4,'b'); +* s="bcdef" +* +*/ +const char *str_find_char_left(const char *const p,const char *s,char c) +{ + while(*s--) + { + if(*s==c) return s; + if(s<=p) break; + } + return 0; +} + + +/* +* +* 计算字符串 s 的长度 +* +*/ +int str_len(const char *s) +{ + int len=0; + while(*s++) len++; + return len; +} + + +/* +* +* 把 s2 中的内容复制到 s1 中,长度为 n +* +*/ +void str_memcpy(char *s1,const char *s2,int n) +{ + while(n--) + *s1++=*s2++; +} + + + + + +/* +* +* 把 s2 中第一个 c 字符前的字符复制到 s1 中,如果没找到则全部复制,返回复制的字符个数 +* +*/ +int str_cpystr(char *s1,const char *s2,char c) +{ + int len; + const char *str=str_find_char_right((char *)s2,c); + if(str==0) len=str_len(s2); + else len=str-s2; + str_memcpy(s1,s2,len); + s1[len]=0; + return len; +} + + + + +/* +* +* 把整数字符串传化为int,直到遇到非数字字符 +* +*/ +static int str_ainttoi(const char *s) +{ + int ret=0; + int sig=1; + if(*s=='-'){ + s++; + sig=-1; + } + while(*s) + { + if(*s>='0'&&*s<='9') + { + ret*=10; + ret+=*s-'0'; + } + else return ret; + s++; + } + return ret*sig; +} +int str_ahextoi(const char *s) +{ + int ret=0; + while(*s) + { + if(*s>='0'&&*s<='9') + { + ret*=16; + ret+=*s-'0'; + } + else if(*s>='a'&&*s<='f') + { + ret*=16; + ret+=*s-'a'+10; + } + else if(*s>='A'&&*s<='F') + { + ret*=16; + ret+=*s-'A'+10; + } + else return ret; + s++; + } + return ret; +} +int str_atoi(const char *s) +{ + if(s[0]=='0'&&((s[1]=='x')||(s[1]=='X'))){ + return str_ahextoi(&s[2]); + }else{ + return str_ainttoi(s); + } +} + + + +/* +* +* 把字符串以字符c分割为列表 +* +*/ +list_def *str_split(const char *s,char c) +{ + int len=str_len(s)+1; + char *t=malloc(len); + char *ptr1,*ptr2; + list_def *l=list_creat_str(); + str_memcpy(t,s,len); + ptr1=t; + ptr2=t; + while(*ptr1) + { + if(*ptr1==c){ + *ptr1=0; + list_append_str(l,ptr2); + ptr2=ptr1+1; + } + ptr1++; + } + list_append_str(l,ptr2); + free(t); + return list_temp(l); +} + + + + + +/* +* +* 把字符串转化为数字列表,每个数字之间分隔符是c +* +*/ +list_def *str_atod_list(const char *s, char c) +{ + list_def *sl=str_split(s,c); + list_def *dl=list_creat_int(); + for(int i=0;i=' '&&str[i]<='~'))) + return 0; + } + return 1; +} + + + + + +/* +* +* 去除字符串中多余的空白字符 '\t', '\n', '\v', '\f', '\r', and ' ',返回临时指针 +* +*/ +char *str_simplified(const char *str) +{ + int is_empty=0; + array_def *arr=arr_creat(); + param_check(arr); + while(str_is_empty_char(*str)){ + str++; + } + while(*str){ + if(str_is_empty_char(*str)==0){ + if(is_empty==1){ + arr_append(arr,' '); + is_empty=0; + } + arr_append(arr,*str); + }else{ + is_empty=1; + } + str++; + } + char *ret=tmalloc(arr_length(arr)+1); + param_check(ret); + memcpy(ret,arr_data(arr),arr_length(arr)); + ret[arr_length(arr)]=0; + arr_delete(arr); + return ret; +} + + + + + +/* +* +* 给字符串指针设置值 +* +*/ +void _str_set(char **p,const char *str) +{ + param_check(p); + int len=0; + if(str) + len=str_len(str); + else + len=0; + if(*p!=0) + { + free(*p); + } + *p=malloc(len+1); + str_cpystr(*p,str,len); + (*p)[len]=0; +} + + + +/* +* +* 创建一个字符串副本 +* +*/ +char *str_duplicate(char *p) +{ + int len=str_len(p); + char *s=malloc(len+1); + param_check(s); + str_cpystr(s,p,len+1); + return s; +} + + + diff --git a/source/soft/mystring.h b/source/soft/mystring.h new file mode 100644 index 0000000..9f4caf6 --- /dev/null +++ b/source/soft/mystring.h @@ -0,0 +1,50 @@ +#ifndef mystring_h__ +#define mystring_h__ + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +const char *str_find_char_right(const char *s, char c); +const char *str_find_char_right_p(const char *s,const char *const p, char c); +const char *str_find_char_left(const char *const p,const char *s, char c); +int str_ahextoi(const char *s); +int str_atoi(const char *s); +int str_len(const char *s); +int str_cpystr(char *s1, const char *s2, char c); +list_def *str_split(const char *s,char c);/*temp_ptr*/ +list_def *str_atod_list(const char *s, char c);/*temp_ptr*/ +char *str_simplified(const char *str);/*temp_ptr*/ +char *str_duplicate(char *p); +int str_is_print_str(const char *str,int len); + + + + + +#define str_set(p,str) _str_set(&p,str) +#define str_temp(p) tappend(p,0) + + +void _str_set(char **p,const char *str); + + +#ifdef __cplusplus +} +#endif + + + + + + + + + + +#endif + diff --git a/source/soft/signal.c b/source/soft/signal.c new file mode 100644 index 0000000..d3908b1 --- /dev/null +++ b/source/soft/signal.c @@ -0,0 +1,296 @@ + + +#include "signal.h" +#include "board.h" +#include "stdlib.h" +#include "stdio.h" +#include "debug.h" + + + + + + +typedef struct{ + void *mutex; + signal_list *head; +}self_def; + + +static self_def g_self; + + + +int signal_init(void) +{ + self_def *s=&g_self; + if(s->mutex==0) + { + s->mutex=rt_mutex_create("signal_",RT_IPC_FLAG_FIFO); + } + return 0; +} + + + + + + + +static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) +{ + for(int i=0;irun) + { + rt_mq_recv(s->mb,msg,msg_size,RT_WAITING_FOREVER); + SLOT_FUN_RUN(msg->fun,msg->param); + } + free(msg); +} + + + +// 创建一个线程 +sig_thread thread_creat(int pro) +{ + static uint16_t count=0; + char name[20]={0}; + slot_run_def *run=calloc(1,sizeof(slot_run_def)); + run->run=1; + sprintf(name,"sig_mq#%d",count); + run->mb=rt_mq_create(name,(sizeof(slot_msg_def)+sizeof(uint32_t)*8),50,RT_IPC_FLAG_FIFO); + sprintf(name,"sig_t#%d",count); + rt_thread_t rt_t=rt_thread_create(name,slot_run,run,2048,pro,20); + rt_thread_startup(rt_t); + count++; + return run->mb; +} + + +void thread_delete(sig_thread t) +{ + // 删除线程需要删除与此线程相关的所有信号槽 + // 删除消息队列 + param_check(0); +} + + +// 如果这个类的信号已注册 +static signal_list *find(void *sig_obj,void *signal_) +{ + self_def *s=&g_self; + signal_list *l=s->head; + while(l!=0) + { + if(l->signal_==signal_&&l->sig_obj==sig_obj) + return l; + l=l->next; + } + return 0; +} + + +int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) +{ + self_def *s=&g_self; + signal_def *sig; + sig=signal_find(signal_); + if(sig==0) return -1; + rt_mutex_take(s->mutex,RT_WAITING_FOREVER); + slot_list *slo=calloc(1,sizeof(slot_list)); + param_check(slo); + slo->fun=slot; + slo->mb=t; + slo->next=0; + slo->obj=slot_obj; + signal_list *sig_l=find(sig_obj,signal_); + + if(sig_l==0){ + sig_l=calloc(1,sizeof(signal_list)); + param_check(sig_l); + sig_l->signal_=signal_; + sig_l->sig_obj=sig_obj; + sig_l->next=s->head; + s->head=sig_l; + } + slo->next=sig_l->head; + sig_l->head=slo; + //DBG_LOG("signal connect:%08x",slo); + rt_mutex_release(s->mutex); + return 0; +} + + + +int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) +{ + self_def *s=&g_self; + signal_list *sig; + sig=find(sig_obj,signal_); + if(sig==0) return -1; + int ret=-1; + rt_mutex_take(s->mutex,RT_WAITING_FOREVER); + slot_list *next=sig->head; + slot_list *prev=0; + while(next!=0) + { + if(next->fun==slot&&next->obj==slot_obj) + { + if(prev) prev->next=next->next; + else sig->head=next->next; + //DBG_LOG("signal disconnect:%08x",next); + free(next); + ret=0; + break; + } + prev=next; + next=next->next; + } + rt_mutex_release(s->mutex); + return ret; +} + + +// 消除与指定对象相关的所有信号槽连接 +int disconnect_sig(void *sig_obj) +{ + self_def *s=&g_self; + rt_mutex_take(s->mutex,RT_WAITING_FOREVER); + signal_list *sig=s->head; + signal_list *prev_sig=0; + while(sig!=0) + { + if(sig->sig_obj==sig_obj) + { + slot_list *next=sig->head; + while(next!=0) + { + sig->head=next->next; + free(next); + next=sig->head; + } + if(prev_sig) prev_sig=sig->next; + else s->head=sig->next; + free(sig); + break; + } + prev_sig=sig; + sig=sig->next; + } + rt_mutex_release(s->mutex); + return 0; +} + + +// 消除与指定对象相关的所有信号槽连接 +int disconnect_slot(void *slot_obj) +{ + self_def *s=&g_self; + rt_mutex_take(s->mutex,RT_WAITING_FOREVER); + signal_list *sig=s->head; + while(sig!=0) + { + slot_list *next=sig->head; + slot_list *prev=0; + while(next!=0) + { + if(next->obj==slot_obj) + { + if(prev) prev->next=next->next; + else sig->head=next->next; + free(next); + break; + } + prev=next; + next=next->next; + } + sig=sig->next; + } + rt_mutex_release(s->mutex); + return 0; +} + + + + +signal_def *signal_find(void *signal_) +{ + extern const int signalstruct$$Base; + extern const int signalstruct$$Limit; + signal_def *start=(signal_def *)&signalstruct$$Base; + signal_def *end=(signal_def *)&signalstruct$$Limit; + for(signal_def *t=start;tsignal_==signal_) + { + return t; + } + } + return 0; +} + + +// 发送信号 +int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num) +{ + self_def *s=&g_self; + signal_list *sig=find(sig_obj,signal_); + if(sig==0) return -1; + if(param_num>7) return -2; + int size=sizeof(slot_msg_def)+sizeof(uint32_t)*(8); + slot_msg_def *m=malloc(size); + rt_mutex_take(s->mutex,RT_WAITING_FOREVER); + slot_list *h=sig->head; + m->param_num=param_num; + m->src=signal_; + while(h) + { + m->fun=h->fun; + if(h->obj) + { + cpy4byte(m->param+1,param,param_num); + m->param[0]=(uint32_t)h->obj; + }else{ + cpy4byte(m->param,param,param_num); + } + if(h->mb){ + rt_mq_send(h->mb,m,size); + }else{ + SLOT_FUN_RUN(m->fun,m->param); + } + h=h->next; + } + rt_mutex_release(s->mutex); + free(m); + return 0; +} + + + + + + + + + + diff --git a/source/soft/signal.h b/source/soft/signal.h new file mode 100644 index 0000000..068a5b9 --- /dev/null +++ b/source/soft/signal.h @@ -0,0 +1,96 @@ +#ifndef signal_h__ +#define signal_h__ + + +#include "stdint.h" +#include "rtthread.h" +#include +#include "string.h" + + + + +#define signal void +#define emit + +typedef struct _slot_list{ + struct _slot_list *next; + void *fun; + void *mb; + void *obj; +}slot_list; + + +typedef struct _signal_list{ + struct _signal_list *next; + slot_list *head; + void *sig_obj; + void *signal_; +}signal_list; + + + + +typedef struct{ + const char *name; + void *signal_; +// slot_list *head; +}signal_def; + + +typedef struct{ + void *fun; + void *src; + int param_num; + uint32_t param[0]; +}slot_msg_def; + + + + +typedef struct{ + void *mb; + int run; +}slot_run_def; + + +typedef void * sig_thread; + + + + + + + +#define signal_export(name_) \ + const static char __sig_##name_##_name[] SECTION(".rodata.sigstr") = #name_; \ + RT_USED static signal_def _signal_##name_ SECTION("signalstruct")= \ + {\ + .name=__sig_##name_##_name,\ + .signal_=name_,\ + }; + + + +sig_thread thread_creat(int pro); +void thread_delete(sig_thread t); +signal_def *signal_find(void *signal_); +int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot); +int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot); +int signal_init(void); +int disconnect_sig(void *sig_obj); +int disconnect_slot(void *slot_obj); + + + + + + + + +int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num); + + + +#endif + diff --git a/source/soft/sort.c b/source/soft/sort.c new file mode 100644 index 0000000..5b10a91 --- /dev/null +++ b/source/soft/sort.c @@ -0,0 +1,131 @@ + +#include "list.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" +#include "board.h" +#include "mystdlib.h" + + + + + + +// 计算对应节点序号 +#define GET_FATHER_INDEX(index) (((index)-1)/2) +#define GET_LEFT_INDEX(index) ((((index)+1)*2)-1) +#define GET_RIGHT_INDEX(index) (((index)+1)*2) + + + + + +//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) +//{ +// for(int i=0;i0) + { + cpy4byte(temp,l_left,temp_size/4); + index = left; + } + else + { + cpy4byte(temp,l_right,temp_size/4); + index = right; + } + } + else if (left < size) + { + cpy4byte(temp,l_left,temp_size/4); + index = left; + } + else + { + // 序号超出堆范围 + break; + } + // 子节点比父节点小 + l_i=list_get(l,i); + if(sub(temp,l_i)<=0) + break; + l_index=list_get(l,index); + //array[index] = array[i]; + cpy4byte(l_index,l_i,temp_size/4); + //array[i] = temp; + cpy4byte(l_i,temp,temp_size/4); + i = index; + } + free(temp); +} + + + + + +// 把序列初始化为大顶堆 +static void heap_init(list_def *l, sub_fun_def sub,int size) +{ + // 最后一层没有子节点,所以从倒数第二层开始 + // 当然,从最后一层开始也不影响结果 + for (int i = size/2; i > 0; i--) + { + heap_sink(l, sub,i - 1, size); + } +} + + +void _list_sort(list_def *l,sub_fun_def sub) +{ + param_check(l); + param_check(sub); + int temp_size=list_block_size4(l); + void *temp=malloc(temp_size); + void *l_i,*l_0; + int size=list_length(l); + heap_init(l, sub,size); + //heap_print(array, size); + for (int i = size; i > 0; i--) + { + l_0=list_get(l,0); + l_i=list_get(l,i-1); + //temp = array[0]; + cpy4byte(temp,l_0,temp_size/4); + //array[0] = array[i-1]; + cpy4byte(l_0,l_i,temp_size/4); + //array[i - 1] = temp; + cpy4byte(l_i,temp,temp_size/4); + heap_sink(l,sub,0, i - 1); + } + free(temp); +} + + + + diff --git a/source/soft/sort.h b/source/soft/sort.h new file mode 100644 index 0000000..e69de29