SD Card write/read & button setup
答复
19-6-10 下午2:31

Hi everyone,

I am workingn on an application with the XDK. 

I want the application to do this:

  • write the temperature, pressure, RH and light data on the SD card every time the button 1 is pressed. And stop doing this when the button 2 is pressed.

I started this project using the SDExample availale on the XDK Welcome Page (Workbench 3.6).

Although the XDK can write the sensor data with no problem (the data on the SD is right), there is still an issue when I try to read what was written in the SD Card (the error I get comes from lines 313 - 319). I guess this happens because of the data type, but I have not been able to figure out how to fix it.

The error I get is this one:

 

 

Regarding the button implementation, I have a problem with the setup. I think this happens because there are two structures that need the handle AppCmdProcessor, one for the sensor setup and the other for the button setup, lines 542 - 546.

 

I attach my code:

/* module includes ********************************************************** */

/* own header files */
#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* own header files */
#include "AppController.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "XDK_Sensor.h"
#include "XDK_Button.h"
#include "XDK_Storage.h"
#include "XDK_LED.h"
#include "BCDS_SDCard_Driver.h"
#include "BCDS_CmdProcessor.h"
#include "XDK_Utils.h"
#include "BSP_BoardType.h"
#include "BCDS_Assert.h"
#include <FreeRTOS.h>
#include <timers.h>
/* constant definitions ***************************************************** */
/* Ram buffers
 * BUFFERSIZE should be between 512 and 1024, depending on available ram on efm32
 */
#define BUFFER_SIZE                 UINT16_C(512)
#define NUMBER_SAMPLES              UINT16_C(5)
#define SINGLE_BLOCK                UINT8_C(1)      /**< SD- Card Single block write or read */
#define DRIVE_ZERO                  UINT8_C(0)      /**< SD Card Drive 0 location */
#define SECTOR_VALUE                UINT8_C(6)      /**< SDC Disk sector value */
#define SINGLE_SECTOR_LEN           UINT32_C(512)   /**< Single sector size in SDcard */

#define APP_TEMPERATURE_OFFSET_CORRECTION   (-3459)

/* local variables ********************************************************** */

int statusGeneral=1;

/* local module global variable declarations */
Storage_Setup_T StorageSetupInfo =
        {
                .SDCard = true,
                .WiFiFileSystem = false
        };/**< Storage setup parameters */

static Sensor_Setup_T SensorSetup =
        {
                .CmdProcessorHandle = NULL,
                .Enable =
                        {
                                .Accel = false,
                                .Mag = false,
                                .Gyro = false,
                                .Humidity = true,
                                .Temp = true,
                                .Pressure = true,
                                .Light = true,
                                .Noise = true,
                        },
                .Config =
                        {
                                .Accel =
                                        {
                                                .Type = SENSOR_ACCEL_BMA280,
                                                .IsRawData = false,
                                                .IsInteruptEnabled = false,
                                                .Callback = NULL,
                                        },
                                .Gyro =
                                        {
                                                .Type = SENSOR_GYRO_BMG160,
                                                .IsRawData = false,
                                        },
                                .Mag =
                                        {
                                                .IsRawData = false,
                                        },
                                .Light =
                                        {
                                                .IsInteruptEnabled = false,
                                                .Callback = NULL,
                                        },
                                .Temp =
                                        {
                                                .OffsetCorrection = APP_TEMPERATURE_OFFSET_CORRECTION,
                                        },
                        },
        };/**< Sensor setup parameters */

static void Button1Callback(ButtonEvent_T buttonEvent);
static void Button2Callback(ButtonEvent_T buttonEvent);

static Button_Setup_T ButtonSetup =
        {
                .CmdProcessorHandle = NULL,
                .InternalButton1isEnabled = true,
                .InternalButton2isEnabled = true,
                .InternalButton1Callback = Button1Callback,
                .InternalButton2Callback = Button2Callback,
        };/**< Button setup parameters */

static CmdProcessor_T * AppCmdProcessor;/**< Handle to store the main Command processor handle to be used by run-time event driven threads */

static xTaskHandle AppControllerHandle = NULL;/**< OS thread handle for Application controller to be used by run-time blocking threads */

/* global variables ********************************************************* */

/* inline functions ********************************************************* */

/* local functions ********************************************************** */
/*
 * Function to compute average
 */
float averageFunction(long int array[],int sizeArray);

float averageFunction(long int array[], int sizeArray)
{
    float average=0;
    long int sum=0;
    int i;

    for(i=0;i<sizeArray;i++)
    {
        sum=sum+array[i];
    }

    average=(float)sum/sizeArray;
    return average;
}

static void Button1Callback(ButtonEvent_T buttonEvent)
{
    Retcode_T retcode = RETCODE_OK;
    switch (buttonEvent)
    {
    case BUTTON_EVENT_PRESSED:
        {
            statusGeneral=1;
            retcode = LED_On(LED_INBUILT_YELLOW);
            if (RETCODE_OK == retcode)
            {
                retcode = LED_Off(LED_INBUILT_ORANGE);
            }
            if (RETCODE_OK == retcode)
            {
                printf("Button1Callback : PB1 Pressed \r\n");
            }
            else
            {
                printf("Button1Callback : PB1 Pressed but setting LED state failed \r\n");
            }
        }
            break;
    default:
        printf("Button1Callback : Unsolicited button event occurred for PB1 \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INVALID_PARAM);
        break;
    }
    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
    }
}

/**
 * @brief
 *      ThIS API uses the FAT file system library calls.
 *      This API will write and read files and it will compare the contents which has been
 *      written and read.
 *
 * @retval
 *      RETCODE_OK - All the file operations are success
 *
 * @retval
 *      #SDCARD_APP_ERROR - when there is a mismatch in read and write buffer
 *
 * @retval
 *      #FILE_WRITE_ERROR - when file system write is failed
 *
 * @retval
 *      #FILE_READ_ERROR - when file system read is failed
 */

static Retcode_T AppControllerFatFileSystemWriteRead(int8_t stringTestBuffer[])
{
    uint8_t ramBufferWrite[BUFFER_SIZE]; /* Temporary buffer for write file */
    uint8_t ramBufferRead[BUFFER_SIZE]; /* Temporary buffer for read file */

    uint16_t fileSize = strlen(stringTestBuffer);

    static uint32_t writeOffset = 0, readOffset = 0;
    Retcode_T retcode = RETCODE_OK;

    printf("Size of buffer: %u \r\n",fileSize);

    for (uint32_t index = 0; index < fileSize; index++)
    {
        ramBufferWrite[index] = stringTestBuffer[index];
    }

    Storage_Read_T readCredentials =
            {
                    .FileName = TEST_FILENAME,
                    .ReadBuffer = ramBufferRead,
                    .BytesToRead = fileSize,
                    .ActualBytesRead = 0UL,
                    .Offset = 0UL,
            };
    Storage_Write_T writeCredentials =
            {
                    .FileName = TEST_FILENAME,
                    .WriteBuffer = ramBufferWrite,
                    .BytesToWrite = fileSize,
                    .ActualBytesWritten = 0UL,
                    .Offset = 0UL,
            };

    writeCredentials.Offset = writeOffset;
    retcode = Storage_Write(STORAGE_MEDIUM_SD_CARD, &writeCredentials);
    if (RETCODE_OK == retcode)
    {
        if (writeCredentials.BytesToWrite == writeCredentials.ActualBytesWritten)
        {
            writeOffset = writeOffset + writeCredentials.BytesToWrite;
            readCredentials.Offset = readOffset;
            retcode = Storage_Read(STORAGE_MEDIUM_SD_CARD, &readCredentials);
        }
        else
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, FILE_WRITE_ERROR);
        }
    }
    if (RETCODE_OK == retcode)
    {
        if (readCredentials.BytesToRead == readCredentials.ActualBytesRead)
        {
            readOffset = writeOffset - readCredentials.BytesToRead;
        }
        else
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, FILE_READ_ERROR);
        }
    }
    if (RETCODE_OK == retcode)
    {
        for (uint32_t index = 0; index < fileSize; index++)
        {
            printf("%u ",ramBufferWrite[index]);
        }
        printf("\r\n");
        for (uint32_t index = 0; index < fileSize; index++)
        {
            printf("%u ",ramBufferRead[index]);
        }
        printf("\r\n");

        for (uint8_t index = 0; index < fileSize; index++)
        {
            if ((ramBufferWrite[index]) != (ramBufferRead[index]))
            {
                /* Error compare buffers*/
                retcode = RETCODE(RETCODE_SEVERITY_ERROR, SDCARD_APP_ERROR);
            }
        }

    }
    return (retcode);
}

/**
 * @brief Responsible for controlling the SD card example flow
 *
 * - Check whether the storage medium (SD Card)is available or not
 * - if FAT_FILE_SYSTEM==1 then will write and read files and it will compare the contents which has been
 *   written and read.
 * - if FAT_FILE_SYSTEM==0 then it will write some string and read the string.
 *   then validate the written and read string.
 *
 * @param[in] pvParameters
 * Unused
 */
static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);
    Retcode_T retcode = RETCODE_OK, ledRetcode = RETCODE_OK;
    bool sdcardEject = false, status = false, sdcardInsert = false;
    while (1)
    {
        retcode = Storage_IsAvailable(STORAGE_MEDIUM_SD_CARD, &status);
        if ((RETCODE_OK == retcode) && (true == status))
        {
            sdcardInsert = true;
            printf("SD card is inserted in XDK\n\r");
//            ledRetcode = LED_On(LED_INBUILT_YELLOW);
//            if (RETCODE_OK != ledRetcode)
//            {
//                printf("SD card is inserted LED indication failure XDK\n\r");
//            }
            if (sdcardEject == true)
            {
                retcode = Storage_Disable(STORAGE_MEDIUM_SD_CARD);
                if (RETCODE_OK == retcode)
                {
                    retcode = Storage_Enable();
                }
                if (RETCODE_OK == retcode)
                {
                    sdcardEject = false;
                }
            }
            /* Already restrict this value to be 0 or 1. */
            if (RETCODE_OK == retcode)
            {
            //    if(statusGeneral==1)
                //{
                    Sensor_Value_T sensorValue;
                    memset(&sensorValue, 0x00, sizeof(sensorValue));
                    retcode = Sensor_GetData(&sensorValue);

                    int8_t EnvironmentalData[BUFFER_SIZE] = { 0 }; //to store sensor data
                    int timeSample=1000;
                    long int TempArray[NUMBER_SAMPLES]={ 0 };
                    long int PressArray[NUMBER_SAMPLES]={ 0 };
                    long int RHArray[NUMBER_SAMPLES]={ 0 };
                    long int LightArray[NUMBER_SAMPLES]={ 0 };
                    //long int NoiseArray[NUMBER_SAMPLES]={ 0 };

                    for(int i=0;i<NUMBER_SAMPLES;i++)
                    {
                        TempArray[i]=(long int) sensorValue.Temp;
                        PressArray[i]=(long int) sensorValue.Pressure;
                        RHArray[i]=(long int) sensorValue.RH;
                        LightArray[i]=(long int) sensorValue.Light;
                        //NoiseArray[i]=(long int) sensorValue.Noise;
                        vTaskDelay(timeSample);
                    }

                    long int TempAverage=(long int)averageFunction(TempArray,NUMBER_SAMPLES);
                    long int PressAverage=(long int)averageFunction(PressArray,NUMBER_SAMPLES);
                    long int RHAverage=(long int)averageFunction(RHArray,NUMBER_SAMPLES);
                    long int LightAverage=(long int)averageFunction(LightArray,NUMBER_SAMPLES);
                    //long int NoiseAverage=(long int)averageFunction(NoiseArray,NUMBER_SAMPLES);

                    if (RETCODE_OK == retcode)
                    {
                        sprintf((char*)EnvironmentalData, "T=%ld P=%ld RH=%ld L=%ld\n",
                                TempAverage,PressAverage,RHAverage,LightAverage);

                        //printf("Temperature: %ld milliC\r\n",TempAverage);
                        retcode = AppControllerFatFileSystemWriteRead((int8_t*)EnvironmentalData);
                    }
                //}
            }
            if (RETCODE_OK == retcode)
            {
                printf("Write and read using FAT file system success \n\r");
            }
            else
            {
                printf("Write and read using FAT file system failed\n\r");
            }
        }
        else
        {
            if (Retcode_GetCode(retcode) == (Retcode_T) RETCODE_STORAGE_SDCARD_UNINITIALIZED)
            {
                printf("\r\n SD card is not inserted in XDK\n\r");
                retcode = Storage_Enable();
            }
            else
            {
                if (true == sdcardInsert)
                {
                    sdcardEject = true;
                }
                sdcardInsert = false;
                printf("\r\nSD card is removed from XDK\n\r");
                ledRetcode = LED_Off(LED_INBUILT_RED);
                if (RETCODE_OK != ledRetcode)
                {
                    printf("SD card is not inserted LED indication failure XDK\n\r");
                }

            }
        }
        if (RETCODE_OK != retcode)
        {
            Retcode_RaiseError(retcode);
        }
        //vTaskDelay(pdMS_TO_TICKS(WRITEREAD_DELAY));
        printf("--------------------------------\r\n");
    }
}

/**
 * @brief To enable the necessary modules for the application
 * - SD Card
 * - LED
 *
 * @param[in] param1
 * Unused
 *
 * @param[in] param2
 * Unused
 */
static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode, fileDeleteRetcode = RETCODE_OK;

    retcode = Sensor_Enable();
    if (RETCODE_OK == retcode)
    {
        retcode = Storage_Enable();
    }
    if ((Retcode_T) RETCODE_STORAGE_SDCARD_NOT_AVAILABLE == Retcode_GetCode((retcode)))
    {
        /* This is only a warning error. So we will raise and proceed */
        Retcode_RaiseError(retcode);
        retcode = RETCODE_OK; /* SD card was not inserted */
    }
    if (RETCODE_OK == retcode)
    {
        fileDeleteRetcode = Storage_Delete(STORAGE_MEDIUM_SD_CARD, TEST_FILENAME);
        if (RETCODE_OK != fileDeleteRetcode)
        {
            printf("File does not exist. \n\r");
        }
    }
    if (RETCODE_OK == retcode)
    {
        retcode = LED_Enable();
    }
    if (RETCODE_OK == retcode)
    {
        retcode = Button_Enable();
    }

    if (RETCODE_OK == retcode)
    {
        if (pdPASS != xTaskCreate(AppControllerFire, (const char * const ) "AppController", TASK_STACK_SIZE_APP_CONTROLLER, NULL, TASK_PRIO_APP_CONTROLLER, &AppControllerHandle))
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES);
        }
    }
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerEnable : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }

    Utils_PrintResetCause();
}

/**
 * @brief To setup the necessary modules for the application
 * - SD Card
 * - LED
 *
 * @param[in] param1
 * Unused
 *
 * @param[in] param2
 * Unused
 */
static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);

    SensorSetup.CmdProcessorHandle = AppCmdProcessor;

    Retcode_T retcode = Sensor_Setup(&SensorSetup);

    if (RETCODE_OK == retcode)
    {
        retcode = Storage_Setup(&StorageSetupInfo);
    }

    if (RETCODE_OK == retcode)
    {
        retcode = LED_Setup();
    }
    if (RETCODE_OK == retcode)
   {
        ButtonSetup.CmdProcessorHandle = AppCmdProcessor;
        retcode = Button_Setup(&ButtonSetup);
    }
    if (RETCODE_OK == retcode)
    {
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));
    }
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/* global functions ********************************************************* */

/** Refer interface header for description */
void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/**@} */
/** ************************************************************************* */

Thank you for your help.

0 (0 票)
RE: SD Card write/read & button setup
答复
19-6-11 下午1:53 回复Bruno Rodriguez。

Hi Bruno,

I think for the SD card, this example is much better:

https://developer.bosch.com/web/xdk/sd-card#5

There is also a detailed documentation for the use of the SD card.
Regarding the buttons, do you have any error codes or what do you mean exactly?

regards

Saeid

0 (0 票)
RE: SD Card write/read & button setup
答复
19-6-12 上午7:29 回复Saeid Kajlar。

Hi Saeid,

why do i get an error in this example ?

"Symbol 'FR_OK' could not be resolved".

 

regards

Michael

0 (0 票)
RE: SD Card write/read & button setup
答复
19-6-12 上午11:57 回复Michael Österreicher。

Hi Michael,

That's just an index error. It is because the mingw/eclipse tool is not able to find the FR_OK, but the project knows the location of FR_OK, hence during compilation there is no error.

regards

Saeid

0 (0 票)
RE: SD Card write/read & button setup
答复
19-6-13 下午2:03 回复Saeid Kajlar。

Hi Saeid,

As to the SD Card problem, my code works find when it comes to writing the right data and format, but it fails when it tries to read what was written on the SD Card. Although this issue could be fixed by removing the lines 314 to 321, I want to keep them to be sure the info on the SD card has no errors. I am almost sure this problem has to do with type casting. By implementing the example you mentioned, is this error fixed? I am using the 3.6 version of the workbench.

Regarding the buttons' setup, I do not know how to pass the handle AppCmdProcessor to both  SensorSetup.CmdProcessorHandle and ButtonSetup.CmdProcessorHandle. I get an error when I do so as shown in the attached picture. 

Thanks for your help.

Regards

0 (0 票)