Speichern von Dateien auf einem Stick
Dependencies: KL46Z-USBHost MODSERIAL-RTOS mbed-rtos mbed
main.cpp
- Committer:
- rs27
- Date:
- 2014-05-11
- Revision:
- 0:dc4ad683fe77
File content as of revision 0:dc4ad683fe77:
//------------------------------------------------------------------------ // // kl25z_USB_4 // Programm zum Speichern von Dateien auf einem memery Stick // // Erstellt am 10.05.14 R. Schäfer // #include "mbed.h" #include "rtos.h" #include "USBHostMSD.h" #include "MODSERIAL.h" #define LED_OFF 1 #define LED_ON 0 #define COM_LINE_LEN 128 // maximale Länge der Eingabezeile struct com_struct { uint8_t flag; // Flag zur Steuerung uint8_t sm; // State maschine uint8_t index; // Index für Zeichenzähler char line[COM_LINE_LEN]; }; struct msd_struct { bool connect; // wird bei Verbindung true uint8_t flag; // Flag zur Steuerung uint8_t sm; // State maschine uint8_t index; // Index für Zeichenzähler char line[COM_LINE_LEN]; }; extern "C" void NVIC_SystemReset(); Thread *(msdTaskp); Serial pc(USBTX,USBRX); // Make TX buffer 1024bytes and RX buffer use 512bytes. // MODSERIAL uart1(PTA2, PTA1, 256, 1024); // tx, rx MODSERIAL uart1(PTC4, PTC3, 128, 1024); // tx, rx DigitalOut led1(PTB18); DigitalOut led2(PTB19); int err_counter = 0; // ---- globle Veariablen ---------------------------------------------- // Bitposition und Belegung // bit 1 CR Flag // bit 2 byte speichern // bit 4 // bit 8 struct com_struct com; // Eingangszeile // Bitposition und Belegung // bit 1 Daten speichern in aktion // bit 2 Datei anlegen // bit 4 Daten schreiben // bit 8 Datei schließen struct msd_struct m_msd; // Speicher für Stick // mit dieser Task werden die Datem in Hintergrund im Stick abgespeichert // es wird auch geprüft ob für das Speichern ein Stick vorhanden ist // falls kein Stick erkannt wird, löst das Programm einen Reset aus, womit // die USB Schnittstelle neu initialiesiert wird. Damit kann auch ein Stick // im Betieb abgesteckt und wieder angestecht werden. // // Änderungen // Thread Zeit reduzieren // Dateinamen über globale Variable ersetzen void msd_task(void const *) { int i = 0; int n; FILE * fp = 0; USBHostMSD msd("usb"); err_counter = 0; // in a loop, append a file // if the device is disconnected, we try to connect it again while(msd.connect()) { m_msd.connect = true; Thread::signal_wait(0x1); // uart1.printf("\nmsd> "); // // for (i = 0; i < com.index; i++) // { // uart1.printf(" %02x",m_msd.line[i]); // } // uart1.printf("\n"); switch (m_msd.line[0]) { case 02: // Datei anlegen char buffer[40]; sprintf(buffer, "/usb/%s", &m_msd.line[1]); fp = fopen(buffer, "w"); // uart1.printf("\nMSD Datei %s anlegen",buffer); break; case 03: // Daten schreiben if (fp) { n = fprintf(fp,"%s",&m_msd.line[1]); // uart1.printf("\nwrite file [%d] %s",n,&m_msd.line[1]); } // if (fp .. break; case 04: // Datei schließen if (fp) n = fclose(fp); // uart1.printf("\n close file"); break; } // end switch(msd-line[0] // Speicher für die Zeile löschen for (i=0; i < COM_LINE_LEN; i++) m_msd.line[i] = 0; m_msd.flag &= ~0x01; // if device disconnected, try to connect again if (!msd.connected()) { // uart1.printf("\n disconnected break"); m_msd.connect = false; break; } } // end while (msd_connected) // Task wird beendet } // In dieser therad werden Daten aus der Seriellen Schnittstelle gelesen. Nach dem lesen // von einem Telegramm wird dieses falls es für das Speicher verwendet wird in m_msd abgelegt. // Die anderen Telergamme und die Antworten werde in dieser thread gleich bearbeitet. void com_thread(void const *args) { char ch; int i; while (true) { if ((uart1.readable()) && ((com.flag & 0x80) == 0)) { //---------------------------------------------------------------------------------------------------- // Eingehende Zeichen lesen und abspeichern ch = uart1.getc(); // Zeichen lesen und auswerten // uart1.printf("\ntel> "); com.line[com.index] = ch; // Zeichen einfuegen com.index++; // Zeichenzähler erhöhen if (com.index >= 125) com.sm = 2; // ein Telegramm enthält maximal 1125 Zeichen // for (i = 0; i < com.index; i++) // { // uart1.printf(" %02x",com.line[i]); // } // uart1.printf("\n"); //---------------------------------------------------------------------------------------------------- // Abschlußbit auswerten und Telegramm umsetzen switch (com.sm) // com.sm ist state machine { case 0 : // erstes Zeichen aus einem Telegramm switch(ch) { case 0x00: // Endzeichen an erter Stelle zum testen // uart1.puts("Telegramm 0x00\n"); // direkt ausführen com.sm = 12; // neues Telegramm break; case 0x01: // Reset // uart1.puts("Telegramm 0x01\n"); // direkt ausführen com.sm = 12; // nur ein Zeichen break; case 0x02: // Datei anlegen und öffnen com.sm = 1; // Kommando Byte abspeichern break; // Dateinamen bis 0x00 lesen case 0x03: // Daten schreiben com.sm = 1; // Kommando Byte abspeichern break; // Dateinamen bis 0x00 lesen case 0x04: // Datei schließen // uart1.puts("Telegramm 0x04\n"); // direkt ausführen com.sm = 10; // Kommando besteht nur aus einem Zeichen break; case 0x05: // SD Stick erkannt, direkt ausführen if (m_msd.connect) uart1.puts("\nStick erkannt"); else uart1.puts("\nStick nicht erkannt"); com.sm = 12; // Kommando besteht nur aus einem Zeichen break; default: // Zeichen zum abspeichern // uart1.puts("\nsm 0 unbekannter Befehl"); com.sm = 12; // Speicher löschen break; } // ende SWITCH break; // end case 0: case 1: // Lesen von weitern Zeichen nach dem ersten Zeichen //---------------------------------------------------------------------------------------------------- // bis Abschlussbit alle Zeichen lesen und bei Abschlußzeichen die Auswertung angehen if (ch == 0x00) { com.sm = 10; } // end if (ch == 0x00) break; // end case 1: case 2: // Zeichenkette ist länger als 125 Zeichen // uart1.puts("\nsm 2 String ist groesser 125 Zeichen"); com.sm = 11; break; // end case 2 } // end switch //---------------------------------------------------------------------------------------------------- // Telegramme die an die Task msd weitergeleitet werden if (com.sm == 10) { if ((m_msd.flag & 0x01) == 0) { // uart1.puts("\nsm 10 Speicher kopieren"); for (i = 0; i < COM_LINE_LEN; i++) { m_msd.line[i] = com.line[i]; if (com.line[i] == 0x00) break; } m_msd.flag = 0x01; com.sm = 12; msdTaskp->signal_set(0x1); } else { com.flag |= 0x80; // kann erst später gespeichert werden } } //---------------------------------------------------------------------------------------------------- // bei mehr asl 125 Zeichen werden die Daten an die msd Task übergeben if (com.sm == 11) { //---------------------------------------------------------------------------------------------------- // Daten abspeichern if ((m_msd.flag & 0x01) == 0) { for (i = 0; i < COM_LINE_LEN; i++) { m_msd.line[i] = com.line[i]; if (com.line[i] == 0x00) break; } m_msd.flag = 0x01; m_msd.sm = 0x03; msdTaskp->signal_set(0x1); for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00; com.index = 1; com.sm = 1; } else { com.flag |= 0x80; // kann erst später gespeichert werden } } // end if com.sm == 11 //---------------------------------------------------------------------------------------------------- // Zeile wieder löschen if (com.sm == 12) { // uart1.puts("\nsm 12 Speicher loeschen"); for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00; com.index = 0; com.flag = 0; com.sm = 0; } } // end if (uart1.readabel else { //---------------------------------------------------------------------------------------------------- // prüfen ob die Daten auf dem Stick schon abgespeichert sind if ((com.flag & 0x80) == 0x80) { if ((m_msd.flag & 0x01) == 0) { //---------------------------------------------------------------------------------------------------- // Telegramme die an die Task msd weitergeleitet werden if (com.sm == 10) { for (i = 0; i < COM_LINE_LEN; i++) { m_msd.line[i] = com.line[i]; if (com.line[i] == 0x00) break; } m_msd.flag = 0x01; com.sm = 12; msdTaskp->signal_set(0x1); } if (com.sm == 11) { //---------------------------------------------------------------------------------------------------- // Daten abspeichern for (i = 0; i < COM_LINE_LEN; i++) { m_msd.line[i] = com.line[i]; if (com.line[i] == 0x00) break; } m_msd.flag = 0x01; msdTaskp->signal_set(0x1); for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00; com.index = 1; com.sm = 1; } // end if com.sm == 11 //---------------------------------------------------------------------------------------------------- // Zeile wieder löschen if (com.sm == 12) { // uart1.puts("\nsm 10 Speicher loeschen"); for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00; com.index = 0; com.flag = 0; com.sm = 0; } } Thread::wait(10); // falls keine Zeichn mehr im Buffer 10 ms warten } else { Thread::wait(100); // falls keine Zeichn mehr im Buffer 10 ms warten } } led2 = !led2; } } //--------------------------------------------------------------------- int main() { int i; // Speicher für die Eingangszeile löschen for (i=0; i < COM_LINE_LEN; i++) { com.line[i] = 0; } com.flag = 0; com.sm = 0; com.index = 0; // Speicher für den Stick Speicher löschen for (i=0; i < COM_LINE_LEN; i++) { m_msd.line[i] = 0; } m_msd.connect = false; m_msd.flag = 0; m_msd.sm = 0; m_msd.index = 0; led2 = LED_OFF; // Uhrzeit initialisieren struct tm t; t.tm_sec = 00; // 0-59 t.tm_min = 01; // 0-59 t.tm_hour = 11; // 0-23 t.tm_mday = 4; // 1-31 t.tm_mon = 2; // 0-11 0 = Januar t.tm_year = 114; // year since 1900 // Zeit umwandeln und setzen >> die Zeit wird für die Datei benötigt time_t seconds = mktime(&t); set_time(seconds); // pc ist die USB Schnittstelle des Debuggers pc.baud(56700); pc.printf("\nUSB_4 Test Programm V1.0d"); // uart1 ist die Schnittstelle zur microSPS uart1.baud(56700); // uart1.printf("\nUSB_2 Test Programm V1.0d"); //uart1.attach(&txCallback, MODSERIAL::TxIrq); //uart1.attach(&rxCallback, MODSERIAL::RxIrq); //uart1.attach(&txEmpty, MODSERIAL::TxEmpty); // diese Task werden die nakommenden Zeichen gelesen und ausgewertet Thread thread(com_thread, NULL, osPriorityNormal, 512); // diese Taks ist die Schnittstelle zum Stick Thread msdTask(msd_task, NULL, osPriorityNormal, 1024 * 4); msdTaskp = &msdTask; while(1) { // falls der Stick gezogen wurde, wird damit die USB Schnittstelle neu initialisiert if (err_counter >= 10) { NVIC_SystemReset(); } // Systemzeit neu setzen, da keine Hardwareuhr // auf der oginal Karte wird die Uhr über einen Eingang angesteuert time_t seconds = time(NULL); char buffer[40]; strftime(buffer, 40, "%a,%d %m %Y.%H:%M:%S", localtime(&seconds)); pc.printf("\nTime as a custom formatted string = %s %02x %02x %02x", buffer, com.index, com.sm, com.flag); // uart1.printf("\nTime as a custom formatted string"); seconds++; set_time(seconds); // Zeitintervall // könnte auch in eine Taks verlagert werden led1 = !led1; Thread::wait(1000); } // end while }