Dual-Core Comprehensive Example
Source code path: example/get-started/dualcore
Supported Platforms
This example can run on the following development boards:
sf32lb52-lcd_n16r8
eh-lb561
ec-lb587
eh-lb523
Overview
This example demonstrates how to develop dual-core applications. The project supports Bluetooth and low power consumption, builds user interface based on LVGL v8 (referencing multimedia/lvgl/watch
), with HCPU and LCPU running their respective programs (SF32LB52 series chips’ LCPU is dedicated to Bluetooth and does not run user programs).
Directory Structure
.
└── hmi_demo
├── project
│ ├── hcpu // HCPU project directory
│ └── lcpu // LCPU project directory
└── src
├── hcpu // HCPU code directory
└── lcpu // LCPU code directory
Example Usage
Compilation and Flashing
Switch to the project/hcpu
directory and run the scons command to compile:
scons --board=sf32lb52-lcd_n16r8 -j32
Run build_sf32lb52-lcd_n16r8_hcpu\uart_download.bat
, select the port as prompted to download:
Executing the scons
command in the HCPU project directory will automatically compile the LCPU project, and the download script will download all firmware including the LCPU.
Code Analysis
Build Script
Since LCPU is used, you need to add the following code to project/hcpu/SConstruct
to include the LCPU project in the build. For SF32LB52X
, because the LCPU is dedicated to Bluetooth and does not support custom projects, you should directly use the AddLCPU
command to add the common LCPU project.
For other chip series, use the AddChildProj
command to add the project under the lcpu
directory as a subproject in the build.
# Add LCPU project
if not GetDepend('SOC_SF32LB52X'):
lcpu_proj_path = '../lcpu'
lcpu_proj_name = 'lcpu'
AddChildProj(lcpu_proj_name, lcpu_proj_path, True, core="LCPU")
else:
# use common LCPU project
AddLCPU(SIFLI_SDK, rtconfig.CHIP)
HCPU
The HCPU’s main
function is in src/hcpu/main.c
, completing Bluetooth initialization:
int main(void)
{
int count = 0;
app_env_t *env = ble_app_get_env();
env->mb_handle = rt_mb_create("app", 8, RT_IPC_FLAG_FIFO);
sifli_ble_enable();
env->time_handle = rt_timer_create("app", app_timeout_handler, NULL,
rt_tick_from_millisecond(BLE_APP_TIMEOUT_INTERVAL), RT_TIMER_FLAG_SOFT_TIMER);
#ifdef SF32LB52X
env->rc10k_time_handle = rt_timer_create("rc10", rc10k_timeout_handler, NULL,
rt_tick_from_millisecond(15 * 1000), RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); // 15s
rt_timer_start(env->rc10k_time_handle);
#endif
while (1)
{
uint32_t value;
int ret;
rt_mb_recv(env->mb_handle, (rt_uint32_t *)&value, RT_WAITING_FOREVER);
if (value == BLE_POWER_ON_IND)
{
env->is_power_on = 1;
env->conn_para.mtu = 23; /* Default value. */
ble_app_service_init();
/* First enable connectable adv then enable non-connectable. */
ble_app_advertising_start();
LOG_I("receive BLE power on!\r\n");
}
}
return RT_EOK;
}
Graphics initialization is triggered by app_watch_init
in src/hcpu/gui_apps/watch_demo.c
, which is registered as an APP
level automatic initialization function, executing earlier than the main
function in main.c
. In app_watch_init
, the app_watch
thread is created, and graphics initialization is actually completed in the app_watch
thread.
INIT_APP_EXPORT(app_watch_init);
LCPU
The LCPU’s main
function is in src/lcpu/main.c
, as follows:
int main(void)
{
if (HAL_LXT_DISABLED())
{
rc10k_time_handle = rt_timer_create("rc10", rc10k_timeout_handler, NULL,
rt_tick_from_millisecond(15 * 1000), RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); // 15s
RT_ASSERT(rc10k_time_handle);
rt_timer_start(rc10k_time_handle);
}
while (1)
{
rt_kprintf("main loop\n");
rt_thread_mdelay(3000);
}
return RT_EOK;
}
Expected Results
After power-on, a honeycomb interface appears. Clicking the clock icon opens the watch face. If there is no operation on the interface or button press for 10 seconds, the screen will automatically turn off. At this time, the HCPU sleeps and enters low power mode. Button (Key1) wakes up the HCPU and turns on the screen.