You are here

FreeRTOS FAT SL PSoC Example Project (part-1) | 赛普拉斯半导体

FreeRTOS FAT SL PSoC Example Project (part-1)

[re-printed from iotexpert.com]

In the previous articles I discussed using the FRAM, and making a FreeRTOS FAT SL media driver. In this article I will discuss building an example project that uses that work to make a real FreeRTOS FAT SL system example.  I was originally planning on making just one article explaining the example, but my example code turned out to be a little bit sprawling, so I decided to break it into two pieces.  In part 1 (this article) I will

  1. Build the FreeRTOS Template
  2. Import the FreeRTOS FAT SL FileSystem & FRAM Media Driver
  3. Build a command line interpreter
  4. Nuke the data in the FRAM

In the next article I will show you the details of using the FreeRTOS FAT SL filesystem.

Build the FreeRTOS Template & Schematic

I start the project from my FreeRTOS template project.  You can read all about that here.  Then I add in the components required to make things work.  The schematic is simple:

  • A UART component to run the Command Line Interpreter
  • An I2C to control the FRAM

CY3295 Kit Image

The I2C is setup as a master at it highest speed setting.

CY3295 Kit Image

On the CY8CKIT-044 the pins need to be configured as so:

CY3295 Kit Image

Import the FreeRTOS FAT SL FileSystem & FRAM Media Driver

The first step in importing the FreeRTOS FAT SL FileSystem and and media driver is to copy the FreeRTOS-Plus-FAT-SL directory into my project.  Once that is done, my folder structure looks like this:

CY3295 Kit Image

The next step is to fix the include paths to include the config, api and psp include directories.  This can be done on the build settings menu.

CY3295 Kit Image

Finally I import the .h and .c files into my project so that it looks like this:

CY3295 Kit Image

Build a Command Line Interpreter (CLI)

I think that it is convenient to have a command line utility (one that connects to the UART port) to send commands to my program to test it.  To build the CLI, I create a task called uartTask which takes keys from the terminal and then processes them in a giant switch statement.  While I was building the FreeRTOS FAT SL system, I noticed that FreeRTOS also has a scheme for CLIs which I will try out in the future.

In the UART configuration I turn on the “RX FIFO not empty” interrupt (meaning that there is data in the fifo that needs to be processed)

CY3295 Kit Image

I connect the interrupt to the interrupt service routine on line 64.  In the ISR I use the FreeRTOS notification scheme to send notifications to the uartTask to wakeup and process data (line 50).

My CLI has two different things that it does:

  • It calls functions in the file extestfs.c that start with “ex” , meaning example, to format, initalize etc.
  • It keeps a “currentSector” variable that lets me print out the raw data in a sector.  The currentSector variable is incremented (with the keyboard +) and decremented (with the keyboard -) and set to 0 with the (keyboard 0)

Once all of the keys have been processed (the Rx FIFO buffer is empty – line 71), it turns back on the Rx FIFO interrupt (lines 150-151), then waits for another notification from the ISR (line 69)

TaskHandle_t uartTaskHandle;
void uartISR()
{
    
    BaseType_t xHigherPriorityTaskWoken;
    // disable the interrupt
    UART_SetRxInterruptMode(0);
    vTaskNotifyGiveFromISR(uartTaskHandle,&xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    
}
 
// This is the main task which processes commands from the UART and prints the results
// on the screen.
void uartTask(void *arg)
{
    (void)arg;
    UART_Start();
    I2C_Start();
    clearScreen();
    UART_UartPutString("Start Filesystem Demo\n");
    UART_SetCustomInterruptHandler(uartISR);
    
    int currentSector=0;    
    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': // Initialize the RTOS
exInit();
break;
case 'f': // Format the FRAM
exFormat();
break;
                    
case 'q': // Return the drive information
exDriveInfo();
break;
                case 'w': // Create a file
    exCreateFile();
break;
case 'r': // Read the file that was created (if it exists)
    exReadFile();
break;
case '0': // Goto to sector 0 and print the data
    currentSector = 0;
exPrintSector(0,0,0);
break;
    case '+': // Print the "current" sector and go to the next
    exPrintSector(0,0,currentSector);
    currentSector += 1;
    break;
    case '-': // print the current sector and go to the previous
    exPrintSector(0,0,currentSector);
    currentSector -= 1;
    if(currentSector<0)
    currentSector =0;
    break;
                    
    case 'd': // Do a directory
    exDirectory();
    break;
                    
                case 'c':
                    clearScreen();
                break;
                    
                case 'b': // Erase the FRAM (write all 0's)
                    blankFRAM();
                break;
                case '?': // Print out the list of commands
                    UART_UartPutString("b - Blank FRAM - write all 0's\n");
                    UART_UartPutString("i - Initalize Filesystem\n");
                    UART_UartPutString("f - Format FRAM\n");
                    UART_UartPutString("q - Print FileSystem Information\n");
                    UART_UartPutString("w - Create a file called \"afile.bin\"\n");
                    UART_UartPutString("r - Read the file called \"afile.bin\" and print contents\n");
                    UART_UartPutString("0 - Goto sector 0 and print contents\n");
                    UART_UartPutString("+ - Goto next sector and print contents\n");
                    UART_UartPutString("- - Goto previous sector and print contents\n");
                    UART_UartPutString("d - Print Directory\n");
                    UART_UartPutString("c - Clear Screen\n");
                    UART_UartPutString("? - Print help\n");        
                    
                break;
                    
    default:
    UART_UartPutString("Unknown :");
    UART_UartPutChar(c);
    UART_UartPutChar('\n');
    break;
}
        }
        // Turn the interrupts back on
        UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY);
        UART_SetRxInterruptMode(UART_INTR_RX_NOT_EMPTY);
    }
}

Nuke the FRAM Data

I thought that it would be a good idea to have a function to put 0’s in all of the locations in the FRAM, to prove that I could start with a clean slate.  This function does just that.  Specifically it write 0’s to the 64K locations in I2C address 0x50 (the first bank) and to I2C address 0x51 (the second bank)

// This function erases - write 0's into the FRAM... also known as NUKE the FRAM
void blankFRAM(void)
{
    int i;
    UART_UartPutString("Starting Erase 1st Block\n");
    I2C_I2CMasterSendStart(0x50,I2C_I2C_WRITE_XFER_MODE);
    I2C_I2CMasterWriteByte(0);
    I2C_I2CMasterWriteByte(0);
    for(i=0;i<0xFFFF;i++) // Write 64K of 0's to erase first bank
    {
        I2C_I2CMasterWriteByte(0);
    }
    I2C_I2CMasterSendStop();
    UART_UartPutString("Starting Erase 2nd Block\n");
    I2C_I2CMasterSendStart(0x51,I2C_I2C_WRITE_XFER_MODE);
    I2C_I2CMasterWriteByte(0);
    I2C_I2CMasterWriteByte(0);
    for(i=0;i<0xFFFF;i++) // write 64k of 0's to erase 2nd bank
    {
        I2C_I2CMasterWriteByte(0);
    }
    I2C_I2CMasterSendStop();
    
    UART_UartPutString("Erase Complete\n");
 
}

As always you can find this project on the IoT Expert GitHub site git@github.com:iotexpert/PSoC-FileSystem.git

Blog: 

Comments

wasi2_3144216's picture

 I thought that it would be a good idea to have a function to put 0’s in all of the locations in the FRAM, to prove that I could start with a clean slate.  hot-slimming-pants This function does just that.  

electionresults2017.com_3146876's picture

how to get Freedom 251 phone in online at lowest price and offers...

本网站上的所有内容和材料均“按原样”提供。赛普拉斯半导体公司及其各个供应商对这些材料用于任何用途的适用性不作陈述,并且对关于这些材料的所有担保和条件概不负责,包括但不限于有关适销性、针对特定用途之适用性、权利和不侵犯任何第三方知识产权的所有暗示担保和条件。赛普拉斯半导体公司不授予任何明示或暗示的许可(无论是以默许方式或是任何其他方式)。使用本网站上的信息可能需要第三方的许可,或赛普拉斯半导体公司的许可。

本网站上的内容可能包含或必须遵守关于使用的特定准则或限制。所有帖子和使用本网站上的内容都必须遵守本网站的条款与条件;使用这些内容的第三方必须同意遵守任何限制或准则,并遵守本网站的条款与条件。赛普拉斯半导体公司及其供应商保留随时对内容和材料、产品、计划和服务进行纠正、删除、修改、增强、改进或其他变更,或者移动或终止任何内容、产品、计划或服务的权利,恕不另行通知。