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函數時產生了串口中斷,當中斷返回時就可能出現棧溢出的問題,因此觸發硬件中斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章