| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- #include "crc16.h"
- #include "mcu_ctrl_board.h"
- #include "../swapi/subjects/serial/serial.h"
- // 模块名称
- static const char MODULE_NAME[] = "MCUCtrlBoard";
- // 告诉编译器使用一字节内存对齐
- #pragma pack(push, 1)
- // 单片机控制板运行配置(小端序)
- typedef struct {
- uint8_t version[4]; // 版本号
- uint8_t ctrl_mode; // 定时控制模式(0=光控, 1=时控)
- uint8_t light_duration; // 光控定时时长(单位: 小时, 范围: 1-10, 仅光控模式有效)
- uint8_t start_hour; // 时控开始时间(小时, 0-23, 一天24小时, 仅时控模式有效)
- uint8_t end_hour; // 时控结束时间(小时, 0-23, 一天24小时, 仅时控模式有效)
- uint8_t tp_intvl_min[2];// 拍照间隔(分钟,其值不得超过当前控制模式下允许的最大值)
- } MCUScheduleCfg;
- // 恢复之前原有内存字节对齐方式
- #pragma pack(pop)
- // 定义与单片机进行通讯的结构体
- typedef struct
- {
- void *h; // 打开的串口句柄
- char work_state[4]; // 工作状态位图(共32个状态)
- void *state_rwlock; // 状态位图读写锁
- SensorEnvData data[24]; // 接收传感器采集的环境数据
- void *edata_rwlock; // 环境数据读写锁
- } SMCBCom;
- static MCUScheduleCfg cfg_params;
- static SMCBCom s_myCom;
- // 声明Go中的判断RTU是否已联网在线的函数(Go实现, 供C/C++调用)
- extern int RTU_IsInetAvailable(); // 0未联网, 1已联网
- // 声明Go中的判断RTU是否已同步时间的函数(Go实现, 供C/C++调用)
- extern int RTU_IsSyncedNtpTime(); // 0未同步, 1已同步
- // 声明Go中的判断RTU是否已登录后台服务器(Go实现, 供C/C++调用)
- extern int RTU_IsLoginMqServer(); // 0未登录, 1已登录
- // 声明Go中发送一组 温湿度光照数据的函数(Go实现, 供C/C++调用)
- extern int RTU_SendGrpEnvData(SensorEnvData *pGrpData, int cnt/*数量, 一次全发是24*/); // 0成功, <0时失败
- // 声明Go中发送一条 温湿度光照数据的函数(Go实现, 供C/C++调用)
- extern int RTU_SendOneEnvData(SensorEnvData *pOneData); // 0成功, <0时失败
- // 声明Go中通知RTU需要进行一次拍照的函数(Go实现, 供C/C++调用)
- extern int RTU_RequestTakePhoto(); // 0成功, <0时失败
- // 声明Go中加载MCU配置项"运行参数"的函数(Go实现, 供C/C++调用)
- extern int RTU_LoadMCUParamsCfg(); // 0成功, <0时失败
- // 声明Go中通知RTU进行一次掉电关机的函数(Go实现, 供C/C++调用)
- extern int RTU_NotifyPwrWillOff(); // 0成功, <0时失败
- // 反转字节, 可用于处理大小端字节序的相互转换,"n"不必是2的倍数
- static inline void swap_bytes(char *a, size_t n)
- {
- for(char *p = a, *q = a + n - 1; p < q; p++, q--) { char t = *p; *p = *q; *q = t; }
- }
- // 获取32位秒级时间戳(存在"2038-01-19 03:14:07 UTC"溢出风险)
- static inline uint32_t now_sec32(void)
- {
- return (uint32_t)time(NULL);
- }
- // 发送数据前, 处理帧内容的转义, 返回添加转义后的数据帧及其长度
- static int frame_doEscapeChars(const unsigned char *src, int len, unsigned char **dst)
- {
- if(!src ||!dst || len < 2 || src[0]!= 0x7D || src[len-1]!= 0x7E) return -1;
- unsigned char *ptr = (unsigned char *)sw_heap_malloc(2+2*(len-2));
- if(!ptr) return -2;
- ptr[0] = src[0]; int j = 1;
- for(int i = 1; i < (len-1); i++)
- {
- if(0);
- else if(src[i] == 0x7D) { ptr[j++] = 0x7D; ptr[j++] = 0x5D; }
- else if(src[i] == 0x7E) { ptr[j++] = 0x7D; ptr[j++] = 0x5E; }
- else ptr[j++] = src[i];
- }
- ptr[j++] = src[len-1]; *dst = ptr;
- return j;
- }
- // 接收数据后, 反转义帧数据内容, 返回去掉转义后的原始帧及其长度
- static int frame_unescapeChars(const unsigned char *src, int len, unsigned char **dst)
- {
- if(!src ||!dst || len < 2 || src[0]!= 0x7D || src[len-1]!= 0x7E) return -1;
- unsigned char *ptr = (unsigned char *)sw_heap_malloc(2+1*(len-2));
- if(!ptr) return -2;
- ptr[0] = src[0]; int j = 1;
- for(int i = 1; i < (len-1); i++)
- {
- if(0);
- else if(src[i] == 0x7D && src[i+1] == 0x5D) { ptr[j++] = 0x7D; i++; }
- else if(src[i] == 0x7D && src[i+1] == 0x5E) { ptr[j++] = 0x7E; i++; }
- else ptr[j++] = src[i];
- }
- ptr[j++] = src[len-1]; *dst = ptr;
- return j;
- }
- // 接收、处理来自MCU控制板的数据报文帧, 串口-线程回调
- #define MIN_FRAME_LEN 6 // 最小帧(数据区为零)的长度
- static int comio_data_recv_proc(unsigned long wParam/*传递打开的串口句柄*/, unsigned long lParam/*保留暂未使用*/)
- {
- SMCBCom *pComIO = &s_myCom; void *pSerial = pComIO->h;
- const unsigned char *pRecvBuf = serial_get_recv_buffer(pSerial); int nRecvBytes = serial_get_recv_buffer_bytes(pSerial);
- const char *log_prefix = serial_get_log_prefix(pSerial); int ret; bool bPrintRecvBuf = true;
- unsigned char *req = NULL; int nReqBytes; u_int16_t crc1, crc2, crc3; int nReqDataLen;
- unsigned char sendBuf[MAX_LINE_CHARS] = { 0 }; int nSendBytes;
- unsigned char *rsp = NULL; int nRspBytes; char log_rsp[MAX_LINE_CHARS] = { 0 }; static bool bTakenPhoto = false; /*标记本次是否已拍照*/
- // 0, 判定接收有效的请求帧
- if((nRecvBytes == 1 && pRecvBuf[0] != 0x7D) || (nRecvBytes == 2 && pRecvBuf[1] == 0x5D)) goto ret_p3;
- else if(nRecvBytes >= MIN_FRAME_LEN && pRecvBuf[nRecvBytes-1] == 0x7E) goto ret_p1;
- else goto ret_p4;
- // 1, 收到一个完整的请求帧
- ret_p1:
- // 1.1, 打印接收到的帧内容
- bPrintRecvBuf = false;
- serial_printf_recv_buffer(pSerial, LEVEL_DEBUG);
- sw_log_debug("[%s] %s received a request(%d bytes)", MODULE_NAME, log_prefix, nRecvBytes);
- // 1.2, 去掉转义得到原始帧
- ret = frame_unescapeChars(pRecvBuf, nRecvBytes, &req);
- if(ret < MIN_FRAME_LEN)
- {
- sw_log_error("[%s] %s failed to unescape the received request(%d)!!", MODULE_NAME, log_prefix, ret);
- goto ret_p3;
- }
- nReqBytes = ret;
- // 1.3, 该请求帧合法性校验
- crc1 = MAKEWORD(req[nReqBytes-3], req[nReqBytes-2]);
- crc2 = CRC16(req+1, nReqBytes-4);
- if(crc1 != crc2)
- {
- sw_log_error("[%s] %s received a request with invalid crc16(0x%02x != 0x%02x)!!", MODULE_NAME, log_prefix, crc1, crc2);
- goto ret_p3;
- }
- // 1.4, 解析处理该帧的请求
- nReqDataLen = nReqBytes-MIN_FRAME_LEN; // 数据区长度
- switch(req[2])
- {
- case 0x01: // MCU查询RTU的工作状态
- if(nReqDataLen != 1) { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- int pwr_reason = (int)req[3];
- bool bTakePhoto = ((pwr_reason == 1 || pwr_reason == 2) ? true : false);
- if(bTakePhoto && !bTakenPhoto) { RTU_RequestTakePhoto()/*请求RTU进行拍照(异步执行)*/; bTakenPhoto = true/*只请求一次*/; }
- unsigned char tmpBuf1[10] = { 0x7D, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E };
- sw_rwlock_wrlock(pComIO->state_rwlock, WAIT_FOREVER);
- if(RTU_IsInetAvailable() == 1 && RTU_IsLoginMqServer() == 1) sw_chararry_setBit(pComIO->work_state, 4, 0, 0x01); // 联机
- else sw_chararry_setBit(pComIO->work_state, 4, 0, 0x00); // 脱机
- for(int i = 0; i < 4; i++) { tmpBuf1[3+i] = pComIO->work_state[3-i]; } // 小端转大端
- sw_rwlock_unlock(pComIO->state_rwlock);
- crc3 = CRC16(tmpBuf1+1, 6);
- memcpy(&tmpBuf1[7], &crc3, 2); // 小端字节序
- nSendBytes = sizeof(tmpBuf1); memcpy(sendBuf, tmpBuf1, nSendBytes);
- goto ret_p2;
- case 0x02: // 24小时温湿度光照数据, 每组14字节, 正常是24组
- case 0x05: // RTU单次的请求MCU, 发送一组当前实时的环境数据
- if(nReqDataLen <= 0 || (nReqDataLen%14) != 0 || (nReqDataLen/14) <= 0 || (nReqDataLen/14) > 24)
- { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- int groupCnt = nReqDataLen/14;
- if(req[2] == 0x05 && groupCnt != 1)
- { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- sw_rwlock_wrlock(pComIO->edata_rwlock, WAIT_FOREVER);
- for(int i = 0; i < groupCnt; i++)
- {
- memcpy(&pComIO->data[i].timestamp, req+3 +i*14, 4); // 时间戳(秒, 存在"2038-01-19 03:14:07 UTC"溢出风险)
- swap_bytes((char *)&pComIO->data[i].timestamp, 4); // 大端转小端
- memcpy(&pComIO->data[i].temperature, req+7 +i*14, 2); // 温度, 单位: 0.1°C
- swap_bytes((char *)&pComIO->data[i].temperature, 2); // 大端转小端
- memcpy(&pComIO->data[i].humidity, req+9 +i*14, 2); // 湿度, 单位: 0.1%RH
- swap_bytes((char *)&pComIO->data[i].humidity, 2); // 大端转小端
- memcpy(&pComIO->data[i].illuminance, req+11+i*14, 4); // 光照, 单位: lux
- swap_bytes((char *)&pComIO->data[i].illuminance, 4); // 大端转小端
- memcpy(&pComIO->data[i].voltage, req+15+i*14, 2); // 电压, 单位: 0.1V
- swap_bytes((char *)&pComIO->data[i].voltage, 2); // 大端转小端
- }
- if(req[2] == 0x02) RTU_SendGrpEnvData(&pComIO->data[0], groupCnt); // 异步发送一组环境数据到RTU
- if(req[2] == 0x05) RTU_SendOneEnvData(&pComIO->data[0]); // 异步发送一条环境数据到RTU
- sw_rwlock_unlock(pComIO->edata_rwlock);
- if(req[2] == 0x05) goto ret_p3; // 应答帧不需要再回复
- unsigned char tmpBuf2[6] = { 0x7D, 0x01, 0x02, 0x81, 0xE1, 0x7E };
- nSendBytes = sizeof(tmpBuf2); memcpy(sendBuf, tmpBuf2, nSendBytes);
- goto ret_p2;
- case 0x03: // MCU请求RTU, 进行对时
- if(nReqDataLen != 4) { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- unsigned char tmpBuf3[10] = { 0x7D, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E };
- if(RTU_IsSyncedNtpTime() == 1)
- { // 使用RTU时间同步返回
- uint32_t now = now_sec32();
- swap_bytes((char *)&now, 4); // 小端转大端
- memcpy(&tmpBuf3[3], &now, 4);
- }
- else
- { // 使用MCU时间原路返回
- tmpBuf3[3] = req[3]; tmpBuf3[4] = req[4]; tmpBuf3[5] = req[5]; tmpBuf3[6] = req[6];
- uint32_t now = ((uint32_t)req[3] << 24) | ((uint32_t)req[4] << 16) | ((uint32_t)req[5] << 8) | (uint32_t)req[6];
- char timestamp[MAX_LINE_CHARS]; sprintf(timestamp, "%u", now);
- if(xsetlocaltime(timestamp) == 0) sw_log_info("[%s] %s set local time to %s with MCU clock", MODULE_NAME, log_prefix, timestamp);
- else sw_log_warn("[%s] %s failed to set local time to %s with MCU clock!", MODULE_NAME, log_prefix, timestamp);
- }
- crc3 = CRC16(tmpBuf3+1, 6);
- memcpy(&tmpBuf3[7], &crc3, 2); // 小端字节序
- nSendBytes = sizeof(tmpBuf3); memcpy(sendBuf, tmpBuf3, nSendBytes);
- goto ret_p2;
- case 0x04: // MCU请求RTU, 同步参数
- if(nReqDataLen != 4) { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- if(RTU_LoadMCUParamsCfg() != 0) goto ret_p3;
- unsigned char tmpBuf4[16] = { 0x7D, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E };
- tmpBuf4[3] = cfg_params.version[3]; tmpBuf4[4] = cfg_params.version[2];
- tmpBuf4[5] = cfg_params.version[1]; tmpBuf4[6] = cfg_params.version[0];
- tmpBuf4[7] = cfg_params.ctrl_mode; // 定时控制模式
- tmpBuf4[8] = cfg_params.light_duration; // 光控定时时长
- tmpBuf4[9] = cfg_params.start_hour; // 时控开始时间
- tmpBuf4[10] = cfg_params.end_hour; // 时控结束时间
- tmpBuf4[11] = cfg_params.tp_intvl_min[1]; // 拍照时间间隔
- tmpBuf4[12] = cfg_params.tp_intvl_min[0]; // 拍照时间间隔
- crc3 = CRC16(tmpBuf4+1, 12);
- memcpy(&tmpBuf4[13], &crc3, 2); // 小端字节序
- nSendBytes = sizeof(tmpBuf4); memcpy(sendBuf, tmpBuf4, nSendBytes);
- goto ret_p2;
- case 0x06: // MCU通知RTU, 准备掉电
- if(nReqDataLen != 1) { sw_log_error("[%s] %s received a request with invalid data length!!", MODULE_NAME, log_prefix); goto ret_p3; }
- unsigned char tmpBuf6[10] = { 0x7D, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E };
- uint32_t work_state;
- sw_rwlock_rdlock(pComIO->state_rwlock, WAIT_FOREVER);
- memcpy(&work_state, pComIO->work_state, 4); // 保持小端序
- for(int i = 0; i < 4; i++) { tmpBuf6[3+i] = pComIO->work_state[3-i]; } // 小端转大端
- sw_rwlock_unlock(pComIO->state_rwlock);
- crc3 = CRC16(tmpBuf6+1, 6);
- memcpy(&tmpBuf6[7], &crc3, 2); // 小端字节序
- if(work_state == 0x00000000 || work_state == 0x00000001)
- { // 空闲状态, 通知RTU准备掉电, 非空闲状态时MCU应继续查询等待
- RTU_NotifyPwrWillOff();
- sw_log_warn("[%s] %s notified \"RTU\" to power off!", MODULE_NAME, log_prefix);
- }
- nSendBytes = sizeof(tmpBuf6); memcpy(sendBuf, tmpBuf6, nSendBytes);
- goto ret_p2;
- default:
- sw_log_warn("[%s] %s unknown a data req(type=0x%02x)!", MODULE_NAME, log_prefix, req[2]);
- goto ret_p3;
- }
- // 2, 回复该请求帧的应答包
- ret_p2:
- ret = frame_doEscapeChars(sendBuf, nSendBytes, &rsp);
- if(ret < MIN_FRAME_LEN)
- {
- sw_log_error("[%s] %s failed to escape the response(%d)!!", MODULE_NAME, log_prefix, ret);
- goto ret_p3;
- }
- nRspBytes = ret;
- xstrfromhex(rsp, nRspBytes, log_rsp, NULL, NULL);
- ret = serial_send_data(pComIO->h, rsp, nRspBytes);
- if(ret == nRspBytes) sw_log_debug("[%s] %s sent a response(%d bytes)(hex): %s", MODULE_NAME, log_prefix, nRspBytes, log_rsp);
- else sw_log_error("[%s] %s failed to send a response(%d bytes, ret=%d)(hex): %s!!", MODULE_NAME, log_prefix, nRspBytes, ret, log_rsp);
- // 3, 清空接收缓存区(重置)
- ret_p3:
- if(req) sw_heap_free(req);
- if(rsp) sw_heap_free(rsp);
- if(nRecvBytes > 0 && bPrintRecvBuf)
- {
- serial_printf_recv_buffer(pSerial, LEVEL_TRACE);
- sw_log_warn("[%s] %s discarded %d bytes of meaningless data!", MODULE_NAME, log_prefix, nRecvBytes);
- }
- if(nRecvBytes > 0) serial_clear_recv_buffer(pSerial);
- // 4, 持续累加的接收新数据
- ret_p4:
- return 1;
- }
- // 打开与MCU控制板的通讯, 返回: 0成功, <0时失败
- int MCBComInit()
- {
- s_myCom.state_rwlock = sw_rwlock_create();
- s_myCom.edata_rwlock = sw_rwlock_create();
- if(!s_myCom.state_rwlock || !s_myCom.edata_rwlock)
- {
- sw_log_error("[%s] failed to create the rwlocks!!", MODULE_NAME);
- MCBComExit(); return -1;
- }
- #ifdef _DEBUG // 上位机单元测试时使用
- const char *serialName = "/dev/ttyS0"; int baudrate = 115200;
- #else
- const char *serialName = "/dev/ttymxc2"; int baudrate = 115200;
- #endif
- const char *parityCheck = "none"; // 无校检
- s_myCom.h = serial_open(serialName, baudrate, parityCheck, \
- comio_data_recv_proc, comio_data_recv_proc, NULL);
- if(!s_myCom.h)
- {
- sw_log_error("[%s] failed to open the \"%s:%d(%s parity)\" device!!", \
- MODULE_NAME, serialName, baudrate, parityCheck);
- MCBComExit(); return -2;
- }
- return 0;
- }
- // 关闭与MCU控制板的通讯, 返回: 0成功, <0时失败
- int MCBComExit()
- {
- if(s_myCom.h) serial_close(s_myCom.h, WAITTHRD_SAFEEXIT_TIMEOUT);
- if(s_myCom.state_rwlock) sw_rwlock_destroy(s_myCom.state_rwlock);
- if(s_myCom.edata_rwlock) sw_rwlock_destroy(s_myCom.edata_rwlock);
- memset(&s_myCom, 0, sizeof(s_myCom));
- return 0;
- }
- // 配置单片机控制板-运行参数, 返回: 0成功, <0时失败
- int MCBConfParameters(uint32_t version, uint8_t ctrl_mode, uint8_t light_duration, uint8_t start_hour, uint8_t end_hour, uint16_t tp_intvl_min)
- {
- memcpy(cfg_params.version, &version, 4);
- cfg_params.ctrl_mode = ctrl_mode;
- cfg_params.light_duration = light_duration;
- cfg_params.start_hour = start_hour;
- cfg_params.end_hour = end_hour;
- memcpy(cfg_params.tp_intvl_min, &tp_intvl_min, 2);
- return 0;
- }
- // 设置工作状态位图-固件运维, 返回: 0成功, <0时失败
- int MCBSetMNTStateBit(uint8_t state/*1bit位, 0x00:空闲, 0x01:运维中*/)
- {
- if(!s_myCom.state_rwlock || (state != 0x00 && state != 0x01)) return -1;
- sw_rwlock_wrlock(s_myCom.state_rwlock, WAIT_FOREVER);
- if(state == 0x01) sw_chararry_setBit(s_myCom.work_state, 4, 1, 0x01); // 升级程序
- else sw_chararry_setBit(s_myCom.work_state, 4, 1, 0x00); // 正常工作
- sw_rwlock_unlock(s_myCom.state_rwlock);
- return 0;
- }
- // 设置工作状态位图-相机拍照, 返回: 0成功, <0时失败
- int MCBSetCamStateBit(uint8_t state/*2bit位, 0x00:空闲, 0x01:拍照中, 0x10:上传中, 0x11:保留*/)
- {
- if(!s_myCom.state_rwlock || (state != 0x00 && state != 0x01 && state != 0x10)) return -1;
- sw_rwlock_wrlock(s_myCom.state_rwlock, WAIT_FOREVER);
- switch(state)
- {
- case 0x00: // 空闲
- sw_chararry_setBit(s_myCom.work_state, 4, 2, 0x00);
- sw_chararry_setBit(s_myCom.work_state, 4, 3, 0x00);
- break;
- case 0x01: // 拍照中
- sw_chararry_setBit(s_myCom.work_state, 4, 2, 0x01);
- sw_chararry_setBit(s_myCom.work_state, 4, 3, 0x00);
- break;
- case 0x10: // 上传中
- sw_chararry_setBit(s_myCom.work_state, 4, 2, 0x00);
- sw_chararry_setBit(s_myCom.work_state, 4, 3, 0x01);
- break;
- }
- sw_rwlock_unlock(s_myCom.state_rwlock);
- return 0;
- }
- // 设置工作状态位图-环境数据, 返回: 0成功, <0时失败
- int MCBSetEnvStateBit(uint8_t state/*2bit位, 0x00:空闲, 0x01:收集中, 0x10:上传中, 0x11:保留*/)
- {
- if(!s_myCom.state_rwlock || (state != 0x00 && state != 0x01 && state != 0x10)) return -1;
- sw_rwlock_wrlock(s_myCom.state_rwlock, WAIT_FOREVER);
- switch(state)
- {
- case 0x00: // 空闲
- sw_chararry_setBit(s_myCom.work_state, 4, 4, 0x00);
- sw_chararry_setBit(s_myCom.work_state, 4, 5, 0x00);
- break;
- case 0x01: // 收集中
- sw_chararry_setBit(s_myCom.work_state, 4, 4, 0x01);
- sw_chararry_setBit(s_myCom.work_state, 4, 5, 0x00);
- break;
- case 0x10: // 上传中
- sw_chararry_setBit(s_myCom.work_state, 4, 4, 0x00);
- sw_chararry_setBit(s_myCom.work_state, 4, 5, 0x01);
- break;
- }
- sw_rwlock_unlock(s_myCom.state_rwlock);
- return 0;
- }
- // 请求获取当前实时-环境数据, 返回: 0成功, <0时失败
- int MCBReqEnvCurData()
- {
- if(!s_myCom.h) return -1;
- unsigned char req[6] = { 0x7D, 0x01, 0x05, 0xC0, 0x23, 0x7E };
- int ret = serial_send_data(s_myCom.h, req, sizeof(req));
- if(ret != sizeof(req)) return -2;
- sw_log_debug("[%s] sent a request(6 bytes)(hex): %s", MODULE_NAME, "7d0105c0237e");
- return 0;
- }
- #ifdef _DEBUG
- void *MCBGetSerialHandle()
- {
- return s_myCom.h;
- }
- #endif
|