I've recently started to convert an existing single core (M7) project on an MIMXRT1176 to become a multicore project. The existing project uses USB MSD functionality to save a log to a text file. This functions as expected in the single core project, but in the process of changing the project to multicore, the USB no longer functions as expected.
I've narrowed down the issue to be that the ECHI ISR function in the multicore doesn't get the USB interrupt status or USB error interrupt status, there never sending the transaction done event to the event handler, code snippet that doesn't execute can be found below:
void USB_HostEhciIsrFunction(void *hostHandle)
{
usb_host_ehci_instance_t *ehciInstance;
static uint32_t interruptStatus = 0;
if (hostHandle == NULL)
{
return;
}
ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
interruptStatus = ehciInstance->ehciIpBase->USBSTS;
interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
while (0U != interruptStatus) /* there are usb interrupts */
{
ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */
if (0U != (interruptStatus & USBHS_USBSTS_SRI_MASK)) /* SOF interrupt */
{
}
if (0U != (interruptStatus & USBHS_USBSTS_SEI_MASK)) /* system error interrupt */
{
}
/** PART THAT DOESN'T EXECUTE **/
if ((0U != (interruptStatus & USBHS_USBSTS_UI_MASK)) ||
(0U != (interruptStatus & USBHS_USBSTS_UEI_MASK))) /* USB interrupt or USB error interrupt */
{
(void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE);
}
/** END OF PART THAT DOESN'T EXECUTE **/
if (0U != (interruptStatus & USBHS_USBSTS_PCI_MASK)) /* port change detect interrupt */
{
(void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE);
}
if (0U != (interruptStatus & USBHS_USBSTS_TI0_MASK)) /* timer 0 interrupt */
{
(void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0);
}
interruptStatus = ehciInstance->ehciIpBase->USBSTS;
interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
}
}
On the existing project that works, I can see the Port Change Interrupts, followed by several Transaction Done Interrupts, finally followed by Timer 0 Interrupts for the remainder of the time.
Is there anything known reason why the USBSTS register is not getting the Transaction Done interrupts? It's not hardware as the existing project works on the current hardware, I think I may have missed something in the setup.
Solved! Go to Solution.
The project I posted can be made to work correctly by modifying a few things, this is also the case for my project on our custom carrier board.
In FreeRTOSConfig.h
- Set configAPPLICATION_ALLOCATED_HEAP from 0 to 1.
- Decrease the configTOTAL_HEAP_SIZE from 0x60000 to 0x10000
In the M7 projects settings:
C/C++ Build -> Settings -> MCU Linker -> Managed Linker Script
Change the *(NonCacheable.init) and *(NonCacheable) from NCACHE_REGION to SRAM_DTC_cm7.
The project should work as intended now.
I find this odd as the only thing I had to change on my dual core project with the custom carrier board was the Managed Linker Script, but in the M7 standalone version works with the NonCacheable sections being mapped to the NCACHE_REGION in SDRAM (0x83000000).
Hi @CMoran ,
Was the M7 core still running the working project? is there any other tasks assigned to M7 as well? What does the M4 core run in your new multicore project?
Have a great day,
Kan
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi @Kan_Li,
The existing project that works runs solely on the M7 core. The FreeRTOS tasks consist of:
- LVGL task for our GUI.
- RTC task that updates the global time variable used to display date/time on the GUI.
- GPIB task used to facilitate communication between the device and a PC.
- The application task, used to perform the device functionality.
- USB tasks, using code from the host_msd_fatfs_freertos_cm7 SDK example, is split between 2 tasks, a USB host task and a USB app task.
Now for the multicore project, it has all the same FreeRTOS tasks as the single core M7 project, with the addition of the multicore communication tasks. The core task layout would look like below:
M7 Tasks
- LVGL task for our GUI.
- RTC task that updates the global time variable used to display date/time on the GUI.
- USB tasks, using code from the host_msd_fatfs_freertos_cm7 SDK example, is split between 2 tasks, a USB host task and a USB app task.
- Multicore communication task
M4 Tasks
- GPIB task used to facilitate communication between the device and a PC.
- The application task, used to perform the device functionality.
- Multicore communication task
Our project does run on a custom carrier board using an Embedded Artists iMX RT1176 uCOM system on module. I want to emphasize that the issue isn't hardware because if it was it shouldn't work with the original project. I must be missing a setting or config or something with the memory map.
I will in the meantime try to setup a project the exemplifies the issue on an RT1170-EVK board so that you may also see the issue.
Hi @Kan_Li
I've replicated the issue on the MIMXRT1170-EVK board using the RK055HDMIPI4MA0. In this demo there is the RTC, LVGL, USB, and multicore threads running on the M7, and just the multicore running on the M4. Pushing the button on the touch screen will print to the debug console that the button was pushed on the M7 along with a timestamp from the RTC. The M7 will then send a message to the M4 and the M4 will print out "Hello World". Plugging in a USB to USB1 (SDP) J20 will start the USB interrupts, inside I've added print outs to the USBSTS of the interrupt. I can see the port change interrupt, no transaction complete interrupt, and then the timer 0 interrupts. When unplugging the USB a port change interrupt will fire, along with an enumeration failed.
The project I posted can be made to work correctly by modifying a few things, this is also the case for my project on our custom carrier board.
In FreeRTOSConfig.h
- Set configAPPLICATION_ALLOCATED_HEAP from 0 to 1.
- Decrease the configTOTAL_HEAP_SIZE from 0x60000 to 0x10000
In the M7 projects settings:
C/C++ Build -> Settings -> MCU Linker -> Managed Linker Script
Change the *(NonCacheable.init) and *(NonCacheable) from NCACHE_REGION to SRAM_DTC_cm7.
The project should work as intended now.
I find this odd as the only thing I had to change on my dual core project with the custom carrier board was the Managed Linker Script, but in the M7 standalone version works with the NonCacheable sections being mapped to the NCACHE_REGION in SDRAM (0x83000000).