14 双核相关¶
14.1 双核资源访问规则¶
1) Hcpu can use all peripheral resources of Lcpu including PB port, I2C, UART, etc. when Lcpu is in the wake-up state;;
2) When Hcpu uses Lcpu peripherals, the macro definitions corresponding to Lcpu peripherals also need to be enabled;,比如Hcpu要使用Lcpu PWM5驱动马达,If GPTIM4 and PWM5 of Lcpu are not enabled in the code, the existing SDK code will turn off this module after Lcpu initialization to save power, causing Hcpu to fail to output PWM5 by operating GPTIM4;;
HAL_RCC_DisableModule(RCC_MOD_GPTIM4);//关闭GPTIM4模块
同理Hcpu needs to perform the same operation when using Lcpu’s I2C, UART, and SPI resources;;
3)56x、52x系列中,The IO of each core can only be configured as the resource owned by that core;
例如:The PA05_I2C_UART function of PA05, this IO can be configured to use any set of I2C or UART, but it must follow the rule that PA port can only specify the I2C resources owned by Hcpu;,比如56x,PA口只能配置属于Hcpu的资源i2c1-i2c4,不能配置为属于Lcpu的资源i2c5-i2c7,
同理Lcpu同理PB口只能配置该核的资源,同样PA05_TIM,这样的PWM配置也需要遵循该原则。
4) Lcpu cannot use Hcpu’s peripheral resources such as PA port, nor can it access Hcpu’s registers; accessing them will cause a Hardfault crash;;
例如:在bsp_pinmux.c,bsp_power.c文件的BSP_PIN_Init,BSP_Power_Up,BSP_IO_Power_Down,等这些Hcpu,Lcpu共用的函数,Operations on the PA port must be placed under the #ifdef SOC_BF0_HCPU macro definition to prevent Lcpu from calling PA’s IO operation functions;。
5) 55x、58x、56x系列SDK配置中,The software has been designed so that whenever Hcpu wakes up, it will also wake up Lcpu. After Hcpu wakes up, it will wake up Lcpu through the HAL_HPAON_WakeCore(CORE_ID_LCPU); function;(52x系列Hcpu/Lcpu分别单独休眠),在Hcpu休眠函数sifli_standby_handler或者sifli_deep_handler中,通过函数HAL_HPAON_CANCEL_LP_ACTIVE_REQUEST;();允许Lcpu进行休眠;
After allowing Lcpu to sleep, if Hcpu accesses Lcpu’s peripheral resources at this time, a Hardfault will also occur;,因此在休眠过程中,要谨慎处理,代码如下:
14.2 大小核通讯通讯接口¶
You can refer to the SparkChips Software Development Kit documentation and check out the two dual-core communication routines ipc_queue and data_service under example\multicore;
14.2.1 Communication can be carried out using the registration and subscription method of datasevice;¶
datas_register(btn_service_name;, &button_service_cb); //#注册按键发布
sensors_service_handle = datas_register("SENSORS_APP", &sensors_service_cb); //#注册sensor发布
datas_push_data_to_client(service, sizeof(action), &action); //#发布消息到客户端
datac_subscribe(key2_button_handle, "btn1", button_service_callback_key2, 0); //#注册订阅
14.2.2 直接通过solution现有的sensor或者ble的IPC机制通讯¶
通过现有的sensor通道:
ipc_send_msg_from_sensor_to_app;(SENSOR_APP_EVENT_BATTERY_IND, sizeof(event_remind_t), &remind_ind); //发消息给Hcpu
ipc_send_msg_from_app_to_sensor;(&msgx); //Hcpu发给Lcpu的sensor
通过现有的ble通道:
ipc_send_msg_from_ble_to_app;(BLE_APP_OTA_RECV_IND, len, (uint8_t *)param); //发消息给Hcpu
ipc_send_msg_from_app_to_ble;(&msgx); //Hcpu发给Lcpu
To debug dual-core communication issues, you can check the specific content of the global structure variable ipc_cxt;
typedef struct
{
bool active; /**< whether the queue is opened, true: opened */
uint32_t data_len; /**< len of data in rx_ring_buffer */
struct circular_buf *rx_ring_buffer;
struct circular_buf *tx_ring_buffer;
ipc_hw_q_handle_t hw_q_handle; /**< handle of hw queue */
ipc_queue_cfg_t cfg; /**< queue configuration */
} ipc_queue_t;
14.3 Jlink(SWD)切换到不同核调试¶
Usage scenario: Jlink connects to debug Lcpu or Ozone online debugs Lcpu while Hcpu is already in sleep mode;
Operation method: Operate the SWSEL bit of the register SWCR in hwp_lpsys_cfg;
SWSEL
0: SWD connected to HCPU
1: SWD connected to LCPU 方法1:When Hcpu is connected to jlink, execute the corresponding \tools\segger\jlink_lcpu_56x.bat batch processing under the SDK directory;
55系列调用jlink_lcpu_a0.bat
55系列调用jlink_lcpu_pro.bat
方法2:在代码中进行修改
//直接寄存器物理地址操作
#define _WWORD(reg,value) \
{ \
volatile uint32_t * p_reg=(uint32_t *) reg; \
*p_reg=value; \
}
_WWORD(0x4004f000, 0x1); // 55X Jlink SW Switch to LCPU
_WWORD(0x4004f000, 0x0); // 55X Jlink SW Switch to HCPU
_WWORD(0x5000f000, 0x1); // 56X,58X Jlink SW Switch to LCPU
_WWORD(0x5000f000, 0x0); // 56X,58X Jlink SW Switch to HCPU
或者指定寄存器操作
hwp_lpsys_cfg->SWCR = 1; // Jlink SW Switch to LCPU
hwp_lpsys_cfg->SWCR = 0; // Jlink SW Switch to HCPU
If Lcpu crashes early after waking up, it is recommended to add it at the entry point of Lcpu wake-up, specifically refer to the 56X standby process, but note that the GPIO configuration needs to be turned on in advance;:
HAL_LPAON_ENABLE_PAD;();//打开Lcpu的GPIO配置
14.4 双核通讯如何判断dataservice队列满导致的死机¶
1) 如下图,Assert occurs within the data_send_proxy function of Lcpu;。
2) Check whether the high 16 bits of read_idx_mirror and write_idx_mirror in tx_ring_buffer are equal, with one low 16 bits being all 0 and the other all 1. Conversely, if the high 16 bits are equal and the low 16 bits are also equal, it means the buffer is empty;。
如下图,The first 16 bits are both 0x01AF, which are equal, and the last 16 bits, one is all 0 and the other is all 1, indicating that the buffer is full, causing the crash;。
3) This kind of crash is usually because the other core (here is Hcpu) has crashed or is busy, causing it to fail to handle dataservice messages in time. It is necessary to investigate the reason for the crash or task busyness of the other core;。