增加内存管理模块,重载new和delete,方便调试堆溢出

增加调试管理模块,调试使用的主要代码实现在此
This commit is contained in:
nnhy 2014-08-18 17:37:02 +00:00
parent 32b7598933
commit dbffea32b9
7 changed files with 96 additions and 51 deletions

47
Debug.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "Sys.h"
// 仅用于调试使用的一些函数实现RTM不需要
#if DEBUG
void* operator new(uint size)
{
debug_printf("new size: %d\r\n", size);
void * p = malloc(size);
return p;
}
void operator delete(void * p)
{
debug_printf("delete 0x%08x\r\n", p);
if(p) free(p);
}
void operator delete [] (void * p)
{
debug_printf("delete[] 0x%08x\r\n", p);
if(p) free(p);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: debug_printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/*if(_printf_sp) */debug_printf("Assert Failed! Line %d, %s\r\n", line, file);
/* Infinite loop */
while (1) { }
}
#endif
#endif

View File

@ -16,10 +16,6 @@
*/ */
TInterrupt Interrupt; TInterrupt Interrupt;
void IntcHandler(); // 标准中断处理
uint GetInterruptNumber(); // 获取中断号
void FAULT_SubHandler();
// 没有必要重定向中断向量表把所有中断硬编码指向IntcHandler和FAULT_SubHandler即可 // 没有必要重定向中断向量表把所有中断硬编码指向IntcHandler和FAULT_SubHandler即可
// 真正的向量表 64k=0x10000 // 真正的向量表 64k=0x10000
@ -52,15 +48,15 @@ void TInterrupt::Init()
#if VEC_TABLE_ON_RAM #if VEC_TABLE_ON_RAM
memset((void*)_Vectors, 0, VectorySize << 2); memset((void*)_Vectors, 0, VectorySize << 2);
_Vectors[2] = (Func)&FAULT_SubHandler; // NMI _Vectors[2] = (Func)&FaultHandler; // NMI
_Vectors[3] = (Func)&FAULT_SubHandler; // Hard Fault _Vectors[3] = (Func)&FaultHandler; // Hard Fault
_Vectors[4] = (Func)&FAULT_SubHandler; // MMU Fault _Vectors[4] = (Func)&FaultHandler; // MMU Fault
_Vectors[5] = (Func)&FAULT_SubHandler; // Bus Fault _Vectors[5] = (Func)&FaultHandler; // Bus Fault
_Vectors[6] = (Func)&FAULT_SubHandler; // Usage Fault _Vectors[6] = (Func)&FaultHandler; // Usage Fault
_Vectors[11] = (Func)&FAULT_SubHandler; // SVC _Vectors[11] = (Func)&FaultHandler; // SVC
_Vectors[12] = (Func)&FAULT_SubHandler; // Debug _Vectors[12] = (Func)&FaultHandler; // Debug
_Vectors[14] = (Func)&FAULT_SubHandler; // PendSV _Vectors[14] = (Func)&FaultHandler; // PendSV
_Vectors[15] = (Func)&FAULT_SubHandler; // Systick _Vectors[15] = (Func)&FaultHandler; // Systick
#ifdef STM32F10X #ifdef STM32F10X
__DMB(); // 确保中断表已经被写入 __DMB(); // 确保中断表已经被写入
@ -211,7 +207,7 @@ void TInterrupt::DecodePriority (uint priority, uint priorityGroup, uint* pPreem
void TInterrupt::OnHandler() void TInterrupt::OnHandler()
{ {
uint num = GetInterruptNumber(); uint num = GetIPSR();
//if(num >= VectorySize) return; //if(num >= VectorySize) return;
//if(!Interrupt.Vectors[num]) return; //if(!Interrupt.Vectors[num]) return;
assert_param(num < VectorySize); assert_param(num < VectorySize);
@ -223,9 +219,9 @@ void TInterrupt::OnHandler()
isr(num - 16, param); isr(num - 16, param);
} }
void FAULT_SubHandler() void TInterrupt::FaultHandler()
{ {
uint exception = GetInterruptNumber(); uint exception = GetIPSR();
if (exception) { if (exception) {
debug_printf("EXCEPTION 0x%02x:\r\n", exception); debug_printf("EXCEPTION 0x%02x:\r\n", exception);
} else { } else {
@ -239,18 +235,18 @@ void FAULT_SubHandler()
{ {
// 0xE000ED2C // 0xE000ED2C
uint n = *(uint*)(SCB_BASE + 0x2C); uint n = *(uint*)(SCB_BASE + 0x2C);
debug_printf("\r\n硬件错误 %d\r\n", n); debug_printf("\r\n硬件错误 %d ", n);
if(n & (1<<1)) if(n & (1<<1))
{ {
debug_printf("硬fault 是在取向量时发生\r\n"); debug_printf("在取向量时发生\r\n");
} }
else if(n & (1u<<30)) else if(n & (1u<<30))
{ {
debug_printf("硬fault 是总线fault存储器管理fault 或是用法fault 上访的结果\r\n"); debug_printf("是总线fault存储器管理fault 或是用法fault 上访的结果\r\n");
} }
else if(n & (1u<<31)) else if(n & (1u<<31))
{ {
debug_printf("硬fault 因调试事件而产生\r\n"); debug_printf("因调试事件而产生\r\n");
} }
} }
else if(exception==5) else if(exception==5)
@ -261,7 +257,7 @@ void FAULT_SubHandler()
#endif #endif
if(i & (1<<0)) if(i & (1<<0))
{ {
debug_printf("IBUSERR 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了 debug_printf("IBUSERR 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
} }
else if(i & (1<<1)) else if(i & (1<<1))
{ {
@ -293,7 +289,7 @@ void FAULT_SubHandler()
#endif #endif
if(i & (1<<0)) if(i & (1<<0))
{ {
debug_printf("IACCVIOL 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了 debug_printf("IACCVIOL 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
} }
else if(i & (1<<1)) else if(i & (1<<1))
{ {
@ -311,7 +307,6 @@ void FAULT_SubHandler()
{ {
debug_printf("MMARVALID 表示MMAR有效\r\n"); // 表示MMAR有效 debug_printf("MMARVALID 表示MMAR有效\r\n"); // 表示MMAR有效
} }
//debug_printf("\r\n");
} }
else if(exception==6) else if(exception==6)
{ {
@ -341,14 +336,13 @@ void FAULT_SubHandler()
{ {
debug_printf("DIVBYZERO 表示除法运算时除数为零。引发此fault的指令可以从入栈的PC读取\r\n"); // 表示除法运算时除数为零只有在DIV_0_TRP置位时才会发生。引发此fault的指令可以从入栈的PC读取 debug_printf("DIVBYZERO 表示除法运算时除数为零。引发此fault的指令可以从入栈的PC读取\r\n"); // 表示除法运算时除数为零只有在DIV_0_TRP置位时才会发生。引发此fault的指令可以从入栈的PC读取
} }
//debug_printf("\r\n");
} }
#endif #endif
while(true); while(true);
} }
__asm uint GetInterruptNumber() __asm uint TInterrupt::GetIPSR()
{ {
mrs r0,IPSR // exception number mrs r0,IPSR // exception number
bx lr bx lr
@ -357,8 +351,11 @@ __asm uint GetInterruptNumber()
#if !VEC_TABLE_ON_RAM #if !VEC_TABLE_ON_RAM
extern "C" extern "C"
{ {
void NMI_Handler() { FAULT_SubHandler(); } void NMI_Handler() { TInterrupt::FaultHandler(); }
void HardFault_Handler() { FAULT_SubHandler(); } void HardFault_Handler() { TInterrupt::FaultHandler(); }
void MemManage_Handler() { TInterrupt::FaultHandler(); }
void BusFault_Handler() { TInterrupt::FaultHandler(); }
void UsageFault_Handler() { TInterrupt::FaultHandler(); }
void SVC_Handler() { TInterrupt::OnHandler(); } void SVC_Handler() { TInterrupt::OnHandler(); }
void PendSV_Handler() { TInterrupt::OnHandler(); } void PendSV_Handler() { TInterrupt::OnHandler(); }
void SysTick_Handler() { TInterrupt::OnHandler(); } void SysTick_Handler() { TInterrupt::OnHandler(); }

View File

@ -19,6 +19,8 @@ private:
InterruptCallback Vectors[VectorySize]; // 对外的中断向量表 InterruptCallback Vectors[VectorySize]; // 对外的中断向量表
void* Params[VectorySize]; // 每一个中断向量对应的参数 void* Params[VectorySize]; // 每一个中断向量对应的参数
static uint GetIPSR(); // 获取中断号
static void FaultHandler(); // 错误处理程序
public: public:
void Init(); // 初始化中断向量表 void Init(); // 初始化中断向量表
virtual ~TInterrupt(); virtual ~TInterrupt();

16
Memory.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __Memory_H__
#define __Memory_H__
#include "Sys.h"
#ifdef DEBUG
void* operator new(uint size);
void operator delete(void * p);
void operator delete [] (void * p);
//#define DEBUG_NEW new(__FILE__, __LINE__)
//#define new DEBUG_NEW
#endif
#endif

View File

@ -299,6 +299,7 @@ extern "C"
#define CR1_UE_Set ((uint16_t)0x2000) /*!< USART Enable Mask */ #define CR1_UE_Set ((uint16_t)0x2000) /*!< USART Enable Mask */
SerialPort* _printf_sp; SerialPort* _printf_sp;
bool isInFPutc;
/* 重载fputc可以让用户程序使用printf函数 */ /* 重载fputc可以让用户程序使用printf函数 */
int fputc(int ch, FILE *f) int fputc(int ch, FILE *f)
@ -310,6 +311,8 @@ extern "C"
USART_TypeDef* port = g_Uart_Ports[_com]; USART_TypeDef* port = g_Uart_Ports[_com];
if(isInFPutc) return ch;
isInFPutc = true;
// 检查并打开串口 // 检查并打开串口
if((port->CR1 & CR1_UE_Set) != CR1_UE_Set && _printf_sp == NULL) if((port->CR1 & CR1_UE_Set) != CR1_UE_Set && _printf_sp == NULL)
{ {
@ -321,26 +324,7 @@ extern "C"
TUsart_SendData(port, (byte*)&ch); TUsart_SendData(port, (byte*)&ch);
isInFPutc = false;
return ch; return ch;
} }
} }
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: debug_printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
if(_printf_sp) debug_printf("Assert Failed! Line %d, %s\r\n", line, file);
/* Infinite loop */
while (1) { }
}
#endif

View File

@ -404,10 +404,6 @@ void TSys::ShowInfo()
debug_printf(" ARMv6-M"); debug_printf(" ARMv6-M");
else if(cpu->Constant == 0x0F) else if(cpu->Constant == 0x0F)
debug_printf(" ARMv7-M"); debug_printf(" ARMv7-M");
/*if(cpu->PartNo == 0x0C20)
debug_printf(" Cortex-M0");
if(cpu->PartNo == 0x0C23)
debug_printf(" Cortex-M3");*/
if((cpu->PartNo & 0x0FF0) == 0x0C20) debug_printf(" Cortex-M%d", cpu->PartNo & 0x0F); if((cpu->PartNo & 0x0FF0) == 0x0C20) debug_printf(" Cortex-M%d", cpu->PartNo & 0x0F);
debug_printf(" R%dp%d", cpu->Revision, cpu->Variant); debug_printf(" R%dp%d", cpu->Revision, cpu->Variant);
debug_printf("\r\n"); debug_printf("\r\n");

3
Sys.h
View File

@ -127,6 +127,9 @@ __inline void debug_printf( const char *format, ... ) {}
#endif // !defined(BUILD_RTM) #endif // !defined(BUILD_RTM)
} }
// 内存管理
#include "Memory.h"
#include "Time.h" #include "Time.h"
#include "Interrupt.h" #include "Interrupt.h"