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