class SDCard -- ไดรเวอร์การ์ด SD / MMC

คลาส SDCard ขับเคลื่อนช่องเสียบการ์ด SD / MMC บน OpenMV Cam ที่มีช่องดังกล่าว ไดรเวอร์นี้ใช้งานอินเทอร์เฟซ vfs.AbstractBlockDev เพื่อให้สามารถส่งตรงไปยัง vfs.mount() ได้:

import machine
import vfs

sd = machine.SDCard()
vfs.mount(sd, "/sd")

Note

เฟิร์มแวร์ OpenMV จะเมานต์การ์ด SD โดยอัตโนมัติเมื่อบูต ดังนั้นสคริปต์ส่วนใหญ่จึงไม่ต้องสร้าง SDCard โดยตรง แต่จะอ่านและเขียนผ่านเส้นทางที่เมานต์ไว้อัตโนมัติ สร้างขึ้นเองเฉพาะเมื่อต้องการจุดเมานต์ที่ไม่ใช่ค่าเริ่มต้น หรือต้องการเข้าถึงระดับบล็อกโดยตรงผ่าน readblocks() / writeblocks() / ioctl()

บน OpenMV Cam M7 / H7 / H7 Plus / Pure Thermal / N6 ช่องเสียบขับเคลื่อนโดยคอนโทรลเลอร์ SDMMC ในชิป STM32 ในโหมด SD 4 บิต บน OpenMV Cam RT1062 ช่องเสียบขับเคลื่อนโดยคอนโทรลเลอร์ USDHC ของ i.MX RT ซึ่งก็ใช้โหมด SD 4 บิตเช่นกัน ไม่จำเป็นต้องระบุอาร์กิวเมนต์ pin-mux บนบอร์ด OpenMV ปัจจุบัน เนื่องจากไดรเวอร์รู้การต่อสายของบอร์ดอยู่แล้ว

ไม่รองรับบน OpenMV Cam AE3 (พอร์ต alif)

คอนสตรักเตอร์

class machine.SDCard(id: int = 1) SDCard

คืนค่าซิงเกิลตัน SDCard สำหรับช่องเสียบ SD ที่ระบุด้วย id id รับมาเพื่อความเข้ากันได้ข้ามพอร์ต แต่พอร์ตที่ OpenMV รองรับนั้นเปิดเผยเพียงช่องเดียว จึงส่ง 1 หรือละไว้ก็ได้

บน STM32 คอนสตรักเตอร์ไม่รับอาร์กิวเมนต์ใดเลย ส่วนบน mimxrt อาร์กิวเมนต์ id รับได้ แต่มีค่าที่ถูกต้องเพียง 1 เท่านั้น

เมธอด

present() bool

คืนค่า True หากตรวจพบการ์ดในช่องเสียบในขณะนั้น มิฉะนั้นคืนค่า False

บนบอร์ดที่ต่อสัญญาณตรวจจับการ์ด เมธอดนี้จะสะท้อนสัญญาณนั้นแบบเรียลไทม์ จึงสามารถโพลหลังจากสร้างออบเจกต์ SDCard แล้วเพื่อตอบสนองต่อการเสียบหรือถอดการ์ดแบบ hot-swap บนบอร์ดที่ไม่มีสัญญาณตรวจจับการ์ด ค่าจะถูกล็อกไว้ตั้งแต่ตอนสร้าง โดยรายงานผลของการทดสอบ CMD0 เริ่มต้นที่ไดรเวอร์ทำเมื่อสร้างออบเจกต์ และการ์ดที่เสียบเข้ามาภายหลังจะไม่ปรากฏจนกว่าจะสร้างออบเจกต์ใหม่อีกครั้ง (หรือเรียก init() บน mimxrt)

info() tuple[int, int, int]

คืนค่า 3-tuple ที่อธิบายการ์ดที่เสียบอยู่ในขณะนั้น:

  • [0] num_blocks -- ความจุรวมในหน่วยบล็อก 512 ไบต์ คูณด้วย 512 เพื่อให้ได้ความจุไบต์ดิบ

  • [1] block_size -- เป็น 512 เสมอสำหรับการ์ด SD รวมไว้เพื่อให้ผู้เรียกสามารถคำนวณ num_blocks * block_size ได้แบบพกพา

  • [2] card_type -- ประเภทการ์ดที่รายงานโดย SD bus ระหว่างการจับมือ CMD8 / OCR ค่าทั่วไปได้แก่ 0 (SDSC -- ความจุมาตรฐาน), 0x40 (SDHC / SDXC -- ความจุสูง / ขยาย) และ 0x80 (MMC)

มีประโยชน์สำหรับตรวจสอบว่าการ์ดได้รับการรับรองแล้ว หรือแสดงตัวเลขพื้นที่ว่างเทียบกับความจุรวม

power(state: bool, /) None

เปิดหรือปิดราง power ของช่องเสียบการ์ด เฟิร์มแวร์ STM32 เปิดเผยเมธอดนี้ แต่ OpenMV Cam ปัจจุบันไม่มีการควบคุมจ่ายไฟ SD จึงเรียกได้เปล่า ๆ เก็บไว้เพื่อความเข้ากันได้กับโค้ดที่เขียนสำหรับบอร์ดอ้างอิง STM32 ต้นน้ำของ MicroPython พอร์ต STM32 เท่านั้น

read(block_num: int, /) bytes

อ่านบล็อก 512 ไบต์เดี่ยวจากการ์ดและคืนค่าเป็นออบเจกต์ bytes ที่จัดสรรใหม่

นี่คือการอ่านบล็อกเดี่ยวแบบ legacy ที่มาพร้อมพอร์ต STM32 โค้ดใหม่ควรใช้ readblocks() แทน เนื่องจากเมธอดนั้นทำงานได้บนทุกพอร์ต OpenMV อ่านได้หลายบล็อกต่อเนื่องในการโอนย้ายเดียว และหลีกเลี่ยงการจัดสรรต่อการเรียกด้วยการเขียนลงในบัฟเฟอร์ที่ผู้เรียกส่งมา พอร์ต STM32 เท่านั้น

write(block_num: int, data: bytes, /) None

เขียนบล็อก 512 ไบต์เดี่ยวลงในการ์ด data ต้องมีความยาวพอดี 512 ไบต์

นี่คือการเขียนบล็อกเดี่ยวแบบ legacy ที่มาพร้อมพอร์ต STM32 โค้ดใหม่ควรใช้ writeblocks() แทน ซึ่งทำงานได้บนทุกพอร์ต OpenMV และเขียนได้หลายบล็อกต่อเนื่องต่อการเรียก พอร์ต STM32 เท่านั้น

readblocks(block_num: int, buf: bytearray) None
readblocks(block_num: int, buf: bytearray, offset: int) None

อ่านข้อมูลดิบแบบบล็อกจากการ์ดลงใน buf จุดเข้าของบล็อกดีไวซ์ vfs.AbstractBlockDev มาตรฐานที่ใช้โดยเลเยอร์ระบบไฟล์

รูปแบบธรรมดา (readblocks(block_num, buf)): อ่านบล็อกเต็มตั้งแต่ดัชนีบล็อก block_num len(buf) ต้องเป็นทวีคูณของขนาดบล็อก SD (512 ไบต์)

รูปแบบขยาย (readblocks(block_num, buf, offset)): อ่าน len(buf) ไบต์ -- ไม่จำเป็นต้องเป็นจำนวนบล็อกเต็ม -- เริ่มต้นที่ไบต์ offset ภายในบล็อก block_num ใช้โดย littlefs และระบบไฟล์แบบ byte-addressable อื่น ๆ

writeblocks(block_num: int, buf: bytes | bytearray) None
writeblocks(block_num: int, buf: bytes | bytearray, offset: int) None

เขียนข้อมูลดิบแบบบล็อกจาก buf ลงในการ์ด จุดเข้าของบล็อกดีไวซ์ vfs.AbstractBlockDev มาตรฐานที่ใช้โดยเลเยอร์ระบบไฟล์

รูปแบบธรรมดา (writeblocks(block_num, buf)): เขียนบล็อกเต็มตั้งแต่ดัชนีบล็อก block_num len(buf) ต้องเป็นทวีคูณของขนาดบล็อก SD (512 ไบต์) แต่ละบล็อกที่ได้รับผลกระทบจะถูกเขียนทับทั้งหมด

รูปแบบขยาย (writeblocks(block_num, buf, offset)): เขียน len(buf) ไบต์ -- ไม่จำเป็นต้องเป็นจำนวนบล็อกเต็ม -- เริ่มต้นที่ไบต์ offset ภายในบล็อก block_num ใช้โดย littlefs และระบบไฟล์แบบ byte-addressable อื่น ๆ

ioctl(cmd: int, arg: int) int | None

จุดเข้าควบคุม vfs.AbstractBlockDev มาตรฐาน ถูกเรียกโดยเลเยอร์ระบบไฟล์เมื่อเมานต์/ยกเลิกเมานต์ และทุกครั้งที่ sync ค่า cmd ที่รองรับได้แก่:

  • 1 -- เริ่มต้น คืนค่า 0 หากสำเร็จ

  • 2 -- ยกเลิกการเริ่มต้น คืนค่า 0 หากสำเร็จ

  • 3 -- ซิงก์การเขียนที่รอดำเนินการ คืนค่า 0 (ไดรเวอร์ SDMMC เขียนแบบซิงโครนัส ไม่มีอะไรต้องล้าง)

  • 4 -- คืนค่าจำนวนบล็อกบนดีไวซ์

  • 5 -- คืนค่าขนาดของบล็อกเดี่ยว (512 เสมอ)

  • 6 -- ลบบล็อก (ไม่มีผลบน SD เก็บไว้ตามสัญญา vfs.AbstractBlockDev)

  • 7 -- คืนค่าว่าดีไวซ์รองรับการลบบล็อกหรือไม่ (0 บน SD)

โดยปกติผู้เรียกตรงจะไม่ใช้เมธอดนี้ ไดรเวอร์ระบบไฟล์จะส่งรหัสมาตรฐานทั้งหมดโดยอัตโนมัติเมื่อเมานต์ SDCard แล้ว

init(*args, **kwargs) None

เริ่มต้นอินเทอร์เฟซ SD ใหม่ตั้งแต่ต้น รับอาร์กิวเมนต์เดียวกับคอนสตรักเตอร์ มีประโยชน์สำหรับตรวจจับการ์ดที่เสียบเข้ามาแบบ hot-swap บนบอร์ดที่ไม่มีสัญญาณตรวจจับการ์ด เนื่องจาก present() จะถูกล็อกไว้ตั้งแต่ตอนสร้างออบเจกต์ พอร์ต mimxrt เท่านั้น

deinit() None

ยกเลิกการเริ่มต้นอินเทอร์เฟซ SD โดยปล่อยคอนโทรลเลอร์ SDMMC/USDHC และพินที่ใช้อยู่ ออบเจกต์ SDCard จะใช้งานไม่ได้จนกว่าจะเรียก init() อีกครั้ง ใช้เมื่อต้องการแฟลชการ์ดใหม่จากอินเทอร์เฟซอื่น หรือเพื่อตัดไฟยังช่องเสียบในแอปพลิเคชันที่ใช้แบตเตอรี่ พอร์ต mimxrt เท่านั้น