Speichern von Dateien auf einem Stick
Dependencies: KL46Z-USBHost MODSERIAL-RTOS mbed-rtos mbed
main.cpp
00001 //------------------------------------------------------------------------ 00002 // 00003 // kl25z_USB_4 00004 // Programm zum Speichern von Dateien auf einem memery Stick 00005 // 00006 // Erstellt am 10.05.14 R. Schäfer 00007 // 00008 #include "mbed.h" 00009 #include "rtos.h" 00010 #include "USBHostMSD.h" 00011 #include "MODSERIAL.h" 00012 00013 #define LED_OFF 1 00014 #define LED_ON 0 00015 #define COM_LINE_LEN 128 // maximale Länge der Eingabezeile 00016 00017 struct com_struct { 00018 uint8_t flag; // Flag zur Steuerung 00019 uint8_t sm; // State maschine 00020 uint8_t index; // Index für Zeichenzähler 00021 char line[COM_LINE_LEN]; 00022 }; 00023 00024 struct msd_struct { 00025 bool connect; // wird bei Verbindung true 00026 uint8_t flag; // Flag zur Steuerung 00027 uint8_t sm; // State maschine 00028 uint8_t index; // Index für Zeichenzähler 00029 char line[COM_LINE_LEN]; 00030 }; 00031 00032 extern "C" void NVIC_SystemReset(); 00033 00034 Thread *(msdTaskp); 00035 00036 Serial pc(USBTX,USBRX); 00037 00038 // Make TX buffer 1024bytes and RX buffer use 512bytes. 00039 // MODSERIAL uart1(PTA2, PTA1, 256, 1024); // tx, rx 00040 MODSERIAL uart1(PTC4, PTC3, 128, 1024); // tx, rx 00041 00042 DigitalOut led1(PTB18); 00043 DigitalOut led2(PTB19); 00044 int err_counter = 0; 00045 00046 // ---- globle Veariablen ---------------------------------------------- 00047 00048 // Bitposition und Belegung 00049 // bit 1 CR Flag 00050 // bit 2 byte speichern 00051 // bit 4 00052 // bit 8 00053 00054 struct com_struct com; // Eingangszeile 00055 00056 // Bitposition und Belegung 00057 // bit 1 Daten speichern in aktion 00058 // bit 2 Datei anlegen 00059 // bit 4 Daten schreiben 00060 // bit 8 Datei schließen 00061 00062 struct msd_struct m_msd; // Speicher für Stick 00063 00064 // mit dieser Task werden die Datem in Hintergrund im Stick abgespeichert 00065 // es wird auch geprüft ob für das Speichern ein Stick vorhanden ist 00066 // falls kein Stick erkannt wird, löst das Programm einen Reset aus, womit 00067 // die USB Schnittstelle neu initialiesiert wird. Damit kann auch ein Stick 00068 // im Betieb abgesteckt und wieder angestecht werden. 00069 // 00070 // Änderungen 00071 // Thread Zeit reduzieren 00072 // Dateinamen über globale Variable ersetzen 00073 00074 void msd_task(void const *) 00075 { 00076 int i = 0; 00077 int n; 00078 FILE * fp = 0; 00079 00080 USBHostMSD msd("usb"); 00081 err_counter = 0; 00082 00083 // in a loop, append a file 00084 // if the device is disconnected, we try to connect it again 00085 while(msd.connect()) 00086 { 00087 m_msd.connect = true; 00088 Thread::signal_wait(0x1); 00089 00090 // uart1.printf("\nmsd> "); 00091 // 00092 // for (i = 0; i < com.index; i++) 00093 // { 00094 // uart1.printf(" %02x",m_msd.line[i]); 00095 // } 00096 00097 // uart1.printf("\n"); 00098 00099 switch (m_msd.line[0]) 00100 { 00101 case 02: // Datei anlegen 00102 00103 char buffer[40]; 00104 sprintf(buffer, "/usb/%s", &m_msd.line[1]); 00105 fp = fopen(buffer, "w"); 00106 00107 // uart1.printf("\nMSD Datei %s anlegen",buffer); 00108 00109 break; 00110 00111 case 03: // Daten schreiben 00112 00113 if (fp) 00114 { 00115 n = fprintf(fp,"%s",&m_msd.line[1]); 00116 // uart1.printf("\nwrite file [%d] %s",n,&m_msd.line[1]); 00117 } // if (fp .. 00118 00119 break; 00120 00121 case 04: // Datei schließen 00122 00123 if (fp) n = fclose(fp); 00124 // uart1.printf("\n close file"); 00125 break; 00126 00127 } // end switch(msd-line[0] 00128 00129 // Speicher für die Zeile löschen 00130 for (i=0; i < COM_LINE_LEN; i++) m_msd.line[i] = 0; 00131 m_msd.flag &= ~0x01; 00132 00133 // if device disconnected, try to connect again 00134 if (!msd.connected()) 00135 { 00136 // uart1.printf("\n disconnected break"); 00137 m_msd.connect = false; 00138 break; 00139 } 00140 00141 } // end while (msd_connected) 00142 00143 // Task wird beendet 00144 } 00145 00146 // In dieser therad werden Daten aus der Seriellen Schnittstelle gelesen. Nach dem lesen 00147 // von einem Telegramm wird dieses falls es für das Speicher verwendet wird in m_msd abgelegt. 00148 // Die anderen Telergamme und die Antworten werde in dieser thread gleich bearbeitet. 00149 00150 void com_thread(void const *args) 00151 { 00152 char ch; 00153 int i; 00154 00155 while (true) 00156 { 00157 if ((uart1.readable()) && ((com.flag & 0x80) == 0)) 00158 { 00159 //---------------------------------------------------------------------------------------------------- 00160 // Eingehende Zeichen lesen und abspeichern 00161 00162 ch = uart1.getc(); // Zeichen lesen und auswerten 00163 // uart1.printf("\ntel> "); 00164 00165 com.line[com.index] = ch; // Zeichen einfuegen 00166 com.index++; // Zeichenzähler erhöhen 00167 if (com.index >= 125) com.sm = 2; // ein Telegramm enthält maximal 1125 Zeichen 00168 00169 // for (i = 0; i < com.index; i++) 00170 // { 00171 // uart1.printf(" %02x",com.line[i]); 00172 // } 00173 00174 // uart1.printf("\n"); 00175 00176 //---------------------------------------------------------------------------------------------------- 00177 // Abschlußbit auswerten und Telegramm umsetzen 00178 00179 switch (com.sm) // com.sm ist state machine 00180 { 00181 case 0 : // erstes Zeichen aus einem Telegramm 00182 00183 switch(ch) 00184 { 00185 case 0x00: // Endzeichen an erter Stelle zum testen 00186 // uart1.puts("Telegramm 0x00\n"); // direkt ausführen 00187 com.sm = 12; // neues Telegramm 00188 break; 00189 00190 case 0x01: // Reset 00191 // uart1.puts("Telegramm 0x01\n"); // direkt ausführen 00192 com.sm = 12; // nur ein Zeichen 00193 break; 00194 00195 case 0x02: // Datei anlegen und öffnen 00196 com.sm = 1; // Kommando Byte abspeichern 00197 break; // Dateinamen bis 0x00 lesen 00198 00199 case 0x03: // Daten schreiben 00200 com.sm = 1; // Kommando Byte abspeichern 00201 break; // Dateinamen bis 0x00 lesen 00202 00203 case 0x04: // Datei schließen 00204 // uart1.puts("Telegramm 0x04\n"); // direkt ausführen 00205 com.sm = 10; // Kommando besteht nur aus einem Zeichen 00206 break; 00207 00208 case 0x05: // SD Stick erkannt, direkt ausführen 00209 if (m_msd.connect) 00210 uart1.puts("\nStick erkannt"); 00211 else 00212 uart1.puts("\nStick nicht erkannt"); 00213 00214 com.sm = 12; // Kommando besteht nur aus einem Zeichen 00215 break; 00216 00217 default: // Zeichen zum abspeichern 00218 // uart1.puts("\nsm 0 unbekannter Befehl"); 00219 com.sm = 12; // Speicher löschen 00220 break; 00221 00222 } // ende SWITCH 00223 00224 break; // end case 0: 00225 00226 case 1: // Lesen von weitern Zeichen nach dem ersten Zeichen 00227 00228 //---------------------------------------------------------------------------------------------------- 00229 // bis Abschlussbit alle Zeichen lesen und bei Abschlußzeichen die Auswertung angehen 00230 00231 if (ch == 0x00) 00232 { 00233 com.sm = 10; 00234 } // end if (ch == 0x00) 00235 00236 break; // end case 1: 00237 00238 case 2: // Zeichenkette ist länger als 125 Zeichen 00239 00240 // uart1.puts("\nsm 2 String ist groesser 125 Zeichen"); 00241 com.sm = 11; 00242 00243 break; // end case 2 00244 00245 } // end switch 00246 00247 //---------------------------------------------------------------------------------------------------- 00248 // Telegramme die an die Task msd weitergeleitet werden 00249 00250 if (com.sm == 10) 00251 { 00252 if ((m_msd.flag & 0x01) == 0) 00253 { 00254 // uart1.puts("\nsm 10 Speicher kopieren"); 00255 00256 for (i = 0; i < COM_LINE_LEN; i++) 00257 { 00258 m_msd.line[i] = com.line[i]; 00259 if (com.line[i] == 0x00) break; 00260 } 00261 00262 m_msd.flag = 0x01; 00263 com.sm = 12; 00264 00265 msdTaskp->signal_set(0x1); 00266 } 00267 else 00268 { 00269 com.flag |= 0x80; // kann erst später gespeichert werden 00270 } 00271 00272 } 00273 00274 //---------------------------------------------------------------------------------------------------- 00275 // bei mehr asl 125 Zeichen werden die Daten an die msd Task übergeben 00276 00277 if (com.sm == 11) 00278 { 00279 //---------------------------------------------------------------------------------------------------- 00280 // Daten abspeichern 00281 00282 if ((m_msd.flag & 0x01) == 0) 00283 { 00284 for (i = 0; i < COM_LINE_LEN; i++) 00285 { 00286 m_msd.line[i] = com.line[i]; 00287 if (com.line[i] == 0x00) break; 00288 } 00289 00290 m_msd.flag = 0x01; 00291 m_msd.sm = 0x03; 00292 00293 msdTaskp->signal_set(0x1); 00294 00295 for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00; 00296 00297 com.index = 1; 00298 com.sm = 1; 00299 00300 } 00301 else 00302 { 00303 com.flag |= 0x80; // kann erst später gespeichert werden 00304 } 00305 00306 } // end if com.sm == 11 00307 00308 //---------------------------------------------------------------------------------------------------- 00309 // Zeile wieder löschen 00310 00311 if (com.sm == 12) 00312 { 00313 // uart1.puts("\nsm 12 Speicher loeschen"); 00314 00315 for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00; 00316 00317 com.index = 0; 00318 com.flag = 0; 00319 com.sm = 0; 00320 } 00321 00322 00323 } // end if (uart1.readabel 00324 else 00325 { 00326 //---------------------------------------------------------------------------------------------------- 00327 // prüfen ob die Daten auf dem Stick schon abgespeichert sind 00328 00329 if ((com.flag & 0x80) == 0x80) 00330 { 00331 if ((m_msd.flag & 0x01) == 0) 00332 { 00333 //---------------------------------------------------------------------------------------------------- 00334 // Telegramme die an die Task msd weitergeleitet werden 00335 00336 if (com.sm == 10) 00337 { 00338 for (i = 0; i < COM_LINE_LEN; i++) 00339 { 00340 m_msd.line[i] = com.line[i]; 00341 if (com.line[i] == 0x00) break; 00342 } 00343 00344 m_msd.flag = 0x01; 00345 com.sm = 12; 00346 00347 msdTaskp->signal_set(0x1); 00348 } 00349 00350 if (com.sm == 11) 00351 { 00352 //---------------------------------------------------------------------------------------------------- 00353 // Daten abspeichern 00354 00355 for (i = 0; i < COM_LINE_LEN; i++) 00356 { 00357 m_msd.line[i] = com.line[i]; 00358 if (com.line[i] == 0x00) break; 00359 } 00360 00361 m_msd.flag = 0x01; 00362 00363 msdTaskp->signal_set(0x1); 00364 00365 for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00; 00366 00367 com.index = 1; 00368 com.sm = 1; 00369 00370 } // end if com.sm == 11 00371 00372 //---------------------------------------------------------------------------------------------------- 00373 // Zeile wieder löschen 00374 00375 if (com.sm == 12) 00376 { 00377 // uart1.puts("\nsm 10 Speicher loeschen"); 00378 00379 for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00; 00380 00381 com.index = 0; 00382 com.flag = 0; 00383 com.sm = 0; 00384 } 00385 } 00386 Thread::wait(10); // falls keine Zeichn mehr im Buffer 10 ms warten 00387 } 00388 else 00389 { 00390 Thread::wait(100); // falls keine Zeichn mehr im Buffer 10 ms warten 00391 } 00392 } 00393 00394 led2 = !led2; 00395 } 00396 } 00397 00398 //--------------------------------------------------------------------- 00399 00400 int main() 00401 { 00402 int i; 00403 00404 // Speicher für die Eingangszeile löschen 00405 for (i=0; i < COM_LINE_LEN; i++) 00406 { 00407 com.line[i] = 0; 00408 } 00409 com.flag = 0; 00410 com.sm = 0; 00411 com.index = 0; 00412 00413 // Speicher für den Stick Speicher löschen 00414 for (i=0; i < COM_LINE_LEN; i++) 00415 { 00416 m_msd.line[i] = 0; 00417 } 00418 m_msd.connect = false; 00419 m_msd.flag = 0; 00420 m_msd.sm = 0; 00421 m_msd.index = 0; 00422 00423 led2 = LED_OFF; 00424 00425 // Uhrzeit initialisieren 00426 struct tm t; 00427 t.tm_sec = 00; // 0-59 00428 t.tm_min = 01; // 0-59 00429 t.tm_hour = 11; // 0-23 00430 t.tm_mday = 4; // 1-31 00431 t.tm_mon = 2; // 0-11 0 = Januar 00432 t.tm_year = 114; // year since 1900 00433 00434 // Zeit umwandeln und setzen >> die Zeit wird für die Datei benötigt 00435 time_t seconds = mktime(&t); 00436 set_time(seconds); 00437 00438 // pc ist die USB Schnittstelle des Debuggers 00439 pc.baud(56700); 00440 pc.printf("\nUSB_4 Test Programm V1.0d"); 00441 00442 // uart1 ist die Schnittstelle zur microSPS 00443 uart1.baud(56700); 00444 // uart1.printf("\nUSB_2 Test Programm V1.0d"); 00445 00446 //uart1.attach(&txCallback, MODSERIAL::TxIrq); 00447 //uart1.attach(&rxCallback, MODSERIAL::RxIrq); 00448 //uart1.attach(&txEmpty, MODSERIAL::TxEmpty); 00449 00450 // diese Task werden die nakommenden Zeichen gelesen und ausgewertet 00451 Thread thread(com_thread, NULL, osPriorityNormal, 512); 00452 00453 // diese Taks ist die Schnittstelle zum Stick 00454 Thread msdTask(msd_task, NULL, osPriorityNormal, 1024 * 4); 00455 msdTaskp = &msdTask; 00456 00457 while(1) 00458 { 00459 // falls der Stick gezogen wurde, wird damit die USB Schnittstelle neu initialisiert 00460 if (err_counter >= 10) 00461 { 00462 NVIC_SystemReset(); 00463 } 00464 00465 // Systemzeit neu setzen, da keine Hardwareuhr 00466 // auf der oginal Karte wird die Uhr über einen Eingang angesteuert 00467 time_t seconds = time(NULL); 00468 char buffer[40]; 00469 strftime(buffer, 40, "%a,%d %m %Y.%H:%M:%S", localtime(&seconds)); 00470 pc.printf("\nTime as a custom formatted string = %s %02x %02x %02x", buffer, com.index, com.sm, com.flag); 00471 // uart1.printf("\nTime as a custom formatted string"); 00472 seconds++; 00473 set_time(seconds); 00474 00475 // Zeitintervall 00476 // könnte auch in eine Taks verlagert werden 00477 led1 = !led1; 00478 Thread::wait(1000); 00479 00480 } // end while 00481 } 00482
Generated on Fri Jul 15 2022 20:44:01 by 1.7.2