88207
arduino IDEで開発しています。  
使用しているSDカードの容量情報を取得したいのですが、どのようなプログラムを書けば情報を取得できるでしょうか。
CC BY-SA 4.0
2022-04-05T08:21:31.777
88177
2022-04-07T04:56:24.073
2022-04-07T04:56:24.073
3060
36346
question
spresense
SDカードの総容量や使用量を取得するには？
使用している量ということであれば、次のようなコードはどうでしょうか？

```

    #include <SDHCI.h>
    SDClass SD;
    
    uint32_t read_directory_size(File& dir) {
      uint32_t dir_file_size;
      while (true) {
          File myfile = dir.openNextFile();
          if (!myfile) break; // ファイルがない場合処理終了
          if (myfile.isDirectory()) {
            dir_file_size += read_directory_size(myfile);
          }; 
          Serial.println(String(myfile.name()) + ":" + String(myfile.size()));
          dir_file_size += myfile.size();
          myfile.close(); 
      }
      dir.close();
      return dir_file_size;
    }
    
    void setup() {
      uint32_t total_file_size = 0;
      Serial.begin(115200);
      while (!SD.begin()) { Serial.println("Insert SD card"); }
      File sd_root = SD.open("/");
      total_file_size = read_directory_size(sd_root);
      Serial.println("Total size:" + String(total_file_size));
    }
    
    void loop() {}
    
```

追記：  
差されたSDカードのボリュームを知りたい場合は、あまりエレガントなやり方ではないですが `/proc/fs/usage`
の情報を読み込めばおおよそのボリュームサイズが分かります。（もっと良い方法があるとは思いますが、、、）

```

    #include <stdlib.h>
    #include <fcntl.h>
    #include <SDHCI.h>
    #define IOBUFFERSIZE 256
    SDClass SD;
    char buff[IOBUFFERSIZE];
    
    void setup() {
      Serial.begin(115200);
      while (!SD.begin()) {Serial.println("insert sd card");}
     
      memset(buff, NULL, IOBUFFERSIZE*sizeof(char));
      int fd = open("/proc/fs/usage", O_RDONLY);
      if (fd < 0) {
        printf("file open error\n");
        return;
      }
      int readnbytes = read(fd, buff, IOBUFFERSIZE);
      if (readnbytes <= 0) {
        Serial.println("fail to read /proc/fs/usage");
        return;
      }
      close(fd);
      String fs_usage = String(buff);
      fs_usage.trim();
      Serial.println(fs_usage);
    
      int str_cnt = 0;
      int index = 0;
      String strs[100];
      memset(strs, '\0', sizeof(String)*100);
      while (fs_usage.length() > 0) {
        int index = fs_usage.indexOf(' ');
        if (index == -1) {
          strs[str_cnt++] = fs_usage;
          break;
        } else {
          String str  = fs_usage.substring(0, index);
          str.trim();
          strs[str_cnt++] = str;
          fs_usage = fs_usage.substring(index+1);
          fs_usage.trim();
        }
      }
      // for debug
      for (int i = 0; i < str_cnt; i++) {
        Serial.println(String(i) + ": \"" + strs[i] + "\"");
      }
      // get available size of SD card (vfat)
      String str_sd_size = strs[9];
      String unit;
      int str_len = str_sd_size.length();
      switch(str_sd_size[str_len-1]) {
      case 'K': unit = "KB"; break;
      case 'M': unit = "MB"; break;
      case 'G': unit = "GB"; break;
      }
    
      uint32_t sd_size = str_sd_size.substring(0, str_len-1).toInt();
      Serial.println("SD card volume : " + String(sd_size) + unit);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    }
    
```
CC BY-SA 4.0
2022-04-06T03:40:29.257
88193
2022-04-07T01:27:08.150
2022-04-07T01:27:08.150
27334
27334
88177
answer
Arduino環境からでも`#include <sys/statfs.h>`をインクルードすれば  
`statfs`関数(<https://linuxjm.osdn.jp/html/LDP_man-
pages/man2/statfs.2.html>)を使って  
次のコードでSDカードの全体容量や空き容量を取得することができそうです（できました）。

```

    #include <sys/statfs.h>
    #include <SDHCI.h>
    SDClass SD;
    
    void setup()
    {
      Serial.begin(115200);
    
      /* Initialize SD */
      while (!SD.begin()) {
        ; /* wait until SD card is mounted. */
      }
    
      struct statfs statfsbuf;
    
      if (0 == statfs("/mnt/sd0", &statfsbuf)) {
        printf("Total: %lld [MB]\n", statfsbuf.f_bsize * statfsbuf.f_blocks / 1024 / 1024);
        printf("Free : %lld [MB]\n", statfsbuf.f_bsize * statfsbuf.f_bfree / 1024 / 1024);
      }
    }
    
    void loop()
    {
    }
    
```

ご参考まで。
CC BY-SA 4.0
2022-04-07T02:48:25.087
88207
2022-04-07T02:48:25.087
31378
88177
answer