Speichern von Dateien auf einem Stick

Dependencies:   KL46Z-USBHost MODSERIAL-RTOS mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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