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

FStorage Without Peer Manager

I've been trying to add flash storage to some BLE firmware we have developed using uVision under SDK version 12.3.0 and am running into issues. At first, we were having the issue that our flash event handler wasn't firing. On this site, I found someone saying to use to call fs_init after initializing the peer manager. However, we were not initially using the peer manager to begin with. But, to test it, I added the peer manager. However, the peer manager required more libraries and some of those libraries required more libraries. The code size is now to the point where our code has exceeded the maximum size for the version we were using, all because we were attempting to use the peer_manager.

Is there a way to get the fs_evt_handler to fire without having to include the peer manager?

Parents
  • Hi,

    There must be some misunderstanding. The Peer Manager has dependencies on Fstorage (indirectly, via FDS), but it is not the other way around. There is absolutely no reason to include the peer manager just because you want to use Fstorage.

    Fstorage itself is quite simple and has very few dependencies. Assuming that my understanding is correct and that you don't need the peer manager (don't do any pairing or bonding), then I suggest you revert back your changes to where you had no peer manager code. Then start looking at what was problematic with storage, using the documentation to see how it is used. That shows with code all you need to do to initialize (including configuring an event handler), erase and write data.

  • Ok, it's good to know that Peer Manager isn't required. This still leaves me confused as to why my code isn't working. I have my FS_REGISTER_CONFIG near the start of my code just as shown in the documentation and I have fs_init() running successfully in my main. The only difference I see between my code and the documentation is that my code is asking for a p_context variable while the documentation doesn't seem to reference it at all. Other example code I've seen has just passed NULL to it. Is that incorrect? If so, what should I be passing?

  • Hi,

    The context parameter is just a way for you to pass some context/data/whatever that you want, for instance, so that you can see for which write you got an event. This is just a feature that the library provides, passing the value without using it for anything, so how you use it or not is up to you and does not matter to the storage library.

    Perhaps you can share your code and describe in more detail in what way your code does not work?

  • I'll describe what I can say publicly with some variable names changed. Anything more specific might require a private email.

    We are trying to write code for a BLE device that periodically samples data based on a timer on then store it to flash every other sample. We're also monitoring things over UART. So, in total, we are using UART, BLE, Timers, and Flash. We were trying to use the scheduler as well, but we ended up falling into the same issue with the flash event handler not firing.

    Here's the code I have to initialize the Flash and the event handler as well as some constants we set up for use.

    #define NUM_PAGES 16
    
    static uint16_t flashOffset = 0;   
    static uint32_t flashTemp = 0;
    static void fs_evt_handler(fs_evt_t const * const, fs_ret_t);
    static uint8_t fs_callback_flag;
    
    FS_REGISTER_CFG(fs_config_t fs_config) =
    {
    		.callback  = fs_evt_handler, // Function for event callbacks.
    		.num_pages = NUM_PAGES,      // Number of physical flash pages required.
    		.priority  = 0xFE            // Priority for flash usage.
    };
    
    void flashErrorPrint(fs_ret_t fs_err) {
        //simply prints a string of which error occurred
    }
    
    static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) {
    	printf("In fs_evt_handler");
        if (result != FS_SUCCESS) {
            printf("fsEvtH: Flash Storage Event Error=0x%x\n", result);    // An error occurred (Not displayed).
            APP_ERROR_CHECK(result);
            return;
        } else {
    		fs_callback_flag = 0;
    	}
        if (evt->id == FS_EVT_ERASE) {
            printf("fsEvtH: Completed fs_erase on pages= %d through %d (%d of 256).\n", evt->erase.first_page, evt->erase.last_page - 1, evt->erase.last_page - evt->erase.first_page);
        } else if (evt->id == FS_EVT_STORE) {
            printf("fsEvtH: Completed fs_store #%d at 0x%x\n\n", sampleCount/2, flashOffset);
    		uint32_t stored = *(fs_config.p_start_addr + flashOffset);
    		if (stored != flashTemp) {
    			printf("fsEvtH: Stored data: 0x%x does not match intended value: 0x%x\n", stored, flashTemp);
    		}
    		flashOffset++;   // advance the sample store-to address
        } else {
            printf("fsEvtH: Error. Illegal fs_store Event Type=0x%x\n", evt->id);
        }
    }

    And, in the main loop, we initialize the flash and use like this

    static void periodic_handler(void * p_context){
        //...
    	printf("Updating values");
    	//...
    }
    
    int main(void)
    {
        //...
        
        printf("Initializing Flash\r\n");
    		
    	fs_ret_t ret = fs_init();
        if (ret != FS_SUCCESS) {
    		printf("main: Failed fs_init call. Err=");
    		flashErrorPrint(ret);
    	} else {
    		printf("Init Successful!\n");
    	}
    	
    	//...
    	printf("\tCreating Timer\r\n");
    	app_timer_create(&periodic_callback_id, APP_TIMER_MODE_REPEATED, periodic_handler);
    	err_code = app_timer_start(periodic_callback_id, BSP_MS_TO_TICK(cfgData2.interval * 1000), NULL);
        APP_ERROR_CHECK(err_code);
    	printf("\terr_code=%i\r\n", err_code);
    	
    	//...
    	
    	for (;;)
        {	
    		if (prevCount < sampleCount){
    		  printf("\nSetting flash at %i\n", sampleCount);
    			if ((logSampleCount % 2) == 1){
    				flashTemp  = collectedData << 16;
    				flashTemp &= 0xFFFF0000;
    				printf("Storing to flashTemp\n");
    			} else {
    				flashTemp &= 0x0000FFFF;
    				flashTemp |= collectedData;
    			
    				fs_callback_flag = 1;
    				fs_ret_t ret;
    				ret = fs_store(&fs_config, (fs_config.p_start_addr + flashOffset), &flashTemp, 1, NULL);
    				if (ret != FS_SUCCESS) {
    					printf("main: Failed store call. Err=");
    					flashErrorPrint(ret);
    				} else {
    					printf("Store Successful!\n");
    				}
    				while(fs_callback_flag == 1)  { power_manage(); } // <-- PROBLEM LINE
    				printf("Done Flash Storage\n");
    			}
    			prevCount = sampleCount;
    		}
            power_manage();
        }
    }

    The problem happens on line 38 of the second code box. The code waits for the fs_callback_flag variable to be reset, but it never gets unset as it should in line 26 of the first code box. However, none of the print statements in fs_evt_handler are called at all.

    Here's an example of our UART output where "Updating values" is printed by the function triggered by periodic_handler function triggered by our timer as seen in the second code box.

    Initializing Flash
    Init Successful!
    
    Updating values
    Setting flash at 1
    Storing to flashTemp
    
    Updating values
    Setting flash at 2
    Store Successful!
    
    Updating values
    Updating values

    I'm not sure if it's due to one of the other game libraries causing problem or my setup or something simple. Like I said, I attempted to do this via a scheduler and ran into the same issue. So, I don't think the problem is that it's in my main loop. But, I'm still not sure where to look first.

  • Hi,

    I don't see any issue with your usage of fstorage.

    Also, I do not see any indication of what the problem could be in another part of your code. When you debug and break, could it bee that execution is stuck in another same or higher priority interrupt? or could it be a problem with the callback function section variable (do you get any warnings when building or linking?)

    It would be useful to see more of your code in order to try to see what could happen. Also, preferably with a way to run it on a DK, or a detailed explanation. I could be missing something, but if not, I suspect the issue is not directly related to fstorage. You can create a private ticket and refer to this thread if you want to share additional code and information privately.

  • I can run the debugger on my code, but as soon as I add breakpoints it crashes. However, I am able to stop code execution to see it is stuck on the power_manage loop.

    I'll create a private ticket to continue the discussion.

  • Hi,

    Seth said:
    I can run the debugger on my code, but as soon as I add breakpoints it crashes. However, I am able to stop code execution to see it is stuck on the power_manage loop.

    Yes, you can use breakpoints but not continue from them. If you continue after a breakpoint (or another pause in the execution), the SoftDevice will assert. This is because it was not able to process events on time. This is slightly annoying, but there is no good way around it other than using a single breakpoint that you move and reset and run to the new location after the reset.

    Seth said:
    I'll create a private ticket to continue the discussion.

    Sounds good. We will continue there.

Reply
  • Hi,

    Seth said:
    I can run the debugger on my code, but as soon as I add breakpoints it crashes. However, I am able to stop code execution to see it is stuck on the power_manage loop.

    Yes, you can use breakpoints but not continue from them. If you continue after a breakpoint (or another pause in the execution), the SoftDevice will assert. This is because it was not able to process events on time. This is slightly annoying, but there is no good way around it other than using a single breakpoint that you move and reset and run to the new location after the reset.

    Seth said:
    I'll create a private ticket to continue the discussion.

    Sounds good. We will continue there.

Children
No Data
Related