LPC55s28 SDK USB example are not working with -O2 optimization level

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

LPC55s28 SDK USB example are not working with -O2 optimization level

跳至解决方案
3,268 次查看
emblink182
Contributor III

Hello, I have an issue with the SDK USB examples code on the LPC55S28 dev board.

The default optimization level on Release builds is set to -Os, and with it, the examples are working fine.

However, when I change the optimization level to -O2 examples stop working. USB FS/HS device can't enumerate.

For demonstration, I took lpcxpresso55s28_dev_hid_generic_freertos, because I have to use RTOS in my application, but I believe this issue applies to bare metal and other USB examples also.

No code changes were made to the example.

All manipulations were done on the latest SDK and MCUXpresso IDE version, all of my board and project settings are attached.

Please help to solve this issue.

标签 (1)
0 项奖励
回复
1 解答
3,188 次查看
emblink182
Contributor III

Hi @HangZhang 

Thanks for the search direction, I found the solution. It turned out that this bug was reported previously back in 2021, by @cgarcia in this post

But his fix wasn't added in the SDK for some reason.

Please add it, cause all of the USB examples have the same issue for HS and FS.

 

#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS)
    CLOCK_EnableClock(kCLOCK_Usbh1);
    /* Put PHY powerdown under software control */
    volatile uint32_t registerAddress = USBHSH_BASE + 0x50; // TODO: Add
    *((uint32_t *)(registerAddress)) = USBHSH_PORTMODE_SW_PDCOM_MASK; // TODO: Add 
    //TODO: REMOVE *((uint32_t *)(USBHSH_BASE + 0x50)) = USBHSH_PORTMODE_SW_PDCOM_MASK;
    /* According to reference mannual, device mode setting has to be set by access usb host register */
    *((uint32_t *)(registerAddress)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK; // TODO: Add
    //TODO: REMOVE *((uint32_t *)(USBHSH_BASE + 0x50)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
    /* enable usb1 host clock */
    CLOCK_DisableClock(kCLOCK_Usbh1);
#endif
#if (defined USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS)
    POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
    CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
    /* enable usb0 host clock */
    CLOCK_EnableClock(kCLOCK_Usbhsl0);
    /*According to reference mannual, device mode setting has to be set by access usb host register */
    //TODO: REMOVE*((uint32_t *)(USBFSH_BASE + 0x5C)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
    volatile uint32_t registerAddress = USBFSH_BASE + 0x5C; // TODO: Add
    *((uint32_t *)(registerAddress)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK; // TODO: Add
    /* disable usb0 host clock */
    CLOCK_DisableClock(kCLOCK_Usbhsl0);
#endif

 

在原帖中查看解决方案

0 项奖励
回复
11 回复数
1,826 次查看
Swetha123
Contributor I

Hello, Greetings.
I need to optimize my project at the O3 level for LPC5516 board, which uses HS-USB.
The fact that USB is not identified in the device manager after O3 and O2 optimization indicates that USB is not working.
Please assist with helping me resolve this issue.

0 项奖励
回复
1,822 次查看
emblink182
Contributor III
Hi Swetha123, have you tried the solution code posted on this topic?
0 项奖励
回复
1,806 次查看
Swetha123
Contributor I

Hello, emblink182. I appreciate your speedy response.
We tried the recommended solution but saw no progress.
Even using the SDK "lpcxpresso55s16_dev_cdc_vcom_freertos" with O3 and O2 optimization did not work.
SDK Version: 2.14.0.
Manifest version: 3.13.0.
IDE version: MCUXpresso IDE 11.8.0 [Build 1165] [2023-07-26]
I've attached the source file for reference.

0 项奖励
回复
1,778 次查看
emblink182
Contributor III

Hi Swetha123, I don't have a 55s16 board so I can't debug your project. But looks like there is a typo in the code, please check the screenshots attached. I tried the same modifications on my 55s28 board and they worked fine with -O2 and -O3.

0 项奖励
回复
1,659 次查看
Swetha123
Contributor I

Hello, emblink182

Apologies for the delayed response. After correcting the typo once more, we were able to run the USB SDK at the O2 level, but the O3 level is still not functioning.
The same piece of solution was patched to the project where HS-USB operates, however it still fails in O2 and O3.

However, in the project, we discovered that USB began to function at the O2 level when the usb initialization function was called from the main accessible in the USB source file "virtual_com.c", but failed when the usb initialization function was called from the main produced in our project.

0 项奖励
回复
1,639 次查看
emblink182
Contributor III
Hi Swetha123, I think it's something related to your specific project because my 55s28 board has the same USB hardware and uses the same SDK driver as yours 5516. Try to narrow down the search by using the technique suggested in this topic. Apply these preprocessor directives to suspected files or functions.

#pragma GCC push_options

#pragma GCC optimize ("O0")

#pragma GCC pop_options
0 项奖励
回复
3,234 次查看
frank_m
Senior Contributor III

To be honest, IMHO this is a common occurence.
Most vendor-supplied free libraries are not fit for aggressive optimisations, and robust commercial deployment. These libraries are churned out in far too much variants and too short timeframe to allow for proper (and costly) testing.
And in my experience this applies to all other vendors, too.

The "-O2" optimisation is a general setting. You could try to disable certain specific optimisations implied by O2, and see if it works.
Or you can try to debug the code, which could be quite surprising and confusing with high optimisation.
One common mistake is for instance the neglect of declaring all variables written to in interrupts as "volatile".

In rare cases high optimisation settings expose compiler bugs, but I think this is rather unlikely in this case.

0 项奖励
回复
3,222 次查看
emblink182
Contributor III

Hi frank_m

So far most of their examples worked great, which means they tested them. But if all SDK USB examples simply do not work with the -O2, it means they didn't test this case at all, and should look at this problem.

-O2 is not something rare it's a common optimization for production code. My code requires it.

LPC MCUs aren't the cheapest on the market, and many devices are built on these platforms, so decent testing, support, and bug fixing are expected in this case.

0 项奖励
回复
3,203 次查看
HangZhang
NXP Employee
NXP Employee

Hi @emblink182 

I tested lpcxpresso55s28_dev_hid_generic_freertos, the project with optimization level ' -O2' can not work.

I have work around, you can try. I change the hig_generit.c optimization level to -O0, it can work.

Another way, in hig_generit.c, you can

 

#pragma GCC push_options

#pragma GCC optimize ("O2")

 

main{}

 

#pragma GCC pop_options

 

 It also can work.

And I will report this issue to our SDK team.

 

Best regards,

Hang

3,189 次查看
emblink182
Contributor III

Hi @HangZhang 

Thanks for the search direction, I found the solution. It turned out that this bug was reported previously back in 2021, by @cgarcia in this post

But his fix wasn't added in the SDK for some reason.

Please add it, cause all of the USB examples have the same issue for HS and FS.

 

#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS)
    CLOCK_EnableClock(kCLOCK_Usbh1);
    /* Put PHY powerdown under software control */
    volatile uint32_t registerAddress = USBHSH_BASE + 0x50; // TODO: Add
    *((uint32_t *)(registerAddress)) = USBHSH_PORTMODE_SW_PDCOM_MASK; // TODO: Add 
    //TODO: REMOVE *((uint32_t *)(USBHSH_BASE + 0x50)) = USBHSH_PORTMODE_SW_PDCOM_MASK;
    /* According to reference mannual, device mode setting has to be set by access usb host register */
    *((uint32_t *)(registerAddress)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK; // TODO: Add
    //TODO: REMOVE *((uint32_t *)(USBHSH_BASE + 0x50)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
    /* enable usb1 host clock */
    CLOCK_DisableClock(kCLOCK_Usbh1);
#endif
#if (defined USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS)
    POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
    CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
    /* enable usb0 host clock */
    CLOCK_EnableClock(kCLOCK_Usbhsl0);
    /*According to reference mannual, device mode setting has to be set by access usb host register */
    //TODO: REMOVE*((uint32_t *)(USBFSH_BASE + 0x5C)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
    volatile uint32_t registerAddress = USBFSH_BASE + 0x5C; // TODO: Add
    *((uint32_t *)(registerAddress)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK; // TODO: Add
    /* disable usb0 host clock */
    CLOCK_DisableClock(kCLOCK_Usbhsl0);
#endif

 

0 项奖励
回复
3,207 次查看
frank_m
Senior Contributor III

> So far most of their examples worked great, which means they tested them. But if all SDK USB examples simply do not work with the -O2, it means they didn't test this case at all, and should look at this problem.

> LPC MCUs aren't the cheapest on the market, and many devices are built on these platforms, so decent testing, support, and bug fixing are expected in this case.

The problem is, what effort can you expect for free ?
Take the large number different MCUs and variants into account that require support.
Being involved with safety-related applications and code, efforts for testing, validating and documenting is a multiple of the time required for coding. A few years ago, my company purchased licenses for a safety-certified RT-OS for a six-figure sum - assessing this to be cheaper than developing it ourselves. 

> -O2 is not something rare it's a common optimization for production code. My code requires it.

You have two options, I would say.
The first one is to locate the bug, and try to fix it. This might take some time, effort and experience.
The second option is to lower the bar. You could reduce the optimisation level to e.g. "-O1". This can be done on file level, and with some effort even on function level.
Or, you can get into optimisation details.
As said, "-O1" and "-O2" are just overall settings, that switch a number of individual optimisations on or off. Here the meaning for the GCC : https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
You can try to leave O2 active and explicitly disable individual optimisations until the code works fine.