3.10.1 Dateiorganisation

Modi

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.

ModusAnwendung
1Kontakte
2Kontakte (Beruf)
3MEMO
4Termine
5pocket sheet
6mail
7Ausgaben
8Clock (City setting)
9Dual window
10Addins
11Quickmemo
Zusatzbemerkungen:
Submodi

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.
ModusSubmodus 
1 = TEL00h Common
01hPersonal
02hCompany
03hUntitled1
04hUntitled2
05hUntitled3
06hUntitled4
07hUntitled5
0FhOwner
3 = Memo00hCommon
01hUntitled1
02hUntitled2
03hUntitled3
04hUntitled4
05hUntitled5
4 = Schedule01hSchedule
02hSchedule (Term registration)
03hReminder
04hHoliday setting
06hSchedule (Common)
08hTODO (Common)
09hTODO (CATEGORY A)
0AhTODO (CATEGORY B)
0BhTODO (CATEGORY C)
0ChTODO (CATEGORY D)
0DhTODO (CATEGORY E)
0EhTODO (CATEGORY E)
0FhTODO (CATEGORY F)
00hCommon
7 = EXPENSE01hAccount
02hTransaction
03hPayment type
9 = Dual-window01hClip
11 = Quick-Memo00hCommon
01hUntitled1
02hUntitled2
03hUntitled3
Der geheime Bereich

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.

Datei-Typen

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:

ModusAnwendungDateityp
1KontakteText
2Kontakte (Beruf)Text
3MEMOText
4TermineText
5pocket sheetbinär
6mailbinär
7AusgabenText
8Clock (City setting)Text
9Dual windowText
10Addinsbinär
11Quickmemobinär

Datensätze

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.

Addin-Programme

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