SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (ModusToolbox)
Loading...
Searching...
No Matches
ภาคผนวก X — กับดักและ anti-pattern
variant ที่ใช้ได้
mtb-mpy และ mtb-only

ทะเบียนที่รวบรวมไว้ ทุกรายการอ้างบรรทัดที่เป็นหลักฐานยืนยัน หมายเลขของแต่ละรายการตรงกับเอกสารออกแบบที่ถือเป็นฉบับอ้างอิง เพื่อให้บทต่าง ๆ อ้างถึงด้วยหมายเลขได้

1. printf บน CM55 กลายเป็น no-op เงียบ ๆ ทันทีที่ลิงก์ libbento_edge_ai.a

archive (ไฟล์ไลบรารีแบบสแตติก .a) ตัวนี้นิยาม printf และ puts เป็น no-op stub โดยเจตนา (ai_engine.c:276-288; nm -S รายงาน symbol ชนิด T ขนาด 8 และ 4 ไบต์) UART เป็นของ CM33_NS และ newlib stdio บน CM55 จะไปจับ lock ที่ไม่ใช่ของตนแล้ว panic (ai_engine.c:270-275) printf ใด ๆ ในโค้ด CM55 ที่เขียนเองจะไม่พิมพ์อะไรออกมา และลิงก์ newlib stdio เข้ากับคอร์นี้ไม่ได้ ให้ถือว่า symbol ทั้ง 2 ตัวเป็น link-time ABI hazard ไม่ใช่ API

2. ห้ามส่ง IPC_CMD_TOUCH_RESUME ดิบ ๆ

CM55 ตีความคำสั่งนั้นเป็น touch_disabled = false แบบไม่มีเงื่อนไข ซึ่งยกเลิกการจับการสัมผัส (touch) ที่ task อื่นถืออยู่ และทำให้เกิด OPTIGA_COMMS_ERROR (0x0102) บนบัสที่ใช้ร่วมกัน (ipc_hsm_handler.c:1393-1405) ให้ใช้คู่ optiga_manager_touch_hold()/_release() ที่มีการนับแทน

3. optiga_chip_enter() ไม่ใช่การตรวจว่า init แล้วหรือยัง

ฟังก์ชันนี้จงใจคืนค่า true แม้ manager จะยังไม่เคย init เลย (tesaiot_optiga_manager.c:157-169) ตัวทดสอบว่า "manager ขึ้นแล้วหรือยัง" คือ optiga_manager_lock() การเข้าใจ 2 อย่างนี้สลับกัน คือสาเหตุที่บันทึกไว้ของข้อบกพร่องเรื่องการเข้าถึงโดยไม่ผ่าน gate (ด่านกั้น) หลายกรณี

4. ห้ามเรียก ai_engine_resume_sensor() ทันทีหลัง set_sensor_rate()

ทั้งสองใช้บัฟเฟอร์ s_rate_msg ใน CY_SECTION_SHAREDMEM ร่วมกัน และ Cy_IPC_Pipe_SendMessage ทำงานแบบอะซิงโครนัส memset ที่นำหน้าของ op=1 จึงล้าง op=2 ที่ยังเดินทางอยู่ให้เป็นศูนย์ แล้ว CM33 อ่านได้เป็น PAUSE (ai_engine.c:522-536) resume_sensor ไม่มีผู้เรียกในเฟิร์มแวร์ที่ส่งมอบจริง

5. ห้ามใช้ ai_engine_active() เป็น gate ของ fallback ของโมเดล

active() คือค่า s_current ซึ่งตามหลังคำขออยู่หนึ่ง cold-init เต็ม ๆ ข้อบกพร่องที่บันทึกไว้คือ "select Radar, Load, get Motion" (ai_engine.c:1868-1873) ให้กันด้วย ai_engine_requested() แทน

6. ai_engine_snapshot() ในชุด parallel set ทำให้ผลตรวจจับหาย

เป็นแบบผู้เขียนรายสุดท้ายชนะบน slot เดียว: "a cough detected at 0.94 is overwritten by three 'unlabelled' … The detection is not late, it is gone" (ai_engine.c:1876-1885) ให้ใช้ snapshot_model() ทีละสมาชิกแทน

7. การเรียก ipc_lcd_toggle_panel() แบบตาบอดทำให้สถานะกลับด้าน

ไม่มีรูปแบบ set ที่เป็น idempotent ให้ใช้ ต้องกันด้วย ipc_lcd_is_panel_visible() เสมอ (ipc_core แถวที่ 2, page_playground.c:167-188) คอนโซลกับ widget ใช้ร่วมกันไม่ได้ ต้องเลือกอย่างใดอย่างหนึ่ง

8. การลืม set_container(NULL) ตอนทำลายหน้าคือ use-after-free

lv_screen_load_anim(auto_del) ปลดหน่วยความจำอ็อบเจ็กต์ของหน้านั้น แล้ว IPC handler ที่มาทีหลังจะเขียนลงไปในอ็อบเจ็กต์เหล่านั้น (ipc_core แถวที่ 3, page_playground.c:342-349) ให้ตั้ง container ทั้งสองเป็น NULL ตอนทำลายหน้าโดยเรียงลำดับเหมือนตอนผูก

9. ipc_sensorhub_snapshot ล้าง changed flag

"Safe to call from any task context" แต่ "Clears the 'changed' flags after reading" (ipc_sensorhub.h:66-67) — ต่อหนึ่ง tick มีผู้อ่านได้รายเดียวเท่านั้น UI เก็บ snapshot หนึ่งชุดทุก 33 ms แล้วกระจายต่อ

10. ดัชนีในรายการบน UI ไม่ใช่ดัชนี slot ของ OPTIGA

ให้แปลง SSID → slot ด้วย wifi_saved_find() ก่อนการลบทุกครั้ง (wifi_connect_native.c:118-134) และคืนค่า < 0 เมื่อไม่พบ

11. การเขียนข้อมูลรับรองลงจริง (flush) ของ mtb-mpy ไม่เคยทำงานเมื่อ /main.py วนลูปไม่จบ

wifi_creds_flush_if_dirty มีการเรียกเฉพาะที่ mpy_main.c:709 และ :686 (ตอน REPL ว่างหรือตอนออก) โปรแกรมที่ไม่เคยคืนกลับสู่ REPL จึงไม่เคยเก็บข้อมูลรับรองไว้อย่างถาวรเลย ส่วน mtb-only เขียนทันที (sensor_auto_task.c:784-789 เทียบกับ :828-854)

12. bundle ของ Protected Update ที่ค้างแบบ retained จะเล่นซ้ำ

bundle ที่ค้างแบบ retained จะมาถึงทุกครั้งที่เชื่อมต่อ พบมาแล้ว 3 ครั้งเมื่อ 2026-08-07 โดยทำงานของรอบก่อนซ้ำอย่างเงียบ ๆ trustm_current_correlation_id() == NULL หมายความว่าไม่มีงานค้างอยู่ — ให้ ทิ้ง (tesaiot_pu_ingest.c:752-768) ที่จุดซึ่งใช้ symbol แบบ weak ให้ตรวจพอยน์เตอร์ฟังก์ชันก่อน แล้วจึงตรวจข้อความ

13. timeout ของ I2C ที่ไม่มีขอบเวลาบนบัสจอแสดงผลที่ใช้ร่วมกัน ทำให้ CM55 อดทำงาน

GFX task ทำงานที่ MAX−1 อุปกรณ์ที่ค้างและยืดสัญญาณนาฬิกา เมื่อมาพร้อม timeout ของ PDL แบบบล็อกตลอดกาล เคยทำให้ task ของ CM55 ที่ priority ต่ำกว่าทั้งหมดอดทำงาน ให้ใช้ timeout ที่มีขอบเวลา (2 ms) กับ disp_touch_i2c_controller_context (cm55_sensor_poll.c:49-53)

14. ลำดับเลข (ordinal) ของ PAGE_ID เป็น ABI ที่ฝังอยู่ใน libbento_ipc.a

page_id_ordinal_assert.c:22-25; lib/ipc_core/PROVENANCE.txt บันทึกไว้ว่า PAGE_ID_PLAYGROUND == 7 หากไม่ตรงกัน จะเชื่อม (link) ผ่านอย่างสะอาดแล้วไปเทียบกับหน้าที่ผิด ให้เพิ่มต่อท้ายเท่านั้น ห้ามเปลี่ยนเลขลำดับ และห้ามเปลี่ยนตัวกันของรายการเดิม

15. cfg.port เก็บไว้แต่ไม่ได้ใช้

พอร์ตของ MQTT คำนวณมาจาก tls_mode (mqtt_client_config.c:105-118) การแก้ port ใน /.tesaiot_config ไม่ทำให้อะไรเปลี่ยน

16. การต่อดีบักเกอร์ทำให้ CM33 ของ mtb-only ที่กำลังทำงานค้างอยู่ในลูปของ boot ROM

main.c:278-287 สัญญาณชีพ (heartbeat) มีอยู่เพราะ variant นี้ไม่มีเครื่องมือวัดใดที่ "that is not also the murder weapon" ให้แฟลชแล้วตัดไฟจ่ายไฟใหม่ ห้ามต่อเข้ากับบอร์ดที่กำลังทำงานอยู่

18. ผู้เขียนข้อมูลรับรอง 2 รายที่ไม่ได้จับ lock ทำให้เกิด race condition กับไฟล์ LFS ได้

modwifi.c:261-285 และ wifi_init.c:261-302 ทำ read-modify-write กับไฟล์นั้นโดยตรงโดยไม่จับ wifi_creds_lock และข้าม g_boot_wifi_creds ไป ไม่มี lock ระดับไฟล์อยู่นอกเหนือจาก bs_lock() ของ mtb-only (J8 thin-evidence #6)

19. symbol ของ HSM ที่ใช้แบบ weak ต้องตรวจ NULL ที่พอยน์เตอร์ก่อนเรียก

ฟังก์ชัน tesaiot_hsm 6 ตัวจากทั้งหมด 18 ตัว เชื่อม (link) เข้ามาเฉพาะภายใต้ ENABLE_OPTIGA_CLM=1 และผู้เรียกใช้ในรูป weak symbol ได้แก่ publish_csr, tesaiot_publish_protected_update, trustm_reset_state, trustm_current_correlation_id, trustm_requested_target_oid, trustm_requested_anchor_oid (คำนำของหัวข้อ A.5; ข้อความปฏิเสธที่ ipc_hsm_handler.c:2158-2161)

20. bento_buddy_auto_start_install มีของใหม่มาแทนแล้ว

task รุ่นเก่าข้ามขั้น init ของ WL_REG_ON / WCM ที่ CYW55513 ต้องการ (main.c:344-347) ไม่มีผู้เรียกที่ใดเลย ให้ใช้ install_chip_power_then_ble() แทน

21. ตัดไฟแล้วจ่ายไฟใหม่หลังการแฟลชทุกครั้ง

การรีเซ็ตจากดีบักเกอร์ทำให้จอดับ ซึ่งดูเหมือนการแฟลชที่ล้มเหลวทุกประการ (README ในแพ็กเกจที่ส่งมอบ: ฉบับ dist mtb-mpy :51-52, mtb-only :54; ฉบับในไฟล์ zip :47-49) อธิบายไว้ในบท A1/A2 ที่จุดตรวจแรก จอดับหลังการแฟลช = การรีเซ็ต ไม่ใช่ความล้มเหลว

22. ไฟส่องหลังจอ (backlight) ตอนบูตเย็น (mtb-only)

backlight อาจต้องการการถอดสายแล้วเสียบกลับอีกครั้งหนึ่งเมื่อบูตเย็น (README ฉบับ dist ของ mtb-only :55) จอที่ดับหลังตัดไฟแล้วจ่ายไฟใหม่ยังไม่ใช่หลักฐานว่าอิมเมจเสีย

23. ช่องว่างต่อท้ายใน bsp_features.mk ทำให้คุณสมบัตินั้นหายไปเงียบ ๆ

ค่าต้องเป็น 1 หรือ 0 เปล่า ๆ เท่านั้น Makefile ที่นำค่าไปใช้เทียบด้วย ifeq ($(VAR),1) ซึ่งไวต่อช่องว่าง ดังนั้น BSP_HAS_CAPSENSE=1 (หรือคอมเมนต์ต่อท้ายค่าในบรรทัดเดียวกัน) จะประเมินได้เป็นเท็จ และ INCLUDES/CFLAGS ของคุณสมบัตินั้นจะหายไปโดยไม่มี error ที่ใดเลย — build สำเร็จ แต่เซนเซอร์ไม่มีอยู่เฉย ๆ ไฟล์นั้นระบุกฎข้อนี้ไว้เอง (bsp_features.mk:28-30 และย้ำอีกครั้งที่ :55-57) อธิบายไว้ใน flag ของ BSP ตามที่บอร์ดนี้ตั้งไว้