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

Writing Files to Flash Memory Using Flash FDS

I'm writing a program that receives a time from an RTC over TWI then writes that time into flash memory using the example from the flash FDS library.  The problem I'm running into is that I receive my clock data as an array that holds values for the time ie: rx_data[0] = 13 rx_data[1] = 56.  This would represent the time 13:56, but I want to store the time in a formatted char array which I create in line 14. 

I want to save this entire char array to the flash memory, but the program seems to only be able to write static const char arrays to memory.  So my questions are:

1.) Why can I only write static const char arrays to memory?  Is there a way to store character arrays in some other format?

2.) Is there a way to convert my static char array that holds the formatted time to a static const char array?  In c++ I would use something like strcpy but I'm not sure how to do this in C.  

Here is my code:

void writeTime()
{
   #define FILE_ID         0x0005  /* The ID of the file to write the records into. */
   #define RECORD_KEY_1    0x5555  /* A key for the first record. */

   ret_code_t rc = NULL;

   uint8_t* rx_data = clockTime(); //get the pointer to the array that holds the clockTime
   static char m_timeStart[50] = {0};


   //generate a char array that holds the start time from the array
  
  snprintf(m_timeStart, sizeof(m_timeStart), "%x:%x:%x on %x/%x/%x", rx_data[2], rx_data[1], rx_data[0], rx_data[5], rx_data[4], rx_data[6]);
  


   fds_record_t        record;
   fds_record_desc_t   record_desc;


   // Set up record.

   record.file_id           = FILE_ID;
   record.key               = RECORD_KEY_1;
   record.data.p_data       = &m_timeStart;
   /* The following calculation takes into account any eventual remainder of the division. */
   record.data.length_words = (sizeof(m_timeStart) + 3) / 4;
   rc = fds_record_write(&record_desc, &record);
   
}

Thanks!

Parents
  • I don't see how this should fail, you may check out:
    https://devzone.nordicsemi.com/f/nordic-q-a/32208/what-should-i-start-in-order-to-use-the-maximum-memory-space-in-fstorage/125086#125086 

    Have in mind though that the write operation may take some time, so you can't read it back before it's stored to flash.

  • I checked out that example and tried repeating what they did to fix it by declaring an intermediate container and then using that to write to the variable that will be written to memory.  Unfortunately this didn't work with a static uint8_t array like the person in that post used or with a static character array. 

    The only datatype that I've successfully written to memory is static const character array but I don't think there's a way to get data from an array at runtime in C (getting my RTC data over TWI) then write it to a static const array is there?  If there is that would solve the problem.  I'm also not sure why I'm only able to write static const types to the memory.

    I also checked the ret code of the write function which returned 0x8602 which correlates to FDS_ERR_UNALIGNED_ADDR.  Looking into this now but maybe declaring the variable as a constant automatically aligns the word, and I have to align manually if not using a constant datatype?

  • Update: Got it working, the alignment was the error.  The changes I made were to lines 10, 11, 16, and 17.  

    void writeTime()
    {
       #define FILE_ID         0x0005  /* The ID of the file to write the records into. */
       #define RECORD_KEY_1    0x5555  /* A key for the first record. */
    
       ret_code_t rc = NULL;
    
       uint8_t* rx_data = clockTime(); //get the pointer to the array that holds the clockTime
       
        static char intermediate[50] = {0};
        __ALIGN(4) static char m_timeStart[50] = {0};
    
    
       //generate a char array that holds the start time from the array
      
       snprintf(intermediate, sizeof(intermediate), "%x:%x:%x on %x/%x/%x", rx_data[2], rx_data[1], rx_data[0], rx_data[5], rx_data[4], rx_data[6]);
       memcpy(m_timeStart, intermediate, sizeof(intermediate));
    
    
       fds_record_t        record;
       fds_record_desc_t   record_desc;
    
    
       // Set up record.
    
       record.file_id           = FILE_ID;
       record.key               = RECORD_KEY_1;
       record.data.p_data       = &m_timeStart;
       /* The following calculation takes into account any eventual remainder of the division. */
       record.data.length_words = (sizeof(m_timeStart) + 3) / 4;
       rc = fds_record_write(&record_desc, &record);
       
    }

    It was actually a combination of the question you linked as well as the alignment issue.  I first tried just using one variable m_timeStart that was aligned but writing to it with snprintf broke the alignment and I got the alignment error again.

    So I created an intermediate container called intermediate and wrote the string I wanted into it.  I then copied the desired string into the aligned m_timeStart which kept the alignment and allowed me to write the string to memory.

Reply
  • Update: Got it working, the alignment was the error.  The changes I made were to lines 10, 11, 16, and 17.  

    void writeTime()
    {
       #define FILE_ID         0x0005  /* The ID of the file to write the records into. */
       #define RECORD_KEY_1    0x5555  /* A key for the first record. */
    
       ret_code_t rc = NULL;
    
       uint8_t* rx_data = clockTime(); //get the pointer to the array that holds the clockTime
       
        static char intermediate[50] = {0};
        __ALIGN(4) static char m_timeStart[50] = {0};
    
    
       //generate a char array that holds the start time from the array
      
       snprintf(intermediate, sizeof(intermediate), "%x:%x:%x on %x/%x/%x", rx_data[2], rx_data[1], rx_data[0], rx_data[5], rx_data[4], rx_data[6]);
       memcpy(m_timeStart, intermediate, sizeof(intermediate));
    
    
       fds_record_t        record;
       fds_record_desc_t   record_desc;
    
    
       // Set up record.
    
       record.file_id           = FILE_ID;
       record.key               = RECORD_KEY_1;
       record.data.p_data       = &m_timeStart;
       /* The following calculation takes into account any eventual remainder of the division. */
       record.data.length_words = (sizeof(m_timeStart) + 3) / 4;
       rc = fds_record_write(&record_desc, &record);
       
    }

    It was actually a combination of the question you linked as well as the alignment issue.  I first tried just using one variable m_timeStart that was aligned but writing to it with snprintf broke the alignment and I got the alignment error again.

    So I created an intermediate container called intermediate and wrote the string I wanted into it.  I then copied the desired string into the aligned m_timeStart which kept the alignment and allowed me to write the string to memory.

Children
No Data
Related