STM32+UCOSIII系统死机
1、堆栈空间太小;
2、调度信号问题;
3、硬件问题(通讯频率);
4、数组溢出;
一般来说运行操作系统 是以下几个问题
1.开始的时候给ucos分配的堆栈太小了,随着项目做多了,这类问题一般很容易解决
#define TASK_IO_SIZE 300
#define TASK_IO_PRIO 6
OS_STK TASK_IO_STK[TASK_IO_SIZE];
比如修改300到 1000,做开发的时候 如果ram允许,尽量大些,免的麻烦
2.数组溢出
这类问题一般在通信中,接受数据的时候,特别是长度不定的时候
比如协议为 :开始 功能码 长度 数据1 数据2 。。结束
长度决定了后面的数据多少,在分配接受缓冲的时候 ,突然来了个错误的长度比如255
但是我们分配buffer[100],只定义了100,这样数组就溢出了
所有在放数据之前要对长度进行判断是否合理,以后 如果有长度 或者索引就要想到溢出。。
3.使用了非法的指针 ,比如空指针 ,编译对的 但是运行就错了
u8 *p = null;
*p = 1;
把0地址的数据强制设置为1, 不错才怪
4.使用 OS_ENTER_CRITICAL();
使用了 OS_ENTER_CRITICAL(); 却忘了OS_EXIT_CRITICAL(); 退出临界区
特别是在这个函数OS_ENTER_CRITICAL(); 调用了子函数 也有的这类情况,很容易忘记关闭的这样就造成了“死机现象”
因此如果调用的话 建议在函数中加入OS_CPU_SR cpu_sr = 0u;局部变量 在管理临界区 os的内核程序也是这么用的 ,而且要注意,临界区一般用于全局变量的写操作,时间要非常快的,任务中的变量可以不用添加 。
解决:
1、单任务测试(SHT11+NOISE_ISR)
10:49->10:56->10:59->11:00
死机
2、死机原因:mymalloc()不能分配内存。
//NOISE
u8 NOISE_Buf[20]={0};
void USART2_IRQHandler(void)
{
float *temp;
char i=0;
float NOISE=0.0;
OS_ERR err;
OSIntEnter();
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏ
{
for(i=0;i<6;i++)
{
NOISE_Buf[i] = NOISE_Buf[i+1];
}
NOISE_Buf[6]=USART_ReceiveData(USART2);
if((NOISE_Buf[0]==0x01)&&(NOISE_Buf[1]==0x03)&&(NOISE_Buf[2]==0x02))
{
NOISE=(NOISE_Buf[3]*256+NOISE_Buf[4])/10;
``
temp = mymalloc(SRAMIN,4);//死在这儿
`///`
if(temp)
{
temp[0]=NOISE;
printf("noise=%3.1f dB\r\n",NOISE);
OSQPost((OS_Q* )&NOISE_Msg,
(void* )temp,
(OS_MSG_SIZE)4,
(OS_OPT )OS_OPT_POST_FIFO,
(OS_ERR* )&err);
if(err != OS_ERR_NONE)
{
myfree(SRAMIN,temp);
}
}
if(err != OS_ERR_NONE)
{
myfree(SRAMIN,temp);
}
}
}
OSIntExit();
}
ISR中断进去一直分配内存知道分配完内部内存池。死在mymalloc()函数。