Browse Source

平峰项目测试,增加ringbuffer和RTT打印,仍然存在重启问题,重启地点在字符串分割和read_ringbuffer的memcpy中

LAPTOP-KB7QFH2U\ChenJie-PC 2 years ago
parent
commit
2945053610

+ 2 - 0
.cproject

@@ -39,6 +39,7 @@
 								<option id="com.nxp.s32ds.cle.arm.mbs.arm32.bare.tool.c.compiler.option.target.sysroot.2141010934" name="Sysroot" superClass="com.nxp.s32ds.cle.arm.mbs.arm32.bare.tool.c.compiler.option.target.sysroot" useByScannerDiscovery="false" value="--sysroot=&quot;${S32DS_ARM32_NEWLIB_DIR}&quot;" valueType="string"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.203066772" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
 									<listOptionValue builtIn="false" value="../FreeRTOS/Source/include"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cm_backtrace}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
 									<listOptionValue builtIn="false" value="../RTD/include"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS/Source/portable/GCC/ARM_CM4F}&quot;"/>
@@ -192,6 +193,7 @@
 						<entry excluding="Linker_Files|Debugger" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Project_Settings"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="RTD"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="board"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cm_backtrace"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="generate"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
 					</sourceEntries>

+ 1 - 0
.settings/com.freescale.s32ds.cross.sdk.support.prefs

@@ -1,2 +1,3 @@
+FILTER_SDKs_SHOW_LATEST_VERSIONS=false
 com.freescale.s32ds.cross.sdk.support.attachedSDKs=PlatformSDK_S32K1_2021_08_S32K146_M4F_1.0.0_PATH|Debug_FLASH|Release_FLASH|Debug_RAM|Release_RAM
 eclipse.preferences.version=1

+ 2 - 0
FreeRTOS/Source/include/FreeRTOS.h

@@ -1180,6 +1180,8 @@ typedef struct xSTATIC_TCB
     uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
     #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
         void * pxDummy8;
+	#else
+        UBaseType_t     uxSizeOfStack;      /*< Support For CmBacktrace >*/
     #endif
     #if ( portCRITICAL_NESTING_IN_TCB == 1 )
         UBaseType_t uxDummy9;

+ 28 - 2
FreeRTOS/Source/tasks.c

@@ -269,7 +269,9 @@ typedef struct tskTaskControlBlock       /* The old naming convention is used to
     #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
         StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */
     #endif
-
+	#if( portSTACK_GROWTH <= 0)
+        UBaseType_t     uxSizeOfStack;      /*< Support For CmBacktrace >*/
+ 	 #endif
     #if ( portCRITICAL_NESTING_IN_TCB == 1 )
         UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
     #endif
@@ -861,7 +863,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
 
             /* Check the alignment of the calculated top of stack is correct. */
             configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
-
+            pxNewTCB->uxSizeOfStack = ulStackDepth;
             #if ( configRECORD_STACK_HIGH_ADDRESS == 1 )
                 {
                     /* Also record the stack's high address, which may assist
@@ -5404,3 +5406,27 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
     #endif
 
 #endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */
+
+        /*-----------------------------------------------------------*/
+        /*< Support For CmBacktrace >*/
+        uint32_t * vTaskStackAddr()
+        {
+            return pxCurrentTCB->pxStack;
+        }
+
+
+        uint32_t vTaskStackSize()
+        {
+            #if ( portSTACK_GROWTH > 0 )
+            return (pxNewTCB->pxEndOfStack - pxNewTCB->pxStack + 1);
+            #else /* ( portSTACK_GROWTH > 0 )*/
+            return pxCurrentTCB->uxSizeOfStack;
+            #endif /* ( portSTACK_GROWTH > 0 )*/
+        }
+
+
+        char * vTaskName()
+        {
+            return pxCurrentTCB->pcTaskName;
+        }
+        /*-----------------------------------------------------------*/

+ 1 - 1
Project_Settings/Debugger/S32K146_4G_Debug_FLASH_PNE.launch

@@ -216,5 +216,5 @@
 </listAttribute>
 <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;&gt;&#13;&#10;&lt;gdbmemoryBlockExpression address=&quot;536806032&quot; label=&quot;RX_Buffer[UART_LPUART2]&quot;/&gt;&#13;&#10;&lt;gdbmemoryBlockExpression address=&quot;536823956&quot; label=&quot;GpsBufferGet&quot;/&gt;&#13;&#10;&lt;gdbmemoryBlockExpression address=&quot;255&quot; label=&quot;SocketId&quot;/&gt;&#13;&#10;&lt;gdbmemoryBlockExpression address=&quot;536805632&quot; label=&quot;0x1fff0100&quot;/&gt;&#13;&#10;&lt;gdbmemoryBlockExpression address=&quot;536806632&quot; label=&quot;0x1fff04e8&quot;/&gt;&#13;&#10;&lt;/memoryBlockExpressionList&gt;&#13;&#10;"/>
 <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
-<stringAttribute key="saved_expressions&lt;seperator&gt;Unknown" value="0x1fffbcd7,0x10000010,0x1000000,0x10000000,0x1fffbea0,0x1fff7dee,0x1fffbbed,0x1fffbc88,0x1fffbc8a,0x14200,0x80000,0x1fffbb20,0x1fffbb3e,0x1fffb348,0x1fffb5cd"/>
+<stringAttribute key="saved_expressions&lt;seperator&gt;Unknown" value="0x10000010,0x1000000,0x10000000,0x1fffbea0,0x1fff7dee,0x1fffbbed,0x1fffbc88,0x1fffbc8a,0x14200,0x80000,0x1fffbb20,0x1fffbb3e,0x1fffb348,0x1fffb5cd,0x14600"/>
 </launchConfiguration>

+ 8 - 0
cm_backtrace/Languages/README.md

@@ -0,0 +1,8 @@
+# CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库
+
+## 多语言支持
+
+| Language             | Location (or type)         | Language tag |
+|----------------------|----------------------------|--------------|
+| English              | United States              | en-US        |
+| Chinese (Simplified) | People's Republic of China | zh-CN        |

+ 71 - 0
cm_backtrace/Languages/en-US/cmb_en_US.h

@@ -0,0 +1,71 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
+ *                     Chenxuan, <chenxuan.zhao@icloud.com>
+ *
+ * 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.
+ *
+ * NOTE: DO NOT include this file on the header file.
+ * Encoding: UTF-8
+ * Created on: 2020-09-06
+ */
+
+[PRINT_MAIN_STACK_CFG_ERROR]  = "ERROR: Unable to get the main stack information, please check the configuration of the main stack",
+[PRINT_FIRMWARE_INFO]         = "Firmware name: %s, hardware version: %s, software version: %s",
+[PRINT_ASSERT_ON_THREAD]      = "Assert on thread %s",
+[PRINT_ASSERT_ON_HANDLER]     = "Assert on interrupt or bare metal(no OS) environment",
+[PRINT_THREAD_STACK_INFO]     = "===== Thread stack information =====",
+[PRINT_MAIN_STACK_INFO]       = "====== Main stack information ======",
+[PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow",
+[PRINT_MAIN_STACK_OVERFLOW]   = "Error: Main stack(%08x) was overflow",
+[PRINT_CALL_STACK_INFO]       = "Show more call stack info by run: addr2line -e %s%s -a -f %s",
+[PRINT_CALL_STACK_ERR]        = "Dump call stack has an error",
+[PRINT_FAULT_ON_THREAD]       = "Fault on thread %s",
+[PRINT_FAULT_ON_HANDLER]      = "Fault on interrupt or bare metal(no OS) environment",
+[PRINT_REGS_TITLE]            = "=================== Registers information ====================",
+[PRINT_HFSR_VECTBL]           = "Hard fault is caused by failed vector fetch",
+[PRINT_MFSR_IACCVIOL]         = "Memory management fault is caused by instruction access violation",
+[PRINT_MFSR_DACCVIOL]         = "Memory management fault is caused by data access violation",
+[PRINT_MFSR_MUNSTKERR]        = "Memory management fault is caused by unstacking error",
+[PRINT_MFSR_MSTKERR]          = "Memory management fault is caused by stacking error",
+[PRINT_MFSR_MLSPERR]          = "Memory management fault is caused by floating-point lazy state preservation",
+[PRINT_BFSR_IBUSERR]          = "Bus fault is caused by instruction access violation",
+[PRINT_BFSR_PRECISERR]        = "Bus fault is caused by precise data access violation",
+[PRINT_BFSR_IMPREISERR]       = "Bus fault is caused by imprecise data access violation",
+[PRINT_BFSR_UNSTKERR]         = "Bus fault is caused by unstacking error",
+[PRINT_BFSR_STKERR]           = "Bus fault is caused by stacking error",
+[PRINT_BFSR_LSPERR]           = "Bus fault is caused by floating-point lazy state preservation",
+[PRINT_UFSR_UNDEFINSTR]       = "Usage fault is caused by attempts to execute an undefined instruction",
+[PRINT_UFSR_INVSTATE]         = "Usage fault is caused by attempts to switch to an invalid state (e.g., ARM)",
+[PRINT_UFSR_INVPC]            = "Usage fault is caused by attempts to do an exception with a bad value in the EXC_RETURN number",
+[PRINT_UFSR_NOCP]             = "Usage fault is caused by attempts to execute a coprocessor instruction",
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+    [PRINT_UFSR_STKOF]        = "Usage fault is caused by indicates that a stack overflow (hardware check) has taken place",
+#endif
+[PRINT_UFSR_UNALIGNED]        = "Usage fault is caused by indicates that an unaligned access fault has taken place",
+[PRINT_UFSR_DIVBYZERO0]       = "Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)",
+[PRINT_DFSR_HALTED]           = "Debug fault is caused by halt requested in NVIC",
+[PRINT_DFSR_BKPT]             = "Debug fault is caused by BKPT instruction executed",
+[PRINT_DFSR_DWTTRAP]          = "Debug fault is caused by DWT match occurred",
+[PRINT_DFSR_VCATCH]           = "Debug fault is caused by Vector fetch occurred",
+[PRINT_DFSR_EXTERNAL]         = "Debug fault is caused by EDBGRQ signal asserted",
+[PRINT_MMAR]                  = "The memory management fault occurred address is %08x",
+[PRINT_BFAR]                  = "The bus fault occurred address is %08x",

+ 71 - 0
cm_backtrace/Languages/zh-CN/cmb_zh_CN.h

@@ -0,0 +1,71 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
+ *                     Chenxuan, <chenxuan.zhao@icloud.com>
+ *
+ * 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.
+ *
+ * NOTE: DO NOT include this file on the header file.
+ * Encoding: GB18030
+ * Created on: 2020-09-06
+ */
+
+[PRINT_MAIN_STACK_CFG_ERROR]  = "错误:无法获取主栈信息,请检查主栈的相关配置",
+[PRINT_FIRMWARE_INFO]         = "固件名称:%s,硬件版本号:%s,软件版本号:%s",
+[PRINT_ASSERT_ON_THREAD]      = "在线程(%s)中发生断言",
+[PRINT_ASSERT_ON_HANDLER]     = "在中断或裸机环境下发生断言",
+[PRINT_THREAD_STACK_INFO]     = "=========== 线程堆栈信息 ===========",
+[PRINT_MAIN_STACK_INFO]       = "============ 主堆栈信息 ============",
+[PRINT_THREAD_STACK_OVERFLOW] = "错误:线程栈(%08x)发生溢出",
+[PRINT_MAIN_STACK_OVERFLOW]   = "错误:主栈(%08x)发生溢出",
+[PRINT_CALL_STACK_INFO]       = "查看更多函数调用栈信息,请运行:addr2line -e %s%s -a -f %s",
+[PRINT_CALL_STACK_ERR]        = "获取函数调用栈失败",
+[PRINT_FAULT_ON_THREAD]       =  "在线程(%s)中发生错误异常",
+[PRINT_FAULT_ON_HANDLER]      = "在中断或裸机环境下发生错误异常",
+[PRINT_REGS_TITLE]            = "========================= 寄存器信息 =========================",
+[PRINT_HFSR_VECTBL]           = "发生硬错误,原因:取中断向量时出错",
+[PRINT_MFSR_IACCVIOL]         = "发生存储器管理错误,原因:企图从不允许访问的区域取指令",
+[PRINT_MFSR_DACCVIOL]         = "发生存储器管理错误,原因:企图从不允许访问的区域读、写数据",
+[PRINT_MFSR_MUNSTKERR]        = "发生存储器管理错误,原因:出栈时企图访问不被允许的区域",
+[PRINT_MFSR_MSTKERR]          = "发生存储器管理错误,原因:入栈时企图访问不被允许的区域",
+[PRINT_MFSR_MLSPERR]          = "发生存储器管理错误,原因:惰性保存浮点状态时发生错误",
+[PRINT_BFSR_IBUSERR]          = "发生总线错误,原因:指令总线错误",
+[PRINT_BFSR_PRECISERR]        = "发生总线错误,原因:精确的数据总线错误",
+[PRINT_BFSR_IMPREISERR]       = "发生总线错误,原因:不精确的数据总线错误",
+[PRINT_BFSR_UNSTKERR]         = "发生总线错误,原因:出栈时发生错误",
+[PRINT_BFSR_STKERR]           = "发生总线错误,原因:入栈时发生错误",
+[PRINT_BFSR_LSPERR]           = "发生总线错误,原因:惰性保存浮点状态时发生错误",
+[PRINT_UFSR_UNDEFINSTR]       = "发生用法错误,原因:企图执行未定义指令",
+[PRINT_UFSR_INVSTATE]         = "发生用法错误,原因:试图切换到 ARM 状态",
+[PRINT_UFSR_INVPC]            = "发生用法错误,原因:无效的异常返回码",
+[PRINT_UFSR_NOCP]             = "发生用法错误,原因:企图执行协处理器指令",
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+    [PRINT_UFSR_STKOF]        = "发生用法错误,原因:硬件检测到栈溢出",
+#endif
+[PRINT_UFSR_UNALIGNED]        = "发生用法错误,原因:企图执行非对齐访问",
+[PRINT_UFSR_DIVBYZERO0]       = "发生用法错误,原因:企图执行除 0 操作",
+[PRINT_DFSR_HALTED]           = "发生调试错误,原因:NVIC 停机请求",
+[PRINT_DFSR_BKPT]             = "发生调试错误,原因:执行 BKPT 指令",
+[PRINT_DFSR_DWTTRAP]          = "发生调试错误,原因:数据监测点匹配",
+[PRINT_DFSR_VCATCH]           = "发生调试错误,原因:发生向量捕获",
+[PRINT_DFSR_EXTERNAL]         = "发生调试错误,原因:外部调试请求",
+[PRINT_MMAR]                  = "发生存储器管理错误的地址:%08x",
+[PRINT_BFAR]                  = "发生总线错误的地址:%08x",

+ 71 - 0
cm_backtrace/Languages/zh-CN/cmb_zh_CN_UTF8.h

@@ -0,0 +1,71 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
+ *                     Chenxuan, <chenxuan.zhao@icloud.com>
+ *
+ * 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.
+ *
+ * NOTE: DO NOT include this file on the header file.
+ * Encoding: UTF-8
+ * Created on: 2020-09-06
+ */
+
+[PRINT_MAIN_STACK_CFG_ERROR]  = "错误:无法获取主栈信息,请检查主栈的相关配置",
+[PRINT_FIRMWARE_INFO]         = "固件名称:%s,硬件版本号:%s,软件版本号:%s",
+[PRINT_ASSERT_ON_THREAD]      = "在线程(%s)中发生断言",
+[PRINT_ASSERT_ON_HANDLER]     = "在中断或裸机环境下发生断言",
+[PRINT_THREAD_STACK_INFO]     = "=========== 线程堆栈信息 ===========",
+[PRINT_MAIN_STACK_INFO]       = "============ 主堆栈信息 ============",
+[PRINT_THREAD_STACK_OVERFLOW] = "错误:线程栈(%08x)发生溢出",
+[PRINT_MAIN_STACK_OVERFLOW]   = "错误:主栈(%08x)发生溢出",
+[PRINT_CALL_STACK_INFO]       = "查看更多函数调用栈信息,请运行:addr2line -e %s%s -a -f %s",
+[PRINT_CALL_STACK_ERR]        = "获取函数调用栈失败",
+[PRINT_FAULT_ON_THREAD]       =  "在线程(%s)中发生错误异常",
+[PRINT_FAULT_ON_HANDLER]      = "在中断或裸机环境下发生错误异常",
+[PRINT_REGS_TITLE]            = "========================= 寄存器信息 =========================",
+[PRINT_HFSR_VECTBL]           = "发生硬错误,原因:取中断向量时出错",
+[PRINT_MFSR_IACCVIOL]         = "发生存储器管理错误,原因:企图从不允许访问的区域取指令",
+[PRINT_MFSR_DACCVIOL]         = "发生存储器管理错误,原因:企图从不允许访问的区域读、写数据",
+[PRINT_MFSR_MUNSTKERR]        = "发生存储器管理错误,原因:出栈时企图访问不被允许的区域",
+[PRINT_MFSR_MSTKERR]          = "发生存储器管理错误,原因:入栈时企图访问不被允许的区域",
+[PRINT_MFSR_MLSPERR]          = "发生存储器管理错误,原因:惰性保存浮点状态时发生错误",
+[PRINT_BFSR_IBUSERR]          = "发生总线错误,原因:指令总线错误",
+[PRINT_BFSR_PRECISERR]        = "发生总线错误,原因:精确的数据总线错误",
+[PRINT_BFSR_IMPREISERR]       = "发生总线错误,原因:不精确的数据总线错误",
+[PRINT_BFSR_UNSTKERR]         = "发生总线错误,原因:出栈时发生错误",
+[PRINT_BFSR_STKERR]           = "发生总线错误,原因:入栈时发生错误",
+[PRINT_BFSR_LSPERR]           = "发生总线错误,原因:惰性保存浮点状态时发生错误",
+[PRINT_UFSR_UNDEFINSTR]       = "发生用法错误,原因:企图执行未定义指令",
+[PRINT_UFSR_INVSTATE]         = "发生用法错误,原因:试图切换到 ARM 状态",
+[PRINT_UFSR_INVPC]            = "发生用法错误,原因:无效的异常返回码",
+[PRINT_UFSR_NOCP]             = "发生用法错误,原因:企图执行协处理器指令",
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+    [PRINT_UFSR_STKOF]        = "发生用法错误,原因:硬件检测到栈溢出",
+#endif
+[PRINT_UFSR_UNALIGNED]        = "发生用法错误,原因:企图执行非对齐访问",
+[PRINT_UFSR_DIVBYZERO0]       = "发生用法错误,原因:企图执行除 0 操作",
+[PRINT_DFSR_HALTED]           = "发生调试错误,原因:NVIC 停机请求",
+[PRINT_DFSR_BKPT]             = "发生调试错误,原因:执行 BKPT 指令",
+[PRINT_DFSR_DWTTRAP]          = "发生调试错误,原因:数据监测点匹配",
+[PRINT_DFSR_VCATCH]           = "发生调试错误,原因:发生向量捕获",
+[PRINT_DFSR_EXTERNAL]         = "发生调试错误,原因:外部调试请求",
+[PRINT_MMAR]                  = "发生存储器管理错误的地址:%08x",
+[PRINT_BFAR]                  = "发生总线错误的地址:%08x",

+ 666 - 0
cm_backtrace/cm_backtrace.c

@@ -0,0 +1,666 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016-2019, Armink, <armink.ztl@gmail.com>
+ *
+ * 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.
+ *
+ * Function: Initialize function and other general function.
+ * Created on: 2016-12-15
+ */
+
+#include <cm_backtrace.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+
+#if __STDC_VERSION__ < 199901L
+    #error "must be C99 or higher. try to add '-std=c99' to compile parameters"
+#endif
+
+#if defined(__ARMCC_VERSION)
+    #define SECTION_START(_name_)                _name_##$$Base
+    #define SECTION_END(_name_)                  _name_##$$Limit
+    #define IMAGE_SECTION_START(_name_)          Image$$##_name_##$$Base
+    #define IMAGE_SECTION_END(_name_)            Image$$##_name_##$$Limit
+    #define CSTACK_BLOCK_START(_name_)           SECTION_START(_name_)
+    #define CSTACK_BLOCK_END(_name_)             SECTION_END(_name_)
+    #define CODE_SECTION_START(_name_)           IMAGE_SECTION_START(_name_)
+    #define CODE_SECTION_END(_name_)             IMAGE_SECTION_END(_name_)
+
+    extern const int CSTACK_BLOCK_START(CMB_CSTACK_BLOCK_NAME);
+    extern const int CSTACK_BLOCK_END(CMB_CSTACK_BLOCK_NAME);
+    extern const int CODE_SECTION_START(CMB_CODE_SECTION_NAME);
+    extern const int CODE_SECTION_END(CMB_CODE_SECTION_NAME);
+#elif defined(__ICCARM__)
+    #pragma section=CMB_CSTACK_BLOCK_NAME
+    #pragma section=CMB_CODE_SECTION_NAME
+#elif defined(__GNUC__)
+    extern const int CMB_CSTACK_BLOCK_START;
+    extern const int CMB_CSTACK_BLOCK_END;
+    extern const int CMB_CODE_SECTION_START;
+    extern const int CMB_CODE_SECTION_END;
+#else
+    #error "not supported compiler"
+#endif
+
+enum {
+    PRINT_MAIN_STACK_CFG_ERROR,
+    PRINT_FIRMWARE_INFO,
+    PRINT_ASSERT_ON_THREAD,
+    PRINT_ASSERT_ON_HANDLER,
+    PRINT_THREAD_STACK_INFO,
+    PRINT_MAIN_STACK_INFO,
+    PRINT_THREAD_STACK_OVERFLOW,
+    PRINT_MAIN_STACK_OVERFLOW,
+    PRINT_CALL_STACK_INFO,
+    PRINT_CALL_STACK_ERR,
+    PRINT_FAULT_ON_THREAD,
+    PRINT_FAULT_ON_HANDLER,
+    PRINT_REGS_TITLE,
+    PRINT_HFSR_VECTBL,
+    PRINT_MFSR_IACCVIOL,
+    PRINT_MFSR_DACCVIOL,
+    PRINT_MFSR_MUNSTKERR,
+    PRINT_MFSR_MSTKERR,
+    PRINT_MFSR_MLSPERR,
+    PRINT_BFSR_IBUSERR,
+    PRINT_BFSR_PRECISERR,
+    PRINT_BFSR_IMPREISERR,
+    PRINT_BFSR_UNSTKERR,
+    PRINT_BFSR_STKERR,
+    PRINT_BFSR_LSPERR,
+    PRINT_UFSR_UNDEFINSTR,
+    PRINT_UFSR_INVSTATE,
+    PRINT_UFSR_INVPC,
+    PRINT_UFSR_NOCP,
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+    PRINT_UFSR_STKOF,
+#endif
+    PRINT_UFSR_UNALIGNED,
+    PRINT_UFSR_DIVBYZERO0,
+    PRINT_DFSR_HALTED,
+    PRINT_DFSR_BKPT,
+    PRINT_DFSR_DWTTRAP,
+    PRINT_DFSR_VCATCH,
+    PRINT_DFSR_EXTERNAL,
+    PRINT_MMAR,
+    PRINT_BFAR,
+};
+
+static const char * const print_info[] = {
+#if (CMB_PRINT_LANGUAGE == CMB_PRINT_LANGUAGE_ENGLISH)
+    #include "Languages/en-US/cmb_en_US.h"
+#elif (CMB_PRINT_LANGUAGE == CMB_PRINT_LANGUAGE_CHINESE)
+    #include "Languages/zh-CN/cmb_zh_CN.h"
+#elif (CMB_PRINT_LANGUAGE == CMB_PRINT_LANGUAGE_CHINESE_UTF8)
+    #include "Languages/zh-CN/cmb_zh_CN_UTF8.h"
+#else
+    #error "CMB_PRINT_LANGUAGE defined error in 'cmb_cfg.h'"
+#endif
+};
+
+static char fw_name[CMB_NAME_MAX] = {0};
+static char hw_ver[CMB_NAME_MAX] = {0};
+static char sw_ver[CMB_NAME_MAX] = {0};
+static uint32_t main_stack_start_addr = 0;
+static size_t main_stack_size = 0;
+static uint32_t code_start_addr = 0;
+static size_t code_size = 0;
+static bool init_ok = false;
+static char call_stack_info[CMB_CALL_STACK_MAX_DEPTH * (8 + 1)] = { 0 };
+static bool on_fault = false;
+static bool stack_is_overflow = false;
+static struct cmb_hard_fault_regs regs;
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \
+    (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+static bool statck_has_fpu_regs = false;
+#endif
+
+static bool on_thread_before_fault = false;
+
+/**
+ * library initialize
+ */
+void cm_backtrace_init(const char *firmware_name, const char *hardware_ver, const char *software_ver) {
+    strncpy(fw_name, firmware_name, CMB_NAME_MAX);
+    strncpy(hw_ver, hardware_ver, CMB_NAME_MAX);
+    strncpy(sw_ver, software_ver, CMB_NAME_MAX);
+
+#if defined(__ARMCC_VERSION)
+    main_stack_start_addr = (uint32_t)&CSTACK_BLOCK_START(CMB_CSTACK_BLOCK_NAME);
+    main_stack_size = (uint32_t)&CSTACK_BLOCK_END(CMB_CSTACK_BLOCK_NAME) - main_stack_start_addr;
+    code_start_addr = (uint32_t)&CODE_SECTION_START(CMB_CODE_SECTION_NAME);
+    code_size = (uint32_t)&CODE_SECTION_END(CMB_CODE_SECTION_NAME) - code_start_addr;
+#elif defined(__ICCARM__)
+    main_stack_start_addr = (uint32_t)__section_begin(CMB_CSTACK_BLOCK_NAME);
+    main_stack_size = (uint32_t)__section_end(CMB_CSTACK_BLOCK_NAME) - main_stack_start_addr;
+    code_start_addr = (uint32_t)__section_begin(CMB_CODE_SECTION_NAME);
+    code_size = (uint32_t)__section_end(CMB_CODE_SECTION_NAME) - code_start_addr;
+#elif defined(__GNUC__)
+    main_stack_start_addr = (uint32_t)(&CMB_CSTACK_BLOCK_START);
+    main_stack_size = (uint32_t)(&CMB_CSTACK_BLOCK_END) - main_stack_start_addr;
+    code_start_addr = (uint32_t)(&CMB_CODE_SECTION_START);
+    code_size = (uint32_t)(&CMB_CODE_SECTION_END) - code_start_addr;
+#else
+    #error "not supported compiler"
+#endif
+
+    if (main_stack_size == 0) {
+        cmb_println(print_info[PRINT_MAIN_STACK_CFG_ERROR]);
+        return;
+    }
+
+    init_ok = true;
+}
+/**
+ * print firmware information, such as: firmware name, hardware version, software version
+ */
+void cm_backtrace_firmware_info(void) {
+    cmb_println(print_info[PRINT_FIRMWARE_INFO], fw_name, hw_ver, sw_ver);
+}
+
+#ifdef CMB_USING_OS_PLATFORM
+/**
+ * Get current thread stack information
+ *
+ * @param sp stack current pointer
+ * @param start_addr stack start address
+ * @param size stack size
+ */
+static void get_cur_thread_stack_info(uint32_t sp, uint32_t *start_addr, size_t *size) {
+    CMB_ASSERT(start_addr);
+    CMB_ASSERT(size);
+
+#if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+    *start_addr = (uint32_t) rt_thread_self()->stack_addr;
+    *size = rt_thread_self()->stack_size;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+    extern OS_TCB *OSTCBCur;
+
+    *start_addr = (uint32_t) OSTCBCur->OSTCBStkBottom;
+    *size = OSTCBCur->OSTCBStkSize * sizeof(OS_STK);
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+    extern OS_TCB *OSTCBCurPtr; 
+    
+    *start_addr = (uint32_t) OSTCBCurPtr->StkBasePtr;
+    *size = OSTCBCurPtr->StkSize * sizeof(CPU_STK_SIZE);
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)   
+    *start_addr = (uint32_t)vTaskStackAddr();
+    *size = vTaskStackSize() * sizeof( StackType_t );
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTX5)
+    osRtxThread_t *thread = osRtxInfo.thread.run.curr;
+    *start_addr = (uint32_t)thread->stack_mem;
+    *size = thread->stack_size;
+#endif
+}
+
+/**
+ * Get current thread name
+ */
+static const char *get_cur_thread_name(void) {
+#if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+    return rt_thread_self()->name;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+    extern OS_TCB *OSTCBCur;
+
+#if OS_TASK_NAME_SIZE > 0 || OS_TASK_NAME_EN > 0
+        return (const char *)OSTCBCur->OSTCBTaskName;
+#else
+        return NULL;
+#endif /* OS_TASK_NAME_SIZE > 0 || OS_TASK_NAME_EN > 0 */
+
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+    extern OS_TCB *OSTCBCurPtr; 
+    
+    return (const char *)OSTCBCurPtr->NamePtr;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)
+    return vTaskName();
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTX5)
+    osThreadId_t id = osThreadGetId();
+    return osThreadGetName(id);
+#endif
+}
+
+#endif /* CMB_USING_OS_PLATFORM */
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+/**
+ * dump current stack information
+ */
+static void dump_stack(uint32_t stack_start_addr, size_t stack_size, uint32_t *stack_pointer) {
+    if (stack_is_overflow) {
+        if (on_thread_before_fault) {
+            cmb_println(print_info[PRINT_THREAD_STACK_OVERFLOW], stack_pointer);
+        } else {
+            cmb_println(print_info[PRINT_MAIN_STACK_OVERFLOW], stack_pointer);
+        }
+        if ((uint32_t) stack_pointer < stack_start_addr) {
+            stack_pointer = (uint32_t *) stack_start_addr;
+        } else if ((uint32_t) stack_pointer > stack_start_addr + stack_size) {
+            stack_pointer = (uint32_t *) (stack_start_addr + stack_size);
+        }
+    }
+    cmb_println(print_info[PRINT_THREAD_STACK_INFO]);
+    for (; (uint32_t) stack_pointer < stack_start_addr + stack_size; stack_pointer++) {
+        cmb_println("  addr: %08x    data: %08x", stack_pointer, *stack_pointer);
+    }
+    cmb_println("====================================");
+}
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+/* check the disassembly instruction is 'BL' or 'BLX' */
+static bool disassembly_ins_is_bl_blx(uint32_t addr) {
+    uint16_t ins1 = *((uint16_t *)addr);
+    uint16_t ins2 = *((uint16_t *)(addr + 2));
+
+#define BL_INS_MASK         0xF800
+#define BL_INS_HIGH         0xF800
+#define BL_INS_LOW          0xF000
+#define BLX_INX_MASK        0xFF00
+#define BLX_INX             0x4700
+
+    if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW) {
+        return true;
+    } else if ((ins2 & BLX_INX_MASK) == BLX_INX) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * backtrace function call stack
+ *
+ * @param buffer call stack buffer
+ * @param size buffer size
+ * @param sp stack pointer
+ *
+ * @return depth
+ */
+size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) {
+    uint32_t stack_start_addr = main_stack_start_addr, pc;
+    size_t depth = 0, stack_size = main_stack_size;
+    bool regs_saved_lr_is_valid = false;
+
+    if (on_fault) {
+        if (!stack_is_overflow) {
+            /* first depth is PC */
+            buffer[depth++] = regs.saved.pc;
+            /* fix the LR address in thumb mode */
+            pc = regs.saved.lr - 1;
+            if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
+                    && (depth < size)) {
+                buffer[depth++] = pc;
+                regs_saved_lr_is_valid = true;
+            }
+        }
+
+#ifdef CMB_USING_OS_PLATFORM
+        /* program is running on thread before fault */
+        if (on_thread_before_fault) {
+            get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        }
+    } else {
+        /* OS environment */
+        if (cmb_get_sp() == cmb_get_psp()) {
+            get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        }
+#endif /* CMB_USING_OS_PLATFORM */
+
+    }
+
+    if (stack_is_overflow) {
+        if (sp < stack_start_addr) {
+            sp = stack_start_addr;
+        } else if (sp > stack_start_addr + stack_size) {
+            sp = stack_start_addr + stack_size;
+        }
+    }
+
+    /* copy called function address */
+    for (; sp < stack_start_addr + stack_size; sp += sizeof(size_t)) {
+        /* the *sp value may be LR, so need decrease a word to PC */
+        pc = *((uint32_t *) sp) - sizeof(size_t);
+        /* the Cortex-M using thumb instruction, so the pc must be an odd number */
+        if (pc % 2 == 0) {
+            continue;
+        }
+        /* fix the PC address in thumb mode */
+        pc = *((uint32_t *) sp) - 1;
+        if ((pc >= code_start_addr + sizeof(size_t)) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
+                /* check the the instruction before PC address is 'BL' or 'BLX' */
+                && disassembly_ins_is_bl_blx(pc - sizeof(size_t)) && (depth < size)) {
+            /* the second depth function may be already saved, so need ignore repeat */
+            if ((depth == 2) && regs_saved_lr_is_valid && (pc == buffer[1])) {
+                continue;
+            }
+            buffer[depth++] = pc;
+        }
+    }
+
+    return depth;
+}
+
+/**
+ * dump function call stack
+ *
+ * @param sp stack pointer
+ */
+static void print_call_stack(uint32_t sp) {
+    size_t i, cur_depth = 0;
+    uint32_t call_stack_buf[CMB_CALL_STACK_MAX_DEPTH] = {0};
+
+    cur_depth = cm_backtrace_call_stack(call_stack_buf, CMB_CALL_STACK_MAX_DEPTH, sp);
+
+    for (i = 0; i < cur_depth; i++) {
+        sprintf(call_stack_info + i * (8 + 1), "%08lx", (unsigned long)call_stack_buf[i]);
+        call_stack_info[i * (8 + 1) + 8] = ' ';
+    }
+
+    if (cur_depth) {
+        call_stack_info[cur_depth * (8 + 1) - 1] = '\0';
+        cmb_println(print_info[PRINT_CALL_STACK_INFO], fw_name, CMB_ELF_FILE_EXTENSION_NAME, call_stack_info);
+    } else {
+        cmb_println(print_info[PRINT_CALL_STACK_ERR]);
+    }
+}
+
+/**
+ * backtrace for assert
+ *
+ * @param sp the stack pointer when on assert occurred
+ */
+void cm_backtrace_assert(uint32_t sp) {
+    CMB_ASSERT(init_ok);
+
+#ifdef CMB_USING_OS_PLATFORM
+    uint32_t cur_stack_pointer = cmb_get_sp();
+#endif
+
+    cmb_println("");
+    cm_backtrace_firmware_info();
+
+#ifdef CMB_USING_OS_PLATFORM
+    /* OS environment */
+    if (cur_stack_pointer == cmb_get_msp()) {
+        cmb_println(print_info[PRINT_ASSERT_ON_HANDLER]);
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        dump_stack(main_stack_start_addr, main_stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    } else if (cur_stack_pointer == cmb_get_psp()) {
+        cmb_println(print_info[PRINT_ASSERT_ON_THREAD], get_cur_thread_name());
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        uint32_t stack_start_addr;
+        size_t stack_size;
+        get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        dump_stack(stack_start_addr, stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    }
+
+#else
+
+    /* bare metal(no OS) environment */
+#ifdef CMB_USING_DUMP_STACK_INFO
+    dump_stack(main_stack_start_addr, main_stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+#endif /* CMB_USING_OS_PLATFORM */
+
+    print_call_stack(sp);
+}
+
+#if (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0)
+/**
+ * fault diagnosis then print cause of fault
+ */
+static void fault_diagnosis(void) {
+    if (regs.hfsr.bits.VECTBL) {
+        cmb_println(print_info[PRINT_HFSR_VECTBL]);
+    }
+    if (regs.hfsr.bits.FORCED) {
+        /* Memory Management Fault */
+        if (regs.mfsr.value) {
+            if (regs.mfsr.bits.IACCVIOL) {
+                cmb_println(print_info[PRINT_MFSR_IACCVIOL]);
+            }
+            if (regs.mfsr.bits.DACCVIOL) {
+                cmb_println(print_info[PRINT_MFSR_DACCVIOL]);
+            }
+            if (regs.mfsr.bits.MUNSTKERR) {
+                cmb_println(print_info[PRINT_MFSR_MUNSTKERR]);
+            }
+            if (regs.mfsr.bits.MSTKERR) {
+                cmb_println(print_info[PRINT_MFSR_MSTKERR]);
+            }
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \
+    (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+            if (regs.mfsr.bits.MLSPERR) {
+                cmb_println(print_info[PRINT_MFSR_MLSPERR]);
+            }
+#endif
+
+            if (regs.mfsr.bits.MMARVALID) {
+                if (regs.mfsr.bits.IACCVIOL || regs.mfsr.bits.DACCVIOL) {
+                    cmb_println(print_info[PRINT_MMAR], regs.mmar);
+                }
+            }
+        }
+        /* Bus Fault */
+        if (regs.bfsr.value) {
+            if (regs.bfsr.bits.IBUSERR) {
+                cmb_println(print_info[PRINT_BFSR_IBUSERR]);
+            }
+            if (regs.bfsr.bits.PRECISERR) {
+                cmb_println(print_info[PRINT_BFSR_PRECISERR]);
+            }
+            if (regs.bfsr.bits.IMPREISERR) {
+                cmb_println(print_info[PRINT_BFSR_IMPREISERR]);
+            }
+            if (regs.bfsr.bits.UNSTKERR) {
+                cmb_println(print_info[PRINT_BFSR_UNSTKERR]);
+            }
+            if (regs.bfsr.bits.STKERR) {
+                cmb_println(print_info[PRINT_BFSR_STKERR]);
+            }
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \
+    (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+            if (regs.bfsr.bits.LSPERR) {
+                cmb_println(print_info[PRINT_BFSR_LSPERR]);
+            }
+#endif
+
+            if (regs.bfsr.bits.BFARVALID) {
+                if (regs.bfsr.bits.PRECISERR) {
+                    cmb_println(print_info[PRINT_BFAR], regs.bfar);
+                }
+            }
+
+        }
+        /* Usage Fault */
+        if (regs.ufsr.value) {
+            if (regs.ufsr.bits.UNDEFINSTR) {
+                cmb_println(print_info[PRINT_UFSR_UNDEFINSTR]);
+            }
+            if (regs.ufsr.bits.INVSTATE) {
+                cmb_println(print_info[PRINT_UFSR_INVSTATE]);
+            }
+            if (regs.ufsr.bits.INVPC) {
+                cmb_println(print_info[PRINT_UFSR_INVPC]);
+            }
+            if (regs.ufsr.bits.NOCP) {
+                cmb_println(print_info[PRINT_UFSR_NOCP]);
+            }
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+            if (regs.ufsr.bits.STKOF) {
+                cmb_println(print_info[PRINT_UFSR_STKOF]);
+            }
+#endif
+            if (regs.ufsr.bits.UNALIGNED) {
+                cmb_println(print_info[PRINT_UFSR_UNALIGNED]);
+            }
+            if (regs.ufsr.bits.DIVBYZERO0) {
+                cmb_println(print_info[PRINT_UFSR_DIVBYZERO0]);
+            }
+        }
+    }
+    /* Debug Fault */
+    if (regs.hfsr.bits.DEBUGEVT) {
+        if (regs.dfsr.value) {
+            if (regs.dfsr.bits.HALTED) {
+                cmb_println(print_info[PRINT_DFSR_HALTED]);
+            }
+            if (regs.dfsr.bits.BKPT) {
+                cmb_println(print_info[PRINT_DFSR_BKPT]);
+            }
+            if (regs.dfsr.bits.DWTTRAP) {
+                cmb_println(print_info[PRINT_DFSR_DWTTRAP]);
+            }
+            if (regs.dfsr.bits.VCATCH) {
+                cmb_println(print_info[PRINT_DFSR_VCATCH]);
+            }
+            if (regs.dfsr.bits.EXTERNAL) {
+                cmb_println(print_info[PRINT_DFSR_EXTERNAL]);
+            }
+        }
+    }
+}
+#endif /* (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0) */
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \
+    (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+static uint32_t statck_del_fpu_regs(uint32_t fault_handler_lr, uint32_t sp) {
+    statck_has_fpu_regs = (fault_handler_lr & (1UL << 4)) == 0 ? true : false;
+
+    /* the stack has S0~S15 and FPSCR registers when statck_has_fpu_regs is true, double word align */
+    return statck_has_fpu_regs == true ? sp + sizeof(size_t) * 18 : sp;
+}
+#endif
+
+/**
+ * backtrace for fault
+ * @note only call once
+ *
+ * @param fault_handler_lr the LR register value on fault handler
+ * @param fault_handler_sp the stack pointer on fault handler
+ */
+void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp) {
+    uint32_t stack_pointer = fault_handler_sp, saved_regs_addr = stack_pointer;
+    const char *regs_name[] = { "R0 ", "R1 ", "R2 ", "R3 ", "R12", "LR ", "PC ", "PSR" };
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+    uint32_t stack_start_addr = main_stack_start_addr;
+    size_t stack_size = main_stack_size;
+#endif
+
+    CMB_ASSERT(init_ok);
+    /* only call once */
+    CMB_ASSERT(!on_fault);
+
+    on_fault = true;
+
+    cmb_println("");
+    cm_backtrace_firmware_info();
+
+#ifdef CMB_USING_OS_PLATFORM
+    on_thread_before_fault = fault_handler_lr & (1UL << 2);
+    /* check which stack was used before (MSP or PSP) */
+    if (on_thread_before_fault) {
+        cmb_println(print_info[PRINT_FAULT_ON_THREAD], get_cur_thread_name() != NULL ? get_cur_thread_name() : "NO_NAME");
+        saved_regs_addr = stack_pointer = cmb_get_psp();
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        get_cur_thread_stack_info(stack_pointer, &stack_start_addr, &stack_size);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    } else {
+        cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);
+    }
+#else
+    /* bare metal(no OS) environment */
+    cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);
+#endif /* CMB_USING_OS_PLATFORM */
+
+    /* delete saved R0~R3, R12, LR,PC,xPSR registers space */
+    stack_pointer += sizeof(size_t) * 8;
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \
+    (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+    stack_pointer = statck_del_fpu_regs(fault_handler_lr, stack_pointer);
+#endif /* (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) */
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+    /* check stack overflow */
+    if (stack_pointer < stack_start_addr || stack_pointer > stack_start_addr + stack_size) {
+        stack_is_overflow = true;
+    }
+    /* dump stack information */
+    dump_stack(stack_start_addr, stack_size, (uint32_t *) stack_pointer);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    /* the stack frame may be get failed when it is overflow  */
+    if (!stack_is_overflow) {
+        /* dump register */
+        cmb_println(print_info[PRINT_REGS_TITLE]);
+
+        regs.saved.r0        = ((uint32_t *)saved_regs_addr)[0];  // Register R0
+        regs.saved.r1        = ((uint32_t *)saved_regs_addr)[1];  // Register R1
+        regs.saved.r2        = ((uint32_t *)saved_regs_addr)[2];  // Register R2
+        regs.saved.r3        = ((uint32_t *)saved_regs_addr)[3];  // Register R3
+        regs.saved.r12       = ((uint32_t *)saved_regs_addr)[4];  // Register R12
+        regs.saved.lr        = ((uint32_t *)saved_regs_addr)[5];  // Link register LR
+        regs.saved.pc        = ((uint32_t *)saved_regs_addr)[6];  // Program counter PC
+        regs.saved.psr.value = ((uint32_t *)saved_regs_addr)[7];  // Program status word PSR
+
+        cmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[0], regs.saved.r0,
+                                                                regs_name[1], regs.saved.r1,
+                                                                regs_name[2], regs.saved.r2,
+                                                                regs_name[3], regs.saved.r3);
+        cmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[4], regs.saved.r12,
+                                                                regs_name[5], regs.saved.lr,
+                                                                regs_name[6], regs.saved.pc,
+                                                                regs_name[7], regs.saved.psr.value);
+        cmb_println("==============================================================");
+    }
+
+    /* the Cortex-M0 is not support fault diagnosis */
+#if (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0)
+    regs.syshndctrl.value = CMB_SYSHND_CTRL;  // System Handler Control and State Register
+    regs.mfsr.value       = CMB_NVIC_MFSR;    // Memory Fault Status Register
+    regs.mmar             = CMB_NVIC_MMAR;    // Memory Management Fault Address Register
+    regs.bfsr.value       = CMB_NVIC_BFSR;    // Bus Fault Status Register
+    regs.bfar             = CMB_NVIC_BFAR;    // Bus Fault Manage Address Register
+    regs.ufsr.value       = CMB_NVIC_UFSR;    // Usage Fault Status Register
+    regs.hfsr.value       = CMB_NVIC_HFSR;    // Hard Fault Status Register
+    regs.dfsr.value       = CMB_NVIC_DFSR;    // Debug Fault Status Register
+    regs.afsr             = CMB_NVIC_AFSR;    // Auxiliary Fault Status Register
+
+    fault_diagnosis();
+#endif
+
+    print_call_stack(stack_pointer);
+}

+ 48 - 0
cm_backtrace/cm_backtrace.h

@@ -0,0 +1,48 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * 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.
+ *
+ * Function: It is an head file for this library. You can see all be called functions.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CORTEXM_BACKTRACE_H_
+#define _CORTEXM_BACKTRACE_H_
+
+#include "cmb_def.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void cm_backtrace_init(const char *firmware_name, const char *hardware_ver, const char *software_ver);
+void cm_backtrace_firmware_info(void);
+size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp);
+void cm_backtrace_assert(uint32_t sp);
+void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CORTEXM_BACKTRACE_H_ */

+ 46 - 0
cm_backtrace/cmb_cfg.h

@@ -0,0 +1,46 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * 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.
+ *
+ * Function: It is the configure head file for this library.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CMB_CFG_H_
+#define _CMB_CFG_H_
+#include "SEGGER_RTT.h"
+/* print line, must config by user */
+#define cmb_println(...)       SEGGER_RTT_printf(__VA_ARGS__);SEGGER_RTT_printf("\r\n");        /* e.g., printf(__VA_ARGS__);printf("\r\n")  or  SEGGER_RTT_printf(0, __VA_ARGS__);SEGGER_RTT_WriteString(0, "\r\n")  */
+/* enable bare metal(no OS) platform */
+/* #define CMB_USING_BARE_METAL_PLATFORM */
+/* enable OS platform */
+#define CMB_USING_OS_PLATFORM
+/* OS platform type, must config when CMB_USING_OS_PLATFORM is enable */
+#define CMB_OS_PLATFORM_TYPE   CMB_OS_PLATFORM_FREERTOS        /*CMB_OS_PLATFORM_RTT or CMB_OS_PLATFORM_UCOSII or CMB_OS_PLATFORM_UCOSIII or CMB_OS_PLATFORM_FREERTOS or CMB_OS_PLATFORM_RTX5 */
+/* cpu platform type, must config by user */
+#define CMB_CPU_PLATFORM_TYPE  CMB_CPU_ARM_CORTEX_M4     /* CMB_CPU_ARM_CORTEX_M0 or CMB_CPU_ARM_CORTEX_M3 or CMB_CPU_ARM_CORTEX_M4 or CMB_CPU_ARM_CORTEX_M7 */
+/* enable dump stack information */
+#define CMB_USING_DUMP_STACK_INFO
+/* language of print information */
+/*#define CMB_PRINT_LANGUAGE            /*  CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE */
+#endif /* _CMB_CFG_H_ */

+ 417 - 0
cm_backtrace/cmb_def.h

@@ -0,0 +1,417 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016-2020, Armink, <armink.ztl@gmail.com>
+ *
+ * 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.
+ *
+ * Function: It is the macro definition head file for this library.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CMB_DEF_H_
+#define _CMB_DEF_H_
+
+#include <cmb_cfg.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* library software version number */
+#define CMB_SW_VERSION                "1.4.1"
+
+#define CMB_CPU_ARM_CORTEX_M0             0
+#define CMB_CPU_ARM_CORTEX_M3             1
+#define CMB_CPU_ARM_CORTEX_M4             2
+#define CMB_CPU_ARM_CORTEX_M7             3
+#define CMB_CPU_ARM_CORTEX_M33            4
+
+#define CMB_OS_PLATFORM_RTT               0
+#define CMB_OS_PLATFORM_UCOSII            1
+#define CMB_OS_PLATFORM_UCOSIII           2
+#define CMB_OS_PLATFORM_FREERTOS          3
+#define CMB_OS_PLATFORM_RTX5              4
+
+#define CMB_PRINT_LANGUAGE_ENGLISH        0
+#define CMB_PRINT_LANGUAGE_CHINESE        1
+#define CMB_PRINT_LANGUAGE_CHINESE_UTF8   2
+
+/* name max length, default size: 32 */
+#ifndef CMB_NAME_MAX
+#define CMB_NAME_MAX                      32
+#endif
+
+/* print information language, default is English */
+#ifndef CMB_PRINT_LANGUAGE
+#define CMB_PRINT_LANGUAGE                CMB_PRINT_LANGUAGE_ENGLISH
+#endif
+
+
+#if defined(__ARMCC_VERSION)
+    /* C stack block name, default is STACK */
+    #ifndef CMB_CSTACK_BLOCK_NAME
+    #define CMB_CSTACK_BLOCK_NAME          STACK
+    #endif
+    /* code section name, default is ER_IROM1 */
+    #ifndef CMB_CODE_SECTION_NAME
+    #define CMB_CODE_SECTION_NAME          ER_IROM1
+    #endif
+#elif defined(__ICCARM__)
+    /* C stack block name, default is 'CSTACK' */
+    #ifndef CMB_CSTACK_BLOCK_NAME
+    #define CMB_CSTACK_BLOCK_NAME          "CSTACK"
+    #endif
+    /* code section name, default is '.text' */
+    #ifndef CMB_CODE_SECTION_NAME
+    #define CMB_CODE_SECTION_NAME          ".text"
+    #endif
+#elif defined(__GNUC__)
+    /* C stack block start address, defined on linker script file, default is _sstack */
+    #ifndef CMB_CSTACK_BLOCK_START
+    #define CMB_CSTACK_BLOCK_START         __Stack_start_c0
+    #endif
+    /* C stack block end address, defined on linker script file, default is _estack */
+    #ifndef CMB_CSTACK_BLOCK_END
+    #define CMB_CSTACK_BLOCK_END           __Stack_end_c0
+    #endif
+    /* code section start address, defined on linker script file, default is _stext */
+    #ifndef CMB_CODE_SECTION_START
+    #define CMB_CODE_SECTION_START         acfls_code_rom_start
+    #endif
+    /* code section end address, defined on linker script file, default is _etext */
+    #ifndef CMB_CODE_SECTION_END
+    #define CMB_CODE_SECTION_END           acfls_code_rom_end
+    #endif
+#else
+    #error "not supported compiler"
+#endif
+
+/* supported function call stack max depth, default is 16 */
+#ifndef CMB_CALL_STACK_MAX_DEPTH
+#define CMB_CALL_STACK_MAX_DEPTH       16
+#endif
+
+/* system handler control and state register */
+#ifndef CMB_SYSHND_CTRL
+#define CMB_SYSHND_CTRL                (*(volatile unsigned int*)  (0xE000ED24u))
+#endif
+
+/* memory management fault status register */
+#ifndef CMB_NVIC_MFSR
+#define CMB_NVIC_MFSR                  (*(volatile unsigned char*) (0xE000ED28u))
+#endif
+
+/* bus fault status register */
+#ifndef CMB_NVIC_BFSR
+#define CMB_NVIC_BFSR                  (*(volatile unsigned char*) (0xE000ED29u))
+#endif
+
+/* usage fault status register */
+#ifndef CMB_NVIC_UFSR
+#define CMB_NVIC_UFSR                  (*(volatile unsigned short*)(0xE000ED2Au))
+#endif
+
+/* hard fault status register */
+#ifndef CMB_NVIC_HFSR
+#define CMB_NVIC_HFSR                  (*(volatile unsigned int*)  (0xE000ED2Cu))
+#endif
+
+/* debug fault status register */
+#ifndef CMB_NVIC_DFSR
+#define CMB_NVIC_DFSR                  (*(volatile unsigned short*)(0xE000ED30u))
+#endif
+
+/* memory management fault address register */
+#ifndef CMB_NVIC_MMAR
+#define CMB_NVIC_MMAR                  (*(volatile unsigned int*)  (0xE000ED34u))
+#endif
+
+/* bus fault manage address register */
+#ifndef CMB_NVIC_BFAR
+#define CMB_NVIC_BFAR                  (*(volatile unsigned int*)  (0xE000ED38u))
+#endif
+
+/* auxiliary fault status register */
+#ifndef CMB_NVIC_AFSR
+#define CMB_NVIC_AFSR                  (*(volatile unsigned short*)(0xE000ED3Cu))
+#endif
+
+/**
+ * Cortex-M fault registers
+ */
+struct cmb_hard_fault_regs{
+  struct {
+    unsigned int r0;                     // Register R0
+    unsigned int r1;                     // Register R1
+    unsigned int r2;                     // Register R2
+    unsigned int r3;                     // Register R3
+    unsigned int r12;                    // Register R12
+    unsigned int lr;                     // Link register
+    unsigned int pc;                     // Program counter
+    union {
+      unsigned int value;
+      struct {
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+        unsigned int IPSR : 9;           // Interrupt Program Status register (IPSR)
+        unsigned int EPSR : 18;          // Execution Program Status register (EPSR)
+        unsigned int APSR : 5;           // Application Program Status register (APSR)
+#else
+        unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)
+        unsigned int EPSR : 19;          // Execution Program Status register (EPSR)
+        unsigned int APSR : 5;           // Application Program Status register (APSR)
+#endif
+      } bits;
+    } psr;                               // Program status register.
+  } saved;
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active
+      unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+      unsigned int HARDFAULTACT   : 1;   // Read as 1 if hardfault is active
+#else
+      unsigned int UnusedBits1    : 1;
+#endif
+      unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+      unsigned int SECUREFAULTACT : 1;   // Read as 1 if secure fault exception is active
+      unsigned int NMIACT         : 1;   // Read as 1 if NMI exception is active
+      unsigned int UnusedBits2    : 1;
+#else
+      unsigned int UnusedBits2    : 3;
+#endif
+      unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
+      unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active
+      unsigned int UnusedBits3    : 1;
+      unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active
+      unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
+      unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a higher-priority exception
+      unsigned int MEMFAULTPENDED : 1;   // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
+      unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
+      unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority exception
+      unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
+      unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable
+      unsigned int USGFAULTENA    : 1;   // Usage fault handler enable
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+      unsigned int SECUREFAULTENA : 1;   // Secure fault handler enable
+      unsigned int SECUREFAULTPENDED : 1;   // Secure fault pended; Secure fault handler was started but was replaced by a higher-priority exception
+      unsigned int HARDFAULTPENDED   : 1;   // Hard fault pended; Hard fault handler was started but was replaced by a higher-priority exception
+#else
+      // None
+#endif
+    } bits;
+  } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
+
+  union {
+    unsigned char value;
+    struct {
+      unsigned char IACCVIOL    : 1;     // Instruction access violation
+      unsigned char DACCVIOL    : 1;     // Data access violation
+      unsigned char UnusedBits  : 1;
+      unsigned char MUNSTKERR   : 1;     // Unstacking error
+      unsigned char MSTKERR     : 1;     // Stacking error
+      unsigned char MLSPERR     : 1;     // Floating-point lazy state preservation (M4/M7)
+      unsigned char UnusedBits2 : 1;
+      unsigned char MMARVALID   : 1;     // Indicates the MMAR is valid
+    } bits;
+  } mfsr;                                // Memory Management Fault Status Register (0xE000ED28)
+  unsigned int mmar;                     // Memory Management Fault Address Register (0xE000ED34)
+
+  union {
+    unsigned char value;
+    struct {
+      unsigned char IBUSERR    : 1;      // Instruction access violation
+      unsigned char PRECISERR  : 1;      // Precise data access violation
+      unsigned char IMPREISERR : 1;      // Imprecise data access violation
+      unsigned char UNSTKERR   : 1;      // Unstacking error
+      unsigned char STKERR     : 1;      // Stacking error
+      unsigned char LSPERR     : 1;      // Floating-point lazy state preservation (M4/M7)
+      unsigned char UnusedBits : 1;
+      unsigned char BFARVALID  : 1;      // Indicates BFAR is valid
+    } bits;
+  } bfsr;                                // Bus Fault Status Register (0xE000ED29)
+  unsigned int bfar;                     // Bus Fault Manage Address Register (0xE000ED38)
+
+  union {
+    unsigned short value;
+    struct {
+      unsigned short UNDEFINSTR : 1;     // Attempts to execute an undefined instruction
+      unsigned short INVSTATE   : 1;     // Attempts to switch to an invalid state (e.g., ARM)
+      unsigned short INVPC      : 1;     // Attempts to do an exception with a bad value in the EXC_RETURN number
+      unsigned short NOCP       : 1;     // Attempts to execute a coprocessor instruction
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)
+      unsigned short STKOF      : 1;     // Indicates a stack overflow error has occured
+      unsigned short UnusedBits : 3;
+#else
+      unsigned short UnusedBits : 4;
+#endif
+      unsigned short UNALIGNED  : 1;     // Indicates that an unaligned access fault has taken place
+      unsigned short DIVBYZERO0 : 1;     // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
+    } bits;
+  } ufsr;                                // Usage Fault Status Register (0xE000ED2A)
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int UnusedBits  : 1;
+      unsigned int VECTBL      : 1;      // Indicates hard fault is caused by failed vector fetch
+      unsigned int UnusedBits2 : 28;
+      unsigned int FORCED      : 1;      // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
+      unsigned int DEBUGEVT    : 1;      // Indicates hard fault is triggered by debug event
+    } bits;
+  } hfsr;                                // Hard Fault Status Register (0xE000ED2C)
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int HALTED   : 1;         // Halt requested in NVIC
+      unsigned int BKPT     : 1;         // BKPT instruction executed
+      unsigned int DWTTRAP  : 1;         // DWT match occurred
+      unsigned int VCATCH   : 1;         // Vector fetch occurred
+      unsigned int EXTERNAL : 1;         // EDBGRQ signal asserted
+    } bits;
+  } dfsr;                                // Debug Fault Status Register (0xE000ED30)
+
+  unsigned int afsr;                     // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
+};
+
+/* assert for developer. */
+#define CMB_ASSERT(EXPR)                                                       \
+if (!(EXPR))                                                                   \
+{                                                                              \
+    cmb_println("(%s) has assert failed at %s.", #EXPR, __FUNCTION__);         \
+    while (1);                                                                 \
+}
+
+/* ELF(Executable and Linking Format) file extension name for each compiler */
+#if defined(__ARMCC_VERSION)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".axf"
+#elif defined(__ICCARM__)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".out"
+#elif defined(__GNUC__)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".elf"
+#else
+    #error "not supported compiler"
+#endif
+
+#ifndef cmb_println
+    #error "cmb_println isn't defined in 'cmb_cfg.h'"
+#endif
+
+#ifndef CMB_CPU_PLATFORM_TYPE
+    #error "CMB_CPU_PLATFORM_TYPE isn't defined in 'cmb_cfg.h'"
+#endif
+
+#if (defined(CMB_USING_BARE_METAL_PLATFORM) && defined(CMB_USING_OS_PLATFORM))
+    #error "CMB_USING_BARE_METAL_PLATFORM and CMB_USING_OS_PLATFORM only one of them can be used"
+#elif defined(CMB_USING_OS_PLATFORM)
+    #if !defined(CMB_OS_PLATFORM_TYPE)
+        #error "CMB_OS_PLATFORM_TYPE isn't defined in 'cmb_cfg.h'"
+    #endif /* !defined(CMB_OS_PLATFORM_TYPE) */
+    #if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+        #include <rtthread.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+        #include <ucos_ii.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+        #include <os.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)
+        #include <FreeRTOS.h>  
+        extern uint32_t *vTaskStackAddr(void);/* need to modify the FreeRTOS/tasks source code */
+        extern uint32_t vTaskStackSize(void);
+        extern char * vTaskName(void);
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTX5)
+        #include "rtx_os.h"
+    #else
+        #error "not supported OS type"
+    #endif /* (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT) */
+#endif /* (defined(CMB_USING_BARE_METAL_PLATFORM) && defined(CMB_USING_OS_PLATFORM)) */
+
+/* include or export for supported cmb_get_msp, cmb_get_psp and cmb_get_sp function */
+#if defined(__CC_ARM)
+    static __inline __asm uint32_t cmb_get_msp(void) {
+        mrs r0, msp
+        bx lr
+    }
+    static __inline __asm uint32_t cmb_get_psp(void) {
+        mrs r0, psp
+        bx lr
+    }
+    static __inline __asm uint32_t cmb_get_sp(void) {
+        mov r0, sp
+        bx lr
+    }
+#elif defined(__clang__)
+    __attribute__( (always_inline) ) static __inline uint32_t cmb_get_msp(void) {
+        uint32_t result;
+        __asm volatile ("mrs %0, msp" : "=r" (result) );
+        return (result);
+    }
+    __attribute__( (always_inline) ) static __inline uint32_t cmb_get_psp(void) {
+        uint32_t result;
+        __asm volatile ("mrs %0, psp" : "=r" (result) );
+        return (result);
+    }
+    __attribute__( (always_inline) ) static __inline uint32_t cmb_get_sp(void) {
+        uint32_t result;
+        __asm volatile ("mov %0, sp" : "=r" (result) );
+        return (result);
+    }
+#elif defined(__ICCARM__)
+/* IAR iccarm specific functions */
+/* Close Raw Asm Code Warning */  
+#pragma diag_suppress=Pe940    
+    static uint32_t cmb_get_msp(void)
+    {
+      __asm("mrs r0, msp");
+      __asm("bx lr");        
+    }
+    static uint32_t cmb_get_psp(void)
+    {
+      __asm("mrs r0, psp");
+      __asm("bx lr");        
+    }
+    static uint32_t cmb_get_sp(void)
+    {
+      __asm("mov r0, sp");
+      __asm("bx lr");       
+    }
+#pragma diag_default=Pe940  
+#elif defined(__GNUC__)
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_msp(void) {
+        register uint32_t result;
+        __asm volatile ("MRS %0, msp\n" : "=r" (result) );
+        return(result);
+    }
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_psp(void) {
+        register uint32_t result;
+        __asm volatile ("MRS %0, psp\n" : "=r" (result) );
+        return(result);
+    }
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_sp(void) {
+        register uint32_t result;
+        __asm volatile ("MOV %0, sp\n" : "=r" (result) );
+        return(result);
+    }
+#else
+    #error "not supported compiler"
+#endif
+
+#endif /* _CMB_DEF_H_ */

+ 43 - 0
cm_backtrace/fault_handler/gcc/cmb_fault.S

@@ -0,0 +1,43 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * 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.
+ *
+ * Function: Fault handler by GCC assembly code
+ * Created on: 2016-12-16
+ */
+
+.syntax unified
+.thumb
+.text
+
+/* NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file. */
+
+.global HardFault_Handler
+.type HardFault_Handler, %function
+HardFault_Handler:
+    MOV     r0, lr                  /* get lr */
+    MOV     r1, sp                  /* get stack pointer (current is MSP) */
+    BL      cm_backtrace_fault
+
+Fault_Loop:
+    BL      Fault_Loop              /* while(1) */

+ 47 - 0
cm_backtrace/fault_handler/iar/cmb_fault.S

@@ -0,0 +1,47 @@
+;/*
+; * This file is part of the CmBacktrace Library.
+; *
+; * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+; *
+; * 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.
+; *
+; * Function: Fault handler by EWARM assembly code
+; * Created on: 2016-12-16
+; */
+/*
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+; NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file.
+    IMPORT cm_backtrace_fault
+    EXPORT HardFault_Handler
+
+HardFault_Handler:
+    MOV     r0, lr                  ; get lr
+    MOV     r1, sp                  ; get stack pointer (current is MSP)
+    BL      cm_backtrace_fault
+
+Fault_Loop
+    BL      Fault_Loop              ;while(1)
+
+    END
+*/

+ 48 - 0
cm_backtrace/fault_handler/keil/cmb_fault.S

@@ -0,0 +1,48 @@
+;/*
+; * This file is part of the CmBacktrace Library.
+; *
+; * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+; *
+; * 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.
+; *
+; * Function: Fault handler by MDK-ARM assembly code
+; * Created on: 2016-12-16
+; */
+/*
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+; NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file.
+    IMPORT cm_backtrace_fault
+    EXPORT HardFault_Handler
+
+HardFault_Handler    PROC
+    MOV     r0, lr                  ; get lr
+    MOV     r1, sp                  ; get stack pointer (current is MSP)
+    BL      cm_backtrace_fault
+
+Fault_Loop
+    BL      Fault_Loop              ;while(1)
+    ENDP
+
+    END
+*/

+ 1 - 1
src/AppGlobalVar.h

@@ -25,7 +25,7 @@
 #define BATT_SN_LEN 17
 #define HWVERSION 0x0001
 #define BLSWVERSION 0x00000002
-#define DRVSWVERSION 0x00000002
+#define DRVSWVERSION 0x00000003
 #define APPSWVERSION 0x00000006
 #define BMS_MANUFACTURE 0xFF
 #define BMS_INFO 0xFF

+ 10 - 0
src/AppTaskMain.c

@@ -27,6 +27,16 @@ void MainTask(void *pvParameters)
 	#endif
 	while(1)
 	{
+//#if SEGGER_PRINTF==1
+//		static uint32 tempcounter = 0;
+//			if((TimerCounter - tempcounter)>1000)
+//			{
+//				tempcounter = TimerCounter;
+//				UBaseType_t uxHighWaterMark;
+//				uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
+//				SEGGER_RTT_printf("[%d] %s->%d\r\n",__LINE__,__func__,uxHighWaterMark);
+//			}
+//#endif
 		vTaskDelay(pdMS_TO_TICKS(10));
 		if(HAL_Is100msTickTimeout())
 		{

+ 0 - 3
src/AppTaskUart0.c

@@ -32,9 +32,6 @@ void Uart0Task(void *pvParameters)
 			vTaskDelay(pdMS_TO_TICKS(10));
 			if ((TimerCounter % 1000) == 0 && 1)
 			{
-#if SEGGER_PRINTF==1
-			SEGGER_RTT_printf("[%d]TimerCounter=%d\r\n",__LINE__,TimerCounter);
-#endif
 				PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_READ);
 			}
 			else if (TimerCounter % 100 == 0)

+ 38 - 24
src/AppTaskUart1.c

@@ -51,7 +51,7 @@ void Uart_4G_Task(void *pvParameters)
 	(void)pvParameters;
 	uint32 SendTimerCounter = 0;
 	uint32 RecvTimerDelay = 0;
-	uint8 UartRecvPtr[256];
+	uint8 UartRecvPtr[512];
 	volatile uint16 tcpErrorCounter = 0;
 	uint16 pReadLen = 0;
 	// 4G开机
@@ -60,7 +60,7 @@ void Uart_4G_Task(void *pvParameters)
 	vTaskDelay(pdMS_TO_TICKS(50));
 	Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON);
 	vTaskDelay(pdMS_TO_TICKS(50));
-	vTaskDelay(pdMS_TO_TICKS(10000));
+	AtcmdDelayRecvFunc(UART_LPUART1,(char *)("SMS DONE"),30000);
 	Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF);
 	_4G_Status = Dio_ReadChannel(DioConf_DioChannel_PTB1_GPIO_IN_MCU_4G_STATUS);
 	InitFunc(); // 4G模块初始化,注:AT同步不通过,没有进行次数判定及跳转
@@ -180,7 +180,7 @@ void Uart_4G_Task(void *pvParameters)
 				vTaskDelay(pdMS_TO_TICKS(2500));
 				Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF);
 				vTaskDelay(pdMS_TO_TICKS(2500));
-				SystemSoftwareReset();
+				tcpErrorCounter = 0;
 			}
 			PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
 			break;
@@ -294,7 +294,7 @@ sint8 TcpConnectFunc(sint8 *ConnectId)
 		}
 		case 4: //创建连接
 		{
-			char AtCmdSend[40] = {0};
+			char AtCmdSend[50] = {0};
 			uint8 AtCmdSendTotalLen = 0;
 			*ConnectId = 0;
 			/*IP测试更改*/
@@ -388,7 +388,7 @@ void InitFunc(void)
 	// 4G模块初始化
 	uint8 _4G_InitStep = 0;
 	sint8 ATRet = -1;
-	uint8 ReadLen = 0;
+	uint16 ReadLen = 0;
 	char *ATCmdSend = NULL;
 	uint8 ATCmdSendLen = 0;
 	uint8 UartRecvPtr[50];
@@ -684,6 +684,7 @@ sint8 at_callbackFunc(char *PSendStr, char *pReadStr, uint8 CmdIdx, uint16 pRead
 void TcpDataEncode(uint32 *PtrSendAddr, uint16 *SendLen)
 {
 	UTC8TimeType UTC8TimeTcp;
+	uint8 *SendBuffer = NULL;
 	uint8 DataIdx = 0;
 	static uint32 TcpSendTimeCounter = 0;
 	TcpSendTimeCounter++;
@@ -719,7 +720,7 @@ void TcpDataEncode(uint32 *PtrSendAddr, uint16 *SendLen)
 		return;
 	}
 	GetUtc8Time(&UTC8TimeTcp); //时间获取
-	uint8 *SendBuffer = NULL;
+	vTaskDelay(pdMS_TO_TICKS(100));
 	switch (DataIdx)
 	{
 	case 0x82:
@@ -1086,7 +1087,7 @@ void GetUtc8Time(UTC8TimeType *UTC8TimeTcp)
 {
 	char *AtCmdAsk = (char *)("AT+CCLK?\r\n");
 	uint8 AtCmdLen = mstrlen(AtCmdAsk);
-	uint8 ReadLen = 0;
+	uint16 ReadLen = 0;
 	uint8 *retptr = NULL;
 	uint8 UartRecvPtr[128];
 	UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdAsk, AtCmdLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
@@ -1108,7 +1109,7 @@ static void GetCSQValue(uint8 *out)
 {
 	char *AtCmdAsk = (char *)("AT+CSQ\r\n");
 	uint8 AtCmdLen = mstrlen(AtCmdAsk);
-	uint8 ReadLen = 0;
+	uint16 ReadLen = 0;
 	uint8 *retptr = NULL;
 	uint8 UartRecvPtr[30];
 	UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdAsk, AtCmdLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
@@ -1329,7 +1330,7 @@ sint8 tcpipConnectionSend(uint8 TcpConnectId, uint8 *SendDataPtr, uint16 SendDat
 {
 	sint8 outValue = -1;
 	uint8  sendErrConuter= 0;
-	uint8 ReadLen = 0;
+	uint16 ReadLen = 0;
 	char AtCmdSend[30] = {0};
 	uint8 AtCmdSendTotalLen = 0;
 	uint8 UartRecvPtr[30];
@@ -1339,7 +1340,7 @@ sint8 tcpipConnectionSend(uint8 TcpConnectId, uint8 *SendDataPtr, uint16 SendDat
 	while(outValue!=0&&sendErrConuter<3)
 	{
 		ret = UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdSend, AtCmdSendTotalLen, UartRecvPtr, &ReadLen, 5000);
-		if (((ret==0)&&(ReadLen>0)&&((uint8 *)strstr((char *)UartRecvPtr, (char *)(">"))))||0)//一个字节收不到的问题,IDE中断间隔过大不行
+		if (((ret==0)&&(ReadLen>0)&&((uint8 *)strstr((char *)UartRecvPtr, (char *)(">"))))||1)//一个字节收不到的问题,IDE中断间隔过大不行,同时收不到> 引起AT指令不回的问题
 		{
 			UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)SendDataPtr, SendDataLen, UartRecvPtr, &ReadLen, 5000);
 			if (ReadLen>0&&(uint8 *)strstr((char *)UartRecvPtr, (char *)("\r\nOK\r\n\r\n+CIPSEND")))
@@ -1369,7 +1370,7 @@ void Fota_Ftp(uint8 *dataPtrIn)
 	char *ATCmdSend = NULL;
 	sint8 recvRet = -1;
 	char ATSendDataBuffer[100] = {0};
-	uint8 UartRecvBuffer[20];
+	uint8 UartRecvBuffer[50];
 	uint16 ReadLen = 0;
 	uint8 *retptr = NULL;
 //	char temp[70]=",qx,qx900,120.27.243.131,21,0,0.0.1.5,0.0.1.5,/Debug/V0.0.1.5.bin,";
@@ -1386,10 +1387,10 @@ void Fota_Ftp(uint8 *dataPtrIn)
 	p = strtok((char *)dataPtrIn, ",");
 	uint8 index = 0;
 	uint8 ftp_EndFlg = 0;
-	while (p)
+	while (p&&index<20)
 	{
 		databuffer[index] = p;
-		p = strtok(NULL, ",");
+		p = strtok(NULL, ",");//报硬件错误
 		index++;
 	}
 	accountPtr = databuffer[0];
@@ -1412,9 +1413,6 @@ void Fota_Ftp(uint8 *dataPtrIn)
 	while(!ftp_EndFlg)
 	{
 		vTaskDelay(pdMS_TO_TICKS(100));
-#if UARTPRINTF==1
-	myPrintf("ftpProcess-%d",ftp_process);
-#endif
 		switch(ftp_process)
 		{
 		case 0://start
@@ -1484,7 +1482,7 @@ void Fota_Ftp(uint8 *dataPtrIn)
 		case 4://logout
 		{
 			ATCmdSend = (char *)("AT+CFTPSLOGOUT\r\n");
-			UART_Send_Data(UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), pdMS_TO_TICKS(100));
+			UART_Send_Data(UART_LPUART1, ATCmdSend, mstrlen(ATCmdSend), pdMS_TO_TICKS(100));
 			recvRet = AtcmdDelayRecvFunc(UART_LPUART1,(char *)("+CFTPSLOGOUT: 0"),2000);
 			if(recvRet==0)
 			{
@@ -1514,7 +1512,6 @@ void Fota_Ftp(uint8 *dataPtrIn)
 		case 6://get data from module
 		{
 			char findDataBuffer[25] = {0};
-			uint8 *UartData = NULL;
 			uint32 currentAddr = 0;
 			uint16 readLenAsk = 256;
 	        uint16 FotaRecvDataLen_8 = 0;
@@ -1522,6 +1519,11 @@ void Fota_Ftp(uint8 *dataPtrIn)
 	        uint32 FlashAddStart = 0;
 	        uint32 appReceviedCRC;
 	        uint16 getDataLenErrCount = 0;
+	        uint8 *UartData = NULL;
+	        UartData = malloc(512);
+#if SEGGER_PRINTF==1
+    	SEGGER_RTT_printf("[%d]UartData1=%X\r\n",__LINE__,UartData);
+#endif
 	        memset(ATSendDataBuffer,0x00,sizeof(ATSendDataBuffer));
 			sprintf(ATSendDataBuffer, "AT+CFTRANTX=\"c:/%s\"\r\n",keyFilename);
 			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartRecvBuffer, &ReadLen, pdMS_TO_TICKS(5000));
@@ -1538,12 +1540,15 @@ void Fota_Ftp(uint8 *dataPtrIn)
 	                Hal_SetAppInfo(fileLen, appReceviedCRC, CONTROLLER_SELF);
 					while(readLenAsk!=0)
 					{
+#if SEGGER_PRINTF==1
+    	SEGGER_RTT_printf("[%d]UartData2=%X\r\n",__LINE__,UartData);
+#endif
+						memset(UartData,0x00,512);
 						memset(ATSendDataBuffer,0x00,sizeof(ATSendDataBuffer));
 						sprintf(ATSendDataBuffer, "AT+CFTRANTX=\"c:/%s\",%d,%d\r\n", filenamePtr,currentAddr, readLenAsk);
-						UartData = malloc(readLenAsk+50);
-						UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), &UartData, &ReadLen, pdMS_TO_TICKS(5000));
+						UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartData, &ReadLen, pdMS_TO_TICKS(5000));
 						sprintf(findDataBuffer, "+CFTRANTX: DATA,%d", readLenAsk);
-						if (ReadLen == (readLenAsk+45))
+						if (ReadLen == (readLenAsk+strlen(findDataBuffer)+26))
 						{
 							retptr = (uint8 *)strstr((char *)UartData, findDataBuffer);
 							if (retptr)
@@ -1554,21 +1559,29 @@ void Fota_Ftp(uint8 *dataPtrIn)
 								//数据处理区域
 								currentAddr = currentAddr + readLenAsk;
 								readLenAsk = min(fileLen-currentAddr,readLenAsk);
+								getDataLenErrCount = 0;
+							}
+							else
+							{
+								getDataLenErrCount++;
 							}
 						}
 						else
 						{
 							getDataLenErrCount++;
 						}
-						free(UartData);
-						if(getDataLenErrCount>=500)
+						if(getDataLenErrCount>=50)
 						{
 							break;
 						}
 					}
-	                if(getDataLenErrCount<500&&Hal_FlsCheckIsTransferSucceed()==TRUE)
+	                if(getDataLenErrCount<50&&Hal_FlsCheckIsTransferSucceed()==TRUE)
 	                {
 	                	ftp_process++;
+	                }
+	                else
+	                {
+	                	ftp_EndFlg = 1;
 	                }
 				}
 			}
@@ -1576,6 +1589,7 @@ void Fota_Ftp(uint8 *dataPtrIn)
 			{
 				ftp_EndFlg = 1;
 			}
+			free(UartData);
 			break;
 		}
 		case 7://delete the bin and zl files

+ 3 - 1
src/Hal_Fls.c

@@ -224,7 +224,9 @@ static uint8 FlashChecksum(void)
 {
     uint32 xCountCrc = 0u;
     CRC_HAL_CreatSoftwareCrc((const uint8 *)(gs_stAppDownloadInfo.appVectoTableStartAddr + APP_FLAST_START_PHY_ADDR), gs_stAppDownloadInfo.appLength, &xCountCrc);
-
+#if SEGGER_PRINTF==1
+	SEGGER_RTT_printf("[%d]%X==%X\r\n",__LINE__,gs_stAppDownloadInfo.receivedCRC,xCountCrc);
+#endif
     if(gs_stAppDownloadInfo.receivedCRC == xCountCrc)
     {
     	return TRUE;

+ 20 - 10
src/hal_adapter.c

@@ -18,8 +18,6 @@ volatile Uart_StatusType Uart_TransmitStatus[3] = {UART_STATUS_TIMEOUT,UART_STAT
 QueueHandle_t UartRecvQueue[3];
 QueueHandle_t UartSendQueue[3];
 QueueHandle_t UartHalQueueHandle;
-void Uart_Hal_RecvTask(void *pvParameters);
-void Uart_Hal_SendTask(void *pvParameters);
 Std_ReturnType UartStartRecvFunc(uint8 channel);
 Std_ReturnType ADC_Converter(Adc_ValueGroupType *Buffer, TP_Value_Type *ConvertedValueR);
 void create_ringBuffer(ringbuffer_t *ringBuf, uint8_t *buf, uint32_t buf_len);
@@ -36,13 +34,13 @@ sint8 AtcmdDelayRecvFunc(uint8 recvChannel,char *ResultStrPtr,uint16 delayTime)
 {
 	sint8 outValue = -1;
 	uint8 delayCnt = 0;
-	uint8 UartData[50];
+	uint8 UartData[256];
 	uint16 ReadLen = 0;
-	uint8 *retptr = NULL;
+	char *retptr = NULL;
 	while (delayCnt<(delayTime/1000)&&outValue!=0)
 	{
 		UART_Receive_Data(recvChannel,UartData, &ReadLen,1000);
-		retptr = (uint8 *)strstr((char *)UartData, ResultStrPtr);
+		retptr = (char *)strstr((char *)UartData, ResultStrPtr);
 		if (retptr)
 		{
 			outValue = 0;
@@ -100,6 +98,7 @@ uint32_t write_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
     uint8_t *ringBuf_source = ringBuf->source;
     if( (ringBuf_bw + size) <= ringBuf_len  )
     {
+    	memset(ringBuf_source + ringBuf_bw, 0x00, size);
         memcpy(ringBuf_source + ringBuf_bw, buffer, size);
     }
     else
@@ -118,6 +117,12 @@ uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
     uint32_t ringBuf_br     = ringBuf->br;
     uint32_t ringBuf_len    = ringBuf->length;
     uint8_t *ringBuf_source = ringBuf->source;
+#if SEGGER_PRINTF==1
+    if(ringBuf_source==0x1fffa63c)
+    {
+    	SEGGER_RTT_printf("[%d]buffer=%X,ringBuf_len=%d-%d-%d\r\n",__LINE__,buffer,ringBuf_len,ringBuf_br,size);
+    }
+#endif
     if( (ringBuf_br + size ) <= ringBuf_len )
     {
         memcpy(buffer, ringBuf_source + ringBuf_br, size);
@@ -132,8 +137,7 @@ uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
     ringBuf->btoRead -= size;
     return size;
 }
-
-Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint8 *rxlen, uint32 T_timeout)
+Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
 {
 	uint16 queueRecvSize = 0;
 	UartMsg_t UartSendMsg;
@@ -179,6 +183,12 @@ Std_ReturnType UART_Receive_Data(uint8 recvChannel, uint8 *rxBuffer, uint8 *rxle
 	}
 	return retVal;
 }
+Std_ReturnType UART_Reset(uint8 recvChannel)
+{
+	uint32 retVal = E_NOT_OK;
+	retVal = xQueueReset(UartRecvQueue[recvChannel]);
+	return retVal;
+}
 Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32 sendLength, uint32 T_timeout)
 {
 	UartMsg_t UartSendMsg;
@@ -206,8 +216,8 @@ Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32
 	 UartSendQueue[2] = xQueueCreate(1, sizeof(UartMsg_t));
 	 UartHalQueueHandle = xQueueCreate(9, sizeof(UartHalMsg_t));
 
-	 xTaskCreate(Uart_Hal_RecvTask, (const char *const)"UartRecv", 1024, (void *)0, main_TASK_PRIORITY + 5, NULL);
-	 xTaskCreate(Uart_Hal_SendTask, (const char *const)"UartSend", 1024, (void *)0, main_TASK_PRIORITY + 4, NULL);
+	 xTaskCreate(Uart_Hal_RecvTask, (const char *const)"UartRecv", 256, (void *)0, main_TASK_PRIORITY + 5, NULL);
+	 xTaskCreate(Uart_Hal_SendTask, (const char *const)"UartSend", 256, (void *)0, main_TASK_PRIORITY + 4, NULL);
  }
  Std_ReturnType UartStartRecvFunc(uint8 channel)
  {
@@ -285,7 +295,7 @@ Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32
 #if SEGGER_PRINTF==1
 					if(UartHalMsgRecv.Channel==1)
 					{
-						SEGGER_RTT_printf("[%d]uart1_r=%s\r\n",__LINE__,RX_Buffer[UartHalMsgRecv.Channel]);
+						SEGGER_RTT_printf("[%d]Len=%d-%d,uart1_r=%s\r\n",__LINE__,recvSize,UartHalMsgRecv.value,RX_Buffer[UartHalMsgRecv.Channel]);
 					}
 #endif
 					T_timeout[UartHalMsgRecv.Channel] = 0;

+ 4 - 2
src/hal_adapter.h

@@ -78,7 +78,8 @@ typedef signed long INT32;
 #define NUM_RESULTS ADC_CFGSET_VS_0_GROUP_0_CHANNELS
 #define BUFFER_SIZE 512
 #define DMA_SIZE 128
-
+void Uart_Hal_RecvTask(void *pvParameters);
+void Uart_Hal_SendTask(void *pvParameters);
 typedef struct {
     uint8_t *source;
     uint32_t br;
@@ -236,9 +237,10 @@ Std_ReturnType HAL_EEP_Write(uint32 eepWriteStartAddr, uint8 *pDataNeedtoWrite,
 Std_ReturnType HAL_EEP_Compare(uint32 eepCompareStartAddr, uint8 *pDataNeedtoCompare, uint32 dataSize);
 Std_ReturnType ADC_ReadValue(void);
 sint8 AtcmdDelayRecvFunc(uint8 recvChannel,char *ResultStrPtr,uint16 delayTime);
-Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint8 *rxlen, uint32 T_timeout);
+Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout);
 Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32 sendLength, uint32 T_timeout);
 Std_ReturnType UART_Receive_Data(uint8 recvChannel, uint8 *rxBuffer, uint8 *rxlen, uint32 T_timeout);
+Std_ReturnType UART_Reset(uint8 recvChannel);
 void UART_Callback(uint32 hwInstance, Lpuart_Uart_Ip_EventType event);
 void UartInit(void);
 void SystemSoftwareReset(void);

+ 8 - 8
src/main.c

@@ -62,9 +62,10 @@
 #include "AppTaskGps.h"
 #include "Hal_Fls.h"
 
-
-
-
+#include "cm_backtrace.h"
+#define APPNAME                        "S32K146_4G"
+#define HARDWARE_VERSION               "V1.0.0"
+#define SOFTWARE_VERSION               "V0.0.1"
 int main(void)
 {
  	volatile int exit_code = 0;
@@ -169,15 +170,15 @@ int main(void)
 	Dio_WriteChannel(DioConf_DioChannel_PTE9_GPIO_OUT_MCU_LED5, STD_OFF);
 	Mcu_ResetType bootreason;
 	bootreason = Mcu_GetResetReason();
+	cm_backtrace_init(APPNAME,HARDWARE_VERSION,SOFTWARE_VERSION);
 #if SEGGER_PRINTF==1
 	SEGGER_RTT_Init();
 	SEGGER_RTT_printf("[%d] boot -%d\r\n",__LINE__,bootreason);
 #endif
-//	vTaskDelay(pdMS_TO_TICKS(100));
 	UartInit();
-	xTaskCreate(MainTask, (const char *const)"MainTask", 512, (void *)0, main_TASK_PRIORITY + 3, NULL);
-	xTaskCreate(Uart0Task, (const char *const)"Uart0_Bms_Task", 2048, (void *)0, main_TASK_PRIORITY + 2, NULL);
-//	xTaskCreate(CanTask, (const char *const)"CanTask", 512, (void *)0, main_TASK_PRIORITY + 2, NULL);
+	xTaskCreate(MainTask, (const char *const)"MainTask", 256, (void *)0, main_TASK_PRIORITY + 3, NULL);
+	xTaskCreate(Uart0Task, (const char *const)"Uart0_Bms_Task", 1024, (void *)0, main_TASK_PRIORITY + 2, NULL);
+	xTaskCreate(CanTask, (const char *const)"CanTask", 512, (void *)0, main_TASK_PRIORITY + 2, NULL);
 	xTaskCreate(GpsTask, (const char *const)"GpsTask", 512, (void *)0, main_TASK_PRIORITY + 1, NULL);
 	xTaskCreate(Uart_4G_Task, (const char *const)"Uart_4G_Task", 2048, (void *)0, main_TASK_PRIORITY + 0, NULL);
 	vTaskStartScheduler();
@@ -190,5 +191,4 @@ int main(void)
 	}
 	return exit_code;
 }
-
 /** @} */