/* 数据通信任务 */ #include "bsp.h" #include "ringbuffer.h" #include "protocol.h" #include "update_protocol.h" #include "app_comm.h" #include "app_tp_collect.h" #include "app_ad_collect.h" #define USING_SIMULATOR ( 0 ) #define COMM_RECV_OUTTIME (20) static struct { ring_buf_t rb; uint8_t rb_pool[128]; } g_comm; static struct { uint8_t rxbuf[256]; int rxbytes; } g_frame; static void rs485_rx_cb(uint8_t data) { ring_buf_put(&g_comm.rb, &data, 1); } /** 返回值:成功:len,失败: 0 ***/ static int recive_frame(void) { uint8_t data = 0; int len = ring_buf_len(&g_comm.rb); if (len == 0) return 0; for (int i = 0; i < len; i++) { if (g_frame.rxbytes < sizeof(g_frame.rxbuf)) { int byte = ring_buf_get(&g_comm.rb, &data, 1); if (byte > 0) { g_frame.rxbuf[ g_frame.rxbytes] = data; g_frame.rxbytes++; } } } return len; } static void update_on_start(uint8_t* frame, int len, uint8_t* pload, int size) { update_protocol_req_t* pReq = (void*)&frame[sizeof(update_protocol_hd_t)]; boot_para_t cfg = {0}; cfg.AppFlag = 0; cfg.UpdateFlag = APP_UPDATE_FLAG; cfg.Crc32Check = pReq->AppCrc32; cfg.PackageNum = pReq->PackageNum; cfg.AppSize = pReq->AppSize; dev_boot_write_param(cfg); update_send_cmd(0x01, 1, pReq->PackageNum); //重启进入BOOT NVIC_SystemReset(); } static int update_cmd_process(uint8_t cmd, void* frame, int len, void* pload, int size) { int res = -1; switch (cmd) { case 0x81: { update_on_start(frame, len, pload, size); res = 0; } break; default: break; } return res; } static int update_process(void* frame, int len) { uint8_t cmd = 0; uint8_t slave_addr = 0; uint8_t user_data[256] = {0}; int user_data_len = 0; int res = update_unpack(frame, len, &cmd, &slave_addr, user_data, &user_data_len); if (res != 0) return -1; if (slave_addr != 0x01) return -2; res = update_cmd_process(cmd, frame, len, user_data, user_data_len); if (res != 0) return -3; return 0; } static void comm_rsp(uint8_t slave_addr,uint8_t frame_cmd,void *pay, int len) { uint8_t frame_ack[128] = {0}; uint16_t frame_ack_len = 0; protocol_pack_frame(slave_addr, frame_cmd - 0x80, pay, len, frame_ack, sizeof(frame_ack), &frame_ack_len); dev_rs485_send(frame_ack, frame_ack_len); } static void comm_process(uint8_t* frame, int len) { uint16_t slave_addr = 0; uint8_t frame_cmd = 0; uint8_t frame_data[64] = {0}; uint16_t frame_data_len = 0; /***数据解码***/ int err = -1; err= protocol_unpack_frame(frame, len, &slave_addr, &frame_cmd, frame_data, &frame_data_len); if (err != PROTOCOL_SUCCESS) return ; //TODO:获取本机地址 uint8_t local_addr = 0; dev_cfg_get_devid(&local_addr); uint8_t rsp_data[64] = {0}; void* payload = rsp_data; uint16_t payload_len = 0; uint8_t is_match =1; switch (frame_cmd) { case PROTOCOL_CMD_SET_ID: { // if (slave_addr != local_addr) return ; id_data_t data = {0}; memcpy(&data, &frame_data, sizeof(data)); dev_cfg_set_devid(data.id); BSP_LOG("set: device id =[%d] =[0x%x] \n", data.id,data.id); } break; case PROTOCOL_CMD_GET_ID:{ id_data_t id_data = {0}; id_data.id = local_addr; payload_len = sizeof(id_data); memcpy(payload ,&id_data,payload_len); BSP_LOG("get: device id =[%d] =[0x%x] \n", id_data.id,id_data.id); }break; case PROTOCOL_CMD_GET_TP: { //TODO: get tp datas if (slave_addr != local_addr) return ; tp_datas_t tp_data = {0}; collect_tp_info_t tp_info={0}; app_collect_tp_get(&tp_info); memcpy( &tp_data,&tp_info.tp_datas,sizeof(tp_data)); //兼容旧协议,没有用到的通道,填充无效数据 for(int i=0; i <8-TP_SENSOR_NUM; i++){ tp_data.channels[i+TP_SENSOR_NUM].status =1; tp_data.channels[i+TP_SENSOR_NUM].value =0; } for (int i = 0; i < TP_SENSOR_NUM ; i++) { char strbuf[128]={0}; snprintf(strbuf,sizeof(strbuf)," comm ad ch[%d] %08.4f \r\n", i, tp_data.channels[i].value); BSP_LOG("%s",strbuf); } BSP_LOG("\r\n"); payload_len = sizeof(tp_data); memcpy(payload, &tp_data, payload_len); }break; case PROTOCOL_CMD_GET_AD: { // if (slave_addr != local_addr) return ; //TODO: get ad datas ad_datas_t ad_data = {0}; app_collect_ad_get(&ad_data); //兼容旧协议,没有用到的通道,填充无效数据 for(int i=0; i <8-YB_SENSOR_NUM; i++){ ad_data.channels[i+5].status =1; } BSP_LOG("\r\n"); for (int i = 0; i < YB_SENSOR_NUM ; i++) { char strbuf[128] = {0}; snprintf(strbuf, sizeof(strbuf), " comm ad ch[%d] %08.4f \r\n", i, ad_data.channels[i].value); BSP_LOG("%s", strbuf); } BSP_LOG("\r\n"); payload_len = sizeof(ad_data); memcpy(payload, &ad_data, payload_len); } break; case PROTOCOL_CMD_SET_TP_OFFSET:{ if (slave_addr != local_addr) return ; offset_set_data_t offset_data={0}; memcpy( &offset_data,frame_data,sizeof(offset_data)); dev_cfg_set_temp_offset(offset_data.id, offset_data.prams.value); char strbuf[128]={0}; snprintf(strbuf,sizeof(strbuf)," set[%d] offset %.2f \r\n", offset_data.id , offset_data.prams.value); BSP_LOG("%s",strbuf); }break; case PROTOCOL_CMD_GET_TP_OFFSET:{ // if (slave_addr != local_addr) return ; offset_get_param_t *param = (void *)frame_data; offset_get_data_t offset_data={0}; float val = 200; dev_cfg_get_temp_offset( param->id,&val); offset_data.id = param->id; offset_data.prams.value = val; payload_len = sizeof(offset_data); memcpy(payload,&offset_data,payload_len); char strbuf[128]={0}; snprintf(strbuf,sizeof(strbuf)," get[%d] offset %.2f \r\n", offset_data.id , offset_data.prams.value); BSP_LOG("%s",strbuf); }break; case PROTOCOL_CMD_RESET_CHANNEL: { // if (slave_addr != local_addr) return ; app_collect_ad_reset_offset(); BSP_LOG("reset offset start"); } break; default: is_match =0; break; } if(is_match ==0) return; comm_rsp(slave_addr,frame_cmd, payload, payload_len); } void app_comm_entry(void *param) { int len = 0; dev_rs485_init(); dev_rs485_rx_register(rs485_rx_cb); ring_buf_init(&g_comm.rb, g_comm.rb_pool, sizeof(g_comm.rb_pool)); /***/ update_init(dev_rs485_send); while (1) { rt_thread_mdelay(1); len = recive_frame(); if (len == 0) { rt_thread_mdelay(5); len = recive_frame(); if (len == 0) { if (g_frame.rxbytes > 0) { update_process(g_frame.rxbuf, g_frame.rxbytes); comm_process(g_frame.rxbuf, g_frame.rxbytes); g_frame.rxbytes = 0; } } } } } ALIGN(RT_ALIGN_SIZE) static uint8_t comm_thd_stack[4096]; static struct rt_thread comm_thd; int app_comm_init(void) { #if USING_SIMULATOR BSP_LOG("comm data using simulator \n"); #endif int ret = rt_thread_init(&comm_thd, "app_comm", app_comm_entry, RT_NULL, comm_thd_stack, sizeof(comm_thd_stack), 10, 20 ); if(ret == RT_EOK){ rt_thread_startup(&comm_thd); } return 0; } INIT_APP_EXPORT(app_comm_init);