Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12606 Discussions

NIOS II - FW doesn't work with compiler optimization turned on

naand
Beginner
1,075 Views
Dear support team,
 
I have a problem with the behavior of the firmware if the project is built in release mode with optimization enabled.
The problem occurs during the write-to-flash routine. I use Generic Serial Flash Interface Intel® FPGA IP and was inspired by the intel_generic_serial_flash_interface_top example to create the code to write a block of data to the Flash. In the example, the memcpy function transfers data into the Flash. I don't know if the critical point of the function is the memcpy, but if optimization is turned on, the firmware seems to perform no write operation to the Flash: the function returns no errors, so it makes me believe that everything was executed correctly, but after a check, there wasn't the expected data in memory. While with the same code built with optimization turned off, the firmware works properly.
The flash_write_function, which generates the problem, is attached. 
 
My questions are:
  1. Why this behavior?
  2. Is it possible to use memcpy as a write function on Flash?
  3. Is it possible to turn off optimization for a block of code?
 
I'm using:
  • Quartus Prima Version 20.1.1
  • Nios II/f processor
  • Eclipse IDE (version: Mars.2 Release (4.5.2) - build id: 20160218-0600)
  • Toolchain used:
naand_0-1711546924941.png

 

The NIOS data cache is disabled, whereas the instruction cache is enabled (see below). I use only the IORD and IOWR functions to perform registers and peripherals accesses.

naand_1-1711546964158.png

 
Here are the Nios II Application Properties:
naand_2-1711549525906.png
 
 
Thanks,

Best regards.

naand

0 Kudos
15 Replies
wwanalim_intel
Employee
1,026 Views

Hi,

 

Greetings and welcome to Intel's forum.

Please give me some time to check on this issue and will get back to you with the update.

 

Thank you.

Regards,

Fathulnaim


0 Kudos
wwanalim_intel
Employee
997 Views

Hi,


I am checking this issue with internal teams.

In the meantime, can you provide the project file as I want to try and monitor the detail of the issue on my side.


0 Kudos
naand
Beginner
987 Views
Hi,
 
cannot share the project files. This is a complete project with corporate know-how, and I cannot share it entirely (I could share only small portions).
Also, the project is not based on a dev board, but on custom hardware, so I don't know how the code can be tried.
 
Thank you.
Regards,
naand
0 Kudos
wwanalim_intel
Employee
960 Views

Hi,

 

Since project cannot be shared, then we will suggest ways for you to debug the issue.

 

We recommend for you to enable a single optimization until the design fails. Once you can find the optimization that cause the issue then can remove it and proceed without using it for your design.

 

Since -O3 is using bunch of optimizations, we should try one by one:

 

-O0 (working or not)

-O1 (work with which optimization)

-O2 (work with O1 and plus which optimization)

-O3 (failing because of which optimization)

 

Based on the closer working/failing pair, we will have a smaller group to investigate.

For example,

If the pair is found to be O2-O3, these are the interested optimization to investigate

 

 

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html


Thank you.

Regards,

Fathulnaim


0 Kudos
naand
Beginner
937 Views

Hi,

 

I tried as you suggested.

With optimization O1 the firmware works properly, whereas the firmware doesn't work with optimization O2, so the pair is O1-O2.

 

To investigate further, is it possible to disable only one optimization flag of O2 and find out which flag generates the issue?

And is it possible to turn off optimization for a block of code?

 

Thank you.

Regards,

naand

0 Kudos
wwanalim_intel
Employee
902 Views

Hi,

 

As the firmware started not working when enable optimization O2, you can proceed to investigate those pairs. Yes, you will need to disable one by one the optimization flag to find out which flag generates the issue.

 

For the turning off optimization for a block of code, I will need to get the information from the internal team first then will inform you on the feedback.



0 Kudos
naand
Beginner
888 Views

Hi, 

 

Thanks for the feedback.

You said I can disable the optimization flags one by one, but I don't understand how I can disable only one. I read the link you shared with me but there is nothing about it.

For example, with the -O2 optimization, if I want to disable only the -finline-functions flag and enable all the others, how can I do that?

 

Thank you.

Regards,

naand

0 Kudos
naand
Beginner
746 Views

Hi,

 

I have news about what optimization flag is responsible for the problem; the flag is the -finline-small-functions.

Another test I did was to set the variable flag_status, used to check the Flash status, as volatile, but nothing changed (the flag_status is found in the flash_write_function.c file attached in the first message).

 

Are there any updates on how to disable optimization for a specific block of code?

 

Thanks.

Best Regards,

naand

 
0 Kudos
wwanalim_intel
Employee
631 Views

Hi,


Sorry for not updating as I just got back from long holiday.

Will check with engineering team on the step if the optimization can be disable for a specific block of code.


Thank you.


0 Kudos
wwanalim_intel
Employee
566 Views

Hi Sir,

 

So far there is no official document or guide from us on how to disable the optimization for a specific block of code.

However, I found this which you can try.

https://programfan.github.io/blog/2015/04/27/prevent-gcc-optimize-away-code/

 

Thank you.

 

0 Kudos
wwanalim_intel
Employee
487 Views

Hi Sir,

 

Any update from your side?

 

 

0 Kudos
naand
Beginner
463 Views

Hi,

 

I am sorry for the delayed response. I have been out of the office for the last few days.

 

Thanks for the link, I tried the #pragma directive to disable GCC optimization for one or more functions and it works.

With this technique I was able to isolate the source of the problem: the function that causes it is flash_read_flag_status_register.

It is implemented in this way:

alt_u32 flash_read_flag_status_register(T_flash_state *st)
{
IOWR(st->csr_base, FLASH_CSR_FL_CMD_SET, 0x00001870);
IOWR(st->csr_base, FLASH_CSR_FL_CMD_CTRL, 0x1);
return IORD(st->csr_base, FLASH_CSR_FL_CMD_RD0);
}

and is used to check if the write operation is finished and then checks for errors:

// check for errors
do {

flag_status = flash_read_flag_status_register(st);

} while (!(flag_status & FLASH_FSR_READY));

flash_clear_flag_status_register(st);
if (flag_status & FLASH_FSR_PROTECTION_ERR)
{

ret_flag = FLASH_SECTOR_PROTECTED;
break;

}
if ((flag_status & FLASH_FSR_ERASE_ERR) || (flag_status & FLASH_FSR_PROGRAM_ERR))
{

ret_flag = FLASH_ERROR;
break;

}

To avoid using #pragma I tried setting the flag_status variable as volatile, but it doesn't work.

Do you know why if I use volatile for flag_status it doesn't work? 

Can you suggest other attentions I can have to avoid other problems with GCC optimization?

 

Thanks.

Best Regards,

naand

0 Kudos
wwanalim_intel
Employee
327 Views

Hi,

 

We are glad that pragma is working.

Currently, this is the only optimization bug we are aware of.  In the meantime, can we know what flash are you using? (the function will change based on flash vendor)

 

It seems using volatile not helping in here maybe the function is too small not because variable is optimized. Can you try this ? 

https://stackoverflow.com/questions/1474030/how-can-i-tell-gcc-not-to-inline-a-function#:~:text=You%20want%20the%20gcc%20%2Dspecific,the%20function%20call%20is%20live.

 

By the way, can you share your pragma example? We are interested to understand how it is used.

 

Thank you.

0 Kudos
naand
Beginner
288 Views

Hi,

 

I'm using the Micron Flash MT25QL256ABA8E12-1SIT. 

 

I tried the solution proposed in the StackOverflow link: the __attribute__ ((noinline)) works, so this is another solution.

My problem is only with the optimization of the flash_read_flag_status_register function, so this is my example of the #pragma directive:

#pragma GCC push_options

#pragma GCC optimize("O0")
alt_u32 flash_read_flag_status_register(T_flash_state *st)
{
IOWR(st->csr_base, FLASH_CSR_FL_CMD_SET, 0x00001870);
IOWR(st->csr_base, FLASH_CSR_FL_CMD_CTRL, 0x1);
return IORD(st->csr_base, FLASH_CSR_FL_CMD_RD0);
}
#pragma GCC pop_options
 

My code works even with the highest level of GCC optimization (-O3) if I use the #pragma solution.

 

Thanks.

Best Regards,

naand

0 Kudos
wwanalim_intel
Employee
223 Views

Hi,


We are glad to hear that both #pragma and __attribute__ ((noinline)) works for your issue.

As for now problem had been solved, we will continue to transition this thread to community support.

Thank you for the example given, will be helpful for others in future.


I’m glad that your question has been addressed, I now transition this thread to community support. If you have a new question, Please login to ‘https://supporttickets.intel.com’, view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions.




0 Kudos
Reply