MSP430 mit Circuit Cillar Code für FAT16 - fehlende Funktionen

OP #2022101
Lesenswert?

Ich habe mir den Source Code für die Anbindung einer SD-Karte an meinen
MSP430 heruntergeladen von Circuit Cellar (sham176.zip) FAT16 MMC/SD mit
MMC/SD Hardwaretreiber für MSP430

Auf den ersten Blick gibt es recht wenige Funktionen, z.B. fehlen 
Suchfunktionen und dgl., aber das kann man sich ja selber 
zusammenbasteln.

Ärgerlich ist aber, dass die Funktion nur dann einen Handle ausgibt, 
wenn es die zu öffnende Datei noch nicht gibt! Das ist ziemlich 
unpraktisch. Wie mach ich das?
1
/**
2
 *  opens the file indicated by the input path name.  If the pathname
3
 *  points to a valid path, the file is created and added to the list of
4
 *  currently opened files for writing and the unique file handle is returned.
5
 *
6
 *  @param  pathname  a pointer to the location of the file to be opened
7
 *
8
 *  @return  -1      invalid pathname
9
 *  @return  -2      file already exist
10
 *  @return  -3      file already opened for writing
11
 *  @return  -4      no directory entries left
12
 *  @return -10      no handles available
13
 *  @return  -20      memory card error
14
 *  @return  -128    other error
15
 *  @return  (non-negative)  file handle of sucessfully opened file
16
 **/
17
signed char fat_openWrite(const char *pathname)
18
{
19
    unsigned char buf[SECTOR_SIZE];
20
  const char *tempPathname;
21
  unsigned long cluster;
22
  unsigned long tempCluster;
23
  unsigned long fileSize = 0;
24
  signed char i = 0;
25
  signed char index = -1;
26

27
  if(detectCard() == FALSE)
28
  {
29
    return -20;
30
  }
31

32
  if(filesOpenedWrite >= BUFFER_SIZE)
33
  {
34
    return -10;
35
  }
36
  else
37
  {
38
    while((i < BUFFER_SIZE) && (index < 0))
39
    {
40
      if(openedWrite[i].fileHandle == -1)
41
      {
42
        index = i;
43
      }
44
      i++;
45
    }
46
  }
47
  cluster = fileSys;
48
  
49
  if(*pathname == 0x5C)
50
  {
51
    pathname++;
52
  }
53
  tempPathname = pathname;
54
  while(*tempPathname)
55
  {
56
    if(*tempPathname == 0x5C)
57
      return -128;
58
    tempPathname++;
59
  }  
60

61
  tempPathname = pathname;
62

63
  if(cluster != 0)
64
  {
65
    tempCluster = cluster;
66
    cluster = getFirstCluster(tempPathname, cluster, buf, FILE, &fileSize);
67
    if(cluster != 0)
68
    {
69
      return -2;
70
    }
71
    else
72
    {  
73
      cluster = createNewEntry(tempPathname, tempCluster, buf, FILE);
74
      if(cluster != 0)
75
      {
76
        openedWrite[index].currentCluster = cluster;
77
        openedWrite[index].dirLocation = tempCluster;
78
        openedWrite[index].fileHandle = getFileHandle();
79
        openedWrite[index].fileSize = 0;
80
        openedWrite[index].sectorCount = 0;
81
        openedWrite[index].firstCluster = cluster;
82
        openedWrite[index].byteCount = 0;
83
                openedWrite[index].updateDir = FALSE;
84
        filesOpenedWrite++;
85
        return openedWrite[index].fileHandle;
86
      }
87
      else
88
      {
89
        return -4;
90
      }
91
    }
92
  }
93
  else
94
  {
95
    return -1;
96
  }
97
  return -128;
98
}
OP #2032087
Lesenswert?

Nochmal zu diesem Thema.
Ich möchte die Dateinamen dynamisch verändern können, wenn eine 
bestimmte Datei schon existiert. Nun verlangt fat_openWrite aber einen 
kostanten String.
Was hat es für Auswirkungen, wenn ich das const an allen Stellen im 
Programm entferne, wo es um pathname geht?
OP #2032212
Lesenswert?

1
/**
2
 *  determines the location of the cluster of the file or directory
3
 *  pointed to by the input pathname.  Only the first token in 
4
 *  the string pointed to by pathname is used (anything before '\').
5
 *
6
 *  @param  buf      the buffer to be used to access the MMC/SD card
7
 *  @param  pathname  pointer to the string of the pathname
8
 *  @param  cluster    location of the current directory where the
9
 *            file or directory being seek is located
10
 *  @param  control    determines whether a file or a directory is being seek
11
 *  @param  fileSize  stores the size of the file being seeked
12
 *
13
 *  @return  0      if the directory or file does not exist
14
 *  @return ...      the first cluster of the directory or file being seeked
15
 **/
16
static unsigned long getFirstCluster(const char *pathname, unsigned long cluster, unsigned char *buf, boolean control, unsigned long * fileSize)
17
{
18
  int offset = 0;
19
  unsigned int sectorCount;
20
  unsigned long sector;    
21
  unsigned char i, j;
22
  unsigned char tokenLength = 0;    // path name contails tokes less than 255 characters long
23
  const char *tempPathname;
24
  boolean matchingNames;
25
  boolean targetFound;
26

27
  if((cluster == 1)&&(fileSys == FAT16))
28
  {
29
    sector = rootDirectory;
30
  }
31
  else
32
  {
33
        return 0;
34
  }
35

36
  tempPathname = pathname;
37

38
  while((*tempPathname != 0x5C)&&(*tempPathname))
39
  {
40
    tokenLength++;
41
    tempPathname++;
42
  }
43
  
44
  targetFound = FALSE;
45
  sectorCount = 0;
46
  i = 0;
47
  readSector(sector, buf);
48
  if(((tokenLength < 13)&&(control == FILE)))
49
  {  
50
    while((targetFound == FALSE)&&(sector > 0))
51
    {
52
      offset = i * 32;
53
      tempPathname = pathname;
54
      matchingNames = TRUE;
55

56
            if (control == FILE)
57
      {                
58
                if (buf[offset] == '\0')
59
                {
60
                    // End of entries.
61
                    break;
62
                }
63

64
                // Check attributes except for ARCHIVE or READONLY, and for deleted entries:
65
        if(((buf[11+offset] & 0xDE) == 0x00)&&((buf[offset] & 0xFF) != 0xE5))
66
        {
67
          for(j = 0; j < 8; j++)
68
          {          
69
                        if (*tempPathname != '.' && *tempPathname != '\0')
70
                        {
71
                            // Before end of filename, characters must match:
72
                            if (!charEquals(buf[offset+j], *tempPathname))
73
                            {
74
                                matchingNames = FALSE;
75
                            }
76

77
              tempPathname++;
78
                        }
79
            else if ((buf[offset+j]) != ' ')
80
            {
81
                            // After end of filename, must have blanks.
82
              matchingNames = FALSE;
83
            }
84
          }
85

86
                    if (*tempPathname != '\0')
87
                    {
88
                        tempPathname++;
89
                    }
90

91
          for(j = 8; j < 11; j++)
92
          {          
93
                        if (*tempPathname != '\0')
94
                        {
95
                            // Before end of extension, characters must match:
96
                            if (!charEquals(buf[offset+j], *tempPathname))
97
                            {
98
                                matchingNames = FALSE;
99
                            }
100

101
              tempPathname++;
102
                        }
103
            else if ((buf[j+offset]) != ' ')
104
            {
105
                            // After end of extension, must have blanks.
106
              matchingNames = FALSE;
107
            }
108
          }
109

110
          if (matchingNames)
111
          {
112
            targetFound = TRUE;
113
          }
114
        }
115

116
      }
117
      i++;
118
      if(i == 16)    // 16 = directory entries per sector (fixed number)
119
      {
120
        i = 0;
121
        sectorCount++;
122
        if((cluster == 1)&&(fileSys == FAT16))
123
        {
124
          if( sectorCount < rootSectors )
125
          {
126
            sector++;
127
          }
128
          else
129
          {
130
            sector = 0;
131
          }
132
        }
133
        else
134
        {
135
          if(sectorCount != sectorsPerCluster)
136
          {
137
            sector++;
138
          }
139
          else
140
          {
141
            sectorCount = 0;
142
            cluster = getNextFAT(cluster, buf);
143
            if((cluster <= 0xFFF6)&&(cluster >= 2))
144
            {
145
              sector = (cluster - 2) * sectorsPerCluster + dataStarts;                
146
            }
147
            else
148
            {
149
              sector = 0;
150
            }
151
          }
152
        }
153
        readSector(sector, buf);
154
      }    
155
    }
156
  }
157

158
  if(targetFound)
159
  {
160
    cluster = buf[26+offset];
161
    cluster |= (unsigned long int)buf[27+offset] << 8;
162
    
163
    *fileSize = buf[28+offset];
164
    *fileSize += (unsigned long int)buf[29+offset] << 8;
165
    *fileSize += (unsigned long int)buf[30+offset] << 16;
166
    *fileSize += (unsigned long int)buf[31+offset] << 24;
167
  }
168
  else
169
  {
170
    cluster = 0;
171
  }
172
  return cluster;
173
}
OP #2032215
Lesenswert?

1
/**
2
 *  creates a new entry (file or directory) at the location indicated by the
3
 *  input cluster.  The input control determines whether a file or a
4
 *  directory is created
5
 *  *****ONLY FILES AND DIRECTORY WITH SHORT FILE NAMES ARE SUPPORTED
6
 *
7
 *  @param  buf      the buffer to be used to access the MMC/SD card  
8
 *  @param  entryName  pointer to the name of the new entry
9
 *  @param  cluster    location of the current directory where the new entry will be added
10
 *  @param  control    FILE or DIRECTORY
11
 *
12
 *  @return  0      if an error occurs while adding a new entry
13
 *  @return  ...      the location of the first cluster of the new entry
14
 **/
15
static unsigned long createNewEntry(const char *entryName, unsigned long cluster, unsigned char *buf, boolean control)
16
{
17
  unsigned int offset;
18
  unsigned int sectorCount = 0;
19
  unsigned int tokenLength = 0;    
20
  unsigned long sector;
21
  unsigned long newCluster;
22
  unsigned char i;  
23
  const char *tempEntryName;  
24
  boolean done = FALSE;
25

26
    // Note:  findEmptyCluster() will mark the returned cluster in the FAT
27
    // as used.  If we fail for some other reason below, we should really
28
    // free the newCluster, but we don't right now.  Also, unless we are
29
    // creating a directory, we really shouldn't allocate a first cluster
30
    // until some data is written to the file.  Additionally, if we re-use a
31
    // deleted entry, we should re-use the cluster chain, adding clusters as
32
    // required, but we don't do that right now either.
33
  newCluster = findEmptyCluster(buf);
34
  if(newCluster == 0)
35
  {
36
    return 0;  // no more empty cluster
37
  }
38

39
  if((cluster == 1) && (fileSys == FAT16))
40
  {
41
    sector = rootDirectory;
42
  }
43
  else
44
  {
45
    sector = (cluster - 2) * sectorsPerCluster + dataStarts;    
46
  }
47

48
  tempEntryName = entryName;
49

50
  while((*tempEntryName != '.')&&(*tempEntryName)&&(*tempEntryName != 0x5C))
51
  {
52
    tokenLength++;
53
    tempEntryName++;
54
  }
55

56
  while(!done)
57
  {        
58
    readSector(sector, buf);
59
    i = 0;
60
    while(i < 16)
61
    {
62
      offset = i * 32;      
63
      if(((buf[offset] & 0xFF) == 0x00) || ( (buf[offset] & 0xFF) == 0xE5) )
64
      {
65
        done = TRUE;
66
        i = 15;
67
      }
68
      i++;
69
    }
70
    if(!done)
71
    {
72
      sectorCount++;
73
      if((cluster == 1)&&(fileSys == FAT16))
74
      {
75
        if(sectorCount < rootSectors)
76
        {
77
          sector++;
78
        }
79
        else
80
        {
81
          return 0;  // no more root directory
82
        }
83
      }
84
      else
85
      {
86
                return 0;
87
      }        
88
    }
89
  }
90

91
  if(control == FILE)
92
  {
93
    buf[offset+11] = 0x20;
94
    if(tokenLength < 9)
95
    {      
96
      for(i = 0; i < 8; i++)
97
      {
98
        if(*entryName != '.')
99
        {
100
          if((*entryName >= 'a')&&(*entryName <= 'z'))
101
          {
102
            buf[offset+i] = (*entryName - 32);
103
          }
104
          else
105
          {
106
            buf[offset+i] = *entryName ;
107
          }
108
          entryName++;
109
        }
110
        else
111
        {
112
          buf[offset+i] = 0x20;
113
        }
114
      }
115
      entryName++;
116
      for(i = 8; i < 11; i++)
117
      {
118
        if(*entryName)
119
        {
120
          if((*entryName >= 'a')&&(*entryName <= 'z'))
121
          {
122
            buf[offset+i] = (*entryName - 32);
123
          }
124
          else
125
          {
126
            buf[offset+i] = *entryName ;
127
          }
128
          entryName++;
129
        }
130
        else
131
        {
132
          buf[offset+i] = 0x20;
133
        }
134
      }            
135
    }
136
    else
137
    {
138
      // file with long file name
139
      return 0;
140
    }
141
  }
142

143
  buf[offset+12] = 0x00;
144
  buf[offset+13] = 0x00;
145

146
    // Set the date and time to January 02, 2005 21:00:00 .
147
    // If a real time clock is available, we could use it.
148
  buf[offset+14] = (04 >> 1) & 0x1F;  // Seconds.
149
  buf[offset+14] |= 03 << 5;  // Part of minutes.
150
  buf[offset+22] = buf[offset+14];
151

152
  buf[offset+15] = (03 >> 3) & 0x07;  // More of minutes.
153
  buf[offset+15] |= 21 << 3;  // Hours.
154
  buf[offset+23] = buf[offset+15];      
155
  
156
  buf[offset+16] = 02 & 0x1F;     // Day.
157
  buf[offset+16] |= (01 << 5) & 0xE0;   // Part of month.
158
  buf[offset+18] = buf[offset+16];
159
  buf[offset+24] = buf[offset+16];
160
        
161
  buf[offset+17] = (01 >> 3) & 0x01;   // More of month.
162
  buf[offset+17] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE;  // Year.
163
  buf[offset+19] = buf[offset+17];
164
  buf[offset+25] = buf[offset+17];
165

166
  buf[offset+26] = (newCluster & 0xFF);
167
  buf[offset+27] = (newCluster >> 8) & 0xFF;
168

169
  for(i = 28; i < 32; i++)
170
  {
171
    buf[offset+i] = 0x00;
172
  }
173
  writeSector(sector, buf);
174

175
  return newCluster;
176
}
Persönliche Seite #2032306
Lesenswert?

Nö, die ändern am Pfadnamen auch nichts. Dein Vorgehen sollte so sein:

1. Du erstellst einen eindeutigen, nicht vorhandenen Dateinamen
   z.B. in einem globalen Array.

2. Die aufrufende Funktion von fat_openWrite() übergibt diesen
   Dateinamen

3. fat_openWrite() und die von fat_openWrite() aufgerufenen Funktionen
   benutzen den Dateinamen lesend wie bisher
Persönliche Seite #2032523
Lesenswert?

> Das funktioniert leider nicht.

Kann ich mir nicht vorstellen.

Das Prinzip:
1
#include <string.h>
2
#include <stdio.h>
3

4
char dateiname[23];
5

6
int bar(const char *dn)  // Dateinamen benutzen #2
7
{
8
  return strlen(dn);
9
}
10

11
int foo(const char *dn)  // Dateinamen benutzen #1
12
{
13
  return bar(dn); 
14
}
15

16
int main(void)
17
{
18
  strcpy(dateiname, "dreiundzwanzig"); // Dateinamen erzeugen
19
  printf("%d\n", foo(dateiname));
20
}

Bekommst du Compilerprobleme oder Laufzeitprobleme?
OP #2032618
Lesenswert?

Laufzeitprobleme. Der Compiler geht durch, im Debugger läuft auch alles.
Aber die Datei ist nachher nicht auf der microSD.

Den Aufruf wie in deiner Main hab ich noch nicht ausprobiert, weil ich 
gerade noch an ner anderen Baustelle bin. Aber ich habs mit nem String 
outputFile versucht:
1
char outputFile[13]={"data.txt"}; //13 Elemente, weil 8.3-Format + Terminator

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren