This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem with fs_init after importing to Segger Embedded Studio

Hi, 

I followed the instructions for importing the Thing:52 firmware into SES and managed to get the firmware compiled and loading, and the code reaches the main function without any apparent problem. When it gets to the application though I get an error in m_ble_flash_init. The problem is in the structure returned by FS_SECTION_ITEM_GET(i) within fs_init (called within m_ble_init->m_ble_flash_init->fsd_init) - particularly in these lines (fstorage.c:363) : - 

p_config_i = FS_SECTION_ITEM_GET(max_index);

        p_config_i->p_end_addr   = p_current_end;
        p_config_i->p_start_addr = p_current_end - (p_config_i->num_pages * FS_PAGE_SIZE_WORDS);

The write of p_current_end to p_config_i>p_end_addr doesn't happen and the value remains 0. The same is true for p_config_i->p_start_addr.

p_current_end is 0x00080000, i.e. the end of the flash section - as expected. The p_config pointer is pointing to 0x5beac.

Of course what then happens is that p_current_end gets update to 0x0: -

p_current_end = p_config_i->p_start_addr;

This causes problems later on. 

There are earlier warnings which Iooked into. The first on happens because all the structure values are 0, so the drv_ext_light_off driver tries to setup a timer with timeout_ticks = 0, so this generated an NRF_ERROR_INVALID_PARAM error.

It seems these errors could all be down to the same root cause - the inability to write to these structures.

Any idea what I am doing wrong?

Thanks in advance for any help.

Phil.

p.s. If it is useful - here is the trace from the debug console.

main :INFO:===== Thingy started! =====
drv_ext_light :WARNING:Err code returned in file: /Users/derrick/work/third-party/Nordic-Thingy52-FW/source/drivers/drv_ext_light.c, line: 754, code 7 
drv_ext_light :WARNING:Err code returned in file: /Users/derrick/work/third-party/Nordic-Thingy52-FW/source/drivers/drv_ext_light.c, line: 858, code 7
drv_ext_light :WARNING:Err code returned in file: /Users/derrick/work/third-party/Nordic-Thingy52-FW/source/drivers/drv_ext_light.c, line: 754, code 7
drv_ext_light :WARNING:Err code returned in file: /Users/derrick/work/third-party/Nordic-Thingy52-FW/source/drivers/drv_ext_light.c, line: 858, code 7
m_env :INFO:Init:
m_motion :INFO:Init
m_sound :INFO:Sound_init
m_ble :WARNING:Too few random bytes available. Trying again
m_ble :WARNING:Too few random bytes available. Trying again
m_ble :WARNING:Too few random bytes available. Trying again
m_ble :INFO:Available random bytes: 16
m_ble :INFO:Random value (hex): 2x2x2x2x
m_ble_flash :INFO:Initialization
m_ble_flash :WARNING:Err code returned in file: /Users/derrick/work/third-party/Nordic-Thingy52-FW/source/modules/m_ble_flash.c, line: 197, code 11
m_ble :ERROR: m_ble_flash_init failed - 11
main :ERROR: id = 16385, pc = 0, file = /Users/derrick/work/third-party/Nordic-Thingy52-FW/project/pca20020_s132/main.c, line number: 304, error code = 11 = NRF_ERROR_INVALID_DATA
Parents
  • I now have this working. The two things I had to change were: - 

    1. Edit the flash_placement.xml file to copy the fs_data to RAM (although this defeats the purpose of using flash storage?) and

    2. Workaround the round functions in optimal_time_settings_risefall_calculate() - the input to this function turns out to be 0/0 for drv_ext_light_off. Workaround is to check if the dividend is '0' before using the round function - and if it is just use 0 for the value. This then allows the correct selection of  LED_DRV_DISABLED_LIGHT_OFF in m_io_ext_oper_mode_chk (called from m_ioext_cmd_process).

    Fixed code can be found in the ses_import branch under

    https://github.com/phild68/Nordic-Thingy52-FW.git
  • Hello,

    I think I found the issue with the flash.

    I assume that you have seen this porting guide to port projects from Keil to SES.

     

    I see that our thumb_crt0.s are a bit different. I use Segger Embedded Studio v3.40. I suspect that many of the differences are a due to that we use different versions, but as it mentions in the guide, you should change one thing in your thumb_crt0.s file.

    ldr r2, =__tdata_end__
    bl memory_copy
    # ADD HERE ... 
    ldr r0, =__fs_data_load_start__
    ldr r1, =__fs_data_start__
    ldr r2, =__fs_data_end__
    bl memory_copy
    # TO HERE ...

    I see that you have something similar, but there is some typos.

    In your thumb_ctr0.s it says:

      ldr r0, =__fs_data_load_start__
      ldr r1, =__start_fs_data
      ldr r2, =__stop_fs_data
      bl memory_copy

    Try to change

    __start_fs_data   and 

    __stop_fs_data

    to

    __fs_data_start__    and

    __fs_data_end__

    as it says in the porting guide. Also, try to use the flash_placement.xml file to the one that is linked in the guide (the one that is meant for sdk14).

    I see that you have copied the thumb_crt0.s, which is fine. Just a note to anyone else might reading this post that if you change the thumb_crt0.s, this might affect the SES projects from the "normal" SDK examples using SES.

     

    My workaround for the light drivers are working, but they are maybe not optimal. They need some more tests. It would be great if you find that my (or your) LED driver workaround causes some other issues Slight smile

     

    Best regards,

    Edvin

     

    Best regards,

    Edvin

  • Hi Edvin, 

    Thank you for your help and detailed response. One problem with your app_timer_start workaround (and it probably isn’t a big problem) is that the processor is already executing the incorrect branch of code. In this case, the intention is to turn the LED off (as this is called from drv_ext_light_off)

        else if (reg_vals->on_time       == 0 &&
                 reg_vals->on_intensity  == DRV_EXT_LIGHT_INTENSITY_OFF &&
                 reg_vals->off_time      == 0 &&
                 reg_vals->off_intensity == 0 &&
                 reg_vals->fade_in_time  == 0 &&
                 reg_vals->fade_out_time == 0 )
        {
            *led_drv_status = LED_DRV_DISABLED_LIGHT_OFF;
            *power_optim_possible = true;

    From line 457 or drv_ext_light.c

    Because of the round() differences, the fade_in_time and fade_out_time are non-zero and so the correct branch (above) is not taken and the following one is: -

        else if (reg_vals->off_time      == 0)
    
        {
    
            *led_drv_status = LED_DRV_ENABLED_SINGLE_SHOT;
    
            if (reg_vals->off_intensity == 0)
    
            {
    
                *power_optim_possible = true;
    
            }
    
        }

    (Line 476).

    This may not be a problem but I wonder if it waste more power as it enables the IO extender oscillator when it isn’t really needed. 

  • That is correct, 

    Also, I saw that my implementation made my LEDs work a bit buggy. No crash, but sometimes the wrong color for a limited amount of time.

    Did you look into the flash_placement.xml and thumb_crt0.s files from the porting guide? Did you manage the flash part? It should not be necessary to use only RAM.

     

    At least for me, the combination of the flash_placement.xml and addiing the fs_data_ lines in the thumb_crt0.s file worked for me.

     

    BR,

    Edvin

  • Hi Edvin, 

    Yes I updated the flash_placement.xml and use the thumb_crt0.s from SES 3.4 with the edits that you detailed, but the results were the same.

    Thanks again for all your help - it is very much appreciated.

    BR,

    Phil 

  • BTW I changed my fix for the round so that it now checks the divisor is non-zero before performing the round.

        /* Fade in */
        divisor = (REG_RISEFALL_TIME_LOW_MULTIPLIER * (reg_val->on_intensity - (4 * reg_val->off_intensity)) * (255 / m_clkx_tics_pr_sec));
        uint32_t fade_in_time_low_mult_reg  = (divisor == 0) ? 0 : (uint32_t) round( (real_val->fade_in_time_ms / divisor) / 1000 ) ;                                                          
    
        divisor = (REG_RISEFALL_TIME_HIGH_MULTIPLIER * (reg_val->on_intensity - (4 * reg_val->off_intensity)) * (255 / m_clkx_tics_pr_sec));
        uint32_t fade_in_time_high_mult_reg = (divisor == 0) ? 0 : (uint32_t) round( (real_val->fade_in_time_ms / divisor) / 1000 );
     

    This is committed to my GitHub account and the ses_import branch has been merged back into the main branch.

Reply
  • BTW I changed my fix for the round so that it now checks the divisor is non-zero before performing the round.

        /* Fade in */
        divisor = (REG_RISEFALL_TIME_LOW_MULTIPLIER * (reg_val->on_intensity - (4 * reg_val->off_intensity)) * (255 / m_clkx_tics_pr_sec));
        uint32_t fade_in_time_low_mult_reg  = (divisor == 0) ? 0 : (uint32_t) round( (real_val->fade_in_time_ms / divisor) / 1000 ) ;                                                          
    
        divisor = (REG_RISEFALL_TIME_HIGH_MULTIPLIER * (reg_val->on_intensity - (4 * reg_val->off_intensity)) * (255 / m_clkx_tics_pr_sec));
        uint32_t fade_in_time_high_mult_reg = (divisor == 0) ? 0 : (uint32_t) round( (real_val->fade_in_time_ms / divisor) / 1000 );
     

    This is committed to my GitHub account and the ses_import branch has been merged back into the main branch.

Children
No Data
Related