各位大侠好,
目前我移植的是uCOS III+STM32版本,出现的问题现象如下:
1. 当我触发一个外部中断进入“void PUMP_Int(s16 index)”中断服务子函数,只要调用"PollPrintf"就会出现"HardFault异常", 从这个看应该是内存溢出。
PollPrintf中有256字节栈分配,但我的系统栈和堆都比较充足,我尝试加大系统的栈和堆大小,问题依然没有解决,因此估计跟系统栈和堆没有关系。
======================================================
Stack_Size EQU 0x00000800
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00002000
2. 我又怀疑是因为系统的中断嵌套导致的问题,因此我又把中断的抢占配置去掉,只留下子优先级,问题依然未得到解决。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); ..............................不设置抢占优先级,只有子优先级
以下代码断详细交待了中断的配置情况以及错误产生的地点,烦请帮我看看是否有什么地方不对,谢谢。
void BSP_InterruptConfig(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Deinitializes the NVIC */
/* Set the Vector Table base address at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
//NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); ..............................不设置抢占优先级,只有子优先级
/* Enable the EXTI(15:10) Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the TIM3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the EXTI(15:10) Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6; ...............................子优先级为6
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the TIM1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler(void) ........................中断服务句柄
{
OSIntEnter();
if (EXTI_GetITStatus(EXTI_Line8) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line8);
#if FUNC_PUMP
PUMP_Int(0);
#endif
}
if (EXTI_GetITStatus(EXTI_Line9) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line9);
#if FUNC_PUMP
PUMP_Int(1);
#endif
}
OSIntExit();
}
void PUMP_Int(s16 index)
{
if (index >= MAX_PUMP)
{
return;
}
if (DebounceCnt[index] > 0)
{
return;
}
DebounceCnt[index] = Config->PumpFunc.DebounceDelay[index];
SecPump[index]++;
if (index == 0)
{
if (!Config->RemotOut.remoteoutE[0])
{
return;
}
if (StartCntStrokePerMin)
{
McStrokePerMinCnt ++;
if (Config->PumpFunc.PumpStrokeMode) //Half stroke mode
{
if (DropFlag)
{
McStrokePerMinCnt--;
}
else
{
PollPrintf("Mc strokes counter:%d\r\n", McStrokePerMinCnt);
}
}
else
{
PollPrintf("Mc strokes counter:%d\r\n", McStrokePerMinCnt);
}
}
else
{
McStrokePerMinCnt = 0;
}
if (TotalMotorPump == 0)
{
if (StrokeMeasure == 0)
{
CaliSec = 0;
}
}
TotalMotorPump++;
if (Config->PumpFunc.PumpStrokeMode) //Half stroke mode
{
if (DropFlag)
{
TotalMotorPump--;
DropFlag = 0;
return;
}
else
{
DropFlag = 1;
}
}
if (CalibrateMotorSpeed)
{
PollPrintf("Motor pump strokes:%d\r\n", TotalMotorPump); ..........................每次只要调用此句打印信息即可导致系统进入“void HardFault_Handler(void) ”,单步跟踪至此函数结束并未发现此句有内存溢出情况,当继续往下运行时立即会进入HardFault异常中断,估计是中断整体压栈造成的问,但如若在函数中不调用此句打印,则不会出现这样的情况,打印语句的定义见下面。
if (StrokeMeasure > 0)
{
SoftIrq_UnRegister(PUMP_SpdMeasureTimeOut);
}
}
}
}
s32 PollPrintf(s8 * format, ...)
{
s32 n;
s8 buf[256] = {0};
va_list ap;
va_start(ap,format);
n = vsprintf(buf, format, ap);
BSP_UartPollSendData(USART1, (void *)buf, n); 此语句内只是纯粹向串口输出数据,再无内存分配了
LOG_FifoWrite((u8 *)buf, n);
va_end(ap);
return n;
} |