stm32_ota/ABM开发板(APP源码)/FreeRTOS版本/APPV4.0/USER/main.c
2024-12-17 20:03:43 +08:00

666 lines
30 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <stdio.h>
#include "usb.h"
#include "sys.h"
#include "systick.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "FreeRTOS.h"
#include "timer.h"
#include "queue.h"
#include "semphr.h"
#include "task.h"
#include "sysport.h"
#include "mac.h"
#include "stm32Temp.h"
#include "watchdog.h"
#include "rtc.h"
#include "user_tcp.h"
#include "key.h"
#include "logflash.h"
#include "user_http.h"
#include "ec20module.h"
#include "ec20tcp.h"
#include "ec20http.h"
#include "userapp.h"
#include "user_flash.h"
#include "usercmd.h"
#include "user_oled.h"
#include "user_key.h"
#include "user_gnss.h"
/**********************************************************************************
*内部函数声明
**********************************************************************************/
/*FreeRTOS任务函数声明*/
void StartTask(void *pvParameters); //开始任务函数 :初始化、创建其他任务
void NetTask(void *pvParameters); //网络任务函数 :初始化网络、维护网络
void Rs232Task(void *pvParameters); //Rs232处理函数 处理RS232串口接收的数据
void Rs485Task(void *pvParameters); //Rs485处理函数 处理RS485串口接收的数据
void LedTask(void *pvParameters); //LED任务函数 DATA作为500ms呼吸灯
void TcpUrcTask(void *pvParameters); //TCP URC任务函数 处理TCP协议中EC20返回的URC
void TcpDownTask(void *pvParameters); //LTE任务函数 处理分发4G模块串口帧数据
void TcpHeartTask(void *pvParameters); //TCP心跳任务函数 TCP心跳
void TcpUpTask(void *pvParameters); //TCP上行任务函数 TCP心跳上行sTcp0Queue队列里的数据
void MenuTask(void *pvParameters); //车牌处理任务函数:处理摄像头任务发来的车牌
void ListTask(void *pvParameters); //LIST任务函数 :打印各个任务信息
void UcmdTask(void *pvParameters); //用户命令任务函数处理用户命令用户命令可能来自USB口或者EC20的TCP下行数据
void UsbTask(void *pvParameters); //USB任务函数 处理USB串口数据
void GnssTask(void *pvParameters); //GNSS任务函数 获取GPS数据
/**********************************************************************************
*内部常变量
**********************************************************************************/
/*FreeRTOS任务优先级*/
#define START_TASK_PRIO 32 //开始任务
#define NET_TASK_PRIO 2 //网络任务
#define RS232_TASK_PRIO 1 //任务优先级
#define RS485_TASK_PRIO 5 //任务优先级
#define LED_TASK_PRIO 31 //任务优先级
#define TCPURC_TASK_PRIO 3 //任务优先级
#define TCPDOWN_TASK_PRIO 1 //任务优先级
#define MENU_TASK_PRIO 3 //任务优先级
#define LIST_TASK_PRIO 32 //任务优先级
#define TCPUP_TASK_PRIO 7 //任务优先级
#define TCPHEART_TASK_PRIO 6 //任务优先级
#define UCMD_TASK_PRIO 29 //任务优先级
#define DEBUG_TASK_PRIO 1 //任务优先级
#define GNSS_TASK_PRIO 30 //任务优先级
#define TEST_TASK_PRIO 33 //任务优先级
/*FreeRTOS任务堆栈大小*/
#define START_STK_SIZE 256 //任务堆栈大小 //256个入栈空间256*4 bytes
#define NET_STK_SIZE 256 //任务堆栈大小 //256个入栈空间256*4 bytes
#define RS232_STK_SIZE 256 //任务堆栈大小 //256个入栈空间256*4 bytes
#define RS485_STK_SIZE 256 //任务堆栈大小 //256个入栈空间256*4 bytes
#define LED_STK_SIZE 128 //任务堆栈大小
#define TCPURC_STK_SIZE 256 //任务堆栈大小
#define TCPDOWN_STK_SIZE 512 //任务堆栈大小
#define MENU_STK_SIZE 256 //任务堆栈大小
#define LIST_STK_SIZE 256 //任务堆栈大小
#define TCPUP_STK_SIZE 256 //任务堆栈大小
#define TCPHEART_STK_SIZE 128 //任务堆栈大小
#define UCMD_STK_SIZE 256 //任务堆栈大小
#define DEBUG_STK_SIZE 256 //任务堆栈大小
#define GNSS_STK_SIZE 128 //任务堆栈大小
#define TEST_STK_SIZE 128 //任务堆栈大小
/*FreeRTOS任务句柄*/
TaskHandle_t StartTaskHandler; //任务句柄
TaskHandle_t NetTaskHandler; //任务句柄
TaskHandle_t rs232TaskHandler; //任务句柄
TaskHandle_t rs485TaskHandler; //任务句柄
TaskHandle_t LedTaskHandler; //任务句柄
TaskHandle_t TcpUrcTaskHandler; //任务句柄
TaskHandle_t tcpDownTaskHandler; //任务句柄
TaskHandle_t menuTaskHandler; //任务句柄
TaskHandle_t ListTaskHandler; //任务句柄
TaskHandle_t TcpUpTaskHandler; //任务句柄
TaskHandle_t TcpHeartTaskHandler; //任务句柄
TaskHandle_t UcmdTaskHandler; //任务句柄
TaskHandle_t DebugTaskHandler; //任务句柄
TaskHandle_t gnssTaskHandler; //任务句柄
TaskHandle_t testTaskHandler; //任务句柄
/*FreeRTOS软件定时器句柄*/
TimerHandle_t timeRefresh_h ; //显示屏时间刷新
int main(void)
{
NVIC_SetVectorTable(FLASH_BASE, FLASH_OFFSET) ; //设置中断向量表的位置和偏移量 SCB->VTOR = FLASH_BASE | FLASH_OFFSET ;
Watchdog_Feed() ; //独立看门狗喂狗
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4) ; //设置系统中断优先级分组4 无子优先级、0~15共计16个抢占优先级
InitIapFlashConfig(&uIapFlash) ; //读出FLASH中的Iap配置初始化共用体变量uIapFlash最后重新写入FLASH中
InitAppFlashConfig(&uAppFlash) ; //读出FLASH中的App配置初始化共用体变量uAppFlash最后重新写入FLASH中
InitApplictationState(&gateApp); //初始化结构体变量gateApp
UsbInit(115200) ; //调试串口、串口转USB口初始化
Watchdog_Feed() ;
/*创建开始任务。*/
xTaskCreate((TaskFunction_t )StartTask, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTaskHandler //任务句柄
) ;
vTaskStartScheduler() ; //开启任务调度 以上代码段系统还未启动,所有可屏蔽中断都出去屏蔽状态。
}
//开始任务任务函数
void StartTask(void *pvParameters)
{
Watchdog_Feed() ; //看门狗喂狗
taskENTER_CRITICAL(); //进入临界区
Board_Init() ; //硬件驱动初始化和功能块初始化
/*创建OS任务运行状态事件标志位*/
//osSafeEventHandler = xEventGroupCreate() ; //OS任务运行状态事件标志组用于监测各个任务的运行状态如果有任务长时间没有轮询执行则说明该任务异常挂起
/*创建网络状态事件标志位*/
//netEventHandler = xEventGroupCreate() ; //网络状态事件标志位,相当于一个状态机,标志网络状态的各个环节
/*创建EC20资源互斥信号量*/
//ec20MutexSemaphore = xSemaphoreCreateMutex(); //创建EC20资源互斥信号量EC20模块需要有严格的命令时序所以无论哪个任务需要操作EC20都需要等待EC20资源空闲。
/*创建软件定时器*/
//timeRefresh_h = xTimerCreate((const char*)"Refresh Time", (TickType_t)1*configTICK_RATE_HZ, (UBaseType_t)pdTRUE, (void*)1, (TimerCallbackFunction_t)RefreshOledTime ) ; //显示屏第4行刷新定时器
//xTimerStart(timeRefresh_h, 0) ; //OLED更新时间OS软件定时器打开
Watchdog_Feed() ;
/*创建任务*/
//xTaskCreate((TaskFunction_t)NetTask, (const char*)"NetTask", (uint16_t)NET_STK_SIZE, (void*)NULL, (UBaseType_t)NET_TASK_PRIO, (TaskHandle_t*)&NetTaskHandler);
xTaskCreate((TaskFunction_t)Rs232Task, (const char*)"Rs232Task", (uint16_t)RS232_STK_SIZE, (void*)NULL, (UBaseType_t)RS232_TASK_PRIO, (TaskHandle_t*)&rs232TaskHandler);
//xTaskCreate((TaskFunction_t)Rs485Task, (const char*)"Rs485Task", (uint16_t)RS485_STK_SIZE, (void*)NULL, (UBaseType_t)RS485_TASK_PRIO, (TaskHandle_t*)&rs485TaskHandler);
xTaskCreate((TaskFunction_t)LedTask, (const char*)"LedTask", (uint16_t)LED_STK_SIZE, (void*)NULL, (UBaseType_t)LED_TASK_PRIO, (TaskHandle_t*)&LedTaskHandler);
//xTaskCreate((TaskFunction_t)MenuTask, (const char*)"MenuTask", (uint16_t)MENU_STK_SIZE, (void*)NULL, (UBaseType_t)MENU_TASK_PRIO, (TaskHandle_t*)&menuTaskHandler);
//xTaskCreate((TaskFunction_t)TcpHeartTask,(const char*)"TcpHeartTask",(uint16_t)TCPHEART_STK_SIZE,(void*)NULL, (UBaseType_t)TCPHEART_TASK_PRIO, (TaskHandle_t*)&TcpHeartTaskHandler);
//xTaskCreate((TaskFunction_t)TcpUpTask, (const char*)"TcpUpTask", (uint16_t)TCPUP_STK_SIZE, (void*)NULL, (UBaseType_t)TCPUP_TASK_PRIO, (TaskHandle_t*)&TcpUpTaskHandler);
//xTaskCreate((TaskFunction_t)UcmdTask, (const char*)"UcmdTask", (uint16_t)UCMD_STK_SIZE, (void*)NULL, (UBaseType_t)UCMD_TASK_PRIO, (TaskHandle_t*)&UcmdTaskHandler);
//xTaskCreate((TaskFunction_t)TcpUrcTask, (const char*)"TcpUrcTask", (uint16_t)TCPURC_STK_SIZE, (void*)NULL, (UBaseType_t)TCPURC_TASK_PRIO, (TaskHandle_t*)&TcpUrcTaskHandler);
//xTaskCreate((TaskFunction_t)TcpDownTask, (const char*)"TcpDownTask", (uint16_t)TCPDOWN_STK_SIZE, (void*)NULL, (UBaseType_t)TCPDOWN_TASK_PRIO, (TaskHandle_t*)&tcpDownTaskHandler);
//xTaskCreate((TaskFunction_t)UsbTask, (const char*)"Debug_task", (uint16_t)DEBUG_STK_SIZE, (void*)NULL, (UBaseType_t)DEBUG_TASK_PRIO, (TaskHandle_t*)&DebugTaskHandler);
//xTaskCreate((TaskFunction_t)ListTask, (const char*)"ListTask", (uint16_t)LIST_STK_SIZE, (void*)NULL, (UBaseType_t)LIST_TASK_PRIO, (TaskHandle_t*)&ListTaskHandler);
//xTaskCreate((TaskFunction_t)GnssTask, (const char*)"GnssTask", (uint16_t)GNSS_STK_SIZE, (void*)NULL, (UBaseType_t)GNSS_TASK_PRIO, (TaskHandle_t*)&gnssTaskHandler);
vTaskDelete(StartTaskHandler) ; //删除开始任务
taskEXIT_CRITICAL() ; //退出临界区
}
/*********************************************************************************************************************
* 网络任务函数
*********************************************************************************************************************/
void NetTask(void *pvParameters)
{
while(1) //EC20初始化过程对时序要求很高所以在此期间需要完全占用EC20资源
{
SETNETTASKOK ; //网络任务已运行标志
static uint8_t failedTimes = 0 ;
if( GETUSERNETSTATE ) //MODULEBIT_0\NETREGBIT_1\TCPBIT_2\HTTPBIT_3 标志位全部置1说明网络全部正常
{
failedTimes = 0 ; //网络维护失败计次清零
}
else //MODULEBIT_0\NETREGBIT_1\TCPBIT_2\HTTPBIT_3 标志位全部置1说明网络全部正常
{
failedTimes++ ; //网络维护失败计次累加
if( failedTimes>2 ) //网络维护失败计次达到2次 直接重启系统
{
WriteLogToFlash("系统网络崩溃,重启系统!") ;
SystemSoftReset() ;
}
OccpyEc20(60*configTICK_RATE_HZ, __FILE__, __LINE__) ; //抢占EC20资源超时时间位60S如果超时则重启系统
RunResult runResult = TIMEOUT ;
if( GETMODULESTATE == STATE_ERR ) /*EC20没有module初始化成功则执行*/
{
StatusBarPrintf("握手中:") ; //显示屏状态栏显示“握手中:”
runResult = EC20_Module_Init() ; //需要保证串口通信正常且关闭模块串口ECHO成功
if( RUNOK == runResult) /*模块UART \gpio\POW\ECHO\RELESE皆无异常*/
{
GNSSInit() ; //GNSS初始化
SETMODULEOK ; //设置“标志位0EC20 moudle初始化状态 STATE_OK"
AppLogPrintf("握手成功") ;
}
else /*EC20_Module_Init初始化失败不做异常处理该任务会一直运行EC20_Module_Init()*/
{
WriteLogToFlash("模块安装异常!") ;
AppLogPrintf("握手失败") ;
}
}
if( GETMODULESTATE == STATE_OK &&
GETNETREGSTATE == STATE_ERR ) //EC20module初始化完成且CSPS初始化未完成则进行CS、PS初始化
{
StatusBarPrintf("入网中:") ; //显示屏状态栏显示“入网中”
char *errInfo = portMalloc(30) ;
runResult = EC20_Net_Reg(errInfo, 30) ; //连接运营商核心网即CS SERVER、PS SERVER
if( RUNOK == runResult) // EC20_Net_RegSIM/CS/PS皆无异常则往下执行
{
SETNETREGOK ; //设置”标志位1EC20 EC20_Net_Reg初始化状态 STATE_OK“
}
else //1、EC20_Net_Reg异常需要重新进行EC20_Module_Init; 2、模块关机
{
WriteLogToFlash(errInfo) ;
SETMODULEERR ; //设置“标志位0EC20 moudle初始化状态 STATE_ERR"
EC20_CLOSE() ; //EC20关机
}
AppLogPrintf(errInfo) ; //提示错误请插入SIM卡、SIM欠费、CSQ
portFree(errInfo) ;
}
if( (GETMODULESTATE == STATE_OK) &&
(GETNETREGSTATE == STATE_OK) &&
(GETTCPSTATE == STATE_ERR) ) //EC20module、EC20_Net_Reg初始化都完成则进行AppTcpInit初始化
{
StatusBarPrintf("连接TCP服务器:") ; //显示屏状态栏显示“连接TCP服务器:”
runResult = AppTcpInit() ; //TCP PDP初始化 SOCKET连接
if( RUNOK == runResult) //TCP连接成功
{
SETTCPOK ; //设置”标志位2EC20 TCP状态 STATE_OK““
TcpWritedata( TCPLOGFRAME, "Device tcp connetced!") ; //上传TCP数据更新服务器硬件客户端列表
AppLogPrintf("TCP连接成功") ;
}
else //TCP连接失败不影响主业务逻辑所以TCP异常只做重新初始化不做异常处理
{
SETTCPERR ; //设置”标志位2EC20 TCP状态 STATE_ERR
AppLogPrintf("TCP连接失败") ;
WriteLogToFlash("TCP连接失败!") ;
}
}
if( (GETMODULESTATE == STATE_OK) &&
(GETNETREGSTATE == STATE_OK) &&
(GETHTTPSTATE == STATE_ERR) ) //EC20module、EC20_Net_Reg初始化都 完成则进行Http_Init
{
runResult = Http_Init() ; //Http PDP /HTTP Config
if( RUNOK == runResult) //Http 初始化正常
{
SETHTTPOK ; //设置”标志位3EC20 HTTP请求状态 STATE_OK“““
StatusBarPrintf("注册中:") ; //显示屏显示“注册中:”
runResult = Reg_Post() ; //通过苏宁提供的对时接口对时注册
TcpWritedata( TCPLOGFRAME, "Device Register!") ; //TCP上报注册结果
if( RUNOK != runResult) //Http 请求数据失败,严重错误,直接重启系统
{
WriteLogToFlash("Http初始化OK注册请求失败重启系统!") ;
SystemSoftReset() ; //系统重启
}
AppLogPrintf("硬件注册成功!") ;
RefreshOledTime() ; //OLED更新时间
}
else //Http 初始化异常 直接重启EC20重新初始化
{
SETHTTPERR ;
AppLogPrintf("HTTP初始化失败") ;
WriteLogToFlash("HTTP初始化失败!") ;
}
}
if( GETUSERNETSTATE ) //MODULEBIT_0\NETREGBIT_1\TCPBIT_2\HTTPBIT_3 标志位全部置1说明网络全部正常
{
EC20_Query_CSQ(sEc20Param.csq) ; //获取CSQ的值
EC20_Query_Voltage(sEc20Param.ec20Voltage) ; //获取EC20电压值
DisplayStatusBar() ; //状态栏显示信号质量和电压
failedTimes = 0 ; //网络维护失败计次清零
}
RELESE_EC20(); //释放EC20资源
AppLogPrintf("释放EC20资源!") ;
}
vTaskDelay(5*configTICK_RATE_HZ) ; //最高网络维护频率5S/次
}
}
/*********************************************************************************************************************
* RS232数据处理任务函数
*********************************************************************************************************************/
void Rs232Task(void *pvParameters)
{
while(1)
{
char *buf = portMalloc(1024) ;
u16 len = 0 ;
AppLogPrintf("Rs232 recdata:%s .", buf) ; //将RS232接收的帧数据通过USB输出用户可以在此对帧数据做其他处理
portFree(buf) ;
vTaskDelay(1*configTICK_RATE_HZ) ; //处理RS232数据1S/次
}
}
/*********************************************************************************************************************
* 同步VIP车牌任务函数
*********************************************************************************************************************/
void Rs485Task(void *pvParameters)
{
while(1)
{
char *buf = portMalloc(1024) ;
u16 len = 0 ;
if( RW_OK == GetQueueMemData(&sRS485Queue, buf, &len)) //从sRS485Queue帧缓冲区中获取一帧数据准备处理
{
AppLogPrintf("Rs485 recdata:%s .", buf) ; //将RS485接收的帧数据通过USB输出用户可以在此对帧数据做其他处理
}
portFree(buf) ;
vTaskDelay(1*configTICK_RATE_HZ) ; //处理RS485数据1S/次
}
}
/*********************************************************************************************************************
* 车牌接收及处理任务函数
*********************************************************************************************************************/
void MenuTask(void *pvParameters)
{
while(1)
{
GetKeylnput() ; //执行菜单处理函数
vTaskDelay(50) ; //50/configTICK_RATE_HZ=0.5S运行一次
}
}
/*********************************************************************************************************************
* 用户命令处理任务函数
*********************************************************************************************************************/
void UcmdTask(void *pvParameters)
{
while(1)
{
SETUCMDTASKOK ;
char *buf = portMalloc(512) ;
uint16_t len = 0 ;
if(RW_OK == GetQueueMemData(&sUsercmdQueue, buf, &len)) //从sUsercmdQueue帧缓冲区中获取一帧数据准备处理
{
Cmd_Process(buf, len) ; //处理用户帧命令
}
portFree(buf) ;
vTaskDelay(0.5*configTICK_RATE_HZ);
}
}
/*********************************************************************************************************************
* DATA灯闪烁任务函数
*********************************************************************************************************************/
void LedTask(void *pvParameters)
{
while(1)
{
Watchdog_Feed() ;
Data_Led_Reverse() ; //DATA LED灯翻转
// Beep_Reverse() ; //蜂鸣器翻转
/* OledPrintf(LINE_LEFT, HIGH_12, LINE4, (char*)uCalendar.bytes) ;
// if( times >= 0xFFFE) //times累加器溢出则清零
// {
// times = 0 ;
// }
// if( (times % CHECKTASKINTERVAL) == 0) //到达检测网络运行状态的时间
// {
// if(GETTASKOSSAFE == STATE_OK) //有任务在CHECKTASKINTERVAL时间内没有被运行 直接记录日志然后重启系统
// {
// AppLogPrintf("各任务运行正常Task事件组0x%x !", READOSSAFEEVENT) ;
// RESETOSSAFEEVENT ; //清除各任务运行正常标志位
// }
// else
// {
// char *buf = portMalloc(128) ;
// snprintf( buf, 128, "存在任务运行异常Task事件组0x%x ,设备重启 !", READOSSAFEEVENT) ;
// WriteLogToFlash(buf) ;
// AppLogPrintf(buf) ;
// portFree(buf) ;
// SystemSoftReset() ;
// }
// }
*/
vTaskDelay(1*configTICK_RATE_HZ) ; //1S钟运行一次
}
}
/*********************************************************************************************************************
* 任务信息列出任务函数
*********************************************************************************************************************/
void ListTask(void *pvParameters)
{
while(1)
{
/*char *freeRTOS_Info = portMalloc(512) ;
vTaskList(freeRTOS_Info) ;
size_t freeHeapSize = xPortGetFreeHeapSize() ;
printf("\r\n*****************************************************\
\r\n系统信息\r\n*****************************************************\r\nName\t State Prio Stack Num\r\n\
%s\r\nOS动态内存剩余freeHeapSize:%dBytes\r\n!\
\r\n******************************************************\r\n ", freeRTOS_Info, freeHeapSize) ; //打印FreeRTOS系统信息
portFree(freeRTOS_Info) ;*/
vTaskDelay(1000*configTICK_RATE_HZ);
}
}
/*********************************************************************************************************************
* TCP心跳任务函数
*********************************************************************************************************************/
void TcpUpTask(void *pvParameters)
{
while(1)
{
SETTCPUPTASKOK ; //TCPUP任务已正常运行
if( GETTCPSTATE == STATE_OK ) //TCP网络正常
{
char *buf = portMalloc(1024) ;
uint16_t len = 0 ;
if( RW_OK == GetQueueMemData(&sTcp0Queue, buf, &len)) //从sTcp0Queue帧缓冲区中获取一帧数据准备处理
{
OccpyEc20(60*configTICK_RATE_HZ, __FILE__, __LINE__) ; //等待获取EC20资源
RunResult status = Tcp_SendData(&sChannal0, (uint8_t*)buf, len) ;
if( RUNOK != status) //TCP第一次发送数据失败
{
status = Tcp_SendData(&sChannal0, (uint8_t*)buf, len) ;
if( RUNOK != status) //TCP第二次发送数据失败
{
SETTCPERR ; //TCP网络状态异常
ErrorLogPrintf("Tcp SendData Err!") ;
WriteLogToFlash("Tcp SendData Err!") ; //本地FLASH记录
}
}
RELESE_EC20() ; //释放EC20资源
}
portFree(buf) ;
}
vTaskDelay(50); //50/configTICK_RATE_HZ=0.5S运行一次
}
}
void TcpHeartTask(void *pvParameters)
{
while(1)
{
SETTCPHEARTTASKOK ; //TCP 心跳任务已正常运行
if( GETTCPSTATE == STATE_OK ) //TCP网络正常
{
OccpyEc20(60*configTICK_RATE_HZ, __FILE__, __LINE__) ; //等待获取EC20资源
EC20_Query_CSQ( sEc20Param.csq ) ; //获取EC20的信号质量CSQ
EC20_Query_Voltage( sEc20Param.ec20Voltage ) ; //获取EC20的供电电压
TcpWritedata( TCPHEARTFRAME, "CSQ:%s, EC20 Voltage:%smV", sEc20Param.csq, sEc20Param.ec20Voltage) ;
RELESE_EC20() ; //释放EC20资源
char *oledBuf = (char*)portMalloc(16) ;
snprintf(oledBuf, 16, "%smV", sEc20Param.ec20Voltage) ; //显示屏显示EC20电压
DisplayBattery(oledBuf) ;
memset(oledBuf, 0, 16) ;
snprintf(oledBuf, 16, "CSQ%s", sEc20Param.csq) ; //显示屏显示csq
DisplayCsq(oledBuf) ;
portFree(oledBuf) ;
}
vTaskDelay(40*configTICK_RATE_HZ); //30s执行一次TCP上行心跳
}
}
/*********************************************************************************************************************
*TcpUrcTask任务函数
*********************************************************************************************************************/
void TcpUrcTask(void *pvParameters)
{
while(1)
{
SETCAMERATASKOK ; //任务已正常运行标志位
char *buf = portMalloc(256) ;
uint16_t len = 0 ;
if(RW_OK == GetQueueMemData(&sUrcQueue, buf, &len)) //从sUrcQueue帧缓冲区中获取一帧数据准备处理
{
TcpUrcType urcType = TcpUrcHandle(buf, len) ; //URC分类解析
switch( urcType )
{
case CLOSED:
SETTCPERR ; //设置TCP状态为 STATE_ERR
ErrorLogPrintf("Tcp server closed .") ;
WriteLogToFlash("Tcp server closed .") ;
break ;
case PDPDEACT:
SETMODULEERR ; //设置MODULE状态为 STATE_ERR
ErrorLogPrintf("Tcp PDP deact .") ;
WriteLogToFlash("Tcp PDP deact .") ;
break ;
case INCOMING_FULL:
ErrorLogPrintf("Tcp incoming full .") ;
WriteLogToFlash("Tcp incoming full .") ;
break ;
case INCOMING_CONT:
ErrorLogPrintf("Tcp incoming .") ;
WriteLogToFlash("Tcp incoming .") ;
break ;
default:
ErrorLogPrintf("Tcp unknown urc .") ;
WriteLogToFlash("Tcp unknown urc .") ;
break ;
}
}
portFree(buf) ;
vTaskDelay(0.5*configTICK_RATE_HZ); // (0.5*configTICK_RATE_HZ)/configTICK_RATE_HZ = 0.5S 运行一次
}
}
void TcpDownTask(void *pvParameters)
{
while(1)
{
SETLTETASKOK ; //该任务已正常运行标志位
char *buf = portMalloc(1024) ;
uint16_t len = 0 ;
if(RW_OK == GetQueueMemData(&sTcpQueue, buf, &len)) //从sTcpQueue帧缓冲区中获取一帧数据准备处理
{
int pos = 0;
pos = kmp(buf, "+QIURC: \"recv\"") ;
if( pos>=0) /*判断是否位接收到TCP下行数据*/
{
/*(L0142MAC:31FFD405524E353728902251;00&I am heart 5 .$X)*/
char *tcpData = portMalloc(512) ;
CopyStr(tcpData, buf+pos, 0x0A, 0x00, 256) ;
TcpFrame_S *psRcmd = (TcpFrame_S*)tcpData ;
int dataLen = strlen(tcpData) ; //接收数据的长度
if( (psRcmd->head == '(')&&
(psRcmd->loadHead == '&')&&
(*(tcpData+dataLen-5) == '$')&&
(*(tcpData+dataLen-3) == ')') //用户数据帧合法性校验
)
{
switch( psRcmd->frameType ) //按照帧类型分类处理
{
case TCPCMDFRAME:
{
if( RW_OK != InsertQueueMemData(&sUsercmdQueue, tcpData, dataLen) )
{
ErrorLogPrintf("sUsercmdQueue溢出") ;
}
break ;
}
case TCPSERVERACK: //Tcp server对硬件上行的数据ACK确认回复包
{
AppLogPrintf("Tcp server确认收到数据帧:%s ", tcpData) ;
break ;
}
default:
{
AppLogPrintf("TCP收到下行未知类型数据帧:%s ", tcpData) ;
TcpWritedata( TCPCMDBACKFRAME, "TCP收到下行未知类型数据帧") ;
break ;
}
}
}
else /*tcp下行数据但是非下行命令帧*/
{
AppLogPrintf("TCP收到下行'非'法数据帧:%s ", tcpData) ;
}
portFree(tcpData) ;
}
else /*TCP下行数据解析失败*/
{
ErrorLogPrintf("TCP 下行数据解析失败:%s ", buf) ;
}
}
portFree(buf) ;
vTaskDelay(3); //3/configTICK_RATE_HZ=0.03s运行一次 30ms
}
}
void UsbTask(void *pvParameters)
{
while(1)
{ //任务已经正常运行标志位
char *buf = portMalloc(512) ;
uint16_t len = 0 ;
if( RW_OK == GetQueueMemData(&sUsbQueue, buf, &len)) //从sUsbQueue帧缓冲区中获取一帧数据准备处理
{
TcpFrame_S *psRcmd = (TcpFrame_S*)buf ;
int bufLen = strlen(buf) ;
if( (psRcmd->head == '(')&&
(psRcmd->loadHead == '&')&&
(*(buf+bufLen-5) == '$')&&
(*(buf+bufLen-3) == ')') //用户数据帧合法性校验 合法命令帧最后5个字节为“$X)\r\n”
)
{
switch( psRcmd->frameType ) //按照帧类型分类处理
{
case COMCMDFRAME: //下行的控制命令帧
{
if( RW_OK != InsertQueueMemData(&sUsercmdQueue, buf, bufLen) )
{
ErrorLogPrintf("sUsercmdQueue溢出") ;
}
break ;
}
case TCPSERVERACK: //USB 上位机软件对硬件上行的数据ACK确认回复包
{
AppLogPrintf("USB上位机确认收到数据帧%s .", buf) ;
break ;
}
default:
{
AppLogPrintf("USB收到下行未知类型数据帧%s .", buf) ;
TcpWritedata( TCPCMDBACKFRAME, "USB收到下行未知类型数据帧") ;
break ;
}
}
}
else /*收到USB数据但是非下行命令帧*/
{
AppLogPrintf("USB收到下行'非'法数据帧:%s .", buf) ;
}
}
portFree(buf) ;
vTaskDelay(0.5*configTICK_RATE_HZ);
}
}
/*********************************************************************************************************************
*GnssTask任务函数
*********************************************************************************************************************/
void GnssTask(void *pvParameters)
{
while(1)
{ //任务已经正常运行标志位
static uint8_t onlyOne = 0 ;
if( GETMODULESTATE == STATE_OK ) //EC20 module初始化成功
{
OccpyEc20(60*configTICK_RATE_HZ, __FILE__, __LINE__) ; //等待获取EC20资源
if( RUNOK == EC20GnssQueryRMC(&sRMCData ) )
{
AppLogPrintf("UTC日期%s度", sRMCData.utcDate ) ;
AppLogPrintf("UTC时间%s", sRMCData.utcTime ) ;
if( (onlyOne == 0) &&
IS_Number_PERIPH(sRMCData.utcDate[0])&&
IS_Number_PERIPH(sRMCData.utcDate[3])&&
IS_Number_PERIPH(sRMCData.utcDate[5])&&
IS_Number_PERIPH(sRMCData.utcTime[0])&&
IS_Number_PERIPH(sRMCData.utcTime[3])&&
IS_Number_PERIPH(sRMCData.utcTime[5])
) //日期和时间数字校验
{
onlyOne ++ ; //仅仅进行一次校时可以选择采用GPS对时
// Calendar_u uSetRTC ; //日期时间
// RMCUtcToBJT(&uSetRTC, &sRMCData ) ; //UTC时间转BJT时间
// RTC_Set( &uSetRTC ) ; //设置新时间到RTC中
}
AppLogPrintf("纬度:%s%c", sRMCData.latitude, sRMCData.eLatitudeDirect ) ;
AppLogPrintf("经度:%s%c", sRMCData.longitude, sRMCData.eLongitudeDirect ) ;
AppLogPrintf("速度:%s节", sRMCData.speed ) ;
AppLogPrintf("角方向:%s度", sRMCData.angDirect ) ;
}
else
{
AppLogPrintf("获取GPS数据失败") ;
}
RELESE_EC20() ; //释放EC20资源
}
vTaskDelay(10*configTICK_RATE_HZ);
}
}