666 lines
30 KiB
C
666 lines
30 KiB
C
#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 ; //设置“标志位0:EC20 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_Reg(SIM/CS/PS)皆无异常则往下执行
|
||
{
|
||
SETNETREGOK ; //设置”标志位1:EC20 EC20_Net_Reg初始化状态 STATE_OK“
|
||
}
|
||
else //1、EC20_Net_Reg异常,需要重新进行EC20_Module_Init; 2、模块关机
|
||
{
|
||
WriteLogToFlash(errInfo) ;
|
||
SETMODULEERR ; //设置“标志位0:EC20 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 ; //设置”标志位2:EC20 TCP状态 STATE_OK““
|
||
TcpWritedata( TCPLOGFRAME, "Device tcp connetced!") ; //上传TCP数据,更新服务器硬件客户端列表
|
||
AppLogPrintf("TCP连接成功") ;
|
||
}
|
||
else //TCP连接失败不影响主业务逻辑,所以TCP异常只做重新初始化,不做异常处理
|
||
{
|
||
SETTCPERR ; //设置”标志位2:EC20 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 ; //设置”标志位3:EC20 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);
|
||
}
|
||
} |