今天完善了昨天的代码但同时也遇到了问题,一起来看看把。
一.代码完善
昨天作者编写了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命令的程序调试好@.@