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函数时产生了串口中断,当中断返回时就可能出现栈溢出的问题,因此触发硬件中断。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南波儿万

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值