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
}