2513 lines
71 KiB
C
2513 lines
71 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* IAR Development Kits
|
||
* on the
|
||
*
|
||
* M451
|
||
*
|
||
* Filename : uart_dtu.c
|
||
* Version : V1.00
|
||
* Programmer(s) : Qian Xianghong
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#include "includes.h"
|
||
|
||
#include "drv_dtu.h"
|
||
#include "drv_gps.h"
|
||
|
||
// 运动状态(默认为1,万一加速度计有问题)
|
||
volatile uint8_t Motion_Status = 1;
|
||
|
||
// 初始唤醒次数(快速发送)
|
||
#define INITIAL_TRAN_COUNT 6
|
||
|
||
// 绝对值
|
||
#define abs(x) ((x) < 0 ? -(x) : (x))
|
||
|
||
// GPS上报数据的时间戳,年基数为2010
|
||
#define GPS_BASE_YEAR 2010
|
||
|
||
// Boot-loader地址(在线升级以后重启运行)
|
||
#define LDROM_BASE 0x100000ul // 1M
|
||
|
||
// GPRS串口接收的循环缓冲
|
||
#define DTU_TASKM_DATA_COUNT 200
|
||
loopbuff_t DTU_TaskM;
|
||
uint8_t DTU_TaskM_Data[sizeof(uint8_t) * (DTU_TASKM_DATA_COUNT + 1)] = {0};
|
||
|
||
// 最近一条上传数据的采集时间
|
||
volatile uint32_t DTU_dataTime = 0;
|
||
// 发送成功时间
|
||
volatile uint32_t DTU_succTime = 0;
|
||
|
||
// 这个缓冲区比较大,不放在stack里面
|
||
char DTU_gpsData[2][DTU_GPSDATA_SIZE] = {0}; // 扩展内存
|
||
char DTU_recvBuff[DTU_RECVBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
// 一次请求升级包数据大小
|
||
#define UPGRADE_DATA_LEN 1024
|
||
|
||
// DTU_Task任务和服务器之间的收发缓冲
|
||
uint8_t Task_sendBuff[TASK_SENDBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
#if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE
|
||
#define TASK_RECVBUFF_SIZE (UPGRADE_DATA_LEN + 32)
|
||
#else
|
||
#define TASK_RECVBUFF_SIZE (SFLASH_ERASE_SIZE)
|
||
#endif
|
||
uint8_t Task_recvBuff[TASK_RECVBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
// 信号量,用于通知执行任务
|
||
SemaphoreHandle_t DTU_semUpgrade = NULL;
|
||
|
||
// 用于发送到服务器的数据结构
|
||
// 和蓝牙的相应命令一致
|
||
#pragma pack(push, 1)
|
||
|
||
typedef struct
|
||
{
|
||
uint16_t mark;
|
||
unsigned ver : 7;
|
||
unsigned trans : 1;
|
||
unsigned reserved: 8;
|
||
uint16_t len;
|
||
union
|
||
{
|
||
uint16_t cmd;
|
||
struct
|
||
{
|
||
uint8_t err;
|
||
uint8_t cmd_L;
|
||
};
|
||
};
|
||
} bluetooth_recv_t;
|
||
|
||
typedef bluetooth_recv_t bluetooth_send_t;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned staEPress3 : 2;
|
||
unsigned staETempr1 : 2;
|
||
unsigned staETempr2 : 2;
|
||
unsigned staETempr3 : 2;
|
||
|
||
unsigned staDiff : 2;
|
||
unsigned staPress : 2;
|
||
unsigned staEPress1 : 2;
|
||
unsigned staEPress2 : 2;
|
||
|
||
} bluetooth_sensor_t;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned maskStamp : 1;
|
||
unsigned maskEPress1 : 1;
|
||
unsigned maskEPress2 : 1;
|
||
unsigned maskEPress3 : 1;
|
||
unsigned : 1;
|
||
unsigned maskLowPower : 1;
|
||
unsigned maskAbnormal : 1;
|
||
unsigned maskCharging : 1;
|
||
|
||
unsigned maskRssi : 1;
|
||
unsigned maskGPS : 1;
|
||
unsigned maskETempr1 : 1;
|
||
unsigned maskETempr2 : 1;
|
||
unsigned maskETempr3 : 1;
|
||
unsigned maskBattery : 1;
|
||
unsigned maskFlow : 1;
|
||
unsigned maskLeak : 1;
|
||
} bluetooth_mask_t;
|
||
|
||
typedef union
|
||
{
|
||
struct
|
||
{
|
||
unsigned sec : 6;
|
||
unsigned min : 6;
|
||
unsigned hour_L : 4;
|
||
unsigned hour_H : 1;
|
||
unsigned day : 5;
|
||
unsigned mon : 4;
|
||
unsigned year : 6;
|
||
};
|
||
uint32_t tm;
|
||
} bluetooth_timestamp_t;
|
||
|
||
typedef union
|
||
{
|
||
unsigned long long ll;
|
||
struct
|
||
{
|
||
unsigned long l;
|
||
unsigned long h;
|
||
};
|
||
} longlong_mask_t;
|
||
|
||
typedef struct
|
||
{
|
||
union
|
||
{
|
||
struct
|
||
{
|
||
unsigned sateCount : 5; // gps可见卫星数量
|
||
unsigned posState : 1; // gps定位状态 (0-GPS未定位,1-GPS已定位)
|
||
unsigned carState : 1; // 车辆是否启动 (0-车辆未启动,1-车辆已启动)
|
||
unsigned carEvent : 1; // 车辆启动或停止事件(0-启动状态未改变,1-启动状态已改变)
|
||
};
|
||
uint8_t state;
|
||
};
|
||
bluetooth_timestamp_t time; // 时间戳
|
||
int32_t latitude;
|
||
int32_t longitude;
|
||
uint16_t speed;
|
||
} gps_data_t;
|
||
|
||
typedef struct // size = 158
|
||
{
|
||
uint32_t sample_time; // 采集时间:自启动以来经过的秒数
|
||
data_dtu_t dtuData; // size = 36
|
||
data_sample_t sampleData; // size = 118
|
||
} gprs_data_t;
|
||
|
||
// 升级进度信息(存放在FRAM中,可断点续传)
|
||
typedef struct
|
||
{
|
||
uint16_t check; // 标志,固定为0x55AA
|
||
uint32_t ver; // 固件版本
|
||
int32_t fileSize; // 固件总字节数
|
||
uint16_t fileCrc; // 固件总的crc
|
||
int32_t offset; // 本次固件偏移量
|
||
int32_t len; // 本次数据长度
|
||
uint16_t crc; // 本记录的crc
|
||
} upgrade_info_t;
|
||
|
||
// 升级包接收记录
|
||
typedef struct
|
||
{
|
||
uint32_t ver; // 固件版本
|
||
int32_t fileSize; // 固件总字节数
|
||
uint16_t fileCrc; // 固件总的crc
|
||
int32_t offset; // 本次固件偏移量
|
||
int32_t len; // 本次数据长度
|
||
uint8_t data[UPGRADE_DATA_LEN]; // 本次数据
|
||
uint16_t crc; // 本次数据的crc
|
||
} upgrade_frame_t;
|
||
|
||
// 升级文件头
|
||
typedef struct // size=12
|
||
{
|
||
unsigned short check; // 数据有效标志, 0x55AA表示有效
|
||
unsigned upgrade_request : 1; // 升级请求标志,0-无升级,1-有升级
|
||
unsigned upgrade_result : 3; // 升级失败标志,0-成功,1-失败,其余保留
|
||
unsigned encrypt_flag : 2; // 加密标志, 0-无加密,其余保留
|
||
unsigned compress_flag : 2; // 压缩标志, 0-无压缩,1-有压缩,其余保留
|
||
unsigned rerseved1 : 8; // 保留,必须为0xFF
|
||
|
||
unsigned long upgrade_length; // 升级文件长度
|
||
|
||
unsigned rerseved2 : 8; // 保留,必须为0xFF
|
||
unsigned rerseved3 : 8; // 保留,必须为0xFF
|
||
unsigned short crc; // 对前面内容的crc校验
|
||
} TUpgradeHeader;
|
||
|
||
#pragma pack(pop)
|
||
|
||
// 升级包记录
|
||
upgrade_info_t upInfo = {0};
|
||
// 下载储罐档案记录
|
||
upgrade_info_t boxesInfo = {0};
|
||
// 储罐档案缓冲区
|
||
char boxesBuff[16384 + 1] = {0};
|
||
|
||
// 计算两个经纬度之间的距离
|
||
const double EARTH_RADIUS = 6378.137;
|
||
double rad(double d)
|
||
{
|
||
return d * PI / 180.0;
|
||
}
|
||
|
||
double GetDistance(int32_t lat1, int32_t lng1, int32_t lat2, int32_t lng2)
|
||
{
|
||
double radLat1 = rad(lat1 * 0.000001);
|
||
double radLat2 = rad(lat2 * 0.000001);
|
||
double a = radLat1 - radLat2;
|
||
double b = rad(lng1 * 0.000001) - rad(lng2 * 0.000001);
|
||
double s = 2 * asin(sqrt(pow(sin(a / 2), 2) +
|
||
cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2)));
|
||
s = s * EARTH_RADIUS;
|
||
return s;
|
||
}
|
||
|
||
// 比较新数据的时间,是否晚于老数据的时间
|
||
int32_t GPS_IsLateThan(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime)
|
||
{
|
||
uint8_t newHour = (pNewTime->hour_H << 4) | pNewTime->hour_L;
|
||
uint8_t oldHour = (pOldTime->hour_H << 4) | pOldTime->hour_L;
|
||
|
||
if(pNewTime->year > pOldTime->year)
|
||
return TRUE;
|
||
if(pNewTime->year < pOldTime->year)
|
||
return FALSE;
|
||
if(pNewTime->mon > pOldTime->mon)
|
||
return TRUE;
|
||
if(pNewTime->mon < pOldTime->mon)
|
||
return FALSE;
|
||
if(pNewTime->day > pOldTime->day)
|
||
return TRUE;
|
||
if(pNewTime->day < pOldTime->day)
|
||
return FALSE;
|
||
if(newHour > oldHour)
|
||
return TRUE;
|
||
if(newHour < oldHour)
|
||
return FALSE;
|
||
if(pNewTime->min > pOldTime->min)
|
||
return TRUE;
|
||
if(pNewTime->min < pOldTime->min)
|
||
return FALSE;
|
||
|
||
return pNewTime->sec > pOldTime->sec;
|
||
}
|
||
|
||
// 计算两个时间间隔的秒数
|
||
uint32_t GPS_CalcInterval(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime)
|
||
{
|
||
// 计算从OldYear以来的秒数
|
||
uint32_t newSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pNewTime->year + GPS_BASE_YEAR, pNewTime->mon,
|
||
pNewTime->day, (pNewTime->hour_H << 4) | pNewTime->hour_L, pNewTime->min, pNewTime->sec);
|
||
uint32_t oldSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pOldTime->year + GPS_BASE_YEAR, pOldTime->mon,
|
||
pOldTime->day, (pOldTime->hour_H << 4) | pOldTime->hour_L, pOldTime->min, pOldTime->sec);
|
||
|
||
return newSeconds - oldSeconds;
|
||
}
|
||
|
||
// 将采集数据中的传感器状态转换为蓝牙协议中的状态
|
||
static uint8_t Bluetooth_ConvertStat(sensor_status_t *pStat)
|
||
{
|
||
if(pStat->notConnect)
|
||
return 3;
|
||
if(pStat->overFlow)
|
||
return 1;
|
||
if(pStat->underFlow)
|
||
return 2;
|
||
return 0;
|
||
}
|
||
|
||
// GPS uart
|
||
void GPS_IRQHandler(USART_Handle *huart)
|
||
{
|
||
uint8_t u8DTU = (uint8_t) huart->Instance->DR;
|
||
|
||
// printf("%c", u8DTU);
|
||
// 直接处理
|
||
DTU_Task0(u8DTU);
|
||
}
|
||
|
||
// GSM uart
|
||
void GPRS_IRQHandler(USART_Handle *huart)
|
||
{
|
||
uint8_t u8DTU = (uint8_t) huart->Instance->DR;
|
||
|
||
if(DTU_uartPrint)
|
||
{
|
||
// if(u8DTU == '\n')
|
||
// printf("\\n\n");
|
||
// else if(u8DTU == '\r')
|
||
// printf("\\r");
|
||
// else
|
||
printf("%c", u8DTU);
|
||
}
|
||
// 加入缓冲
|
||
LoopBuff_PutItem(&DTU_TaskM, &u8DTU);
|
||
}
|
||
|
||
void DTU_Open()
|
||
{
|
||
// 分配扩展内存
|
||
// DTU_gpsData[0] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE);
|
||
// DTU_gpsData[1] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE);
|
||
// DTU_recvBuff = (char *) SRAM_Alloc(DTU_RECVBUFF_SIZE);
|
||
// Task_sendBuff = (uint8_t *) SRAM_Alloc(TASK_SENDBUFF_SIZE);
|
||
// Task_recvBuff = (uint8_t *) SRAM_Alloc(TASK_RECVBUFF_SIZE);
|
||
LoopBuff_Create(&DTU_TaskM, sizeof(uint8_t), DTU_TASKM_DATA_COUNT, 0, (uint32_t) DTU_TaskM_Data);
|
||
|
||
// 创建信号量
|
||
DTU_semUpgrade = xSemaphoreCreateBinary();
|
||
|
||
huart1.RxISR = GPRS_IRQHandler;
|
||
huart6.RxISR = GPS_IRQHandler;
|
||
|
||
SET_BIT(USART1->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||
LL_USART_Enable(USART1);
|
||
|
||
/* 打开GPS端口: GPS和Debug共用一个串口,GPS用到输入,DEBUG用到输出 */
|
||
SET_BIT(USART6->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||
}
|
||
|
||
// 任务主体:采集GPS数据
|
||
void DTU_Task0(uint8_t c)
|
||
{
|
||
static uint16_t RdIdx = 0;
|
||
static uint8_t bufIdx = 0;
|
||
static data_dtu_t sample = {0};
|
||
static int32_t last_latitude, last_longitude;
|
||
static uint8_t gps_flag = 0, motion_count = 0, motionless_count = 0;
|
||
static uint32_t last_time = 0;
|
||
static uint32_t last_gpsTime = 0;
|
||
uint32_t time;
|
||
|
||
if(c == '$' || RdIdx >= DTU_GPSDATA_SIZE)
|
||
RdIdx = 0;
|
||
|
||
if(RdIdx == 0 && c != '$')
|
||
return;
|
||
|
||
if(c != '\r' && c != '\n')
|
||
DTU_gpsData[bufIdx][RdIdx++] = c;
|
||
else
|
||
{
|
||
// 收到完整的一行
|
||
DTU_gpsData[bufIdx][RdIdx] = 0;
|
||
RdIdx = 0;
|
||
|
||
// 解析一行数据
|
||
if(parse_frame(&bufIdx, DTU_gpsData[bufIdx], &sample))
|
||
{
|
||
if(sample.sateCount > 0)
|
||
printf("sateCount:\t%d\n", sample.sateCount);
|
||
|
||
if(sample.posState)
|
||
{
|
||
time = Calc_SecondsFromYear(INITIAL_YEAR, sample.sysTime.year + 2000, sample.sysTime.month,
|
||
sample.sysTime.day, sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second);
|
||
|
||
// 修正时间基准(可显示绝对时间)
|
||
if(RTC_offsetSeconds == 0 && time >= DTU_gpsTime)
|
||
{
|
||
RTC_offsetSeconds = time - DTU_gpsTime;
|
||
// 关联铁电和SFlash的一致性
|
||
CheckFramSFlashValid(DTU_gpsTime);
|
||
}
|
||
// 修正时间基准(可显示绝对时间)
|
||
if(time >= DTU_gpsTime) // 每次成功定位都修正时间
|
||
RTC_offsetSeconds = time - DTU_gpsTime;
|
||
|
||
if(sample.sateCount >= 4)
|
||
{
|
||
if(time >= last_time + dcBuff.configData.intervalGPS)
|
||
{
|
||
last_time = time;
|
||
|
||
// 没有硬件加速度计,用软件方式判断
|
||
if(sample.speed <= 3)
|
||
{
|
||
motion_count = 0;
|
||
if(Motion_Status == 1 && ++motionless_count >= 3)
|
||
{
|
||
Motion_Status = 0;
|
||
printf("\nSoft Motion status = 0\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
motionless_count = 0;
|
||
if(Motion_Status == 0 && ++motion_count >= 3)
|
||
{
|
||
Motion_Status = 1;
|
||
printf("\nSoft Motion status = 1\n");
|
||
}
|
||
}
|
||
|
||
printf("Latitude:\t%10.6f\n", sample.latitude * 0.000001);
|
||
printf("Longitude:\t%10.6f\n", sample.longitude * 0.000001);
|
||
printf("Speed:\t\t%d km/h\n", sample.speed);
|
||
printf("GPS time:\t%d-%02d-%02d %02d:%02d:%02d\n",
|
||
sample.sysTime.year + 2000, sample.sysTime.month, sample.sysTime.day,
|
||
sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second);
|
||
|
||
// 计算和上次定位之间的距离,或者判断运动状态
|
||
if(gps_flag == 1 && (
|
||
!Motion_Status
|
||
// || (sample.speed < 5 && GetDistance(last_latitude, last_longitude, sample.latitude, sample.longitude) < 10)
|
||
))
|
||
{
|
||
printf("\nCalibrate to last position\n");
|
||
sample.latitude = last_latitude;
|
||
sample.longitude = last_longitude;
|
||
}
|
||
else
|
||
{
|
||
gps_flag = 1;
|
||
last_latitude = sample.latitude;
|
||
last_longitude = sample.longitude;
|
||
}
|
||
|
||
// 写入全局缓冲
|
||
dcBuff.dtuData.posState = sample.posState;
|
||
dcBuff.dtuData.sateCount = sample.sateCount;
|
||
dcBuff.dtuData.latitude = sample.latitude;
|
||
dcBuff.dtuData.longitude = sample.longitude;
|
||
dcBuff.dtuData.speed = sample.speed;
|
||
dcBuff.dtuData.sysTime = sample.sysTime;
|
||
|
||
// 每30秒保存一次定位信息,重启有效
|
||
if(time >= last_gpsTime + 30)
|
||
{
|
||
last_gpsTime = time;
|
||
|
||
Ext_GPS.sysTime = dcBuff.dtuData.sysTime;
|
||
Ext_GPS.longitude = dcBuff.dtuData.longitude;
|
||
Ext_GPS.latitude = dcBuff.dtuData.latitude;
|
||
Ext_GPS.speed = dcBuff.dtuData.speed;
|
||
Ext_GPS.sateCount = dcBuff.dtuData.sateCount;
|
||
Ext_GPS.posState = dcBuff.dtuData.posState;
|
||
FRAM_SaveInfo(FRAM_GPS_INFO_BASE, (uint8_t *) &Ext_GPS, sizeof(ext_gps_t));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 清除数据
|
||
memset(&sample, 0, sizeof(sample));
|
||
}
|
||
}
|
||
}
|
||
|
||
uint8_t pack_gprs_tran_data(ext_data_t *pGprs, uint8_t is4G)
|
||
{
|
||
uint16_t i, j;
|
||
bluetooth_sensor_t *pSensor;
|
||
bluetooth_mask_t *pMask;
|
||
uint16_t crc;
|
||
|
||
rf_app_data_t *pData = (rf_app_data_t *) pGprs->payload;
|
||
static data_sample_t sample;
|
||
|
||
// TODO: 将精简数据转换成上传数据
|
||
cacl_gprs_tran_data(pGprs, &sample);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
i = 0;
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, pGprs->oriPSN, 6);
|
||
i += 6;
|
||
// 功能码
|
||
Task_sendBuff[i++] = 0x10;
|
||
// 数据长度:先预设为0,最后再修改,位置为Task_sendBuff[7]
|
||
Task_sendBuff[i++] = 0;
|
||
|
||
// 当前差压值
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(sample.diff);
|
||
i +=2 ;
|
||
// 容积百分比
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(sample.volumePct);
|
||
i += 2;
|
||
// 当前容积
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(sample.volume);
|
||
i += 4;
|
||
// 重量
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(sample.weight);
|
||
i += 4;
|
||
if(pData->Sensor.measure_type == 0) // 差压
|
||
{
|
||
// 高度:mmWC
|
||
*(uint16_t *) (Task_sendBuff + i) = htons((uint16_t) (sample.diff * 101.9716213));
|
||
}
|
||
else if(pData->Sensor.measure_type == 2) // 电容
|
||
{
|
||
// 高度:mm
|
||
*(uint16_t *) (Task_sendBuff + i) = htons((uint16_t) (sample.height));
|
||
}
|
||
i += 2;
|
||
// 压力
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(pData->press);
|
||
i += 2;
|
||
// 温度-调试信息
|
||
*(int16_t *) (Task_sendBuff + i) = htons(is4G ? 3 : 1); // 1-标识为LoRa转发,2-标志为北斗上传,3-标志为4G转发
|
||
i += 2;
|
||
// 液源
|
||
if(pData->Sensor.L_source <= SOURCE_POPO)
|
||
Task_sendBuff[i] = pData->Sensor.L_source;
|
||
i++;
|
||
// 储罐类型
|
||
if(pData->Sensor.bottle_type == BOTTLE_TYPE_STAND)
|
||
Task_sendBuff[i] = 0;
|
||
else if(pData->Sensor.bottle_type == BOTTLE_TYPE_LYING)
|
||
Task_sendBuff[i] = 1;
|
||
else if(pData->Sensor.bottle_type == BOTTLE_TYPE_SPHERICAL)
|
||
Task_sendBuff[i] = 2;
|
||
i++;
|
||
// 故障码
|
||
pSensor = (bluetooth_sensor_t *) (Task_sendBuff + i);
|
||
|
||
pSensor->staDiff = pData->Sensor.staDiff;
|
||
pSensor->staPress = pData->Sensor.staPress;
|
||
pSensor->staEPress1 = 3;
|
||
pSensor->staEPress2 = 3;
|
||
pSensor->staEPress3 = 3;
|
||
pSensor->staETempr1 = pData->Sensor.staETempr1;
|
||
pSensor->staETempr2 = 3;
|
||
pSensor->staETempr3 = 3;
|
||
i += 2;
|
||
// 传感器状态
|
||
pMask = (bluetooth_mask_t *) (Task_sendBuff + i);
|
||
memset(pMask, 0xFF, 2);
|
||
pMask->maskFlow = 0;
|
||
pMask->maskLowPower = pData->Sensor.bat_low;
|
||
pMask->maskAbnormal = 0;
|
||
pMask->maskCharging = pData->Sensor.charging;
|
||
i += 2;
|
||
|
||
// 版本号
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor;
|
||
// rssi
|
||
Task_sendBuff[i++] = 0;
|
||
if(pMask->maskGPS)
|
||
{
|
||
// 经度
|
||
*(int32_t *) (Task_sendBuff + i) = htonl(pData->longitude);
|
||
i += 4;
|
||
// 纬度
|
||
*(int32_t *) (Task_sendBuff + i) = htonl(pData->latitude);
|
||
i += 4;
|
||
}
|
||
// 扩展温度
|
||
if(pMask->maskETempr1)
|
||
{
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(pData->tempr);
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr2)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr3)
|
||
{
|
||
i += 2;
|
||
}
|
||
|
||
// 电池信息
|
||
if(pMask->maskBattery)
|
||
{
|
||
// 电量百分比
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(pData->batPct);
|
||
i += 2;
|
||
// 电池内部温度
|
||
i += 2;
|
||
// 电池当前电压
|
||
*(int16_t *) (Task_sendBuff + i) = htons(pData->voltage);
|
||
i += 2;
|
||
// 电池容量
|
||
i += 2;
|
||
// 电池当前容量
|
||
i += 2;
|
||
// 充电电流,电流的符号表示充放电状态
|
||
*(int16_t *) (Task_sendBuff + i) = htons(pData->batCurrent);
|
||
i += 2;
|
||
// 光照强度
|
||
i += 2;
|
||
}
|
||
|
||
// 流量计
|
||
if(pMask->maskFlow)
|
||
{
|
||
// 天信MODBUS /A1 通信协议 (BCD码)
|
||
// 标况体积总量
|
||
i += 6;
|
||
// 标况流量
|
||
i += 4;
|
||
// 工况流量
|
||
i += 4;
|
||
// 温度
|
||
i += 4;
|
||
// 压力
|
||
i += 4;
|
||
}
|
||
|
||
// 泄露报警
|
||
if(pMask->maskLeak)
|
||
{
|
||
// 类型
|
||
Task_sendBuff[i++] = LEAK_TYPE_SWITCH | LEAK_TYPE_CURRENT | LEAK_TYPE_MODBUS;
|
||
// 状态、报警浓度
|
||
Task_sendBuff[i++] = 0x80;
|
||
}
|
||
|
||
if(pMask->maskStamp)
|
||
{
|
||
if(dcBuff.powerInfo.protocolVer.minor == 107)
|
||
{
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(pData->relative_time + (RTC_offsetSeconds + rf_get_seconds() - pGprs->recvTime));
|
||
}
|
||
// 时间
|
||
i += 4;
|
||
// 年月日
|
||
i += 4;
|
||
}
|
||
|
||
// 扩展压力
|
||
if(pMask->maskEPress1)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress2)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress3)
|
||
{
|
||
i += 2;
|
||
}
|
||
|
||
// 硬件版本
|
||
// Task_sendBuff[i++] = ((pData->hardVer / 10) << 4) + pData->hardVer % 10;
|
||
Task_sendBuff[i++] = pData->hardVer;
|
||
// 软件版本
|
||
// Task_sendBuff[i++] = ((pData->softVer / 10) << 4) + pData->softVer % 10;;
|
||
Task_sendBuff[i++] = pData->softVer;
|
||
|
||
// 真空传感器
|
||
for(j = 0; j < 2; j++)
|
||
{
|
||
// 状态
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(0);
|
||
i += 2;
|
||
// 使用年限
|
||
i += 2;
|
||
// 真空度
|
||
i += 4;
|
||
// 漏放气速率
|
||
i += 4;
|
||
}
|
||
|
||
// 气瓶容量
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(Theoretical_Param.v);
|
||
i += 4;
|
||
// 储罐封头直边长
|
||
*(uint16_t *) (Task_sendBuff + i) = htons(0);
|
||
i += 2;
|
||
// 储罐筒长度
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(pData->L);
|
||
i += 4;
|
||
// 储罐直径
|
||
*(uint32_t *) (Task_sendBuff + i) = htonl(pData->d);
|
||
i += 4;
|
||
// 自动发送频率
|
||
i += 2;
|
||
// 自动发送短信频率
|
||
i += 2;
|
||
|
||
// 修改数据长度
|
||
Task_sendBuff[7] = i - 8;
|
||
|
||
// 校验码
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, i);
|
||
*(uint16_t *)(Task_sendBuff + i) = htons(crc);
|
||
i += 2;
|
||
// 结束符
|
||
Task_sendBuff[i++] = 0x0d;
|
||
Task_sendBuff[i++] = 0x0a;
|
||
|
||
return i;
|
||
}
|
||
|
||
uint8_t pack_modbus_tran_data(ext_data_t *pGprs)
|
||
{
|
||
uint16_t i, j;
|
||
bluetooth_sensor_t *pSensor;
|
||
bluetooth_mask_t *pMask;
|
||
uint16_t crc;
|
||
|
||
rf_app_data_t *pData = (rf_app_data_t *) pGprs->payload;
|
||
static data_sample_t sample;
|
||
|
||
// TODO: 将精简数据转换成上传数据
|
||
cacl_gprs_tran_data(pGprs, &sample);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Modbus_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
i = 0;
|
||
|
||
// PSN
|
||
memmove(Modbus_sendBuff + i, pGprs->oriPSN, 6);
|
||
i += 6;
|
||
// 功能码
|
||
Modbus_sendBuff[i++] = 0x10;
|
||
// 数据长度:先预设为0,最后再修改,位置为Modbus_sendBuff[7]
|
||
Modbus_sendBuff[i++] = 0;
|
||
|
||
// 当前差压值
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(sample.diff);
|
||
i +=2 ;
|
||
// 容积百分比
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(sample.volumePct / 100);
|
||
i += 2;
|
||
// 当前容积
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(sample.volume);
|
||
i += 4;
|
||
// 重量
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(sample.weight);
|
||
i += 4;
|
||
if(pData->Sensor.measure_type == 0) // 差压
|
||
{
|
||
// 高度:mmWC
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons((uint16_t) (sample.diff * 101.9716213));
|
||
}
|
||
else if(pData->Sensor.measure_type == 2) // 电容
|
||
{
|
||
// 高度:mm
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons((uint16_t) (sample.height));
|
||
}
|
||
i += 2;
|
||
// 压力
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(pData->press);
|
||
i += 2;
|
||
// 温度-调试信息
|
||
*(int16_t *) (Modbus_sendBuff + i) = 1; // 1-标识为LoRa转发,2-标志为北斗上传,3-标志为4G转发
|
||
i += 2;
|
||
// 液源
|
||
if(pData->Sensor.L_source <= SOURCE_POPO)
|
||
Modbus_sendBuff[i] = pData->Sensor.L_source;
|
||
i++;
|
||
// 储罐类型
|
||
if(pData->Sensor.bottle_type == BOTTLE_TYPE_STAND)
|
||
Modbus_sendBuff[i] = 0;
|
||
else if(pData->Sensor.bottle_type == BOTTLE_TYPE_LYING)
|
||
Modbus_sendBuff[i] = 1;
|
||
else if(pData->Sensor.bottle_type == BOTTLE_TYPE_SPHERICAL)
|
||
Modbus_sendBuff[i] = 2;
|
||
i++;
|
||
// 故障码
|
||
pSensor = (bluetooth_sensor_t *) (Modbus_sendBuff + i);
|
||
|
||
pSensor->staDiff = pData->Sensor.staDiff;
|
||
pSensor->staPress = pData->Sensor.staPress;
|
||
pSensor->staEPress1 = 3;
|
||
pSensor->staEPress2 = 3;
|
||
pSensor->staEPress3 = 3;
|
||
pSensor->staETempr1 = pData->Sensor.staETempr1;
|
||
pSensor->staETempr2 = 3;
|
||
pSensor->staETempr3 = 3;
|
||
i += 2;
|
||
// 传感器状态
|
||
pMask = (bluetooth_mask_t *) (Modbus_sendBuff + i);
|
||
memset(pMask, 0xFF, 2);
|
||
pMask->maskFlow = 0;
|
||
pMask->maskLowPower = pData->Sensor.bat_low;
|
||
pMask->maskAbnormal = 0;
|
||
pMask->maskCharging = pData->Sensor.charging;
|
||
i += 2;
|
||
|
||
// 版本号
|
||
Modbus_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor;
|
||
// rssi
|
||
Modbus_sendBuff[i++] = 0;
|
||
if(pMask->maskGPS)
|
||
{
|
||
// 经度
|
||
*(int32_t *) (Modbus_sendBuff + i) = htonl(pData->longitude);
|
||
i += 4;
|
||
// 纬度
|
||
*(int32_t *) (Modbus_sendBuff + i) = htonl(pData->latitude);
|
||
i += 4;
|
||
}
|
||
// 扩展温度
|
||
if(pMask->maskETempr1)
|
||
{
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(pData->tempr);
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr2)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr3)
|
||
{
|
||
i += 2;
|
||
}
|
||
|
||
// 电池信息
|
||
if(pMask->maskBattery)
|
||
{
|
||
// 电量百分比
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(pData->batPct);
|
||
i += 2;
|
||
// 电池内部温度
|
||
i += 2;
|
||
// 电池当前电压
|
||
*(int16_t *) (Modbus_sendBuff + i) = htons(pData->voltage);
|
||
i += 2;
|
||
// 电池容量
|
||
i += 2;
|
||
// 电池当前容量
|
||
i += 2;
|
||
// 充电电流,电流的符号表示充放电状态
|
||
*(int16_t *) (Modbus_sendBuff + i) = htons(pData->batCurrent);
|
||
i += 2;
|
||
// 光照强度
|
||
i += 2;
|
||
}
|
||
|
||
// 流量计
|
||
if(pMask->maskFlow)
|
||
{
|
||
// 天信MODBUS /A1 通信协议 (BCD码)
|
||
// 标况体积总量
|
||
i += 6;
|
||
// 标况流量
|
||
i += 4;
|
||
// 工况流量
|
||
i += 4;
|
||
// 温度
|
||
i += 4;
|
||
// 压力
|
||
i += 4;
|
||
}
|
||
|
||
// 泄露报警
|
||
if(pMask->maskLeak)
|
||
{
|
||
// 类型
|
||
Modbus_sendBuff[i++] = LEAK_TYPE_SWITCH | LEAK_TYPE_CURRENT | LEAK_TYPE_MODBUS;
|
||
// 状态、报警浓度
|
||
Modbus_sendBuff[i++] = 0x80;
|
||
}
|
||
|
||
if(pMask->maskStamp)
|
||
{
|
||
if(dcBuff.powerInfo.protocolVer.minor == 107)
|
||
{
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(pData->relative_time + (RTC_offsetSeconds + rf_get_seconds() - pGprs->recvTime));
|
||
}
|
||
// 时间
|
||
i += 4;
|
||
// 年月日
|
||
i += 4;
|
||
}
|
||
|
||
// 扩展压力
|
||
if(pMask->maskEPress1)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress2)
|
||
{
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress3)
|
||
{
|
||
i += 2;
|
||
}
|
||
|
||
// 硬件版本
|
||
// Modbus_sendBuff[i++] = ((pData->hardVer / 10) << 4) + pData->hardVer % 10;
|
||
Modbus_sendBuff[i++] = pData->hardVer;
|
||
// 软件版本
|
||
// Modbus_sendBuff[i++] = ((pData->softVer / 10) << 4) + pData->softVer % 10;;
|
||
Modbus_sendBuff[i++] = pData->softVer;
|
||
|
||
// 真空传感器
|
||
for(j = 0; j < 2; j++)
|
||
{
|
||
// 状态
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(0);
|
||
i += 2;
|
||
// 使用年限
|
||
i += 2;
|
||
// 真空度
|
||
i += 4;
|
||
// 漏放气速率
|
||
i += 4;
|
||
}
|
||
|
||
// 气瓶容量
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(Theoretical_Param.v);
|
||
i += 4;
|
||
// 储罐封头直边长
|
||
*(uint16_t *) (Modbus_sendBuff + i) = htons(0);
|
||
i += 2;
|
||
// 储罐筒长度
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(pData->L);
|
||
i += 4;
|
||
// 储罐直径
|
||
*(uint32_t *) (Modbus_sendBuff + i) = htonl(pData->d);
|
||
i += 4;
|
||
// 自动发送频率
|
||
i += 2;
|
||
// 自动发送短信频率
|
||
i += 2;
|
||
|
||
// 修改数据长度
|
||
Modbus_sendBuff[7] = i - 8;
|
||
|
||
// 校验码
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) Modbus_sendBuff, i);
|
||
*(uint16_t *)(Modbus_sendBuff + i) = htons(crc);
|
||
i += 2;
|
||
// 结束符
|
||
Modbus_sendBuff[i++] = 0x0d;
|
||
Modbus_sendBuff[i++] = 0x0a;
|
||
|
||
return i;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
// 填写双向通讯的固定字段
|
||
uint16_t fill_biDir_fixFields(uint16_t cmd, uint16_t len)
|
||
{
|
||
bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff;
|
||
uint16_t crc;
|
||
|
||
pSend->mark = CONFIG_MARK_LS;
|
||
pSend->ver = htons(dcBuff.powerInfo.protocolVer.major);
|
||
pSend->trans = 0;
|
||
pSend->len = htons(len - sizeof(bluetooth_send_t) + 2);
|
||
pSend->cmd = htons(cmd);
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, len);
|
||
Int2ByteS(Task_sendBuff, len, htons(crc));
|
||
|
||
return len + 2;
|
||
}
|
||
|
||
uint16_t pack_ldms_info_data(uint32_t dataTime, uint32_t totalSeconds)
|
||
{
|
||
uint16_t i = 0;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
bluetooth_timestamp_t t;
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
// 头信息(最后再填内容)
|
||
i += sizeof(bluetooth_send_t);
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
// 软件日期:yyyymmdd
|
||
Int2ByteL(Task_sendBuff, i, htonl((2000 + dcBuff.powerInfo.softDate.year) * 10000 + dcBuff.powerInfo.softDate.month * 100 + dcBuff.powerInfo.softDate.day));
|
||
i += 4;
|
||
// Report format
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor;
|
||
// Config format
|
||
Task_sendBuff[i++] = dcBuff.configBottle.header.ver.major;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.header.ver.minor;
|
||
|
||
// 运行时间:分钟
|
||
Int2ByteL(Task_sendBuff, i, htonl(totalSeconds / 60));
|
||
i += 4;
|
||
Int2ByteS(Task_sendBuff, i, htons(SYS_RSTSTS));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batCurrent));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batVoltage / 10));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.dtuData.batPct;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.batCapa));
|
||
i += 4;
|
||
Task_sendBuff[i] = 0;
|
||
i++;
|
||
if(dcBuff.dtuData.posState)
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.latitude));
|
||
i += 4;
|
||
if(dcBuff.dtuData.posState)
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.longitude));
|
||
i += 4;
|
||
|
||
// 定位时间
|
||
if(dcBuff.dtuData.posState && dcBuff.dtuData.sysTime.year)
|
||
{
|
||
t.year = dcBuff.dtuData.sysTime.year + 2000 - 2010;
|
||
t.mon = dcBuff.dtuData.sysTime.month;
|
||
t.day = dcBuff.dtuData.sysTime.day;
|
||
t.hour_H = dcBuff.dtuData.sysTime.hour >> 4;
|
||
t.hour_L = dcBuff.dtuData.sysTime.hour & 0x0F;
|
||
t.min = dcBuff.dtuData.sysTime.minute;
|
||
t.sec = dcBuff.dtuData.sysTime.second;
|
||
Int2ByteL(Task_sendBuff, i, htonl(t.tm));
|
||
}
|
||
i += 4;
|
||
// 卫星数量
|
||
Task_sendBuff[i++] = dcBuff.dtuData.sateCount;
|
||
// 数据时间
|
||
Wakeup_CalcUTCTime(dataTime + RTC_offsetSeconds, &sRTC);
|
||
t.year = sRTC.u32Year - 2010;
|
||
t.mon = sRTC.u32Month;
|
||
t.day = sRTC.u32Day;
|
||
t.hour_H = sRTC.u32Hour >> 4;
|
||
t.hour_L = sRTC.u32Hour & 0x0F;
|
||
t.min = sRTC.u32Minute;
|
||
t.sec = sRTC.u32Second;
|
||
Int2ByteL(Task_sendBuff, i, htonl(t.tm));
|
||
i += 4;
|
||
// 信号强度
|
||
Task_sendBuff[i++] = dcBuff.dtuData.rssi;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSuccCount));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSendCount - dcBuff.powerInfo.gprsSuccCount));
|
||
i += 4;
|
||
if(dcBuff.powerInfo.gprsSendCount > 0)
|
||
Task_sendBuff[i] = dcBuff.powerInfo.gprsSuccCount * 100 / dcBuff.powerInfo.gprsSendCount;
|
||
i++;
|
||
memmove(Task_sendBuff + i, dcBuff.powerInfo.gprsFailCode, strlen(dcBuff.powerInfo.gprsFailCode));
|
||
i += 6;
|
||
memmove(Task_sendBuff + i, dcBuff.powerInfo.simNumber, strlen(dcBuff.powerInfo.simNumber));
|
||
i += 24;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.bdNumber));
|
||
i += 4;
|
||
|
||
// 储罐类型
|
||
Task_sendBuff[i++] = dcBuff.configBottle.type;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.lenExtra));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(Theoretical_Param.v));
|
||
i += 4;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.chargePct;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.source;
|
||
// Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.dispMode;
|
||
// if(dcBuff.configDisplay.L_Unit == UNIT_KPA)
|
||
// Task_sendBuff[i] = 0;
|
||
// else if(dcBuff.configDisplay.L_Unit == UNIT_KG)
|
||
// Task_sendBuff[i] = 1;
|
||
// else if(dcBuff.configDisplay.L_Unit == UNIT_L)
|
||
// Task_sendBuff[i] = 2;
|
||
// else if(dcBuff.configDisplay.L_Unit == UNIT_MMH2O)
|
||
// Task_sendBuff[i] = 4;
|
||
// else
|
||
// Task_sendBuff[i] = 3;
|
||
i++;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.serverVer));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.server, strlen(dcBuff.configData.server));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.port));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.gpsServer, strlen(dcBuff.configData.gpsServer));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.gpsPort));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.upgServer, strlen(dcBuff.configData.upgServer));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.upgPort));
|
||
i += 2;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample));
|
||
i += 4;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPSTrans));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPS));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.configData.timeLag;
|
||
strcpy((char *) Task_sendBuff + i, DTU_DecideAPN());
|
||
i += 20;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configDisplay.bdCommander));
|
||
i += 4;
|
||
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVolt));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVoltH));
|
||
i += 2;
|
||
//Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.planMount));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.offlineSeconds));
|
||
i += 4;
|
||
//Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.predictMount));
|
||
i += 4;
|
||
//Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.floorLevel));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTempr)); // span
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTemprH)); // spanPeriod
|
||
i += 2;
|
||
|
||
// 测量方式
|
||
// Task_sendBuff[i] = dcBuff.configDisplay.op_USE_CAPACITY_SENSOR ? 2 : dcBuff.configBottle.measureType;
|
||
i++;
|
||
// Task_sendBuff[i] = 0;
|
||
i++;
|
||
// Task_sendBuff[i] = dcBuff.configDisplay.op_USE_PT100_SENSOR ? 0 : 1;
|
||
i++;
|
||
|
||
// 差压传感器参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.fullValue));
|
||
i += 2;
|
||
// 电容传感器参数
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.baseC));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.refC));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c1ADC));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c2ADC));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(CAP_K_C1));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(CAP_K_C2));
|
||
i += 2;
|
||
// 称重传感器参数
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.lowRange));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adDPress));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.highRange));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adPress));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.zeroValue));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[0]));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.fullValue));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[1]));
|
||
i += 4;
|
||
// 压力传感器参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.fullValue));
|
||
i += 2;
|
||
// 扩展压力传感器1参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].fullValue));
|
||
i += 2;
|
||
// 扩展温度传感器1参数
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateT));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateR));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].zeroValue));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].fullValue));
|
||
i += 2;
|
||
// 扩展温度传感器2参数
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateT));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateR));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].zeroValue));
|
||
i += 2;
|
||
// Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].fullValue));
|
||
i += 2;
|
||
|
||
// 填写固定字段
|
||
return fill_biDir_fixFields(0xD035, i);
|
||
}
|
||
|
||
#define D036_PARAM_SIZE (240)
|
||
uint8_t parse_param_D036_data(uint8_t *param, uint8_t *reset)
|
||
{
|
||
longlong_mask_t mask;
|
||
uint16_t i = 0, shift = 0;
|
||
|
||
// 参数有效标志位(用一个无符号长整数表示, 共63项可选配置(bit 0~62), 最高位(bit 63)代表复位命令)
|
||
// 网络字节序: 12 34 56 78 90 ab cd ef
|
||
// h = 0x78563412, l = 0xefcdab90 (网络字节序)
|
||
// h = 0x12345678, l = 0x90abcdef (本机字节序)
|
||
// mask = 0x1234567890abcdef
|
||
mask.h = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
mask.l = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
printf("\nmask = %016llX\n", mask.ll);
|
||
|
||
// 储罐类型
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.type = param[i];
|
||
i++;
|
||
// 直径
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.diameter = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 长度
|
||
if(mask.ll & (1ull << (shift++)))
|
||
{
|
||
dcBuff.configBottle.len = ntohl(Byte2IntL(param, i));
|
||
dcBuff.configBottle.lenExtra = 0;
|
||
}
|
||
i += 4;
|
||
// 充装比
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.chargePct = param[i];
|
||
i++;
|
||
// 介质
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.source = param[i];
|
||
i++;
|
||
// 密度
|
||
if(mask.ll & (1ull << (shift++)))
|
||
;//Config_SetDensity(dcBuff.configBottle.source, ntohs(Byte2IntS(param, i)) / 1000.0);
|
||
i += 2;
|
||
// 显示模式
|
||
if(mask.ll & (1ull << (shift++)))
|
||
{
|
||
dcBuff.configBottle.dispMode = param[i];
|
||
|
||
dcBuff.configBottle.options &= ~0x0003ul;
|
||
if(dcBuff.configBottle.dispMode == DISP_MODE_ALL)
|
||
dcBuff.configBottle.options |= 0x0003ul;
|
||
else if(dcBuff.configBottle.dispMode == DISP_MODE_L)
|
||
dcBuff.configBottle.options |= 0x0001ul;
|
||
else if(dcBuff.configBottle.dispMode == DISP_MODE_KG)
|
||
dcBuff.configBottle.options |= 0x0002ul;
|
||
}
|
||
i++;
|
||
// 显示单位
|
||
if(mask.ll & (1ull << (shift++)))
|
||
{
|
||
if(param[i] == 0)
|
||
dcBuff.configDisplay.L_Unit = UNIT_KPA;
|
||
else if(param[i] == 1)
|
||
dcBuff.configDisplay.L_Unit = UNIT_KG;
|
||
else if(param[i] == 2)
|
||
dcBuff.configDisplay.L_Unit = UNIT_L;
|
||
else if(param[i] == 4)
|
||
dcBuff.configDisplay.L_Unit = UNIT_MMH2O;
|
||
else
|
||
dcBuff.configDisplay.L_Unit = UNIT_PCT;
|
||
}
|
||
i++;
|
||
|
||
// 服务器版本
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.server, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.port = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.gpsServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.upgServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.upgPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 发送频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 采集频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 发送频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalGPSTrans = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 采集频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalGPS = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 时差
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.timeLag = param[i];
|
||
i++;
|
||
// APN
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configDisplay.APN, (char *) param + i);
|
||
i += 20;
|
||
// 北斗指挥机卡号
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configDisplay.bdCommander = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
// 压力报警点低: KPa
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnPress = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力报警点高: KPa
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnPressH = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 满液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.fullPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 关键液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.priPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 订货液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.orderPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 空液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.emptyPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电压报警低点: mV
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnVolt = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电压报警高点: mV
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnVoltH = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 每日计划用量: L
|
||
if(mask.ll & (1ull << (shift++)))
|
||
{
|
||
//dcBuff.configBottle.planMount = ntohl(Byte2IntL(param, i));
|
||
dcBuff.configBottle.offlineSeconds = ntohl(Byte2IntL(param, i));
|
||
}
|
||
i += 4;
|
||
// 每日预测用量: L
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; // dcBuff.configBottle.predictMount = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// TTS-空液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configBottle.floorLevel = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// TTS-变化量报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnTempr = ntohs(Byte2IntS(param, i)); // span
|
||
i += 2;
|
||
// TTS-变化量检测时间: 秒
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnTemprH = ntohs(Byte2IntS(param, i)); // spanPeriod
|
||
i += 2;
|
||
|
||
// 差压传感器量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器量程: 底电容
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorCap.baseC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器量程: 增长电容
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorCap.refC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器标定: C1ADC
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorCap.c1ADC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器标定: C2ADC
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorCap.c2ADC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 称重传感器量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.lowRange = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.highRange = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.zeroValue = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.fullValue = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 压力传感器1量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[0].calibrateT = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[0].calibrateR = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[0].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[0].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[1].calibrateT = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[1].calibrateR = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[1].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
; //dcBuff.configSensor.sensorPTempr[1].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
|
||
*reset = ((mask.ll & (1ull << shift)) != 0);
|
||
|
||
return ((mask.ll & ~(1ull << shift)) != 0);
|
||
}
|
||
|
||
#define D038_CONFIG_SIZE (74)
|
||
uint8_t parse_config_D038_data(uint8_t *param)
|
||
{
|
||
uint16_t i = 0;
|
||
|
||
// 服务器版本
|
||
dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
strcpy(dcBuff.configData.server, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
dcBuff.configData.port = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
strcpy(dcBuff.configData.gpsServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 发送频率
|
||
dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 采集频率
|
||
dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
// 硬件版本
|
||
// dcBuff.configDisplay.op_HARDWARE_VER_MAJOR = param[i];
|
||
i++;
|
||
// 只显示毫米水柱
|
||
// dcBuff.configDisplay.op_DISP_MMWC_ONLY = param[i];
|
||
i++;
|
||
// 罐箱版本
|
||
// dcBuff.configDisplay.op_BOX_VER = param[i];
|
||
i++;
|
||
// 基站定位
|
||
// dcBuff.configDisplay.op_CELL_LOCATION = param[i];
|
||
i++;
|
||
// 发送轨迹
|
||
// dcBuff.configDisplay.op_SEND_GPS_DATA = param[i];
|
||
i++;
|
||
// 通信方式
|
||
// dcBuff.configDisplay.op_SERVER_PROTOCOL = param[i];
|
||
i++;
|
||
// URL索引
|
||
// dcBuff.configDisplay.op_SERVER_INDEX = param[i];
|
||
i++;
|
||
// 单向通信
|
||
// dcBuff.configDisplay.op_UNIDIR_COMM = param[i];
|
||
i++;
|
||
|
||
return 1;
|
||
}
|
||
|
||
// 从服务器获取时间
|
||
void DTU_setOffsetSecondsFromServer()
|
||
{
|
||
bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint32_t totalSeconds1, totalSeconds2;
|
||
int16_t zz;
|
||
uint16_t i, recvLen;
|
||
|
||
// 从服务器获取当前时间
|
||
printf("\nGet time from server ...\n");
|
||
// 连接升级服务器
|
||
if(DTU_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort))
|
||
{
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD03B, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(DTU_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 11
|
||
&& pRecv->cmd == ntohs(0x003B)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + 11) == 0)
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
totalSeconds1 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// UTC日期
|
||
i = sizeof(bluetooth_recv_t);
|
||
|
||
// 年
|
||
sRTC.u32Year = ntohs(Byte2IntS(Task_recvBuff, i));
|
||
i += 2;
|
||
// 月
|
||
sRTC.u32Month = Task_recvBuff[i++];
|
||
// 日
|
||
sRTC.u32Day = Task_recvBuff[i++];
|
||
// 时
|
||
sRTC.u32Hour = Task_recvBuff[i++];
|
||
// 分
|
||
sRTC.u32Minute = Task_recvBuff[i++];
|
||
// 秒
|
||
sRTC.u32Second = Task_recvBuff[i++];
|
||
// 时差(按1/4小时, 带符号)
|
||
recvLen = ntohs(Byte2IntS(Task_recvBuff, i));
|
||
memmove(&zz, &recvLen, 2);
|
||
|
||
printf("\n%04d-%02d-%02d %02d:%02d:%02d %d\n", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second, zz);
|
||
|
||
totalSeconds2 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// 将UTC时间转换为GMT时间(时差为0)
|
||
totalSeconds2 -= zz * 900;
|
||
// 将GMT时间转换为UTC时间(按配置的时差)
|
||
totalSeconds2 += dcBuff.configData.timeLag * 3600;
|
||
|
||
if(RTC_offsetSeconds == 0)
|
||
{
|
||
RTC_offsetSeconds = totalSeconds2 - totalSeconds1;
|
||
// 关联铁电和SFlash的一致性
|
||
CheckFramSFlashValid(totalSeconds1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
}
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
// 任务主体:发送运行数据和GPS数据,读取网络信号强度等
|
||
void DTU_Task(void *p_arg)
|
||
{
|
||
bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff;
|
||
bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff;
|
||
uint16_t i, j, k;
|
||
uint32_t totalSeconds;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint8_t try_count;
|
||
uint16_t recvLen;
|
||
uint8_t upgrade;
|
||
uint8_t ackUpgrade;
|
||
uint8_t downloadParam;
|
||
uint8_t ackParam;
|
||
uint8_t downloadOptions;
|
||
uint8_t ackOptions;
|
||
uint8_t downloadBoxes;
|
||
uint8_t ackBoxes;
|
||
uint8_t downloadConfig;
|
||
uint8_t ackConfig;
|
||
uint8_t reset = 0;
|
||
TUpgradeHeader upHeader;
|
||
upgrade_frame_t *pFrame;
|
||
int32_t nextPtr;
|
||
uint8_t write_count;
|
||
|
||
uint32_t rssiTick = 0;
|
||
uint8_t tranLocked = 0;
|
||
|
||
// 清除数据
|
||
memset(&dcBuff.dtuData, 0, sizeof(dcBuff.dtuData));
|
||
|
||
// 从铁电读取最近一次GPS定位信息,并检查是否合法
|
||
if(FRAM_LoadInfo(FRAM_GPS_INFO_BASE, (uint8_t *) &Ext_GPS, sizeof(ext_gps_t)))
|
||
{
|
||
dcBuff.dtuData.sysTime = Ext_GPS.sysTime;
|
||
dcBuff.dtuData.longitude = Ext_GPS.longitude;
|
||
dcBuff.dtuData.latitude = Ext_GPS.latitude;
|
||
dcBuff.dtuData.speed = Ext_GPS.speed;
|
||
dcBuff.dtuData.sateCount = Ext_GPS.sateCount;
|
||
dcBuff.dtuData.posState = Ext_GPS.posState;
|
||
}
|
||
|
||
// 触发固件升级任务:开机执行一次
|
||
xSemaphoreGive(DTU_semUpgrade);
|
||
|
||
while(1)
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 计算自上次gps定位以来的时间
|
||
totalSeconds = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
// 刚开始运行的时候,回退到刚启动的时间(忽略系统初始化时间)
|
||
if(totalSeconds < 10)
|
||
totalSeconds = 0;
|
||
|
||
// 每30秒刷新一下4G信号
|
||
if(IsTickOut(rssiTick))
|
||
{
|
||
rssiTick = GetDelayTick(30000);
|
||
|
||
DTU_PowerOn();
|
||
// 采集信号强度和注册信息
|
||
Sim808_ReadGPRS();
|
||
|
||
// GPRS拨号和GPS定位同时进行,以节省时间
|
||
if(dcBuff.dtuData.networked)
|
||
Sim808_GPRSDial();
|
||
}
|
||
|
||
// 连接成功,对发送加锁
|
||
if(!dcBuff.dtuData.connected && Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port) && !tranLocked)
|
||
{
|
||
xSemaphoreTake(RF_TranLock, portMAX_DELAY);
|
||
tranLocked = 1;
|
||
}
|
||
|
||
if(!dcBuff.dtuData.connected && tranLocked)
|
||
{
|
||
// 4G连接失败,释放锁让网口有机会发送
|
||
xSemaphoreGive(RF_TranLock);
|
||
tranLocked = 0;
|
||
}
|
||
|
||
// 掉电有效,如果未获取到UTC时间,不转发
|
||
if(RTC_offsetSeconds > 0 && dcBuff.dtuData.connected && LoopBuff_GetCount(&RF_TranM) > 0)
|
||
{
|
||
nextPtr = RF_TranM.info.rdPtr;
|
||
for(k = 0; k < LoopBuff_GetCount(&RF_TranM); k++)
|
||
{
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
if(!SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_TranM, nextPtr), (uint8_t *) &Ext_Data_Rec1, sizeof(ext_data_t)))
|
||
{
|
||
nextPtr = LoopBuff_GetNextPtr(&RF_TranM, nextPtr);
|
||
continue; // 不发送,算失败1次
|
||
}
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&RF_TranM, nextPtr);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
i = pack_gprs_tran_data(&Ext_Data_Rec1, 1);
|
||
|
||
recvLen = 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(tranLocked)
|
||
{
|
||
// 4G发送失败,释放锁让网口有机会发送
|
||
xSemaphoreGive(RF_TranLock);
|
||
tranLocked = 0;
|
||
}
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
break;
|
||
}
|
||
|
||
// 成功发送数据的时间: 取当前时间
|
||
DTU_dataTime = totalSeconds;
|
||
|
||
dcBuff.powerInfo.gprsSuccCount++;
|
||
}
|
||
|
||
// 移除已成功发送的数据
|
||
if(k > 0)
|
||
{
|
||
LoopBuff_RemoveItems(&RF_TranM, k);
|
||
// 保存到铁电
|
||
FRAM_SaveInfo(RF_TranM.info_base, (uint8_t *) &RF_TranM.info, sizeof(RF_TranM.info));
|
||
}
|
||
}
|
||
|
||
// 是否连接维护平台:每隔12小时一次(普莱克斯、林德的每次连接)
|
||
if(xSemaphoreTake(DTU_semUpgrade, 0) == pdTRUE)
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 是否升级或下载参数:维护平台
|
||
upgrade = 0;
|
||
ackUpgrade = 0;
|
||
downloadParam = 0;
|
||
ackParam = 0;
|
||
downloadOptions = 0;
|
||
ackOptions = 0;
|
||
downloadBoxes = 0;
|
||
ackBoxes = 0;
|
||
downloadConfig = 0;
|
||
ackConfig = 0;
|
||
reset = 0;
|
||
k = 1; // 发送1条诊断信息
|
||
|
||
try_count = 2;
|
||
while((try_count--) && (k || upgrade || ackUpgrade || downloadParam || ackParam || downloadOptions || ackOptions || downloadBoxes || ackBoxes || downloadConfig || ackConfig))
|
||
{
|
||
// 连接升级服务器
|
||
if(Sim808_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort))
|
||
{
|
||
if(k)
|
||
{
|
||
// 发送诊断信息,至少接收12个字节
|
||
i = pack_ldms_info_data(DTU_dataTime, totalSeconds);
|
||
recvLen = sizeof(bluetooth_recv_t) + 2 + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2 + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0
|
||
&& pRecv->cmd == ntohs(0x0035))
|
||
{
|
||
upgrade = Task_recvBuff[sizeof(bluetooth_recv_t)];
|
||
downloadParam = Task_recvBuff[sizeof(bluetooth_recv_t) + 1];
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 3 + 2)
|
||
downloadConfig = Task_recvBuff[sizeof(bluetooth_recv_t) + 2];
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 4 + 2)
|
||
downloadOptions = Task_recvBuff[sizeof(bluetooth_recv_t) + 3];
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 5 + 2)
|
||
downloadBoxes = Task_recvBuff[sizeof(bluetooth_recv_t) + 4];
|
||
k--; // 发送成功
|
||
}
|
||
}
|
||
|
||
// 下载参数
|
||
if(downloadParam)
|
||
{
|
||
printf("\nDownload parameters ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD036, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
downloadParam = 0;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2
|
||
&& pRecv->cmd == ntohs(0x0036)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2) == 0)
|
||
{
|
||
// 保存参数
|
||
if(parse_param_D036_data(Task_recvBuff + sizeof(bluetooth_recv_t), &reset))
|
||
{
|
||
// 保存参数
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi);
|
||
}
|
||
ackParam = 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认参数
|
||
if(ackParam)
|
||
{
|
||
printf("\nConfirm download parameters ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 参数时间戳
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD022, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
ackParam = 0;
|
||
}
|
||
|
||
// 下载配置选项
|
||
if(downloadOptions)
|
||
{
|
||
}
|
||
|
||
// 确认配置选项
|
||
if(ackOptions)
|
||
{
|
||
}
|
||
|
||
// 下载罐箱档案
|
||
if(downloadBoxes)
|
||
{
|
||
printf("\nDownload boxes ...\n");
|
||
|
||
if(boxesInfo.fileSize == 0)
|
||
{
|
||
// 从头开始下载
|
||
memset(&boxesInfo, 0, sizeof(boxesInfo));
|
||
}
|
||
|
||
// 下载数据
|
||
while(boxesInfo.fileSize == 0 || boxesInfo.offset < boxesInfo.fileSize)
|
||
{
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前版本号
|
||
i += 4;
|
||
// 文件偏移量
|
||
Int2ByteL(Task_sendBuff, i, htonl(boxesInfo.offset));
|
||
i += 4;
|
||
// 请求数据长度
|
||
Int2ByteL(Task_sendBuff, i, htonl(UPGRADE_DATA_LEN));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E2, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再下载
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
if(pRecv->cmd == ntohs(0x00E2))
|
||
{
|
||
pFrame = (upgrade_frame_t *) (Task_recvBuff + sizeof(bluetooth_recv_t));
|
||
if(MODBUS_RTU_CRC16(pFrame->data, ntohl(pFrame->len) + 2) == 0)
|
||
{
|
||
// 内容下载成功,允许继续下载
|
||
try_count = 2;
|
||
|
||
// 如果储罐档案有变化
|
||
if(boxesInfo.fileSize > 0 && (boxesInfo.fileSize != ntohl(pFrame->fileSize) || boxesInfo.fileCrc != pFrame->fileCrc
|
||
|| boxesInfo.offset > ntohl(pFrame->fileSize)))
|
||
{
|
||
// 从头开始升级
|
||
memset(&boxesInfo, 0, sizeof(boxesInfo));
|
||
continue;
|
||
}
|
||
// 保存下载信息
|
||
// 如果只是网络通信失败,会断点续传
|
||
boxesInfo.fileSize = ntohl(pFrame->fileSize);
|
||
boxesInfo.offset = ntohl(pFrame->offset);
|
||
boxesInfo.len = ntohl(pFrame->len);
|
||
boxesInfo.fileCrc = pFrame->fileCrc;
|
||
printf("\nfileSize = %d, offset = %d, len = %d\n",
|
||
boxesInfo.fileSize, boxesInfo.offset, boxesInfo.len);
|
||
|
||
// 要留1个字节用于添加结束符
|
||
if(boxesInfo.offset + boxesInfo.len < sizeof(boxesBuff))
|
||
{
|
||
memmove(boxesBuff + boxesInfo.offset, pFrame->data, boxesInfo.len);
|
||
boxesInfo.offset += boxesInfo.len;
|
||
}
|
||
else
|
||
{
|
||
// 取消本次下载
|
||
boxesInfo.fileSize = 0;
|
||
downloadBoxes = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else // 命令返回错误
|
||
{
|
||
// 取消本次下载
|
||
boxesInfo.fileSize = 0;
|
||
downloadBoxes = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(boxesInfo.fileSize > 0 && boxesInfo.offset == boxesInfo.fileSize)
|
||
{
|
||
if(do_crc_16(0, (uint8_t *) boxesBuff, boxesInfo.fileSize) == boxesInfo.fileCrc)
|
||
{
|
||
// 校验通过
|
||
printf("\nBoxes confirm passed\n");
|
||
downloadBoxes = 0;
|
||
|
||
// 发送确认
|
||
ackBoxes = 1;
|
||
}
|
||
else
|
||
{
|
||
// 校验未通过
|
||
printf("\n****** Boxes confirm failed\n");
|
||
// 从头开始
|
||
boxesInfo.fileSize = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 继续
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认罐箱档案
|
||
if(ackBoxes)
|
||
{
|
||
printf("\nConfirm boxes ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前版本号
|
||
Int2ByteL(Task_sendBuff, i, htonl(boxesInfo.ver));
|
||
i += 4;
|
||
// 档案的CRC16
|
||
Int2ByteS(Task_sendBuff, i, boxesInfo.fileCrc);
|
||
i += 2;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E3, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
if(recvLen == sizeof(bluetooth_recv_t) + 2 && pRecv->cmd == ntohs(0x00E3))
|
||
{
|
||
ackBoxes = 0;
|
||
|
||
// 更新储罐档案
|
||
boxesBuff[boxesInfo.fileSize] = 0;
|
||
Ext_Update_Boxes(boxesBuff);
|
||
|
||
// 下次再升级从头开始
|
||
boxesInfo.fileSize = 0;
|
||
}
|
||
}
|
||
|
||
// 下载配置
|
||
if(downloadConfig)
|
||
{
|
||
printf("\nDownload configuration ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD038, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
downloadConfig = 0;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + D038_CONFIG_SIZE + 2
|
||
&& pRecv->cmd == ntohs(0x0038)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D038_CONFIG_SIZE + 2) == 0)
|
||
{
|
||
// 保存参数
|
||
if(parse_config_D038_data(Task_recvBuff + sizeof(bluetooth_recv_t)))
|
||
{
|
||
// 保存参数
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi);
|
||
}
|
||
ackConfig = 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认配置
|
||
if(ackConfig)
|
||
{
|
||
printf("\nConfirm download configuration ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD039, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
ackConfig = 0;
|
||
// 配置改变,需要复位
|
||
reset = 1;
|
||
}
|
||
|
||
// 升级
|
||
if(upgrade)
|
||
{
|
||
printf("\nUpgrade software ...\n");
|
||
|
||
// 从FRAM读取初始进度
|
||
FRAM_LoadInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
|
||
if(upInfo.fileSize == 0)
|
||
{
|
||
// 从头开始升级
|
||
memset(&upInfo, 0, sizeof(upInfo));
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
|
||
// 下载数据
|
||
while(upInfo.fileSize == 0 || upInfo.offset < upInfo.fileSize)
|
||
{
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前固件号
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver));
|
||
i += 4;
|
||
// 文件偏移量
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.offset));
|
||
i += 4;
|
||
// 请求数据长度
|
||
Int2ByteL(Task_sendBuff, i, htonl(UPGRADE_DATA_LEN));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E0, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再升级
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
if(pRecv->cmd == ntohs(0x00E0))
|
||
{
|
||
pFrame = (upgrade_frame_t *) (Task_recvBuff + sizeof(bluetooth_recv_t));
|
||
if(MODBUS_RTU_CRC16(pFrame->data, ntohl(pFrame->len) + 2) == 0)
|
||
{
|
||
// 升级内容下载成功,允许继续升级
|
||
try_count = 2;
|
||
|
||
// 如果升级包有变化
|
||
if(upInfo.fileSize > 0 && (upInfo.fileSize != ntohl(pFrame->fileSize) || upInfo.fileCrc != pFrame->fileCrc
|
||
|| upInfo.offset > ntohl(pFrame->fileSize) || upInfo.ver != ntohl(pFrame->ver)))
|
||
{
|
||
// 从头开始升级
|
||
memset(&upInfo, 0, sizeof(upInfo));
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
continue;
|
||
}
|
||
// 保存下载信息
|
||
// 如果只是网络通信失败,会断点续传
|
||
upInfo.ver = ntohl(pFrame->ver);
|
||
upInfo.fileSize = ntohl(pFrame->fileSize);
|
||
upInfo.offset = ntohl(pFrame->offset);
|
||
upInfo.len = ntohl(pFrame->len);
|
||
upInfo.fileCrc = pFrame->fileCrc;
|
||
printf("\nfileSize = %d, offset = %d, len = %d\n",
|
||
upInfo.fileSize, upInfo.offset, upInfo.len);
|
||
|
||
// 如果是第一个包,先将升级请求改为0,以免意外重启导致boot-loader解压
|
||
// 待全部下载完以后,再改为1
|
||
if(upInfo.offset == 0)
|
||
((TUpgradeHeader *) pFrame->data)->upgrade_request = 0;
|
||
#if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE
|
||
// 直接写入flash
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + upInfo.offset, upInfo.len);
|
||
delay_ms(200);
|
||
}
|
||
upInfo.offset += upInfo.len;
|
||
#else
|
||
// 为了减少flash的多次擦写,又节约收发缓冲
|
||
// 先把数据拷到flash页缓冲
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_BufferWrite(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len);
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, upInfo.len);
|
||
delay_ms(200);
|
||
}
|
||
upInfo.offset += upInfo.len;
|
||
|
||
// 够一页了,或者下载完了就从铁电写入flash
|
||
if(upInfo.offset % SFLASH_ERASE_SIZE == 0)
|
||
{
|
||
FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, SFLASH_ERASE_SIZE);
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), SFLASH_ERASE_SIZE);
|
||
delay_ms(200);
|
||
}
|
||
|
||
}
|
||
else if(upInfo.offset == upInfo.fileSize)
|
||
{
|
||
FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE);
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), upInfo.offset % SFLASH_ERASE_SIZE);
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
#endif
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
// 保存到铁电
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
}
|
||
else // 命令返回错误
|
||
{
|
||
// 取消本次升级
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
|
||
upgrade = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(upInfo.fileSize > 0 && upInfo.offset == upInfo.fileSize)
|
||
{
|
||
SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
// 将升级请求改为1
|
||
upHeader.upgrade_request = 1;
|
||
if(upHeader.check == 0x55AA
|
||
&& do_crc_16(0, (uint8_t *) &upHeader, sizeof(upHeader)) == 0
|
||
&& do_sflash_crc(SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length) == 0)
|
||
{
|
||
// 校验通过
|
||
printf("\nUpgrade package confirm passed\n");
|
||
// 发送确认
|
||
ackUpgrade = 1;
|
||
}
|
||
else
|
||
{
|
||
// 校验未通过
|
||
printf("\n****** Upgrade package confirm failed\n");
|
||
// 从头开始
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 继续
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认升级成功
|
||
if(ackUpgrade)
|
||
{
|
||
printf("\nConfirm upgrade software ...\n");
|
||
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前固件号
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver));
|
||
i += 4;
|
||
// 固件的CRC16
|
||
Int2ByteS(Task_sendBuff, i, upInfo.fileCrc);
|
||
i += 2;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E1, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
if(recvLen == sizeof(bluetooth_recv_t) + 2 && pRecv->cmd == ntohs(0x00E1))
|
||
{
|
||
// 将升级请求改为1
|
||
SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
upHeader.upgrade_request = 1;
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE, sizeof(upHeader));
|
||
delay_ms(200);
|
||
}
|
||
|
||
// 下次再升级从头开始
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 关闭DTU电源
|
||
VCC_GSM_OFF();
|
||
delay_ms(200);
|
||
|
||
// 将LDROM映射到地址0x0
|
||
// FMC_Open();
|
||
// FMC_SetVectorPageAddr(LDROM_BASE);
|
||
// FMC_Close();
|
||
// 复位以后执行Bootloader,将升级包解压
|
||
//WDT_Close(); // 先关看门狗,免得bootloader复位
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 确认参数以后才执行复位命令(避免反复复位)
|
||
if(reset && !ackParam)
|
||
{
|
||
VCC_GSM_OFF();
|
||
delay_ms(200);
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 刚处理完,清除等待的信号。等下一个周期再执行(如果有报警必须立即上传)
|
||
xSemaphoreTake(DTU_semUpgrade, 0);
|
||
}
|
||
}
|
||
}
|