JGCtoGdT
Dependencies: ConfigFile MODSERIAL_uVision Watchdog mbed-rtos mbed
main.cpp
00001 #include "mbed.h" 00002 #include "MODSERIAL.h" 00003 #include "rtos.h" 00004 #include "Watchdog.h" 00005 #include "ConfigFile.h" 00006 00007 Watchdog wd; 00008 00009 extern "C" void mbed_reset(); 00010 00011 char InitialMessage[50]; 00012 00013 DigitalOut ledCAN1(LED1); 00014 DigitalOut ledCAN2(LED2); 00015 DigitalOut led3(LED3); 00016 DigitalOut ledPC(LED4); 00017 00018 00019 time_t ctTime; 00020 struct tm * timeinfo; 00021 00022 Ticker SpkTick; 00023 Timer myT; 00024 00025 00026 void LoadPCMail(char comm, char *mess); 00027 00028 /************* Frequency ****************/ 00029 InterruptIn Freq1(p15); 00030 InterruptIn Freq2(p16); 00031 InterruptIn Freq3(p17); 00032 Timer F1; 00033 Timer F2; 00034 Timer F3; 00035 00036 int Period1,Period2,Period3; 00037 00038 void Freq1_Meas(void) 00039 { 00040 Period1=F1.read_us(); 00041 F1.reset(); 00042 } 00043 void Freq2_Meas(void) 00044 { 00045 Period2=F2.read_us(); 00046 F2.reset(); 00047 } 00048 void Freq3_Meas(void) 00049 { 00050 Period3=F3.read_us(); 00051 F3.reset(); 00052 } 00053 /************* End Frequency ************/ 00054 00055 /************* PWM ****************/ 00056 PwmOut PwmO1(LED3); 00057 /************* End PWM ************/ 00058 00059 /************* CAN ***********************/ 00060 #define CAN_MaxMailElements 16 00061 #define CANMessWait 1//ms 00062 #define MessSizeCAN 128 00063 00064 typedef struct { 00065 char command; /* command to execute */ 00066 CANMessage mess; 00067 } CAN_mail_t; 00068 /************* CAN 1 *********************/ 00069 CAN can1(p9,p10); 00070 int CAN1Freq=1000000; 00071 00072 Mail<CAN_mail_t, CAN_MaxMailElements> CAN1_mail; 00073 int CAN1MailNum; 00074 00075 void LoadCAN1Mail(char command, CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc 00076 { 00077 while(CAN1MailNum>=CAN_MaxMailElements) { 00078 Thread::wait(CANMessWait); 00079 } 00080 CAN_mail_t *mail = CAN1_mail.alloc(); 00081 mail->command = command; 00082 mail->mess=mess; 00083 CAN1_mail.put(mail); 00084 CAN1MailNum++; 00085 } 00086 00087 void messageFromCAN1() 00088 { 00089 ledCAN1=true; 00090 CANMessage msg; 00091 can1.read(msg); 00092 LoadCAN1Mail(10,msg); 00093 } 00094 00095 void CAN1_thread_proc(void const *args) //proceso paralelo de gestión CAN1 00096 { 00097 char tmp[MessSizeCAN]; 00098 while(true) { 00099 osEvent evt = CAN1_mail.get(osWaitForever); 00100 if (evt.status == osEventMail) { 00101 CAN_mail_t *mail = (CAN_mail_t*)evt.value.p; 00102 00103 switch (mail->command) { 00104 case 0: //request Reset CAN 00105 can1.reset(); 00106 LoadPCMail(1,"Reset CAN1"); 00107 break; 00108 case 1: //set frequency 00109 can1.frequency(mail->mess.id); 00110 LoadPCMail(1,"Set Frequency CAN1"); 00111 break; 00112 case 10: //Read from CAN 00113 snprintf(tmp,MessSizeCAN,"ID=%i;TYPE=%i;FORMAT=%i;LEN=%d;DATA[0]=%u;DATA[1]=%u;DATA[2]=%u;DATA[3]=%u;DATA[4]=%u;DATA[5]=%u;DATA[6]=%u;DATA[7]=%u",mail->mess.id,mail->mess.type,mail->mess.format,mail->mess.len,mail->mess.data[0],mail->mess.data[1],mail->mess.data[2],mail->mess.data[3],mail->mess.data[4],mail->mess.data[5],mail->mess.data[6],mail->mess.data[7]); 00114 LoadPCMail(2,tmp); 00115 break; 00116 case 20: //Write to CAN 00117 can1.write(mail->mess); 00118 LoadPCMail(1,"Write to CAN1"); 00119 break; 00120 default: // request to send message from code 00121 break; 00122 } 00123 CAN1_mail.free(mail); 00124 CAN1MailNum--; 00125 ledCAN1=false; 00126 } 00127 } 00128 } 00129 /************* END CAN 1 ****************/ 00130 /************* CAN 2 ********************/ 00131 CAN can2(p30,p29); 00132 int CAN2Freq=1000000; 00133 00134 Mail<CAN_mail_t, CAN_MaxMailElements> CAN2_mail; 00135 int CAN2MailNum; 00136 00137 void LoadCAN2Mail(char command, CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc 00138 { 00139 while(CAN2MailNum>=CAN_MaxMailElements) { 00140 Thread::wait(CANMessWait); 00141 } 00142 CAN_mail_t *mail = CAN2_mail.alloc(); 00143 mail->command = command; 00144 mail->mess=mess; 00145 CAN2_mail.put(mail); 00146 CAN2MailNum++; 00147 } 00148 void messageFromCAN2() 00149 { 00150 ledCAN2=true; 00151 CANMessage msg; 00152 can2.read(msg); 00153 LoadCAN2Mail(10,msg); 00154 } 00155 void CAN2_thread_proc(void const *args) //proceso paralelo de gestión CAN1 00156 { 00157 char tmp[MessSizeCAN]; 00158 while(true) { 00159 osEvent evt = CAN2_mail.get(osWaitForever); 00160 if (evt.status == osEventMail) { 00161 CAN_mail_t *mail = (CAN_mail_t*)evt.value.p; 00162 00163 switch (mail->command) { 00164 case 0: //request Reset CAN 00165 can2.reset(); 00166 LoadPCMail(1,"Reset CAN2"); 00167 break; 00168 case 1: //set frequency 00169 can2.frequency(mail->mess.id); 00170 LoadPCMail(1,"Set Frequency CAN2"); 00171 break; 00172 case 10: //Read from CAN 00173 snprintf(tmp,MessSizeCAN,"ID=%i;TYPE=%i;FORMAT=%i;LEN=%d;DATA[0]=%u;DATA[1]=%u;DATA[2]=%u;DATA[3]=%u;DATA[4]=%u;DATA[5]=%u;DATA[6]=%u;DATA[7]=%u",mail->mess.id,mail->mess.type,mail->mess.format,mail->mess.len,mail->mess.data[0],mail->mess.data[1],mail->mess.data[2],mail->mess.data[3],mail->mess.data[4],mail->mess.data[5],mail->mess.data[6],mail->mess.data[7]); 00174 LoadPCMail(3,tmp); 00175 break; 00176 case 20: //Write to CAN 00177 can2.write(mail->mess); 00178 LoadPCMail(1,"Write to CAN2"); 00179 break; 00180 default: // request to send message from code 00181 break; 00182 } 00183 CAN2_mail.free(mail); 00184 CAN2MailNum--; 00185 ledCAN2=false; 00186 } 00187 } 00188 } 00189 /************* END CAN 2 ****************/ 00190 /************* END CAN ******************/ 00191 00192 /************* RS232 PC ******************/ 00193 #define TxBuffer_NumMess 16 00194 #define RxBuffer_NumMess 16 00195 #define MessSizePC 128 00196 #define TxBuffer TxBuffer_NumMess*MessSizePC 00197 #define RxBuffer RxBuffer_NumMess*MessSizePC 00198 #define PC_MaxMailElements 16 00199 #define PCMessWait MessSizePC*10/9.6 //ms 00200 00201 MODSERIAL pc(USBTX, USBRX,TxBuffer,RxBuffer); 00202 bool LOGPC; 00203 int BaudRate; 00204 double TxBufferWait; 00205 char ChEnd; 00206 00207 typedef struct { 00208 char command; /* command to execute */ 00209 char message[MessSizePC]; /* arguments */ 00210 } PC_mail_t; 00211 00212 Mail<PC_mail_t, PC_MaxMailElements> PC_mail; 00213 int PCMailNum; 00214 00215 void TLogSTR(char *Tstr) 00216 { 00217 ctTime = time(NULL); 00218 timeinfo = localtime ( &ctTime ); 00219 timeinfo->tm_hour=(timeinfo->tm_hour+1)%24; 00220 strftime (Tstr,MessSizePC,"%H:%M:%S",timeinfo); 00221 } 00222 00223 void LoadPCMail(char comm, char *mess) //para cargar mensajes de trabajo al proceso paralelo ComPC_thread_proc 00224 { 00225 while(PCMailNum>=PC_MaxMailElements) { 00226 Thread::wait(PCMessWait); 00227 } 00228 if(comm!=1 || LOGPC) { 00229 PC_mail_t *mail = PC_mail.alloc(); 00230 mail->command = comm; 00231 snprintf(mail->message,MessSizePC,"%s",mess); 00232 PC_mail.put(mail); 00233 PCMailNum++; 00234 } 00235 } 00236 00237 void messageFromPC(MODSERIAL_IRQ_INFO *q) //trabajo solicitado desde PC 00238 { 00239 ledPC=true; 00240 MODSERIAL *sys = q->serial; 00241 char temp[MessSizePC]; 00242 00243 int i=sys->move(temp,MessSizePC,ChEnd); 00244 if (temp[i-2]=='\r') { 00245 i-=2; 00246 } else { 00247 i-=1; 00248 } 00249 temp[i]=0; 00250 LoadPCMail(0,temp); 00251 } 00252 00253 int ComPC_Write(char *mess) //sólo para usarse en ComPC_thread_proc 00254 { 00255 int i=strlen(mess); 00256 if(i>0) { 00257 while((TxBuffer-pc.txBufferGetCount())<i) { 00258 Thread::wait(TxBufferWait); 00259 } 00260 return pc.printf(mess); 00261 } 00262 return 0; 00263 } 00264 00265 void ComPC_thread_proc(void const *args) //proceso paralelo de gestión PC: tareas solicitadas y envío a PC 00266 { 00267 00268 while(true) { 00269 osEvent evt = PC_mail.get(osWaitForever); 00270 if (evt.status == osEventMail) { 00271 PC_mail_t *mail = (PC_mail_t*)evt.value.p; 00272 00273 char mess[MessSizePC]; 00274 char Tstr[20]; 00275 TLogSTR(Tstr); 00276 switch (mail->command) { 00277 case 0: //request from PC 00278 CANMessage CanMess; 00279 switch (mail->message[0]) { 00280 case 'T': 00281 float seconds; 00282 sscanf(&mail->message[1],"%f",&seconds); 00283 set_time((double)seconds); 00284 time_t ctTime; 00285 ctTime = time(NULL); 00286 snprintf(mess,MessSizePC,"%s",ctime(&ctTime)); 00287 LoadPCMail(1,mess); 00288 break; 00289 case 'C': //CAN 00290 switch (mail->message[1]) { 00291 case '1': //CAN1, Send from PC a Message to CAN1 00292 switch (mail->message[2]) { 00293 case 'R': //reset CAN 00294 LoadCAN1Mail(0,CanMess); 00295 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00296 break; 00297 case 'F': //set Frequency CAN 00298 sscanf(&mail->message[3],"%i",&CanMess.id); 00299 LoadCAN1Mail(1,CanMess); 00300 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00301 break; 00302 case 'W': //Write CAN 00303 sscanf(&mail->message[3],"%i;%i;%i;%u;%u;%u;%u;%u;%u;%u;%u;%u",&CanMess.id,&CanMess.type,&CanMess.format,&CanMess.len,&CanMess.data[0],&CanMess.data[1],&CanMess.data[2],&CanMess.data[3],&CanMess.data[4],&CanMess.data[5],&CanMess.data[6],&CanMess.data[7]); 00304 LoadCAN1Mail(20,CanMess); 00305 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00306 break; 00307 default: 00308 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00309 break; 00310 } 00311 break; 00312 case '2': //CAN2, Send from PC a Message to CAN2 00313 switch (mail->message[2]) { 00314 case 'R': //reset CAN 00315 LoadCAN2Mail(0,CanMess); 00316 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00317 break; 00318 case 'F': //set Frequency CAN 00319 sscanf(&mail->message[3],"%i",&CanMess.id); 00320 LoadCAN2Mail(1,CanMess); 00321 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00322 break; 00323 case 'W': //Write CAN 00324 sscanf(&mail->message[3],"%i;%i;%i;%u;%u;%u;%u;%u;%u;%u;%u;%u",&CanMess.id,&CanMess.type,&CanMess.format,&CanMess.len,&CanMess.data[0],&CanMess.data[1],&CanMess.data[2],&CanMess.data[3],&CanMess.data[4],&CanMess.data[5],&CanMess.data[6],&CanMess.data[7]); 00325 LoadCAN2Mail(20,CanMess); 00326 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00327 break; 00328 default: 00329 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00330 break; 00331 } 00332 break; 00333 default: 00334 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00335 break; 00336 } 00337 break; 00338 case 'F': //Frequencies 00339 switch (mail->message[1]) { 00340 case '1': //Freq1, Get Freq11 00341 snprintf(mess,MessSizePC,"F1= %i usec\r\n",Period1); 00342 break; 00343 case '2': //Freq2, Get Freq2 00344 snprintf(mess,MessSizePC,"F2= %i usec\r\n",Period2); 00345 break; 00346 case '3': //Freq3, Get Freq3 00347 snprintf(mess,MessSizePC,"F3= %i usec\r\n",Period3); 00348 break; 00349 default: 00350 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00351 break; 00352 } 00353 break; 00354 case 'P': 00355 float duty=0; 00356 int periodus=0; 00357 switch (mail->message[1]) { 00358 case '1': 00359 sscanf(&mail->message[2],"%f;%i",&duty,&periodus); 00360 PwmO1.write(duty); 00361 PwmO1.period_us(periodus); 00362 snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message); 00363 break; 00364 default: 00365 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00366 break; 00367 } 00368 break; 00369 case 'R': 00370 if(strcmp(mail->message,"REBOOT")==0) { 00371 mbed_reset();//wd.Configure(2.0); 00372 } else { 00373 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00374 } 00375 break; 00376 case 'r': 00377 if(strcmp(mail->message,"reboot")==0) { 00378 mbed_reset();//wd.Configure(2.0); 00379 } else { 00380 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00381 } 00382 break; 00383 default: 00384 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message); 00385 break; 00386 } 00387 break; 00388 case 1: //Send LOG to PC 00389 if(LOGPC) { 00390 snprintf(mess,MessSizePC,"LOG(%s):%s\r\n",Tstr ,mail->message); 00391 } else { 00392 mess[0]=0; 00393 } 00394 break; 00395 case 2: //Send to PC a Message from CAN1 00396 snprintf(mess,MessSizePC,"CAN1:%s\r\n",mail->message); 00397 break; 00398 case 3: //Send to PC a Message from CAN2 00399 snprintf(mess,MessSizePC,"CAN2:%s\r\n",mail->message); 00400 break; 00401 default: 00402 break; 00403 } 00404 PC_mail.free(mail); 00405 PCMailNum--; 00406 ledPC=false; 00407 ComPC_Write(mess); 00408 } 00409 } 00410 } 00411 /************* END RS232 PC **************/ 00412 00413 void GetConfig() 00414 { 00415 00416 #define CfgNumParam 6 00417 #define CfgSizeParam 50 00418 00419 pc.format(8,Serial::Even,1); 00420 pc.baud(115200); 00421 ConfigFile cfg; 00422 LocalFileSystem local("local"); 00423 00424 int i; 00425 char value[CfgNumParam][CfgSizeParam]; 00426 char CfgK[CfgNumParam][CfgSizeParam]= {"InitialMessage","BaudRate","ChEnd","LOGPC","CAN1Freq","CAN2Freq"}; 00427 00428 pc.printf("\r\n* * *\r\n* * *\r\n"); 00429 00430 if (!cfg.read("/local/config.cfg")) { 00431 error("\r\nFailure to read a configuration file"); 00432 } 00433 char Tstr[10]; 00434 for (i=0; i<CfgNumParam; i++) { 00435 if (cfg.getValue(CfgK[i], &value[i][0], sizeof(value[i]))) { 00436 TLogSTR(Tstr); 00437 pc.printf("CFG_Param(%s): '%s'='%s'\r\n", Tstr,CfgK[i], value[i]); 00438 } else { 00439 error("Failure Reading '%s'\r\n", CfgK[i]); 00440 } 00441 } 00442 strcpy(InitialMessage,value[0]); 00443 BaudRate=atoi(value[1]); 00444 ChEnd=(char)atoi(value[2]); 00445 LOGPC=(bool)atoi(value[3]); 00446 CAN1Freq=atoi(value[4]); 00447 CAN2Freq=atoi(value[5]); 00448 00449 TxBufferWait= 10000*MessSizePC/BaudRate; 00450 00451 pc.printf("* * *\r\n* * *\r\n"); 00452 00453 while(!pc.txBufferEmpty()) { 00454 Thread::wait(100); 00455 }; 00456 } 00457 00458 int main() 00459 { 00460 00461 //char tempMessPC[MessSizePC]; 00462 PCMailNum=0; 00463 GetConfig(); 00464 00465 // ************ PC ^^^^^^^^^^^^^ 00466 pc.baud(BaudRate); 00467 Thread ComPC_thread (ComPC_thread_proc,NULL,osPriorityBelowNormal); 00468 pc.attach(&messageFromPC, MODSERIAL::RxAutoDetect); 00469 pc.autoDetectChar(ChEnd); 00470 00471 // ************ PC_end ^^^^^^^^^^^^^ 00472 00473 LoadPCMail(1,""); 00474 LoadPCMail(1,""); 00475 LoadPCMail(1,""); 00476 LoadPCMail(1,"*****************************"); 00477 LoadPCMail(1,InitialMessage); 00478 LoadPCMail(1,"*****************************"); 00479 LoadPCMail(1,""); 00480 LoadPCMail(1,""); 00481 LoadPCMail(1,""); 00482 00483 // ************ CAN1 ^^^^^^^^^^^ 00484 Thread CAN1_thread (CAN1_thread_proc,NULL,osPriorityNormal); 00485 can1.frequency(CAN1Freq); 00486 can1.attach(&messageFromCAN1); 00487 // ************ CAN1_end ^^^^^^^ 00488 00489 // ************ CAN2 ^^^^^^^^^^^ 00490 Thread CAN2_thread (CAN2_thread_proc,NULL,osPriorityNormal); 00491 can2.frequency(CAN2Freq); 00492 can2.attach(&messageFromCAN2); 00493 // ************ CAN2_end ^^^^^^^ 00494 00495 // ************ WD ************* 00496 wd.WatchdogCausedReset(); 00497 wd.Configure(5.0); 00498 // ************ WD_end ********* 00499 00500 // ************ Interrupts Freqs 00501 F1.start(); 00502 F2.start(); 00503 F3.start(); 00504 Period1=0; 00505 Period2=0; 00506 Period3=0; 00507 00508 Freq1.rise(Freq1_Meas); 00509 Freq2.rise(Freq2_Meas); 00510 Freq3.rise(Freq3_Meas); 00511 00512 // ************ End Interrupts Freqs 00513 00514 while(true) { 00515 //Thread::wait(osWaitForever); 00516 wd.Service(); 00517 Thread::wait(1000); 00518 } 00519 }
Generated on Wed Jul 13 2022 18:10:03 by 1.7.2