/* * ctrl_process.c * * Created on: May 4, 2015 * Author: root */ #include "common.h" #include #include "thread.h" #include #include "msq.h" #include "serial.h" #include "ysp_debug.h" #include #define MAX_SEND_TIME_CURVE 5 #define MAX_SAVE_TEMP 256 mqd_t ctrl_tx_mq;// extern int ctrl_fd;//控制信号发送串口句柄 COM_HEADER ctrl_tx_header; COM_HEADER ctrl_rx_header; OUTPUT_TYPE_DEF ctrl_tx_data; unsigned char ctrl_tx_buf[128];//串口发送缓冲区 unsigned char ctrl_rx_buf[128];// unsigned char ctrl_tx_mq_buf[CTRL_TX_MESSAGE_SIZE];//消息队列接收缓冲区 static const unsigned int timeout_curve[MAX_SEND_TIME_CURVE]={ 200000,300000,500000,1000000,2000000 };//发送间隔 float latest_spz_temp[MAX_SAVE_TEMP]; unsigned char spz_save_index=0; /* static const char *relay_name[]={ "LJ_FAN", "SAMPLE_FAN", "YV6", "YV4", "no_use", "no_use", "YV7", "YV14", "YV13", "YV10", "YV11", "YV12", "no", "no", "no", "YV16", "YV17", "YV18", "YV19", "YV20", "YV21", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", };*/ void arm_var_f32(float *pSrc,unsigned int blockSize,float *pResult) { float sum = (float) 0.0; float meanOfSquares, mean, in, squareOfMean; unsigned int blkCnt; float *pIn; pIn = pSrc; blkCnt = blockSize>>2u; while(blkCnt>0u) { in = *pSrc++; sum += in * in; in = *pSrc++; sum += in * in; in = *pSrc++; sum += in * in; in = *pSrc++; sum += in * in; blkCnt--; } blkCnt = blockSize % 0x4u; while(blkCnt>0u) { in = *pSrc++; sum += in * in; blkCnt--; } meanOfSquares = sum/((float) blockSize-1.0f); sum = 0.0f; blkCnt = blockSize>>2u; pSrc = pIn; while(blkCnt>0u) { sum += *pSrc++; sum += *pSrc++; sum += *pSrc++; sum += *pSrc++; blkCnt--; } blkCnt = blockSize%0x4u; while(blkCnt>0u) { sum += *pSrc++; blkCnt--; } mean = sum/(float)blockSize; squareOfMean = (mean * mean) *(((float)blockSize)/((float)blockSize-1.0f)); *pResult = meanOfSquares - squareOfMean; } void save_spz_temp(float *temp) { latest_spz_temp[spz_save_index++]=*temp; } int get_spz_stable(float *delt) { lock_input_data(); arm_var_f32(latest_spz_temp,sizeof(latest_spz_temp)/sizeof(float),delt); unlock_input_data(); /*if(*delt>8); ctrl_tx_buf[4]=0x01;//cmd memcpy(&ctrl_tx_buf[5],head,sizeof(COM_HEADER));//拷贝信息头 memcpy(&ctrl_tx_buf[5+sizeof(COM_HEADER)],data,data_length);//拷贝数据 ctrl_tx_buf[5+data_bytes]=cal_sum(ctrl_tx_buf,5+data_bytes); ctrl_tx_buf[6+data_bytes]=0x55; set_gpio_output(0,1); ret=SerialWrite(dev_fd,ctrl_tx_buf,7+data_bytes); //usleep(10000); set_gpio_output(0,0); return ret; } //控制数据重发 int ctrl_data_retrans(void) { static mqd_t ctrl_tx_slave_mq=(mqd_t)-1; unsigned char dumy_msg[16]; if(ctrl_tx_slave_mq==-1) { if((ctrl_tx_slave_mq= open_mq(CTRL_TX_MQ))==((mqd_t)-1)) return -1; } if(mq_send(ctrl_tx_slave_mq,(const char *)dumy_msg,sizeof(dumy_msg),CTRL_MQ_PRIO)==-1) return -2; return 0; } void show_hex(unsigned char *buf,unsigned int len) { unsigned int i; for(i=0;i=5) return -1; if((my_input_data.work_state&(1<=5) return -1; //if((my_input_data.work_state&(1<31) return; lock_output_data(); tmp=my_output_data.relay_ctrl; if(val!=OFF)//=ON { tmp|=pos; } else//=OFF { tmp&=(~pos); } if(tmp!=my_output_data.relay_ctrl) { my_output_data.relay_ctrl=tmp; retrans_flg=1; } unlock_output_data(); if(retrans_flg) { //printf("relay=%x %x %x %x\n",my_output_data.relay_ctrl[0],my_output_data.relay_ctrl[1],my_output_data.relay_ctrl[2],my_output_data.relay_ctrl[3]); if(mode) ctrl_data_retrans(); } //show_hex(my_output_data.relay_ctrl,8); } void relay_set_all(unsigned int val,unsigned int mode) { unsigned int tmp; int retrans_flg=0; lock_output_data(); tmp=my_output_data.relay_ctrl; if(tmp!=val) { my_output_data.relay_ctrl=val; retrans_flg=1; } unlock_output_data(); if(retrans_flg) { if(mode) ctrl_data_retrans(); } } unsigned int relay_get(unsigned int i,unsigned char *val) { unsigned int pos=(1<0) { //清空消息队列? ++ctrl_tx_header.stNum; if(ctrl_tx_header.stNum==0) ++ctrl_tx_header.stNum; //skip over 0 ctrl_tx_header.sqNum = 0; //reset sqNum to 0 on each state change send_index=0; //show_time("tx"); //printf("state change:stNum=%d sqNum=%d\r\n",ctrl_tx_header.stNum,ctrl_tx_header.sqNum); //LOG_DEBUG(COMUNICATION_TRACE_DEBUG,"state change:stNum=%d sqNum=%d\n",ctrl_tx_header.stNum,ctrl_tx_header.sqNum); usleep(10000); } else { if(send_index<(MAX_SEND_TIME_CURVE-1)) { send_index++; } ++ctrl_tx_header.sqNum; //printf("stNum=%d sqNum=%d\n",ctrl_tx_head.stNum,ctrl_tx_head.sqNum); } //发送数据 lock_output_data(); memcpy(&my_output_data.pid_para[0],&my_para_data.mach_run_para.pid_type_def[PID_SPZ],sizeof(PID_TYPE_DEF)); memcpy(&my_output_data.pid_para[1],&my_para_data.mach_run_para.pid_type_def[PID_LJ],sizeof(PID_TYPE_DEF)); memcpy(&my_output_data.pid_para[2],&my_para_data.mach_run_para.pid_type_def[PID_SAMPLE],sizeof(PID_TYPE_DEF)); my_output_data.temperature[TEMP_SPZ]=my_para_data.mach_run_para.temperature[TEMP_SPZ]; my_output_data.temperature[TEMP_LJ]=my_para_data.mach_run_para.temperature[TEMP_LJ]; my_output_data.temperature[TEMP_SAM]=my_para_data.mach_run_para.temperature[TEMP_SAM]; //memcpy(my_output_data.pid_en,my_para_data.mach_run_para.pid_en,sizeof(my_output_data.pid_en)); my_output_data.man_output[0]=(unsigned short)my_para_data.mach_run_para.volt_output[0]; my_output_data.man_output[2]=0; my_output_data.man_output[3]=0; unlock_output_data(); if(send_ctrl_frame(ctrl_fd,&ctrl_tx_header,&my_output_data,sizeof(my_output_data))<(sizeof(my_output_data)+7)) { LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"send data failed\n"); } } } int process_message(unsigned char *msg_buf,unsigned int msg_length) { static unsigned int spz_index=0; //unsigned int i=0; unsigned int length; COM_HEADER received_header; if(msg_length<(7+sizeof(COM_HEADER))) return -1; if(msg_buf[0]!=0xAA) return -2; if(msg_buf[msg_length-1]!=0x55) return -3; length=(unsigned int)256*msg_buf[3]+msg_buf[2]; if(length!=(msg_length-7)) return -4; if(chk_sum(msg_buf,msg_length-2,msg_buf[msg_length-2])!=0) return -5; memcpy(&received_header,msg_buf+5,sizeof(COM_HEADER)); if(received_header.stNum!=ctrl_rx_header.stNum) { //数据有变化 //printf("state change stNum=%d sqNum=%d\n",received_header.stNum,received_header.sqNum); } else if(received_header.sqNum!=(ctrl_rx_header.sqNum+1)) { //丢帧了 printf("lost frame old_sq=%d new_sq=%d\n",ctrl_rx_header.sqNum,received_header.sqNum); } memcpy(&ctrl_rx_header,&received_header,sizeof(COM_HEADER)); //获取信号量 lock_input_data(); //拷贝数据到全局缓冲 memcpy(&my_input_data,&msg_buf[5+sizeof(COM_HEADER)],sizeof(my_input_data)); //保存最近的色谱柱温度,用于分析温度是否稳定 spz_index++; if((spz_index&3)==0) { save_spz_temp(&my_input_data.temperature[TEMP_SPZ]); } //printf("temp=%f %f %f %f pres=%f %f\n",my_input_data.temperature[0],my_input_data.temperature[1],my_input_data.temperature[2],my_input_data.temperature[3],my_input_data.PresVolt[6],my_input_data.Current[0]); //释放信号量 unlock_input_data(); //printf("io_input=0x%2x 0x%2x\n",my_input_data.io_input[0],my_input_data.io_input[1]); return 0; } //接收控制MCU发送的信息,并存入共享内存 void ctrl_rx_routine(void *arg) { int curr_length,last_length,rx_length; int recv_error_tick=0; pthread_t ctrl_tx_thread; rx_length=0; //本次接收的字节长度 last_length=0;//上一次接收的字节长度 //打开全局设备 if((ctrl_fd=SerialOpen(CTRL_SERIAL_DEV,CTRL_SERIAL_SPEED))==-1) { LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"open ctrl serial device failed\n"); pthread_exit(1); } if((ctrl_tx_thread=task_create(ctrl_tx_routine,NULL,0,0))==-1) { LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"create ctrl_tx_routine failed\n"); close(ctrl_fd); pthread_exit(2); } my_input_data.com_flg=1; while(1) { usleep(30000);//wait 30ms curr_length=read(ctrl_fd,ctrl_rx_buf+rx_length,sizeof(ctrl_rx_buf)-rx_length); if(curr_length>0) { //存入缓冲区 rx_length+=curr_length; last_length=curr_length; if(rx_length>=sizeof(ctrl_rx_buf)) { //printf("code1=%d rx_length=%d\n",process_message(ctrl_rx_buf,rx_length),rx_length);//处理消息 if(process_message(ctrl_rx_buf,rx_length)==0) { if(recv_error_tick>200) { LOG_DEBUG(ERROR_DEBUG,"ctrl mcu recovery\n"); } recv_error_tick=0; if(comunication_flg==0) { ysp_glb_data.MoDevConf.v.stVal=0; ysp_glb_data.MoDevConf.q=0; ysp_glb_data.MoDevConf.t.secs=(unsigned int)time(NULL); } comunication_flg=1; } rx_length=0; memset(ctrl_rx_buf,0,sizeof(ctrl_rx_buf)); } } else { if(last_length>0) { //printf("code2=%d rx_length=%d\n",process_message(ctrl_rx_buf,rx_length),rx_length);//处理消息 if(process_message(ctrl_rx_buf,rx_length)==0) { if(recv_error_tick>200) { LOG_DEBUG(ERROR_DEBUG,"ctrl mcu recovery\n"); } recv_error_tick=0; if(comunication_flg==0) { ysp_glb_data.MoDevConf.v.stVal=0; ysp_glb_data.MoDevConf.q=0; ysp_glb_data.MoDevConf.t.secs=time(NULL); } comunication_flg=1; } memset(ctrl_rx_buf,0,sizeof(ctrl_rx_buf)); } else { //出错处理 recv_error_tick++; if(recv_error_tick>256) { comunication_flg=0; if(recv_error_tick==257) { ysp_glb_data.MoDevConf.v.stVal=1; ysp_glb_data.MoDevConf.q=0; ysp_glb_data.MoDevConf.t.secs=(unsigned int)time(NULL); LOG_DEBUG(ERROR_DEBUG,"ctrl mcu lost\n"); } } } last_length=0; rx_length=0; } } //wait ctrl_tx_thread exit close(ctrl_fd); } int ctrl_init(void) { pthread_t ctrl_rx_thread; if((ctrl_rx_thread=task_create(ctrl_rx_routine,NULL,0,0))==-1) { LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"create ctrl_tx_routine failed\n"); return 1; } return 0; }