移植MQTT客户端项目Day5

今天完善了昨天的代码但同时也遇到了问题,一起来看看把。

一.代码完善

昨天作者编写了WIFI模块的程序,也就是ATSendCmd和ATRecvParser这两个函数。今天对其进行了完善。

void AT_Init(void)
{
	platform_mutex_init(&at_ret_mutex);
	platform_mutex_init(&at_packet_mutex);
	
	platform_mutex_lock(&at_ret_mutex);
	platform_mutex_lock(&at_packet_mutex);
}

static int8_t isSpecialAT(uint8_t* buf)
{
	
	if (strcmp((const char *)buf, "+IPD,"))
	{
		return 1;
	}
	else if (strcmp((const char *)buf, ">"))
	{
		return 1;
	}
	return 0;
}

/**
  * @brief 
  * @param  AT返回值数组
  * @retval 1--成功接收到数据包;0--接收数据包失败
  */
static int8_t procSpecialAT(uint8_t* buf)
{
	int buf_len = strlen((const char *)buf);
	int len = 0;
	int index = 0;
	
	for (int i = 0; i < buf_len; i ++)
    {
		if (buf[i] == ',')
		{
			i ++;
			while (buf[i] != ':')
			{
				len = len * 10 + (buf[i] - '0');
				i ++;
			}
			index = i + 1; //搜索到了数据包的起始索引,退出循环
			break;
		}
	}
	
	if (len > AT_RESP_LEN) //数据包过大,无法处理
	{
		return PACKET_ERROR;
	}
	
	for (int i = 0; i < len; i ++) //将数据包copy到全局数组g_at_packet
	{
		g_at_packet[i] = buf[index ++];
	}
	
	g_at_packet[len] = '\0'; //加上结束字符
	platform_mutex_unlock(&at_packet_mutex); //解锁packet
	
	return PACKET_OK;
}

void ATRecvParser(void* params) //void (*ptr) (void* p) 函数类型
{
	uint8_t buf[AT_RESP_LEN];
	int index = 0;
	
	while (1)
	{
		if (index < AT_RESP_LEN) //USART1读不到数据就阻塞,不会空转
		{
			hal_at_recv(buf + index, (int)portMAX_DELAY);
		}
		else
		{
			break; //!<buf满了任务退出,否则数组会越界
		}
		
		/* 只有读到了换行才去解析数据 */
		if (index && buf[index] == '\n' && buf[index - 1] == '\r')
		{
			buf[index + 1] = '\0'; //先给出结束字符方便使用string.h库函数
			
			if (strstr("OK\r\n", (const char *)buf)) //case1,接收到OK
			{
				setATState(AT_OK);
				platform_mutex_unlock(&at_ret_mutex); //成功接收到数据就解锁
				memcpy(g_at_resp, buf, index + 1); /* len?*/
				index = -1; //!<成功接收命令,buf从头开始复用
			}
			else if (strstr("ERROR\r\n", (const char *)buf)) //case2,接收到ERROR
			{
				setATState(AT_ERROR);
				platform_mutex_unlock(&at_ret_mutex);
				index = -1;
			}
			else if (isSpecialAT(buf)) //case3,接收到特殊字符串"+IPD,n:xxxx"
			{
				if (procSpecialAT(buf))
				{
					index = -1;
				}
				//platform_mutex_unlock(&at_ret_mutex); //!<处理完是否该解锁?		
			}
		}
		
		index ++; //只要读到了数据,写指针index都++	
		
		if (index >= AT_RESP_LEN) //!<防止越界,buf复用
		{
			index = 0;
		}
	}
}

完善的地方主要在于:①处理特殊AT返回值"+IPD,n:xxxxx",增加了全局数组用来记录数据包,同样的为了处理不同任务对资源的占有请求,设置了mutex来互斥;②在ATRecvParser函数中增加了对索引越界的处理;③实现了对特殊AT返回值"+IPD,n:xxxxx"的解析,将"xxxx"数据包记录下来;④:在中断函数中直接使用platform_mutex_unlock函数是不安全的(官方文档是这样说的),要使用后缀带"FromISR"的函数。

今天因为作者下午有课,晚上也有点事情,所以仍然没有调试,争取明天能够将收发AT命令的程序调试好@.@

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值