Exception in nested function call in an lwip+ vdk project

I am running a lwip with vdk project on BF527 processor on my custom board. After ethernet communication is established there are some multiple function calls (nested functions). In one of the function call the code goes into exception, excause = 0x21 (undefined instruction) and RETX= 0x00000002. I am using external memory sdram (64MB), with cache enabled. I could not understand how/why the code is going to this location (RETX= 0x00000002) which may be causing this exception? Please advise.

Parents
  • +1
    •  Analog Employees 
    on Mar 29, 2021 1:17 PM

    Hi,

    The EXCAUSE code indicates an illegal instruction exception, thus EXCAUSE value of 0x21 occur if you try to emulate instructions that are not defined for a particular processor implementation.

    You would find more information in the "Blackfin Programming Reference" Manual. The Table titled "Table 4-13 Events That Cause Exceptions" in the chapter "Program Sequencer" gives details on the different exceptions. The type of exception caused, and the reason why it is caused can be identified by viewing the EXCAUSE field in the SEQSTAT register. The link is as given below:
    www.analog.com/.../Blackfin_pgr_rev2.2.pdf

    The exception that you are getting is actually a hardware exception. The code linked into application for VDK will not contain undefined instructions or illegal opcodes. So, this would point to that area of program memory being overwritten so that when your application tries to execute what should be valid code an exception is raised.

    You should be able to confirm that this area of memory is being overwritten by storing a dump of the code present in VDK when your application is first loaded, and then comparing with the same area of memory after you have reached the exception. Ans also, this could be due to a stack overflowing. However, it could equally be due to DMA writing to an incorrect address or a write to memory via a pointer that has been corrupted.

    We would suggest that the first step should be to try to determine what is overwriting that area of memory by setting up hardware watchpoints/breakpoints to cover the area of memory and then run your application until that breakpoint is hit.

    Also, The error hardware exception may been caused by the SDRAM being misconfigured/not configured. Typically this means that the EBIU is not correctly configured for your target.

    As you are using a custom target, these values will probably not be suitable to initialize the EBIU on your custom target. As of VisualDSP++ 5.0 we added 'custom board support', which allows you to associate a custom XML file with your session to ensure that the EBIU is configured appropriately.

    Can we ask you could modify the EBIU values in the XML file. Since it seems the application is crashing within the startup code, there is a possibility that the problem is that your EBIU has not been configured correctly. By default, the option "use xml reset values" is enabled within 'Settings'->'Target Options'. This instructs the Emulator to use
    values contained in an XML file - in your case "...\System\Archdef\adsp-bf527-proc.xml" - to configure certain registers on the target.

    If you take a look at the very bottom of the xml file, in the <register-reset-definitions> section, you will see that it configured the EBIU registers to specific values. These values are set appropriately for the SDRAM part used on the EZ-KIT Lite. Since you are using a custom board, these values will (almost certainly) not be suitable for your target. To allow users with custom boards to configure the EBIU, we offer "Custom Board Support" as of VisualDSP++ 5.0. This allows you to create a separate XML file to handle the register resets to ensure that the EBIU gets configured appropriately for the SDRAM part used on your custom board.

    Please see the help under 'Help'->'Contents'->'Graphical Environment'-.>'Custom Board Support'.

    If it is happening on load, disable "Run to main after load" via 'Settings: Preferences: General', and load the DXE. It should load OK, and you can step through the startup code until the exception occurred. Typically, if there is an exception during the startup code it is an access to SDRAM that has not been correctly initialized. If that appears to be the case, please see the following FAQ:
    ez.analog.com/.../faq-my-application-behaves-incorrectly-when-using-sdram

    Can you please verify your board against EE-281:
    Please find the link of Hardware Design Checklist for the Blackfin® Processors.
    www.analog.com/.../EE-281.pdf

    There is also an App Note EE-312, which might be helpful to you.
    www.analog.com/.../EE-312_Rev2.pdf

    If still you are facing issue, can you please share the sample project to reproduce the "Exception with EXCAUSE=0x21" issue along with steps and screenshot of error message.

    Best Regards,
    Santhakumari.K

  • Thank you for a detailed response.

    I am using lwip_sysboot_threadtype.c (taken from some adi example projects) for ethernet communication. In this file there is a function adi_ssl_Init() to initialise system services. This same function was also placed in another C file of the project and may be that was causing exception (excause 0x21). After commenting it, the problem is resolved!.

    Secondly, in the project there is assembly file also which I have placed in sdram0_bank0. If i place assembly file in sdram0_bank1/2/ or 3, it gives errors li1080: parameter is out of range, valid range is [0x0,0xffff]. Question: How to place my assembly files in other banks of sdram? It appears sdram0_bank0 is reserved for heap and stacks, I've forcibly used it as Input section for program code and data. 

    As suggested by you configuring of EBIU, I am still trying, would get back to you if any issue/ or trouble.

    Thanks and regards

    Sandeep B

  • +1
    •  Analog Employees 
    on Apr 5, 2021 10:55 AM in reply to sandeepb

    Hi Sandeep,

    We could able to place a simple assembly source file in bank1 block of sdram memory(MEM_SDRAM0_BANK1)successfully. Please refer the screenshot "map_file.jpg".

    We added the below lines to an appropriate section in the LDF, to map the whole object file(test_sdram.doj) in different memory section of SDRAM memory.

    sdram0_bank1_extra
    {
    INPUT_SECTION_ALIGN(4)

    INPUT_SECTIONS( test.doj(program) $LIBRARIES(program) )
    } > MEM_SDRAM0_BANK1

    For example, Your LDF should then be roughly of the form:

    PROCESSOR p0
    {
    ......
    SECTIONS
    {
    sdram0_bank1_extra
    {
    INPUT_SECTION_ALIGN(4)

    INPUT_SECTIONS( test_sdram.doj(program) $LIBRARIES(program) )
    } > MEM_SDRAM0_BANK1
    ......
    }
    }

    Also, You will find detailed information on the linker error[li1080] in VisualDSP++ HELP,which is available within the VisualDSP++ environment by selecting 'Help'->'Index'. When Help opens type 'li1080' in the keyword search box.

    This describes the problem and provides information on how to fix the problem.

    There is a Linker switch you can try, -jcs2l (the last character is a lower-case "L", not a 1). This should be added to the 'Additional Options' of Project Options:Link. Note that this will increase the size of your code.

    If that does not work, the only option is to modify the LDF to ensure that the function making the call and function being called are in range of one another (e.g. both in internal memory, or both in external memory).

    Please have a look at the Help topic and let us know how you get on. If you are still having problems, is it possible for you to send us a copy of your application to reproduce your issue here,This will help us to assist you further.

    Also, You can use #pragma section("section_name") directive to force your data into specific memory.If you are encountering problems modifying the LDF to control the placement of your code, it is recommended that you make use of the "#pragma default_section" qualifier.

    Please refer section "#pragma section/#pragma default_section" in the below linked manual for more details.
    www.analog.com/.../50_bf_cc_rtl_mn_rev_5.4.pdf

    Regards,
    Santhakumari.K

  • Thanks a lot, this was very helpful, but in my project (lwip+vdk) there are multiple files (mostly c files and some assembly) let's say x1.c, x2.asm, x3.c.... so on. I used the technique suggested by you like as below-

    PROCESSOR p0
    {
    ......
    SECTIONS
    {
    sdram0_bank1_extra
    {
    INPUT_SECTION_ALIGN(4)

    INPUT_SECTIONS( x1.doj(program) $LIBRARIES(program) )

    INPUT_SECTIONS( x2.doj(program) $LIBRARIES(program) )


    } > MEM_SDRAM0_BANK1
    ......
    }
    }

    but when I rebuild and run the project the files are still in internal memory. Am I mapping the files correctly? as above or there is some other way? Also my lwip file is always in sdram, I want to move it to internal memory for some reasons. how to do that?

    regards

    Sandeep B

  • +1
    •  Analog Employees 
    on Jun 10, 2021 1:53 PM in reply to sandeepb

    Hi Sandeep,

    We have created a simple project having multiple files like x1.c, x2.asm, x3.c as you have mentioned and able to place a those source files in bank1 block of sdram memory(MEM_SDRAM0_BANK1)successfully. Please refer the screenshot "map_bf527_test.JPG".

    Also we have attached that simple example project herewith for your reference.

    We added the below lines in the LDF:
    sdram0_bank1_extra
    {
    INPUT_SECTION_ALIGN(4)

    INPUT_SECTIONS( x1.doj(program) $LIBRARIES(program) )
    INPUT_SECTIONS( x2.doj(program) $LIBRARIES(program) )
    INPUT_SECTIONS( x3.doj(program) $LIBRARIES(program) )
    } > MEM_SDRAM0_BANK1

    Therefore, Please ensure that you have place the above commands(exactly the same format as above) at the beginning of the SECTIONS in your ldf.

    Also, you can follow the same way for moving your source code to internal memory. For example as below:

    l1_code_b_test
    {
    INPUT_SECTION_ALIGN(4)
    INPUT_SECTIONS( test.doj(program) $LIBRARIES(program) )
    } > MEM_L1_DATA_B

    Controlling the placement of the function or data is then a case of adding appropriate output section in LDF.

    You can use #pragma section("section_name") directive to force your data into specific memory. Use this before each function that you want to place in the section. This pragma will only affect the next symbol and if you use this pragma right before a function, that function alone will be placed in the section.

    For more information, take a look at the "#pragma section/#pragma default_section" in the vdsp help:

    Help > contents > Manuals > Software tool manuals > Blackfin C/C++ Compiler and Library Manual >
    C/C++ Compiler Manual for Blackfin® Processors > 1 Compiler > C/C++ Compiler Language Extensions > Pragmas > Linking Control Pragmas > #pragma section/#pragma default_section

    Regards,
    Santhakumari.K

    Ezone_542757.zip

Reply
  • +1
    •  Analog Employees 
    on Jun 10, 2021 1:53 PM in reply to sandeepb

    Hi Sandeep,

    We have created a simple project having multiple files like x1.c, x2.asm, x3.c as you have mentioned and able to place a those source files in bank1 block of sdram memory(MEM_SDRAM0_BANK1)successfully. Please refer the screenshot "map_bf527_test.JPG".

    Also we have attached that simple example project herewith for your reference.

    We added the below lines in the LDF:
    sdram0_bank1_extra
    {
    INPUT_SECTION_ALIGN(4)

    INPUT_SECTIONS( x1.doj(program) $LIBRARIES(program) )
    INPUT_SECTIONS( x2.doj(program) $LIBRARIES(program) )
    INPUT_SECTIONS( x3.doj(program) $LIBRARIES(program) )
    } > MEM_SDRAM0_BANK1

    Therefore, Please ensure that you have place the above commands(exactly the same format as above) at the beginning of the SECTIONS in your ldf.

    Also, you can follow the same way for moving your source code to internal memory. For example as below:

    l1_code_b_test
    {
    INPUT_SECTION_ALIGN(4)
    INPUT_SECTIONS( test.doj(program) $LIBRARIES(program) )
    } > MEM_L1_DATA_B

    Controlling the placement of the function or data is then a case of adding appropriate output section in LDF.

    You can use #pragma section("section_name") directive to force your data into specific memory. Use this before each function that you want to place in the section. This pragma will only affect the next symbol and if you use this pragma right before a function, that function alone will be placed in the section.

    For more information, take a look at the "#pragma section/#pragma default_section" in the vdsp help:

    Help > contents > Manuals > Software tool manuals > Blackfin C/C++ Compiler and Library Manual >
    C/C++ Compiler Manual for Blackfin® Processors > 1 Compiler > C/C++ Compiler Language Extensions > Pragmas > Linking Control Pragmas > #pragma section/#pragma default_section

    Regards,
    Santhakumari.K

    Ezone_542757.zip

Children
  • Thank you, 

    I could place my files in the sdram bank by using the steps provided by you in the project ldf file. 

    But when I want to place the source code/file into the internal memory/L1 the below given example didn't work...

    l1_code_b_test
    {
    INPUT_SECTION_ALIGN(4)
    INPUT_SECTIONS( test.doj(program) $LIBRARIES(program) )
    } > MEM_L1_DATA_B

    In bf527 there is no code_b instruction memory space. Above it is pointing to MEM_L1_DATA_B, does that mean the source code would be placed in data RAM_b??

    I tried to place "lwip" file in internal memory but could not do so as lwip is always placed in sdram??