Virtual-Connectivity-Manager (VCM) is a library that enables connectivity libraries to add multi-core support through virtualization. Virtualization allows the connectivity stack running on one core to be accessed from another core using Inter-Processor Communication (IPC). With VCM, the connectivity stack can be run on two cores, where one core contains the full connectivity stack (primary core) and the other core contains a subset of virtual-only APIs (secondary core).
Internally, VCM uses IPC to send API requests from the secondary core to the primary core where the API is executed, and then the result is sent back to the secondary core. This makes it seem like the API was executed on the secondary core itself. VCM simplifies the process of adding multi-core support by hiding the details of IPC from both the connectivity libraries and the end application.
Features and functionality
The current implementation has the following features and functionality:
- Supports the following WCM virtual APIs:
- cy_wcm_is_connected_to_ap
- cy_wcm_register_event_callback
- cy_wcm_deregister_event_callback
- Supports the following MQTT virtual APIs:
- cy_mqtt_get_handle
- cy_mqtt_register_event_callback
- cy_mqtt_deregister_event_callback
- cy_mqtt_subscribe
- cy_mqtt_unsubscribe
- cy_mqtt_publish
Supported platforms
This library and its features are supported on the following Infineon platforms:
Dependent libraries
This library is not bundled as part of any other library by default.
Quick start
- Define the following compile-time macro in the project Makefile of primary core side:
DEFINES+=ENABLE_MULTICORE_CONN_MW
- Define the following compile-time macros in the project Makefile of secondary core side:
DEFINES+=ENABLE_MULTICORE_CONN_MW USE_VIRTUAL_API
- To use MQTT virtual APIs, define the following compile-time macro in the project Makefile of both cores:
- Call the cy_vcm_init() function provided by the VCM library in both the projects.
- Note
- - To ensure that the VCM initialization is synchronized, the project which boots first (i.e., CM0+ project in case of psoc62) must call cy_vcm_init before it brings up the second project (i.e., CM4 project in case of psoc62).
-
- The first project must initialize VCM by passing config.hal_resource_opt as CY_VCM_CREATE_HAL_RESOURCE in cy_vcm_init. The second project must pass config.hal_resource_opt as CY_VCM_USE_HAL_RESOURCE.
-
- VCM initialization can also be done in any order from any core provided that the first project initializing VCM sets config.hal_resource_opt as CY_VCM_CREATE_HAL_RESOURCE in cy_vcm_init and the second project sets config.hal_resource_opt as CY_VCM_USE_HAL_RESOURCE. In this case synchronizing VCM initialization between the two cores will be the responsibility of the application. If not synchronised correctly, this can lead to unexpected behaviour.
- VCM utilizes HAL IPC queue resource to perform inter-core communication. Each HAL IPC queue is associated with a channel number and queue number. For a given channel number (provided by the application during VCM initialization), VCM uses queue numbers in the range of 1-7 which should not be used by the application while using VCM.
Channel Number | Queue Number |
Any IPC Channel configured by the application for VCM | 1-7(Reserved by VCM) |
- Note
- The application cannot use queue numbers 1-7 for the configured channel number, as they are reserved for VCM.
- VCM utilizes one of the IPC queues to send asynchronous event callback data from the primary core to the secondary core. By default, the size of this queue is set to 20. However, if the application expects to receive event callbacks in the secondary core in large bursts, this queue size can be modified to avoid queue overflow. To customize the event queue size, define and set the CY_VCM_EVENT_QUEUE_SIZE macro in the Makefile of the project which initializes VCM with config.hal_resource_opt as CY_VCM_CREATE_HAL_RESOURCE. For e.g., the Makefile entry for updating the queue size to 25 would be as follows:
DEFINES+=CY_VCM_EVENT_QUEUE_SIZE=25
Enable debug logs in VCM library
Enable VCM log messages
The VCM library disables all the debug log messages by default. To enable log messages, the application must perform the following:
- To enable VCM logs in a dual-core application, add the
ENABLE_VCM_LOGS
macro to the DEFINES in the project Makefile. Depending on where the VCM logs need to be enabled, you can add this macro to either side of the project Makefile.
- Call the cy_log_init() function provided by the cy-log module. cy-log is part of the connectivity-utilities library. See connectivity-utilities library API documentation.
Enable logs in dual core application
To enable debug log messages on both cores, the application needs to reserve two distinct UART ports. If you are using one of Infineon's BSPs for the connectivity application, you can use the on-board KitProg3 USB-UART COM port to print debug logs for one core. However, you still need another USB-UART bridge to print debug logs for the other core.
- One core can use the default CYBSP_DEBUG_UART_TX and CYBSP_DEBUG_UART_RX pins to enable the SCB block for KitProg3 using the retarget-io library.
cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
- The other core can use any of the remaining SCB blocks to select the appropriate TX and RX pins. These TX and RX pins can be configured using the retarget-io library.
- For example, in the CY8CEVAL-062S2-MUR-43439M2 board, the following pins can be configured for an additional UART port.
- P13.4 and P13.5 (CYBSP_MIKROBUS_UART_RX, CYBSP_MIKROBUS_UART_TX)
- P5.4 and P5.5 (CYBSP_D4, CYBSP_D5)
cy_retarget_io_init(CYBSP_D5, CYBSP_D4, CY_RETARGET_IO_BAUDRATE);
- For the second core, the selected TX and RX pins can be connected to an external USB-UART bridge (FTDI) using jumper wires, which will be emulated as a UART COM port.
Code snippets
Snippet 1: Initialize VCM
The following snippet demonstrates how to initialize the VCM library on two cores.
static volatile bool is_vcm_init_complete = false;
{
switch(event)
{
{
is_vcm_init_complete = true;
break;
}
default:
break;
}
}
void snippet_vcm_init_sec_core()
{
cy_rslt_t result;
config.
event_cb = vcm_callback_sec_core;
if(result != CY_RSLT_SUCCESS)
{
printf("\n cy_vcm_init failed on core 1....!\n");
}
Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
while ( !is_vcm_init_complete )
{
cy_rtos_delay_milliseconds(1000);
}
}
{
switch(event)
{
{
break;
}
default:
break;
}
}
void snippet_vcm_init_prim_core()
{
cy_rslt_t result;
config.
event_cb = vcm_callback_prim_core;
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_vcm_init failed on the primary core....!\n");
}
}
cy_vcm_event_t
Virtual-Connectivity-Manager event type.
Definition: cy_vcm.h:75
@ CY_VCM_EVENT_INIT_COMPLETE
Event generated on the core which initializes VCM first when VCM initialization is complete on both c...
Definition: cy_vcm.h:76
@ CY_VCM_EVENT_DEINIT
Event generated on a core when the other core initiates VCM de-initialization.
Definition: cy_vcm.h:77
@ CY_VCM_CREATE_HAL_RESOURCE
Option to be set during cy_vcm_init in the core which initializes VCM first.
Definition: cy_vcm.h:86
@ CY_VCM_USE_HAL_RESOURCE
Option to be set during cy_vcm_init in the core which initializes VCM second.
Definition: cy_vcm.h:87
cy_rslt_t cy_vcm_init(cy_vcm_config_t *config)
Initializes the virtual connectivity manager.
Virtual-Connectivity-Manager config structure.
Definition: cy_vcm.h:124
cy_vcm_event_callback_t event_cb
Callback function which receives the VCM events.
Definition: cy_vcm.h:127
cy_vcm_hal_resource_opt_t hal_resource_opt
This is used to identify the core that should create the HAL resources.
Definition: cy_vcm.h:125
uint32_t channel_num
IPC channel number passed by user during initialization (e.g.
Definition: cy_vcm.h:126
Snippet 2: Deinitialize VCM
The following snippet demonstrates how to deinitialize the VCM library from two cores.
static bool is_vcm_deinit_requested_1 = false;
{
cy_rslt_t result;
switch(event)
{
{
is_vcm_deinit_requested_1 = true;
break;
}
default:
break;
}
}
void snippet_vcm_deinit_sec_core()
{
cy_rslt_t result;
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_vcm_deinit failed on core 1!...\n");
}
}
static bool is_vcm_deinit_requested = false;
{
cy_rslt_t result;
switch(event)
{
{
is_vcm_deinit_requested = true;
break;
}
default:
break;
}
}
void snippet_vcm_deinit_prim_core()
{
cy_rslt_t result;
while( !is_vcm_deinit_requested )
{
cy_rtos_delay_milliseconds(1000);
}
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_deinit failed on primary core! \n");
return;
}
}
cy_rslt_t cy_vcm_deinit()
De-initializes the virtual connectivity manager.