SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (ModusToolbox)
Loading...
Searching...
No Matches
การเปิดใช้งานจอแสดงผล

Functions

BaseType_t tesaiot_display_init (void)
 จุดเข้าใช้งานสาธารณะจุดเดียว — สร้าง GFX task ก่อน scheduler เริ่มทำงาน; เทียบค่าที่คืนกลับมากับ pdPASS
void tesaiot_display_task (void *arg)
 ตัวเนื้อของ GFX task — ห้ามสร้างเอง ห้ามเรียกเอง

Variables

volatile uint8_t tesaiot_display_ready
 flag บอกสถานะการเปิดใช้งานแบบ 3 ค่า: 0 ยังไม่เสร็จ, 1 จอแสดงผลและ IPC พร้อม, 2 ขึ้นเฉพาะ IPC แบบ headless

Detailed Description

Header: tesaiot_display.h ตัวโค้ดจริงที่อยู่ใน archive (libbento_cm55.a) เป็นเจ้าของการเปิดใช้งาน GFXSS, vg_lite และ LVGL, บัส I2C ของจอแสดงผลและการสัมผัส, GFX task และ — เพราะรัน IPC prologue ก่อนจอแสดงผล — ลำดับการบูตทั้งหมดของ CM55 (ดูคู่มืออ้างอิงของ ipc_core)

variant ที่ใช้ได้
mtb-mpy และ mtb-only

tesaiot_display_ready มี 3 ค่า

0 = ยังไม่เสร็จ, 1 = จอแสดงผลและ IPC ขึ้นแล้ว, 2 = ขึ้นเฉพาะ IPC แบบ headless (พาเนลล้มเหลวแต่เส้นทาง IPC ขึ้นมาได้) ผู้เรียกทั้ง 2 รายที่มีอยู่จริงในของที่ส่งมอบตรวจด้วย == 0 บอร์ดที่เป็น headless จึงเดินต่อไปได้ การตรวจด้วย == 1 จะทำให้ผู้ใช้ไลบรารีค้างอยู่บนบอร์ดที่จอดับ — ซึ่งหลังจากรีเซ็ตด้วยดีบักเกอร์แล้ว บอร์ดทุกตัวเป็นเช่นนั้น

Function Documentation

◆ tesaiot_display_init()

BaseType_t tesaiot_display_init ( void )

จุดเข้าใช้งานสาธารณะจุดเดียว — สร้าง GFX task ก่อน scheduler เริ่มทำงาน; เทียบค่าที่คืนกลับมากับ pdPASS

ข้อกำหนดการเรียกใช้
ลำดับที่ต้องใช้: cybsp_init() แล้ว __enable_irq() แล้วจึงเรียกฟังก์ชันนี้ — ISR (interrupt service routine) ของ DC/GPU ใน GFXSS ถูกต่อสายไว้ระหว่างการเริ่ม task ดังนั้นอินเทอร์รัปต์ต้องเปิดอยู่ก่อน เรียกจาก main() ก่อน vTaskStartScheduler() คือสร้าง GFX task ขึ้นมาเท่านั้น ไม่ได้รันมัน เทียบค่าที่คืนกลับมากับ pdPASS ไม่ใช่ CY_RSLT_SUCCESS เทมเพลตจะล้มเหลวแบบไปต่อไม่ได้ เข้าสู่ลูป LED ที่ต่างกัน (LED1 = cybsp_init ล้มเหลว, LED2 = ฟังก์ชันนี้ล้มเหลว) เพื่อให้แยก 2 กรณีออกจากกันได้ด้วยตา ฟังก์ชันนี้เป็นจุดเข้าใช้งานสาธารณะจุดเดียว คือสร้าง GFX task ซึ่งมี tesaiot_display_task() เป็นตัวเนื้อ แล้วเก็บ handle ไว้ใน rtos_cm55_gfx_task_handle task ตัวนี้เปิดใช้งาน IPC ก่อนจอแสดงผล เพื่อให้ IPC ยังอยู่รอดแม้จอแสดงผลจะล้มเหลว — ซึ่งเป็นเหตุผลที่ tesaiot_display_ready มีค่า 2 ได้
variant ที่ใช้ได้
mtb-mpy และ mtb-only
int main(void)
{
cy_rslt_t result;
#if TESAIOT_ENABLE_FACE_RUNTIME && TESAIOT_ENABLE_FACE_RUNTIME_BOOT
/* Alternate boot mode: launch native Face-ID runtime. */
if (face_mode_runtime_requested()) {
face_mode_launch_runtime();
}
#endif
/* Initialize the device and board peripherals */
result = cybsp_init();
if (CY_RSLT_SUCCESS != result)
{
for (;;) {
Cy_GPIO_Inv(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_PIN);
Cy_SysLib_Delay(50);
}
}
/* Enable global interrupts */
__enable_irq();
/* Hold SCB5 for the bus clear and the display bring-up (released by
* scb5_boot_release_task). The IPC semaphores are already attached:
* cybsp_init() calls Cy_IPC_Sema_Init(IPC0_SEMA_CH_NUM, 0, NULL) on this
* core, and CM33 set up the array before it started CM55. CM33 does not use
* the bus this early, so the wait is only a bound, not an expected delay. */
s_scb5_boot_held = ipc_scb5_lock_wait_us(SCB5_BOOT_LOCK_WAIT_US);
if (pdPASS != xTaskCreate(scb5_boot_release_task, "scb5_boot",
configMINIMAL_STACK_SIZE * 2U, NULL,
tskIDLE_PRIORITY + 1U, NULL)) {
/* Nothing would ever give the bus back: do not hold it. */
if (s_scb5_boot_held) {
ipc_scb5_unlock();
s_scb5_boot_held = false;
}
}
/* Release a display bus that a target is still holding from before a warm
* reset. Must run before the display task initialises SCB5 on these pins,
* and only while this core holds the bus -- toggling the pins under a CM33
* transfer would corrupt it. */
if (s_scb5_boot_held) {
disp_i2c_bus_clear();
}
/* GFX task: GFXSS/LVGL init + IPC + sensorhub UI */
BaseType_t xResult = tesaiot_display_init();
if (pdPASS != xResult) {
for (;;) {
Cy_GPIO_Inv(CYBSP_USER_LED2_PORT, CYBSP_USER_LED2_PIN);
Cy_SysLib_Delay(50);
}
}

◆ tesaiot_display_task()

void tesaiot_display_task ( void * arg)

ตัวเนื้อของ GFX task — ห้ามสร้างเอง ห้ามเรียกเอง

ข้อกำหนดการเรียกใช้
ตัวเนื้อของ GFX task ถูกอ้างถึงเฉพาะในฐานะฟังก์ชันของ task ที่ tesaiot_display_init() สร้างขึ้นเท่านั้น anti-example: ห้ามสร้างมันขึ้นมาเอง ห้ามเรียกมันเอง — GFX task ตัวที่ 2 หมายถึงมีเจ้าของ LVGL 2 ราย มี IPC prologue 2 ชุด และมีการเรียก cm55_ipc_communication_setup() ซ้ำ 2 ครั้ง ผู้ใช้ไลบรารีเรียก tesaiot_display_init() เท่านั้น ไม่เรียกอย่างอื่น
variant ที่ใช้ได้
mtb-mpy และ mtb-only
ตัวอย่าง (เขียนขึ้นเอง — ไม่มี call site ในของที่ส่งมอบจริง)
/* Hand-written externs matching dist/cm55_core/include/tesaiot_display.h
* (included here as declarations only, to keep the example free of that
* header's display include chain): */
extern BaseType_t tesaiot_display_init(void);
extern void tesaiot_display_task(void *arg);
static void bento_ex_tesaiot_display_task(void)
{
/* WRONG:
* xTaskCreate(tesaiot_display_task, "gfx2", 4096, NULL, 1, NULL);
* tesaiot_display_task(NULL); // never returns, no init
*
* RIGHT — the one public entry, from main() pre-scheduler: */
if (tesaiot_display_init() != pdPASS) { /* pdPASS, not CY_RSLT_* */
/* distinct LED failure loop in shipped main(); do not continue
* into vTaskStartScheduler() pretending the display exists */
return;
}
}

Variable Documentation

◆ tesaiot_display_ready

volatile uint8_t tesaiot_display_ready
extern

flag บอกสถานะการเปิดใช้งานแบบ 3 ค่า: 0 ยังไม่เสร็จ, 1 จอแสดงผลและ IPC พร้อม, 2 ขึ้นเฉพาะ IPC แบบ headless

ข้อกำหนดการเรียกใช้
ไม่มี header ที่ส่งมอบมาตัวใดประกาศตัวแปรนี้ (bento_secure_undeclared.h) ผู้ใช้ไลบรารีเป็นผู้เขียน extern volatile uint8_t ของตัวเอง และ volatile เป็นสิ่งที่ต้องมี — เพราะ GFX task เป็นฝ่ายเขียนค่าลงไป ให้วนถามค่านี้จาก FreeRTOS task หลัง scheduler เริ่มทำงานแล้วเท่านั้น โดยใช้ vTaskDelay — ห้ามวนรอแบบ busy spin และห้ามเรียกจาก main() การรอมีขอบเขตเสมอ (150 x 100 ms หรือ 10 000 ms) และเมื่อหมดเวลาให้ผ่านเลยไป ไม่ใช่ค้างรอต่อ มี 3 ค่า: 0 = ยังไม่เสร็จ, 1 = จอแสดงผลและ IPC พร้อม, 2 = ขึ้นเฉพาะ IPC แบบ headless ผู้เรียกทั้ง 2 รายที่มีอยู่จริงในของที่ส่งมอบตรวจด้วย == 0 การบูตแบบ headless จึงเดินต่อไปได้ วัตถุประสงค์ตามที่ผู้เรียกฝั่ง radar ระบุไว้: เลี่ยงการแย่งใช้บัสตอนเริ่มระบบกับการเปิดใช้งาน GFX / IPC
variant ที่ใช้ได้
mtb-mpy และ mtb-only
ตัวอย่าง — app task (เทมเพลต)
static void app_task(void *arg)
{
CY_UNUSED_PARAMETER(arg);
/* Wait for display + IPC initialization to complete
* tesaiot_display_ready: 0=pending, 1=display+IPC, 2=IPC-only (headless) */
extern volatile uint8_t tesaiot_display_ready;
uint32_t wait_count = 0;
while (tesaiot_display_ready == 0)
{
vTaskDelay(pdMS_TO_TICKS(100));
wait_count++;
if (wait_count > 150) {
break;
}
}
ตัวอย่าง — แบบที่กำหนดงบเวลาเป็นมิลลิวินาที (เทมเพลต, radar task)
void tesaiot_radar_task(void *arg)
{
(void)arg;
cy_rslt_t result;
/* Wait until display/IPC core is up to avoid startup bus contention with
* GFX/IPC bring-up on CM55. */
extern volatile uint8_t tesaiot_display_ready;
uint32_t wait_ms = 0U;
while ((tesaiot_display_ready == 0U) && (wait_ms < 10000U)) {
vTaskDelay(pdMS_TO_TICKS(50));
wait_ms += 50U;
}