Raspberry Pi Pico File System & SD Card Reader
Written by Mike James & Harry Fairhead   
Monday, 29 May 2023
Article Index
Raspberry Pi Pico File System & SD Card Reader
File Systems
sdcard Driver

The Raspberry Pi Pico doesn't have any removable storage, but you can use its internal flash memory to read and write files and its easy to add an SD card reader. We show how to do it in MicroPython.

This is new material that extends our recent book:

Programming the Raspberry Pi Pico/W In MicroPython Second Edition

By Harry Fairhead & Mike James

picopython2e360

Buy from Amazon.

Contents

  • Preface
  • Chapter 1 The Raspberry Pi Pico – Before We Begin
  • Chapter 2 Getting Started
  • Chapter 3 Getting Started With The GPIO
  • Chapter 4 Simple Output
  • Chapter 5 Some Electronics
  • Chapter 6 Simple Input
             Extract: Simple Input 
  • Chapter 7 Advanced Input – Events and Interrupts
  • Chapter 8 Pulse Width Modulation
             Extract: PWM 
  • Chapter 9 Controlling Motors And Servos
             Extract: DC Motors
  • Chapter 10 Getting Started With The SPI Bus
  • Chapter 11 A-To-D and The SPI Bus 
  • Chapter 12 Using The I2C Bus
  • Chapter 13 Using The PIO   
  • Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
             Extract: A PIO Driver For The DHT22  
  • Chapter 15 The 1‑Wire Bus And The DS1820
  • Chapter 16 The Serial Port
  • Chapter 17 Using The Pico W - WiFi
             Extract: HTTP Client 
             Extract: Sockets***NEW!
  • Chapter 18 Asyncio And Servers
  • Chapter 19 Direct To The Hardware
             Extract: Direct To The Hardware

Also of interest:

Raspberry Pico File System

<ASIN:B0BR8LWYMZ>

<ASIN:B0BL1HS3QD>

The Pico has 2MB of flash memory which is used to store the MicroPython interpreter. The rest of the memory is converted into a file system that you can make use of from within your own MicroPython programs.

The flash memory is divided into a number of partitions that hold the system and data. Unlike some other implementations of MicroPython, only the data partition,1.6MB, is available and it is automatically mounted as the root when the system boots up. You can gain access to this partition using the rp2.Flash() function which returns a Partition object representing the data partition.

Once you have an instance of Partition you can use any of the following methods:

part.readblocks(block_num, buf, offset)
part.writeblocks(block_num, buf, offset)
part.ioctl(cmd, arg)

These methods implement both the simple and extended the block protocols defined by os.AbstractBlockDev. Only a subset of ioctl commands are implemented for the Pico:

  • 4 – Get a count of the number of blocks, should return an integer (arg is unused)

  • 5 – Get the number of bytes in a block, should return an integer, or None in which case the default value of 512 is used (arg is unused)

  • 6 – Erase a block, arg is the block number to erase

Generally these commands are too low level to work with a partition and instead you want to install a file system so that you can work in terms of files. But if you really want to reinvent the wheel then you can work directly in terms of raw blocks.

The Flash object is set up so that it isolates you from the other partitions and its block numbers start at zero. So to write some data to block zero and read it back we can use:

from rp2 import Flash
import os
flash=Flash()
os.umount("/")
print(flash.ioctl(4,0))
print(flash.ioctl(5,0))
flash.ioctl(6,0)
flash.writeblocks(0,b"Hello World")
buf=bytearray(25)
flash.readblocks(0,buf)
print(buf)

First we unmount the file system so that it can't be used. If the partition was left mounted the file system could use the block we are about to use and overwrite it. Next we get the number of blocks and the block size. Before we can write new data to a block we have to erase it using ioctl command 6. After this we can write any number of bytes up to the block size. Reading the data back is just a matter of setting the length of the buffer to specify the number of bytes to read in. If you try this out you will find that we have stored "Hello World":

bytearray(b'Hello World\x00\x00\x00\x00\x008\
x01\x00\x00P\xa0\x00 \x0b')

The bytes beyond "Hello World" are whatever was already stored in the block.



Last Updated ( Thursday, 08 June 2023 )