เกริ่นนำ: จินตนาการว่า STM32 คือ “โรงงานอัจฉริยะ”

สวัสดีครับ ยินดีต้อนรับสู่บทเรียนทฤษฎีที่จะทำให้คุณมองเห็น “ภาพในสมอง” ของ STM32 ได้ชัดเจนขึ้นครับ ในฐานะ Technical Writer ผมจะขอเปลี่ยนเรื่องโครงสร้างสถาปัตยกรรมที่ดูซับซ้อน ให้กลายเป็นเรื่องที่เข้าใจง่ายเหมือนเรากำลังดูผังโรงงานครับ

ระดับความยาก: ⭐⭐⭐ (เนื้อหาเชิงลึกแต่นำไปใช้ประโยชน์ได้จริง) เวลาที่ใช้: ~15 นาที

ถ้าเปรียบ STM32F4 เป็นโรงงานขนาดใหญ่:

  • Cortex-M4 Core: คือ “ผู้จัดการโรงงาน” (CPU) ที่คอยสั่งงาน
  • Flash Memory: คือ “ห้องสมุดคู่มือ” ที่เก็บคำสั่งการทำงาน (Code)
  • SRAM: คือ “โต๊ะทำงาน” ที่วางเอกสารรอการประมวลผล (Variables)
  • Peripherals (GPIO, UART): คือ “แผนกต้อนรับและจัดส่ง” ที่ติดต่อกับโลกภายนอก
  • Bus Matrix: คือ “ระบบถนนและทางด่วน” ภายในโรงงานที่เชื่อมทุกอย่างเข้าด้วยกัน

ความเข้าใจเรื่องถนน (Bus) และแผนที่ (Memory Map) จะทำให้คุณเขียนโค้ดได้มีประสิทธิภาพสูงสุดและแก้ปัญหา Hard Fault ที่ชวนปวดหัวได้ครับ

2. ระบบบัส (Bus Matrix): ถนนหลายชั้น ไม่ใช่แค่เส้นเดียว

หลายคนเข้าใจผิดว่า CPU วิ่งไปหา RAM และ Peripherals บนถนนเส้นเดียวกัน (ซึ่งจะทำให้เกิดคอขวด) แต่ใน STM32F4 (Cortex-M4) ใช้สถาปัตยกรรมแบบ Harvard ที่มีถนนแยกกันชัดเจน และมีชุมทางที่เรียกว่า Multi-AHB Bus Matrix ครับ

2.1 ถนนสายหลักของ CPU (Master Ports)

CPU มี “ขา” หรือพอร์ตเชื่อมต่อหลักๆ 3 เส้นทาง เพื่อให้ทำงานขนานกันได้:

  1. I-Bus (Instruction Bus): ถนนสายด่วนสำหรับวิ่งไปหยิบ “คำสั่ง” จาก Flash เท่านั้น (ห้ามขนของอย่างอื่น)
  2. D-Bus (Data Bus): ถนนสำหรับขนถ่าย “ข้อมูล” (ตัวแปร, Debug) และเชื่อมต่อไปยังหน่วยความจำ CCM (Core Coupled Memory) โดยเฉพาะ เพื่อความเร็วสูงสุด
  3. S-Bus (System Bus): ถนนสายหลักที่วิ่งไปหา Peripherals และ SRAM ทั่วไป

2.2 ชุมทางจราจร (Bus Matrix)

Bus Matrix ทำหน้าที่เหมือน “วงเวียนอัจฉริยะ” ที่ยอมให้ Masters (ผู้สั่งงาน เช่น CPU, DMA1, DMA2) คุยกับ Slaves (ผู้รับคำสั่ง เช่น Flash, RAM, Peripherals) ได้พร้อมกันหลายคู่

Magic Moment: ในขณะที่ CPU กำลังอ่านคำสั่งจาก Flash (ผ่าน I-Bus), ตัว DMA สามารถขนข้อมูลจาก UART ไปเก็บที่ RAM (ผ่าน System Bus) ได้ พร้อมกัน โดยไม่แย่งถนนกัน นี่คือหัวใจของความแรงใน STM32F4 ครับ

3. แผนผังหน่วยความจำ (Memory Map): แผนที่เดียว เที่ยวทั่วไทย (4GB)

มาตรฐาน ARM Cortex กำหนดให้ทุกอย่างอยู่ใน “แผนที่แผ่นเดียว” ขนาด 4GB (32-bit address) ไม่ว่าจะเป็น RAM, Flash หรือขา Pin ต่างๆ ก็มี “บ้านเลขที่” (Address) ของตัวเอง

แผนภาพ Memory Map ของ STM32 แสดงช่วง Address ต่างๆ

โครงสร้างหลักแบ่งเป็นโซนดังนี้:

ช่วง Address (Hex) ชื่อโซน (Region) หน้าที่และการใช้งาน
0x0000 0000 Code (Boot) พื้นที่เริ่มต้นระบบ ปกติจะ Aliased (วาร์ป) ไปยัง Flash หรือ Bootloader
0x0800 0000 Flash Memory บ้านจริงๆ ของ Flash Memory ที่เก็บโปรแกรมของเรา
0x2000 0000 SRAM พื้นที่แรมหลัก (SRAM1, SRAM2) สำหรับเก็บตัวแปรและ Stack
0x4000 0000 Peripherals ที่อยู่ของอุปกรณ์ต่างๆ เช่น GPIO, Timer, UART
0xE000 0000 System โซนหวงห้ามของ CPU เช่น NVIC (ตัวคุม Interrupt) และ Debug

4. การเข้าถึงแบบ Unaligned Access: สะดวกแต่มีราคาที่ต้องจ่าย

ในอดีต (เช่น ยุค ARM7 หรือ Cortex-M0) ถ้าคุณประกาศตัวแปร int (4 bytes) มันต้องวางอยู่ที่ Address ที่หารด้วย 4 ลงตัวเท่านั้น (0, 4, 8, C) ถ้าวางเบี้ยว (เช่น เริ่มที่ 1) จะเกิด Hard Fault ทันที

แต่ Cortex-M3/M4 (STM32F4) ฉลาดกว่านั้นครับ มันรองรับ Unaligned Access

สถานการณ์ตัวอย่าง

สมมติคุณมีตัวแปร uint32_t val (4 bytes) วางอยู่ที่ Address 0x20000001 (เลขคี่ ไม่ลงตัวด้วย 4)

  • Cortex-M0: แจ้ง Error ทันที (Usage Fault) 💥
  • Cortex-M4: อ่านค่าได้ถูกต้อง! ฮาร์ดแวร์จะแอบทำงานเบื้องหลังโดยการอ่าน Memory 2 ครั้ง แล้วเอามาต่อกันให้คุณอัตโนมัติ

ข้อควรระวัง (The Catch) ⚠️

แม้จะทำได้ แต่ “ของฟรีไม่มีในโลก” ครับ:

  1. ช้าลง: เสียเวลา Bus Cycle เพิ่มขึ้นเพราะต้องอ่าน 2 รอบแทนที่จะเป็นรอบเดียว
  2. Atomicity: การอ่านแบบ Unaligned ไม่การันตีว่าเป็น Atomic (อาจถูก Interrupt แทรกกลางระหว่างอ่านไบต์แรกกับไบต์หลังได้)
  3. คำสั่งยกเว้น: คำสั่ง Assembly บางตัว เช่น LDRD (Load Double) หรือ LDM (Load Multiple) ยังคงต้องการ Aligned Address เสมอ ถ้า Compiler เผลอใช้คำสั่งพวกนี้กับข้อมูลที่วางเบี้ยว ก็ Hard Fault ได้ครับ

สรุป: พยายามจัดโครงสร้างข้อมูล (Structure Padding) ให้ลงตัว (Aligned) เสมอ เพื่อประสิทธิภาพสูงสุด แต่ถ้ารับข้อมูลดิบจาก UART ที่เรียงมาแบบติดๆ กัน (Packed) Cortex-M4 ก็ช่วยชีวิตคุณได้โดยไม่ต้องเขียนโค้ดเรียงไบต์เองครับ