Userdaten im Flash-RAM sind als Dateien organisiert. Diese Dateien tragen keinen Namen. Dateien werden unterschieden durch einen Modus. Der Modus kann Werte von 0..15 annehmen. Die Werte sind fest den (eingebauten) Anwendungen zugeordnet.
| Modus | Anwendung |
| 1 | Kontakte |
| 2 | Kontakte (Beruf) |
| 3 | MEMO |
| 4 | Termine |
| 5 | pocket sheet |
| 6 | |
| 7 | Ausgaben |
| 8 | Clock (City setting) |
| 9 | Dual window |
| 10 | Addins |
| 11 | Quickmemo |
Submodi sind eine weitere Unterscheidung von Dateien. Der Submodus kann Werte von 0..15 annehmen. Der Submodus 0 adressiert alle Dateien eines Modus. In der Anwendung entsprechen die Submodi den Kategorien.
Die Submodi entsprechend Memory_ctl.pdf.| Modus | Submodus | |
| 1 = TEL | 00h | Common |
| 01h | Personal | |
| 02h | Company | |
| 03h | Untitled1 | |
| 04h | Untitled2 | |
| 05h | Untitled3 | |
| 06h | Untitled4 | |
| 07h | Untitled5 | |
| 0Fh | Owner | |
| 3 = Memo | 00h | Common |
| 01h | Untitled1 | |
| 02h | Untitled2 | |
| 03h | Untitled3 | |
| 04h | Untitled4 | |
| 05h | Untitled5 | |
| 4 = Schedule | 01h | Schedule |
| 02h | Schedule (Term registration) | |
| 03h | Reminder | |
| 04h | Holiday setting | |
| 06h | Schedule (Common) | |
| 08h | TODO (Common) | |
| 09h | TODO (CATEGORY A) | |
| 0Ah | TODO (CATEGORY B) | |
| 0Bh | TODO (CATEGORY C) | |
| 0Ch | TODO (CATEGORY D) | |
| 0Dh | TODO (CATEGORY E) | |
| 0Eh | TODO (CATEGORY E) | |
| 0Fh | TODO (CATEGORY F) | |
| 00h | Common | |
| 7 = EXPENSE | 01h | Account |
| 02h | Transaction | |
| 03h | Payment type | |
| 9 = Dual-window | 01h | Clip |
| 11 = Quick-Memo | 00h | Common |
| 01h | Untitled1 | |
| 02h | Untitled2 | |
| 03h | Untitled3 |
Weiter wird zwischen dem offenen und dem geheimen Bereich unterschieden. Der geheime Bereich ist erst ansprechbar, wenn das Passwort einmal eingegeben wurde. Damit sollen vertrauliche Daten geschützt werden. Die eingebauten Anwendungen, die geheime Bereiche unterstützen, schalten zwischen geheimen und offenem Bereich um, das heißt, es ist unmöglich, Daten aus beiden Bereichen gleichzeitig zu sehen.
Wie bekannt, bietet der geheime Bereich praktisch keine Sicherheit. Das Passwort steht unkodiert im RAM, so daß jedes Addin es einfach auslesen könnte. Es scheint also sinnvoll, auf diese Form der (nicht vorhandenen) Sicherheit zu verzichten, und den geheimen Bereich als Erweiterung der Adressierungsmöglichkeiten zu nutzen. Bei Verwendung von PVPin und rein numerischem Passwort wird der geheime Bereich sofort freigeschalten.
Mit Modus, Submodus und zwei Bereichen wären theoretisch 512 Dateien ansprechbar. Praktisch kann dies durch Einschränkungen des PVOS jedoch nicht genutzt werden.
Unterschieden wird zwischen Text (FILE_KIND_TEXT) und Binär-Dateien (FILE_KIND_BIN). Bei Textdateien dient das Endebyte 00 als Endekennung, bei Binärdateien ist die Dateilänge im Puffer mit abgelegt. Das Nullbyte hat hier keine spezielle Bedeutung und kann mit in den Daten vorkommen. Zwischen den Modi und dem Dateityp besteht ein fester Zusammenhang:
| Modus | Anwendung | Dateityp |
| 1 | Kontakte | Text |
| 2 | Kontakte (Beruf) | Text |
| 3 | MEMO | Text |
| 4 | Termine | Text |
| 5 | pocket sheet | binär |
| 6 | binär | |
| 7 | Ausgaben | Text |
| 8 | Clock (City setting) | Text |
| 9 | Dual window | Text |
| 10 | Addins | binär |
| 11 | Quickmemo | binär |
In jeder Datei können beliebig viele Datensätze (Records) angelegt werden. Diese enthalten die einzelnen Memos, Kontakte, ... Alle Datensätze können eine unterschiedliche Größe haben.
Zugriff auf Dateien erfolgt stets datensatzweise und innerhalb der Datei sequentiell. Die Datensätze werden in den Funktionen über einen Dateizeiger adressiert. Dieser ist vom Typ word, ein Rechnen mit diesem Wert ist nicht sinnvoll. Der spezielle Wert -1 = 0xffff ist die Kennung für (noch) "kein Datensatz". Dieser Wert wird z.B. verwendet, um beim sequentiellen Zugriff mit LibFileNext den ersten Record zu suchen. Ein entsprechender Rückgabewert nach LibFileNext steht für das Ende, also wenn kein weiterer Datensatz vorhanden ist.
Alle Addin-Programme benutzen den Modus 10. Da es ja mehr als 15 verschiedene Addins geben kann (und sogar schon gibt), kann hier keine feste Zuordnung zu Submodi erfolgen, sondern die geladenenen Addins müssen jeweils einen freien Submodus bekommen. Wie ist das möglich?
Hier und nur hier erhalten Dateien einen Namen. Durch diesen Namen sind Addins in der Lage ihre Datei wiederzufinden, die ja auf jedem PV einen anderen Submodus haben kann. Wenn ein Addin auf seine Datei zugreifen will, muß es sich zunächst die entsprechenden Modus-Informationen besorgen. Dann erfolgt der Zugriff auch hier über Modus und Submodus. Durch die Beschränkung der Submodi auf den Bereich 1 bis 15 wird klar, daß es auch nur 15 Dateien mit Namen geben kann. Jedes kooperativ programmierte Addin (also alle guten?) sollte deshalb auch wirklich nur eine Datei verwenden oder gar eine Datei mit anderen Addins teilen.
Wer Dateien lesen und schreiben will braucht im wesentlichen zwei Datenstrukturen: FILE_BUF bzw. LFILE_BUF und FILE_INFO
FILE_BUF bzw. LFILE_BUF enthalten neben den eigentlichen Daten u.a. den Modus, den Submodus und das Flag für geheimen und offenen Bereich.
typedef struct FILE_BUF {
byte fsb_main_entry_; /* MainEntryNo. */
byte fsb_sub_entry_; /* SubEntryNo. */
byte fsb_scrt_info_; /* SecretInformation */
byte fsb_ararm_chk_; /* AlarmCheckInformation
byte fsb_todo_chek_; /* TODO CheckInformation
byte fsb_todo_rank_; /* TODO RankInformation
byte fsb_date1_buf_[8]; /* Date/DueDate */
byte fsb_date2_buf_[8]; /* CheckDate */
byte fsb_date_aram_[8]; /* AlarmDate */
byte fsb_time1_buf_[4]; /* Time/DueTime(From) */
byte fsb_time2_buf_[4]; /* Time/DueTime(To) */
byte fsb_time3_buf_[4]; /* CheckTime */
byte fsb_time_aram_[4]; /* AlarmTime */
byte fsb_date_srch_[8]; /* SearchBuffer Date */
byte fsb_time_srch_[4]; /* SearchBuffer Time */
byte fsb_text_srch_[33]; /* SearchBuffer RealData(text) */
union{
struct{
byte fsb_text_buf_[2048+1]; /* Buffer to store real data (TEXT) */
}text;
struct{
byte dummy_16by[22]; /* MemoryManagementWork */
word char_num; /* BinaryDataCapacity */
byte bin_buf[3072]; /* Buffer to store real data (BINARY) 3KB*/
}bin;
}fbuf;
} FILE_BUF;
|
LFILE_BUF unterscheidet sich von FILE_BUF durch die Länge des Datenbereiches. In LFILE_BUF ist der Puffer für binäre Date mit byte bin_buf[30720]; definiert. Große binäre Datensätze können nur mit einer LFILE_BUF Datenstruktur gelesen oder geschrieben werden. Wegen ihrer Größe kann diese nur im FAR Speicherbereich angelegt werden. Dieser Unterschied bedingt die Verwendung unterschiedlicher Bibliotheksfunktionen, z.B. LibFileFindNext für FILE_BUF und LibLFileFindNext für LFILE_BUF. Diese unterscheiden sich nur im Parametertyp für den Dateipuffer.
Die FILE_INFO enthält den Dateityp (Text oder binär) und den Dateizeiger (Filepointer).
typedef struct FILE_INFO {
word fp; /* file pointer */
byte kind; /* TEXT/BINARY identification */
} FILE_INFO;
|
Von Addins angelegte Dateien werden über einen Namen verwaltet. Will man auf sie zugreifen, so muß zunächst die Verbindung zwischen Namen und Modus/Submodus hergestellt werden.
Will man Werte speichern, so muß die Datei, wenn nicht vorhanden, angelegt werden. Dies ist möglich mit folgendem C-Code:
/* find or create named file */ if (! LibSubEntrySave(filename,&(fb.fsb_sub_entry_))) return ; /* error handling */ /* get mode/submode */ LibGetAllEntry(filename,&(fb.fsb_main_entry_),&(fb.fsb_sub_entry_)); |
LibSubEntrySave sucht zunächst nach einer Datei dieses Namens
und legt sie, falls nicht vorhanden, neu an.
Die Fehlerbehandlung ist im
Beispiel nur angedeutet.
LibGetAllEntry ermittelt dann den zugehörigen Modus und Submodus. Modus und Submodus sind hier gleich in den Datei-Puffer eingetragen.
Soll die Datei nur gelesen werden, ist es nicht sinnvoll, diese neu anzulegen, falls es sie nicht gibt. Der C-Code dafür sieht dann so aus:
/* find named file */ if (! LibSubEntrySearch(filename,&(fb.fsb_sub_entry_))) return ; /* error handling */ /* get mode/submode */ LibGetAllEntry(filename,&(fb.fsb_main_entry_),&(fb.fsb_sub_entry_)); |
LibSubEntrySearch sucht nach einer Datei dieses Namens,
ohne sie neu anzulegen.
Die Fehlerbehandlung ist im
Beispiel nur angedeutet.
Für Ergänzungen wenden Sie sich bitte an:
Jürgen Wagner