Jump to content
BigG

Non volatile memory options for cc3200

Recommended Posts

According to TI's cc3200 documentation, I believe there is a way to dynamically write data during run time to non volatile memory (i.e. flash) on CC3200.

 

Has anyone achieved this using Energia and if so are any libraries or code examples available. Otherwise what pointers can people offer to do this.

 

I know there is the flash_readwrite example but that is for MSP430 launchpads.

Share this post


Link to post
Share on other sites

FYI-

 

https://github.com/spirilis/SLFS

Zip of current code: SLFS.zip

Unzip that in ~/Documents/Energia/libraries or wherever.

 

Be sure you have an updated copy of the WiFi library, as it needs WiFi.init() to be a public method.

My latest copy is here: simplelink_wifi_library_latest_10142014.zip - unzip that from within your Energia install's toplevel directory (e.g. from within C:\energia-0101E0013).

(that actually has one change ahead of Energia's current github master; it moves the various WiFi buffers to .text section on FRAM chips so they will fit on the Wolverine FR5969 LaunchPad w/ CC3100)

 

 

The SLFS library declares an instance right away called "SerFlash", so SerFlash.open(), SerFlash.close(), SerFlash.write(), SerFlash.print(), SerFlash.println(), etc...

You can delete files using SerFlash.del()

You cannot list the directory contents or know what files are on the flash.  I did not find any API calls in the SimpleLink API that support such a feature.  I'm assuming it's been left out for security reasons or similar.

 

The open() system call is given options based on the sl_FsOpen() SimpleLink API call, so... looking at documentation here- http://software-dl.ti.com/ecs/cc31xx/APIs/public/cc31xx_simplelink/latest/html/index.html ... look at "File System" and then "sl_FsOpen":

open file for read or write from/to storage device

Parameters
[in]	pFileName	File Name buffer pointer
[in]	AccessModeAndMaxSize	Options: As described below
[in]	pToken	Reserved for future use. Use NULL for this field
[out]	pFileHandle	Pointing on the file and used for read and write commands to the file
AccessModeAndMaxSize possible input 
FS_MODE_OPEN_READ - Read a file 
FS_MODE_OPEN_WRITE - Open for write for an existing file 
FS_MODE_OPEN_CREATE(maxSizeInBytes,accessModeFlags) - Open for creating a new file. Max file size is defined in bytes. 
For optimal FS size, use max size in 4K-512 bytes steps (e.g. 3584,7680,117760) 
Several access modes bits can be combined together from SlFileOpenFlags_e enum

The syntax for SerFlash.open() therefore is something like this:

 

SerFlash.open("myfile.txt", FS_MODE_OPEN_READ);  // Open file for reading

SerFlash.open("myfile.txt", FS_MODE_OPEN_CREATE(1024, _FS_FILE_OPEN_FLAG_COMMIT));  // Create new file, allocated 1024 bytes to contain it

SerFlash.open("myfile.txt", FS_MODE_OPEN_WRITE);  // Open file for re-writing

 

From what I've been able to gather, you can't open an existing file and write pieces of it piecemeal; opening the file and writing forces the serial flash to erase the entire block, so what you write replaces the prior contents entirely.  So for updating configuration info, you would need to read it into memory, make your changes and then re-write the entire file.  Also, there's a maximum # of files you can store ... something like 128 I believe, and that includes a number of system files in that count which are already there.  It's not meant to be a huge filesystem.  But it should do the trick for a lot of uses.

 

Share this post


Link to post
Share on other sites

 

 

From what I've been able to gather, you can't open an existing file and write pieces of it piecemeal; opening the file and writing forces the serial flash to erase the entire block, so what you write replaces the prior contents entirely.  So for updating configuration info, you would need to read it into memory, make your changes and then re-write the entire file.  Also, there's a maximum # of files you can store ... something like 128 I believe, and that includes a number of system files in that count which are already there.  It's not meant to be a huge filesystem.  But it should do the trick for a lot of uses.

 

Never been happy with these restrictions as makes too much work. So been looking for simpler external "plug-in" options.

 

I have been looking at one simple option, namely EEPROM using I2C. Came across this handy tutorial for Microchip 24LC256:

 

http://www.hobbytronics.co.uk/tutorials-code/arduino-tutorials/arduino-external-eeprom

http://www.hobbytronics.co.uk/eeprom-page-write

 

I tested both code examples and they worked using CC3200. Just uses with "wire.h" library, nothing else. There were a few code changes to make as code example quite old, such as changing "Wire.send" to "Wire.write" etc.

 

Now here is a curious one to note. If you upload code from "arduino-external-eeprom" page and try and compile using Arduino it gives better clues as to what to fix than when you try compiling using Energia.  Arduino compiler told me that "As of Arduino 1.0, the Wire.send() function was renamed to Wire.write() for consistency with other libraries." while Energia compiler told me "'class TwoWire' has no member named 'send'". Reasons for error here a little more cryptic.

Share this post


Link to post
Share on other sites

Yeah... Energia is written for Arduino API compatibility for the most part but we don't necessarily know the whole history behind the APIs. So Energia's errors are mostly compiler errors.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

I have been trying to test out the SLFS class as kindly provided by Spirilis but have following problem:

Compilation OK

Download OK

First print to console OK - "Start" is fine

Then no further printout to console.

 

Its the same of two different cc3200 dev boards.

 

I am new to Energia and cpp as well. Any help appreciated.

 

 

This is the code:

#include <WiFi.h>
#include <SLFS.h>

void setup()
{
   Serial.begin(9600);
}

void loop()
{
Serial.println("Start");
SerFlash.open("myfile.txt", FS_MODE_OPEN_CREATE(1024, _FS_FILE_OPEN_FLAG_COMMIT));
Serial.println("After Create");
SerFlash.open("myfile.txt", FS_MODE_OPEN_WRITE);  
Serial.println("After Open");
SerFlash.write("HelloWorld");
Serial.println("After Wrting some text);
SerFlash.close();

}
Edited by bluehash
[ADMIN] Added code tags. Please use code tags when writing code.

Share this post


Link to post
Share on other sites

That's a brill suggestion and it works!!

 

The actual syntax is:

SerFlash.begin();

 

I have amended the code snippet (just to stop your memory wearing out):

#include <WiFi.h>
#include <SLFS.h>

void setup()
{
SerFlash.begin(); // <====== Essential! Initiates the SimpleLink API and DMA channels.
Serial.begin(9600);
Serial.println("Start");
SerFlash.open("myfile.txt", FS_MODE_OPEN_CREATE(1024, _FS_FILE_OPEN_FLAG_COMMIT));
Serial.println("After Create");
SerFlash.open("myfile.txt", FS_MODE_OPEN_WRITE);  
Serial.println("After Open");
SerFlash.write("HelloWorld");
Serial.println("After Wrting some text);
SerFlash.close();
// etc
}

void loop()
{

}
Edited by bluehash
[ADMIN] Added code tags.

Share this post


Link to post
Share on other sites

Erm stopped in my tracks, 

 

I just don't get how to read the file's contents back in and print the result out.

 

I presume I use the following to make open the existing file for read mode ?

 

SerFlash.open("myfile2.txt", FS_MODE_OPEN_READ);

 

Then I use the following and assign the contents somehow to a char[] string?


SerFlash.readBytes(char *buffer, size_t len);

 

I just don't know how to get the stored data out (from the buffer??) and show it in the console. Do I need an iterative loop of some sort?

 

Pardon my ignorance - this is probably fundamental.

 


 

Share this post


Link to post
Share on other sites

Ah yes it is- all depends on what the data is. Likewise .read() can help you read it 1 byte at a time. If it's string data, and you supply a "len" value that's as large as buffer (and the amt of data is less than that) then you can probably just do Serial.println(buffer) afterward. I believe SerFlash.readBytes() will return the actual # of bytes read. Subsequent read or readBytes will continue where the previous left off (assuming the file is big enough relative to your buffer size and "len" value)

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

I added to craggmire's example a little bit and it works great!

 

My only issue is that SerFlash.write was able to take "HelloWorld" as the only argument without a 'len' argument:

size_t SLFS::write(const uint8_t *buffer, size_t len).

 

I made sure to SerFlash.close() after every SerFlash.open() because I'm assuming that's how files are supposed to be handled. I could be wrong.

 

Note: I used the latest "SLFS" files from Spirilis' github page. I used the latest files of "/hardware/cc3200/libraries/WiFi" & "/hardware/cc3200/cores/cc3200" from the Energia github page.

 

Here's the example below:


#include <SLFS.h>
#include <WiFi.h>
#include <SPI.h>

char flash_buffer[128];

void setup()
{
  Serial.begin(9600);
  
  pinMode(RED_LED, OUTPUT);
  digitalWrite(RED_LED, HIGH);
  delay(5000);      // wait for a bit
  digitalWrite(RED_LED, LOW);
  
  SerFlash.begin(); // <====== Essential! Initiates the SimpleLink API and DMA channels.

  Serial.println("Start & Create");
  SerFlash.open("myfile.txt", FS_MODE_OPEN_CREATE(1024, _FS_FILE_OPEN_FLAG_COMMIT));
  SerFlash.close();    // I'm assuming this is good practice
  
  Serial.println("Write");  
  SerFlash.open("myfile.txt", FS_MODE_OPEN_WRITE);
  SerFlash.write("HelloWorld");  // 10 characters
  SerFlash.close();
  
  Serial.println("Read");
  SerFlash.open("myfile.txt", FS_MODE_OPEN_READ);
  SerFlash.readBytes(flash_buffer, 11);
  SerFlash.close();
  
  flash_buffer[11] = '\0';  // making sure that trailing character is an EOF
  
  Serial.print("READ DATA: ");
  Serial.println(flash_buffer);
   
}

void loop()
{
  digitalWrite(RED_LED, HIGH);
  delay(1000);
  digitalWrite(RED_LED, LOW);
  delay(1000);
  Serial.println("Loop");
}

Share this post


Link to post
Share on other sites

Yeah the Stream library has lots of variants for print, println, write that can take args in different form- so you can do .write("string!") and end up triggering the .write(const char *) variant which in turn executes .write(buffer, strlen(buffer)) or something appropriate.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

I have put this code together to demonstrate the creation write and read of data to and then from SRAM.

 

I have avoided using the readBytes function and instead just use read(); for the reading in bit. 

 

// Craggmire  8th  November 2014
// CREATE, OPEN & READ demo using SLFS for TO CC3200
#include <WiFi.h>//Even if no WiFi used this file is essential
#include <SLFS.h>//SLFS slfs(); //this creates and instance slfs of the Class SLFS (TI's simpleLink Filing System)
 
void setup()
{
  char initialCharacterString[100]="BrightonToLondonViaEridgeLine";
  char readInString[100];
 
  int openok;
  int filelengthWritten;
  int readStatus;
  int ValueReturnedByRead;
  int n;
 
  Serial.begin(9600);//sets serial line to a manageable speed
  Serial.println("Start");
  Serial.println("The Initial String: ");
  Serial.println("-----------------------------");
  Serial.println(initialCharacterString);
  Serial.println("-----------------------------");
  
  // BEGIN SLFS  
  SerFlash.begin();//Essential fof SLFS sets up the DMA etc actually seems to do a WiFi.init(); function call
 
  // THIS CREATES THE FILE ---------------------------
  openok=SerFlash.open("myfile.txt", FS_MODE_OPEN_CREATE(1024, _FS_FILE_OPEN_FLAG_COMMIT));// create and open the file with this name
  Serial.print("File created :  "); 
  Serial.println(openok);
 
  // THIS OPENS THE FILE FOR WRITING -----------------
  openok=SerFlash.open("myfile.txt", FS_MODE_OPEN_WRITE);  //open ile for writing to
  Serial.print("File Opened : "); 
  Serial.println(openok);
  filelengthWritten =SerFlash.write(initialCharacterString);// write content to the file
  Serial.print("File length WRITTEN out : "); 
  Serial.println(filelengthWritten);
  SerFlash.close();// close the file
  
  // READ IN THE FILE FROM SRAM --------------------------
  Serial.println("=============================");
  Serial.println("---- File now being read:");
  readStatus= SerFlash.open("myfile.txt", FS_MODE_OPEN_READ); 
  Serial.print("File Read Status: ");
  Serial.println(readStatus);
  Serial.println("String returned by Read(): ");
  Serial.println("-----------------------------");
  n=0;
  do
  {
    ValueReturnedByRead=SerFlash.read(); 
    if  (ValueReturnedByRead != -1)
    {
      readInString[n]= (char)ValueReturnedByRead; //integer cast to char
      Serial.print(readInString[n]);
 
      n++;
    }
  }
  while (ValueReturnedByRead != -1);
  Serial.println();
  Serial.println("-----------------------------");
  SerFlash.close();// close the file
}
 
void loop()
{
}

Share this post


Link to post
Share on other sites

Thanks @@craggmire! Remember to null terminate readInString at the end before you do anything with the whole string (actually you never print the readInString var as a whole string, just each individual character as it comes in- you could use a single char variable for that here)

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...