STM32 UCOS-ii malloc线程同步问题

最近在写stm32的串口处理程序,遇到一个问题程序跑着跑着就进入了硬件错误中断不可自拔。

void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

通过调试定位到错误出现在下面的字符串处理函数函数中

char** strsplit(char *str, char stok)
{
	char *p = str, *h = str, *item = NULL;
	char **ret = NULL, **index;
	int size = 0;
	while(*p)
	{
		if(*p == stok)
			size++;
		p++;
	}
	ret = (char **)malloc((size+2) * sizeof(char *));
	if(ret == NULL)
		return NULL;
	p = str;
	index = ret;
	while(*p)
	{
		if(*p == stok)
		{
			size = p - h-1;
			item = (char *)malloc((size+1)*sizeof(char));
			memset(item, '\0', size+1);
			if(h == str)
				memcpy(item, h,size+1);
			else
				memcpy(item, h+1,size);
			h = p;
			*index = item;
			index++;
		}
		p++;
	}
	size = p - h-1;
	item = (char *)malloc(size*sizeof(char));
	memcpy(item, h+1,size);
	*index = item;
	*(index + 1) = NULL;
	return ret;
}

这个函数单独测试没有任何题,但是我的系统使用的ucos-ii的多线程系统,另外我系统里还有5个串口中断处理函数。在这样的多线程系统中这个函数就出现了问题。

要分析这个函数的问题所在,首先要判断这回函数是否可重入。这是判断一个函数是否是线程安全的必要条件。我重读了这个函数,发现函数中没有使用全局变量和全局资源,唯一调用了malloc这个函数。如果这函数是不可重入的则strsplit这个函数也是不可重入的。

我百度发现https://blog.csdn.net/weiganyi/article/details/11142347这篇博文说malloc是不可重入的。于是我找到了 问题的原因:
我的程序结构如下:

//中断处理1
void uart1_hander()
{}
//中断处理2
void uart2_hander()
{}
//中断处理3
void uart3_hander()
{}
//中断处理4
void uart4_hander()
{}
//中断处理5
void uart5_hander()
{}
//解报文
void thread(){
	switch(number){
		case 1:
			message = strsplit(buff, ',');
			break;
		case 2:
			message = strsplit(buff, ',');
			break;
		case 3:
			message = strsplit(buff, ',');
			break;
		case 4:
			message = strsplit(buff, ',');
			break;
		case 5:
			message = strsplit(buff, ',');
			break;
	}
}

如果程序在执行strsplit函数中的malloc函数时产生了串口中断,当中断返回时就可能出现栈溢出的问题,因此触发硬件中断。

发布了23 篇原创文章 · 获赞 27 · 访问量 1152

猜你喜欢

转载自blog.csdn.net/BLUCEJIE/article/details/103952840
今日推荐