Summary
I just finished writing the “last” article about building a FreeRTOS FAT SL filesystem into the Cypress FM24V10 FRAM using a CY8CKIT-044. My implementation works pretty well…. but I am not really that happy with it. As I sit here and write this article I am not totally sure what I should do next.
I suppose the first thing to do is talk about the things that I don’t like in what I did.
- Real Time Clock
- Command Line Interpreter
- DMA Media Driver
- Include files
- F_FS_THREAD_AWARE 0
- Template project
- Performance Metrics
- Wear Leveling
- Performance Metrics
- Discussion of FAT Filesystems
Real Time Clock
As part of the port, you are supposed to provide psp_rtc.c which has one function, psp_getcurrentimedate. This function is used to get the time to use as a timestamp on files. I left it default, which means every transaction is timestamped the same, probably not good. Moreover, there is an RTC in the PSoC4200M that is on the CY8CKIT-044. The board also has the watch crystal which drives the RTC populated so there is really no good reason not to turn it on.
However, when I wrote the original example the command line interpreter that I build only took one character at a time, so there was no good way to set the clock. Which brings me to the next problem.
Command Line Interpreter (CLI)
When I originally build the example project my command interpreter just had an infinite loop that waited for a character from the keyboard, then did one command based on that character. It looks like this:
while(1) { ulTaskNotifyTake(pdTRUE,portMAX_DELAY); while(UART_SpiUartGetRxBufferSize()) // if there is data then read and process { char c; c= UART_UartGetChar(); switch(c) { case 'i': break; case '?': // Print out the list of commands break; default: break; } } // Turn the interrupts back on UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY); UART_SetRxInterruptMode(UART_INTR_RX_NOT_EMPTY); }
What I did was cheap and easy… but, FreeRTOS has a CLI built in, so I suppose that I should have used.
DMA Media Driver
When I read and write from the FRAM I put in code that is blocking. Meaning that it essentially hangs the entire system until they return. Not really good given that this is an RTOS. This is what all of the I2C_ functions below do.
status = I2C_I2CMasterSendStart( calcI2CAddress(sector),I2C_I2C_WRITE_XFER_MODE); if(status != I2C_I2C_MSTR_NO_ERROR) { UART_UartPutString("I2C Error\n"); return MDRIVER_RAM_ERR_SECTOR; } int i; I2C_I2CMasterWriteByte((address>>8)&0xFF); I2C_I2CMasterWriteByte(address & 0xFF); //
There is no reason that I shouldn’t have used the DMA engine to read and write the FRAM which would have freed up the processor.
Include files
I absolutely hate the scheme that I used to name and use the includes in the FreeRTOS FAT SL port. I should fix this for sure.
F_FS_THREAD_AWARE 0
When I originally tried to compile this project I marked this #define from “config_fat_sl.h” as “1”. However when I do that, I end up with this error which I should for sure fix as the code is not reentrant and this #define protects you.
Template project
My good friend Mark Saunders pointed out PSoC Creator has a new feature which you can use to make template projects.. which I didnt know about until he told me. Obviously this would be better than what I am doing.
Performance Metrics
I did not collect any performance metrics when I build this project. How much RAM? Flash? How long does it take to read and write files? I don’t know. Moreover, I put in debugging information into the media driver which was counter productive to good memory usage. For instance in this snip from the readsector function I define a big ass buffer of 128 bytes on line 134, then I printout a message to the uart each time this function is called.
static int fram_readsector ( F_DRIVER * driver, void * data, unsigned long sector ) { char buff[128]; // A scratch buffer for UART Printing (void)driver; uint16 address; uint32_t status; sprintf(buff,"Read sector %d\n",(int)sector); UART_UartPutString(buff);
Error Checking
There are a bunch of places where I could have put in much better error checking, and I didnt. For instance in this section of the readsector function if the I2C_I2CMasterWriteByte function fails, it probably hangs the I2C bus until the chip is reset… this is bad. Even when an error occurs, printing a message probably isn’t a good idea (line 146).
if(status != I2C_I2C_MSTR_NO_ERROR) { UART_UartPutString("I2C Error\n"); return MDRIVER_RAM_ERR_SECTOR; } int i; I2C_I2CMasterWriteByte((address>>8)&0xFF); I2C_I2CMasterWriteByte(address & 0xFF); // I2C_I2CMasterSendRestart(calcI2CAddress(sector),I2C_I2C_READ_XFER_MODE);
Wear Leveling
Many nonvolatile memory chip will wear out if you write them too many time. Even 100K cycles can easily happen on a key sector of the filesystem for instance sector 0. One convient thing about the FRAM is that it doesnt wear out. But, when I started this journey I was originally going to use the PSoC6 development kit which uses a NOR Flash. The NOR Flash will for sure wear out. To combat this problem, people have developed wear leveling schemes. But I don’t address this issue at all with my media driver.
Discussion of FAT Filesystems
As I wrote about the FreeRTOS FAT SL Filesystem I was originally planning a tutorial on file systems. But as I dug a little bit a whole bunch of issues came up which felt a little bit overwhelming to address. The issues that were left unaddressed are:
- Copywrite of the FAT File System
- Efficiency of FAT File Systems
- The licensing of the FreeRTOS FAT SL
- Other FAT implementations
I suppose that at some point I should come back and look at those issues.
4 Comments
Is it possible to use I2C with DMA? It would be a really nice new bog post 😛
Yes that will work (I think I haven’t tried it)… but that is my plan
Hi,
just found this project SPIffs [1] “Wear-leveled SPI flash file system for embedded devices”, it may be interesting to know how they handle the wear-leveling scheme.
[1] https://github.com/pellepl/spiffs
Yes… that is one that I am going to try… along with a half dozen other… unfortunately real work has been getting in the way!
Merry Christmas.