SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (ModusToolbox)
Loading...
Searching...
No Matches
ภาคผนวก W — แผนที่สัญญาณ

เป้าหมายของหัวข้อนี้

จำแนกให้ออก — ไม่ใช่ทำให้เกิด — รูปแบบอาการ (signature) ของความล้มเหลวทุกแบบที่บอร์ดแสดงได้ เมื่อได้ภาพถ่ายของ LED คำบรรยายหน้าจอ หรือผลบันทึกคอนโซลมา ต้องบอกชื่อสถานะนั้นและไฟล์ที่ทำให้เกิดได้ ที่ใดมีวิธีจำลองอาการอย่างไม่เป็นอันตราย ก็จะให้ไว้ ที่ใดไม่มี ก็จะไม่ประดิษฐ์ขึ้นเอง

ลำดับการทำงานจริงของเฟิร์มแวร์

บทนี้ไม่มีลำดับเดียว แต่เป็นตารางสำหรับเปิดหา สร้างจากสามแหล่งโดยอ้างอิงครบทุกแหล่งได้แก่ ข้อเท็จจริงตั้งต้นเรื่องการปิดเสียง printf บน CM33_NS, ตาราง LED ใน proj_cm55/main.c และรหัสขั้นตอนของจอแสดงผลในตัวควบคุมจอแสดงผลของ CM55 (TESAIoT_KIT_PSE84_AI-Micropython-BentoClaw/proj_cm55/modules/lvgl_display/controller/tesaiot_display.c — คอมไพล์รวมอยู่ใน libbento_cm55.a เทมเพลตส่งมอบ archive (ไฟล์ไลบรารีแบบสแตติก .a) ไม่ได้ส่งไฟล์ซอร์สมาด้วย)

ข้อเท็จจริงตั้งต้น: อะไรพิมพ์ออกมาได้บ้าง

CM33_NS เป็นเจ้าของ UART (proj_cm55/main.c:9-10) บนคอร์นั้นมีชั้นการปิดเสียงอยู่ 3 ชั้น และทำงานจริงเพียงชั้นเดียวเท่านั้น

  1. debug_log_disable.h:26 — ไม่ทำงาน เพราะไม่มีที่ใด -include เข้ามาเลย
  2. #ifdef BOOT_VERBOSE — ไม่มีที่ใดนิยาม BOOT_VERBOSE ไว้ ข้อความพิมพ์ทุกตัวใต้เงื่อนไขนี้จึงคอมไพล์ทิ้งไปทั้งหมด
  3. #define printf(...) ((void)0) เฉพาะไฟล์ — ทำงานจริง ใน 7 ไฟล์: sensor_auto_task.c:36, modules/tesaiot_config/tesaiot_config_store.c:26, modules/tesaiot_config/ipc_tesaiot_handler.c:26, tesaiot_mqtt.c:17, publisher_task.c:28, subscriber_task.c:46, modbentoclaw.c:79

กฎคือ เทียบข้อความให้ตรงตัวและดูรูปแบบการเรียก ห้ามเทียบเพียงคำนำหน้า #define printf(...) แบบฟังก์ชันปิดเสียง printf(...) รูปธรรมดาในไฟล์นั้น แต่ไม่ปิด (printf)(...) ที่ใส่วงเล็บไว้ — ไฟล์ที่ปิดเสียงเหล่านั้นใช้ (printf) โดยเจตนาตรงบรรทัดที่ต้องรอด

คำตัดสิน สัญญาณ อยู่ที่ใด
LIVE [HB] t=lus tasks=u proj_cm33_ns/main.c:110-112 (mtb-only)
LIVE [MPY] GC heap u KB @ p in s mpy_main.c:552-554 (mtb-mpy)
LIVE [BOOT] optiga_psa_register failed: d / [BOOT] psa_crypto_init failed: d main.c:238, :242 — เฉพาะตอนล้มเหลว ความสำเร็จเงียบ
LIVE storage: SMIF setup failed 0x%08lx / storage: mount failed (d); volume left untouched bento_storage.c:108, :131 (mtb-only)
LIVE ERROR: storage unavailable — config and WiFi credentials will use defaults / ERROR: tesaiot_config_init failed main.c:306-308, :310-312 (mtb-only)
LIVE FATAL: Stack overflow in task 's' hook รับ stack overflow ใน main.c
LIVE [MQTT] Connected to broker และบรรทัด [MQTT] อื่น ๆ mqtt_task.c:328-356 การปิดเสียงที่ :39 คอมเมนต์ทิ้งไว้
LIVE [MQTT-Config], [mTLS], [CSR], [DirectPub], [PU-Ingest], [WiFi] (modwifi), [wifi-glue] (ทำงานในระดับ compile-time แต่ไปถึงได้เฉพาะเมื่อมีการเชื่อมต่อที่สั่งจาก BLE ภายใต้ ENABLE_PAGE_BENTO_BUDDY=1), [boot] (ต้องมี ENABLE_PAGE_BENTO_BUDDY=1) ดูบทกลุ่ม C, D, I
LIVE บรรทัด [Subscriber] รูป (printf) subscriber_task.c:169,:186,:203-205,:211,:217,:223,:229
LIVE (printf)("[PUB-TASK] stack_free…") publisher_task.c:76
DEAD [WiFi-Boot], [WiFiIPC] printf ธรรมดาใต้การปิดเสียงที่ sensor_auto_task.c:36
DEAD [TESAIOT_CFG], [TESAIOT_IPC] printf ธรรมดาใต้การปิดเสียง 2 จุดใน tesaiot_config/
DEAD [Subscriber] Subscribing to: / Subscribed (QoS…) printf ธรรมดา, subscriber_task.c:98, :104
DEAD [Publisher] Published to … printf ธรรมดา, publisher_task.c:100
DEAD CM33_NS: Booting CM55..., CM33_NS: CM55 boot initiated, [BOOT] HSM OPTIGA handler OK, แบนเนอร์ PSoC Edge AI MicroPython + WiFi เป็น BOOT_VERBOSE ทั้งหมด
PINNED [PSA-Sign] Using Key OID 0x%04X for TLS CertificateVerify (slot=lu) optiga_psa_se.c:364-365, printf เปล่า ไม่มีการปิดเสียง บ่งบอกว่า มีการพยายามลงลายเซ็น ส่วนความสำเร็จยังต้องไม่มี ERROR: trustm_ecdsa_sign status= ตามมาด้วย

หากเอกสารใด — รวมถึงฉบับเก่ากว่าของเอกสารนี้เอง — บอกให้รอบรรทัดที่เป็น DEAD เอกสารนั้นผิด ไม่ใช่บอร์ดผิด หากต้องการบรรทัด DEAD เพื่อไล่จุดบกพร่องของตนเอง ให้คอมเมนต์การปิดเสียงในไฟล์นั้นทิ้ง (เช่นที่ sensor_auto_task.c:36) แล้ว build ใหม่ นั่นเป็นการแก้ไขเฉพาะไฟล์โดยเจตนา ไม่ใช่ flag

รหัส LED ของ CM55

CM55 ไม่มีคอนโซล proj_cm55/main.c และตัวควบคุมจอแสดงผลจึงใช้ LED ผู้ใช้ 2 ดวง LED1 และ LED2 คือ CYBSP_USER_LED1/CYBSP_USER_LED2

รูปแบบอาการ ความหมาย ที่มา
LED1 สลับสถานะทุก 50 ms (≈10 Hz มองเห็นเป็นการกะพริบราว 20 Hz) cybsp_init() ล้มเหลวบน CM55 proj_cm55/main.c:180-188
LED2 สลับสถานะทุก 50 ms tesaiot_display_init() ไม่ได้คืนค่า pdPASS — สร้าง GFX task ไม่สำเร็จ proj_cm55/main.c:193-199
LED2 สลับสถานะทุก 100 ms สร้าง task ของเรดาร์ไม่สำเร็จ (บอร์ดที่มี BSP_HAS_RADAR) proj_cm55/main.c:206-212
LED1 และ LED2 สลับสถานะทุก 100 ms สร้าง app_task ไม่สำเร็จ proj_cm55/main.c:217-224
LED1 และ LED2 สลับสถานะทุก 500 ms scheduler คืนค่ากลับมา — ซึ่งต้องไม่เกิดขึ้นเลย proj_cm55/main.c:232-237
LED2 กะพริบหนึ่งครั้ง แล้วติดค้าง ขั้นที่ 1 ของจอแสดงผล (Cy_GFXSS_Init) กำลังทำงาน tesaiot_display.c:262-263
LED2 กะพริบเร็ว N ครั้ง วนซ้ำทุก 2 s การเริ่มระบบจอแสดงผล (bring-up) ล้มเหลวที่ขั้นที่ N (ดูตารางถัดไป) โดย IPC ยังทำงานอยู่ (ลูป ipc_only) tesaiot_display.c:135-139, :581-582
LED2 กะพริบ 4 ครั้ง การเขียนไปยัง backlight หรือ MCU ของพาเนลได้รับ NAK ระหว่าง bring-up tesaiot_display.c:432
LED2 ดับ การ init จอแสดงผลสำเร็จครบถ้วน tesaiot_display.c:459-468
LED1 กะพริบเป็นชุดละ 1 ครั้ง hook รับ stack overflow ทำงานบน CM55 proj_cm55/main.c:246-254
LED2 กะพริบเป็นชุดละ 2 ครั้ง hook รับ malloc ล้มเหลวทำงานบน CM55 ที่เดียวกัน
LED1+LED2 กะพริบเป็นชุดละ 3 ครั้ง HardFault บน CM55 ที่เดียวกัน

การนับขั้นของจอแสดงผล (tesaiot_display.c:139 ซ้ำอีกที่ :248)

Steps: 1=GFXSS  2=DC_IRQ  3=GPU_IRQ  4=I2C  5=Panel  6=VGLite

ข้อกำหนดของ LED (tesaiot_display.c:135-138)

OFF              = display init succeeded
ON solid         = display init failed
N quick blinks   = failed at step N (visible during ipc_only loop)

marker บอกความผิดพลาดของ CM55 ใน SRAM

proj_cm55/main.c:246-254 เขียนคำบอกร่องรอยไว้หนึ่งคำที่ 0x28000000 ซึ่งคงอยู่จนกว่าจะตัดไฟแล้วจ่ายไฟใหม่

คำ ความผิดพลาด
0xDEAD0001 stack overflow
0xDEAD0002 malloc ล้มเหลว
0xDEAD0003 HardFault

ให้อ่านค่านี้ด้วยการอ่านหน่วยความจำผ่านดีบักเกอร์ เฉพาะบนบอร์ดที่หยุดแล้วหรือบอร์ดที่แครชแล้วเท่านั้น (mem32 0x28000000 1 ตามคอมเมนต์ในซอร์ส) บน mtb-only การต่อเข้ากับบอร์ดที่ กำลังทำงานอยู่ เป็นความผิดพลาดในตัวมันเอง (ภาคผนวก X #16) — ให้อ่าน marker หลังการแครช ห้ามใช้เป็นการตรวจสภาพเครื่อง

สถานะของหน้าจอ

สิ่งที่เห็น ความหมาย ที่มา
จอดับทันทีหลัง make program โดยยังไม่ได้ตัดไฟจ่ายไฟใหม่ เป็นการรีเซ็ตจากดีบักเกอร์ backlight ยังไม่ได้รับขอบสัญญาณ 0→1 แบบเย็น ไม่ใช่การแฟลชที่ล้มเหลว README ที่ส่งมอบ (ฉบับในไฟล์ zip :47-49; ฉบับ dist mtb-mpy:51-52, mtb-only:54)
จอดับหลังตัดไฟจ่ายไฟใหม่หนึ่งครั้ง โดย [HB] ยังเต้นอยู่ (mtb-only) เป็นอาการ backlight ตอนบูตเย็น ให้ถอดสายแล้วเสียบกลับอีกครั้ง ฉบับ dist mtb-only:55
พื้นสีน้ำเงินเข้มเต็มจอ (0x003366) ไม่มีการ์ด CM55 มาถึงขั้นสร้าง UI แล้ว แต่หน้า Home ยังไม่โหลด tesaiot_display.c:435-443
ตารางการ์ดของหน้า Home พร้อมป้าย v…-mtb_mpy / v…-mtb_only สำเร็จ ป้ายนี้บอกว่า variant ใดกำลังทำงานอยู่จริง page_home.c:485-489
ตารางหน้า Home ปรากฏ แต่หน้าที่เพิ่มเข้าไปเองไม่มีการ์ด ไม่มีรายการใน s_card_defs[] ของ page_home.c (ลงทะเบียนแล้ว แต่ไม่มีการ์ด) บทกลุ่ม F
แตะการ์ดแล้วไม่เกิดอะไรขึ้น มีการ์ดแต่ยังไม่ได้ลงทะเบียนหน้า — pm_navigate มีตัวกัน NULL อยู่แล้วจึงเพิกเฉย (เอกสารเก่าเขียนว่า "crashes" ซึ่งเก่าเกินจริงแล้ว) page_manager.c:92; บทกลุ่ม F
ไอคอน WiFi บน topbar ซ่อนอยู่ / ไม่มีนาฬิกา ยังไม่ได้เชื่อมต่อ / ยังไม่ได้ NTP — ไม่ใช่ความผิดพลาด บท B3

ทีละขั้น

ขั้นที่ 1 — จำแนกผลบันทึกคอนโซล

นำผลบันทึกคอนโซลจากบท A1 มาชุดหนึ่ง สำหรับทุกบรรทัดที่ขึ้นต้นด้วยคำนำหน้าในวงเล็บเหลี่ยม ให้ค้นหาบรรทัดนั้นในตารางที่ ข้อเท็จจริงตั้งต้น: อะไรพิมพ์ออกมาได้บ้าง หากไม่อยู่ในแถว LIVE แสดงว่าสิ่งที่เห็นไม่ใช่ผลลัพธ์ของเฟิร์มแวร์ชุดนี้

สิ่งที่ควรสังเกต
บน mtb-only ผลบันทึกที่ปกติคือบรรทัด [HB] t=lus tasks=u ทุก 10 s เท่านั้น ไม่มีอย่างอื่น บน mtb-mpy จะได้ [MPY] GC heap u KB @ p in s หนึ่งบรรทัดตามด้วยพรอมป์ REPL ส่วนบรรทัด [BOOT] … failed, storage: หรือ ERROR: ใด ๆคือความล้มเหลวจริง และจะถูกพิมพ์ออกมาเสมอ

ขั้นที่ 2 — จำแนกรูปแบบการกะพริบของ LED

นับจำนวนครั้งที่กะพริบและจับจังหวะเวลา แล้วเทียบกับ รหัส LED ของ CM55

สิ่งที่ควรสังเกต
LED2 ดับพร้อมกับตารางหน้า Home ปรากฏ คือความสำเร็จ ส่วน LED2 ที่กะพริบซ้ำ N ครั้งพร้อมจอดับ คือความล้มเหลวที่ขั้นใดขั้นหนึ่งของจอแสดงผลโดยที่ IPC ยังมีชีวิตอยู่ — คอนโซลของ CM33 ยังทำงานได้ และบน mtb-mpy ui._diag() ยังตอบได้ เพราะ IPC pipe ตั้งขึ้นก่อนจอแสดงผล (บท B2)

ขั้นที่ 3 — จำลองอาการเดียวที่ไม่เป็นอันตราย

รูปแบบอาการของความล้มเหลวที่มีวิธีทำซ้ำอย่างปลอดภัยมีเพียงแบบเดียว คือจอดับหลังการแฟลช ให้รัน make program แล้ว ห้ามตัดไฟจ่ายไฟใหม่

สิ่งที่ควรสังเกต
programmer รายงาน verified … bytes พาเนลยังดับอยู่ และบน mtb-only [HB] เริ่มเต้นอยู่ดี (คอร์กำลังทำงาน สิ่งที่ดับคือ backlight) เมื่อตัดไฟแล้วจ่ายไฟใหม่ หน้าจอจะปรากฏ ถึงตรงนี้ก็ได้เห็นสภาพที่ดูเหมือนการแฟลชล้มเหลวมาแล้วอย่างไม่มีอันตราย

ไม่มีการให้วิธีทำซ้ำสำหรับรหัส LED บอกความผิดพลาด marker ใน SRAM หรือลูปจากการต่อดีบักเกอร์ สิ่งเหล่านี้มีไว้จำแนก ไม่ใช่มีไว้ทำให้เกิด

กับดัก

  • ภาคผนวก X #21 — จอดับหลังการแฟลชคือผลของการรีเซ็ต ไม่ใช่ผลของอิมเมจ
  • ภาคผนวก X #22 — backlight ตอนบูตเย็นของ mtb-only อาจต้องถอดสายเป็นครั้งที่สอง
  • ภาคผนวก X #16 — ห้ามต่อดีบักเกอร์เข้ากับบอร์ด mtb-only ที่กำลังทำงานเพื่ออ่าน marker บอกความผิดพลาด ให้อ่านหลังความผิดพลาดเกิดขึ้นแล้ว
  • ภาคผนวก X #1printf บน CM55 กลายเป็น no-op เงียบ ๆ ทันทีที่ลิงก์ libbento_edge_ai.a (ai_engine.c:276-288) การใส่ printf ลงในหน้า CM55 ของตนเองเพื่อ "ดูว่าจะเกิดอะไรขึ้น" จะไม่ได้อะไรออกมาเลย และไม่ใช่สัญญาณของการแครช
  • การเทียบเพียงคำนำหน้า [Subscriber] เป็นได้ทั้ง LIVE และ DEAD ขึ้นกับรูปแบบการเรียกที่บรรทัดนั้น ๆ ให้เทียบข้อความให้ตรงตัว

ขอบเขตการใช้กับแต่ละ variant

variant ที่ใช้ได้
mtb-mpy และ mtb-only ตาราง LED, marker และหน้าจอเหมือนกันทั้งหมด (CM55 ไม่ขึ้นกับ variant) ส่วนแถวของคอนโซลกำกับ variant ไว้เฉพาะจุดที่ต่างกัน และ ui._diag() ในขั้นที่ 2 ของหัวข้อทีละขั้น มีเฉพาะบน mtb-mpy