Mita: SD card writing problem
Risposta
28/05/19 13.59

Dear All,

I have experienced a problem when writing to a file on a microSD card: the maximum file size seems to be 65 kB. Rebooting the XDK and continuing to write to the same file doesn't help, it sees as some buffer if full... Maybe it has something to do with the "writer" in a snippet below?

setup sd : SDCard {
	var writer : string = appendingTextWrite("CollectedData.csv");
}

...

every 100 milliseconds {
	sd.writer.write(`${accelerationX} , ${accelerationY} , ${accelerationZ} , ${pressure} , ${realCycleTime} \n`);
}

It might be a trivial issue... Do you have any idea what am I missing?

All the best, Krzysztof

0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
28/05/19 15.03 come risposta a Krzysztof Wilczynski.

Hello Krzystof,

Your code seems to be ok.
Format your SD card with FAT32 file system. Sometimes it helps.

regards

Saeid

0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
29/05/19 5.44 come risposta a Saeid Kajlar.
I already tried formatting the card with FAT32 using different allocation unit sizes additionally. Doesn't help unfortunately... :(
0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
29/05/19 18.44 come risposta a Krzysztof Wilczynski.
Hello Krzysztof,

The FatFs implementation delivered with XDK/Mita is a tricky one. What is the C-code generated by Mita?

Regards,

Francisco
0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
30/05/19 7.12 come risposta a Francisco Llobet Blandino.

Hello Francisco,

Thanks for your reply. I guess I don't fully understand the way Mita ports SD card configuration to C... If you are willing to look into it, I am more than happy to post it in the snippet below (the parts I think may matter):

This is what happens in the main DAQ loop (every x milliseconds):

struct bma2x2_accel_data sensorAccelerometerModalityPreparation_1;
exception = SensorAccelerometer_ReadXYZ(&sensorAccelerometerModalityPreparation_1);
if(exception != NO_EXCEPTION) return exception;
		
accelerationX = sensorAccelerometerModalityPreparation_1.x;
accelerationY = sensorAccelerometerModalityPreparation_1.y;
accelerationZ = sensorAccelerometerModalityPreparation_1.z;
Environmental_Data_T sensorEnvironmentModalityPreparation_2;
exception = Environmental_readData(xdkEnvironmental_BME280_Handle, &sensorEnvironmentModalityPreparation_2);
if(exception != NO_EXCEPTION) return exception;
		
pressure = sensorEnvironmentModalityPreparation_2.pressure;
double realCycleTime = cycleTime * 100;
char result480422229_buf[73] = {0};
char *result480422229 = result480422229_buf;
		
char IfStatement2Result480422229_3_buf[73] = {0};
snprintf(IfStatement2Result480422229_3_buf, sizeof(IfStatement2Result480422229_3_buf), "%" PRId32 " , %" PRId32 " , %" PRId32 " , %" PRIu32 " , %.6g \n", accelerationX, accelerationY, accelerationZ, pressure, realCycleTime);
memcpy(result480422229, IfStatement2Result480422229_3_buf, sizeof(IfStatement2Result480422229_3_buf));

char* _newInputOutputSDCardSd_Writer_1 = result480422229;
exception = InputOutputSDCardSd_Writer_Write(&_newInputOutputSDCardSd_Writer_1);
if(exception != NO_EXCEPTION) return exception;

 

I'll make some experiments with a simple app writing just a static string to a file on the card... Posting my full code with many not-so-important variables is not the best way around...

Which part of the C code do you think is crucial?

Thanks for your will to help!

All the best,

Krzysztof

0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
30/05/19 8.12 come risposta a Krzysztof Wilczynski.

Hello again!

I have made a quick test with a simple code which just writes "blah blah blah" to a csv file on the card. The problem persists. The maximum file size seems to be 65kB... Here is the Mita code:

package main;
import platforms.xdk110;

setup XDK110 {
	applicationName = "SDTest";	
	startupDelay = 5000;		
}
setup sd : SDCard {
	var writer : string = appendingTextWrite("CollectedData.csv");
}
setup led : LED {
	var red : bool = light_up(Red);
}
every XDK110.startup{
	led.red.write(true);
}
every 100 milliseconds {
	sd.writer.write(`Blah , Blah , Blah , Blah , Blah \n`);
}

 

Here are the generated files:

application.c :

/**
 * Generated by Eclipse Mita 0.1.0.
 * @date 2019-05-30 09:17:00
 */


#include <string.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
#include <BCDS_Basics.h>
#include <BCDS_Retcode.h>
#include "InputOutputSDCardSd.h"
#include "ConnectivityLEDLed.h"
#include "MitaExceptions.h"
#include "application.h"

#ifndef BCDS_MODULE_ID
#define BCDS_MODULE_ID 0xCAFE
#endif


Retcode_T initGlobalVariables_application() {
	Retcode_T exception = RETCODE_OK;
	
	return exception;
}

Retcode_T HandleEveryXDK110Startup1(void* userParameter1, uint32_t userParameter2)
{
	
	BCDS_UNUSED(userParameter1);
	BCDS_UNUSED(userParameter2);

	Retcode_T exception = NO_EXCEPTION;
	
	
	bool _newConnectivityLEDLed_Red_1 = true;
	exception = ConnectivityLEDLed_Red_Write(&_newConnectivityLEDLed_Red_1);
	if(exception != NO_EXCEPTION) return exception;


	return NO_EXCEPTION;
}

Retcode_T HandleEvery100Millisecond1(void* userParameter1, uint32_t userParameter2)
{
	
	BCDS_UNUSED(userParameter1);
	BCDS_UNUSED(userParameter2);

	Retcode_T exception = NO_EXCEPTION;
	
	
	char result549480731_buf[36] = {0};
	char *result549480731 = result549480731_buf;
	
	char mainHandleEvery100Millisecond12Result549480731_2_buf[36] = {0};
	snprintf(mainHandleEvery100Millisecond12Result549480731_2_buf, sizeof(mainHandleEvery100Millisecond12Result549480731_2_buf), "Blah , Blah , Blah , Blah , Blah \n");
	memcpy(result549480731, mainHandleEvery100Millisecond12Result549480731_2_buf, sizeof(mainHandleEvery100Millisecond12Result549480731_2_buf));
	
	char* _newInputOutputSDCardSd_Writer_1 = result549480731;
	exception = InputOutputSDCardSd_Writer_Write(&_newInputOutputSDCardSd_Writer_1);
	if(exception != NO_EXCEPTION) return exception;


	return NO_EXCEPTION;
}


 

main.c :

/**
 * Generated by Eclipse Mita 0.1.0.
 * @date 2019-05-30 09:17:00
 */


#include <BCDS_Basics.h>
#include <FreeRTOS.h>
#include <inttypes.h>
#include <BSP_ExtensionPort.h>
#include <BCDS_BSP_Board.h>
#include <BCDS_Retcode.h>
#include <stdio.h>
#include <BCDS_CmdProcessor.h>
#include <XdkSystemStartup.h>
#include <timers.h>
#include "application.h"
#include "ConnectivityLEDLed.h"
#include "InputOutputSDCardSd.h"
#include "MitaTime.h"
#include "MitaEvents.h"
#include "MitaExceptions.h"

static Retcode_T Mita_initialize(void* userParameter1, uint32_t userParameter2);
static Retcode_T Mita_goLive(void* userParameter1, uint32_t userParameter2);

CmdProcessor_T Mita_EventQueue;

/**
 * The priority of the event loop task. The default of 1 is just above the idle task
 * priority. Note that the platform may use tasks of higher prio, but XDK LIVE programs
 * are solely executed in this event loop context.
 */
#define TASK_PRIO_EVENT_LOOP         (UINT32_C(1))

/**
 * The stack size of the event loop task in 32-bit words. If you don't know what this
 * means, be careful when you change this value. More information can be found here:
 * http://www.freertos.org/FAQMem.html#StackSize
 */
#define TASK_STACK_SIZE_EVENT_LOOP   (UINT16_C(2000))

/**
 * The maximum number of events the event queue can hold. The default value should
 * be sufficient in most cases. If you need to handle a lot of events and have some
 * long running computations, you might want to increase this number if you find
 * events are missed.
 */
#define TASK_Q_LEN_EVENT_LOOP        (UINT32_C(10))


int main(void)
{
	/* Mapping Default Error Handling function */
	Retcode_T returnValue = Retcode_initialize(DefaultErrorHandlingFunc);
	if (RETCODE_OK == returnValue)
	{
	    returnValue = systemStartup();
	}
	if (RETCODE_OK == returnValue)
	{
		returnValue = CmdProcessor_Initialize(&Mita_EventQueue, (char *) "EventQueue", TASK_PRIO_EVENT_LOOP, TASK_STACK_SIZE_EVENT_LOOP, TASK_Q_LEN_EVENT_LOOP);
	}
	if (RETCODE_OK == returnValue)
	{
		returnValue = CmdProcessor_Enqueue(&Mita_EventQueue, Mita_initialize, NULL, UINT32_C(0));
	}
	if (RETCODE_OK == returnValue)
	{
	    returnValue = CmdProcessor_Enqueue(&Mita_EventQueue, Mita_goLive, NULL, UINT32_C(0));
	}
	if (RETCODE_OK == returnValue)
	{
		returnValue = CmdProcessor_Enqueue(&Mita_EventQueue, HandleEveryXDK110Startup1, NULL, UINT32_C(0));
	}
	if (RETCODE_OK != returnValue)
	{
	    printf("System Startup failed");
	    assert(false);
	}
	/* start scheduler */
	vTaskStartScheduler();
}

Retcode_T Mita_initialize(void* userParameter1, uint32_t userParameter2)
{
	BCDS_UNUSED(userParameter1);
	BCDS_UNUSED(userParameter2);
	Retcode_T exception = NO_EXCEPTION;
	
	BSP_Board_Delay(5000);

	// setup resources
	exception = InputOutputSDCardSd_Setup();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] setup InputOutputSDCardSd succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to setup InputOutputSDCardSd\n", __FILE__, __LINE__);
		return exception;
	}
	
	exception = ConnectivityLEDLed_Setup();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] setup ConnectivityLEDLed succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to setup ConnectivityLEDLed\n", __FILE__, __LINE__);
		return exception;
	}
	


	// setup time
	exception = SetupTime();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] setup Time succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to setup Time\n", __FILE__, __LINE__);
		return exception;
	}
	return exception;
}

Retcode_T Mita_goLive(void* userParameter1, uint32_t userParameter2)
{
	BCDS_UNUSED(userParameter1);
	BCDS_UNUSED(userParameter2);
	Retcode_T exception = NO_EXCEPTION;
	

	exception = EnableTime();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] enable Time succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to enable Time\n", __FILE__, __LINE__);
		return exception;
	}
	
	exception = InputOutputSDCardSd_Enable();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] enable InputOutputSDCardSd succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to enable InputOutputSDCardSd\n", __FILE__, __LINE__);
		return exception;
	}
	exception = ConnectivityLEDLed_Enable();
	if(exception == NO_EXCEPTION)
	{
		printf("[INFO, %s:%d] enable ConnectivityLEDLed succeeded\n", __FILE__, __LINE__);
	}
	else
	{
		printf("[ERROR, %s:%d] failed to enable ConnectivityLEDLed\n", __FILE__, __LINE__);
		return exception;
	}
	return NO_EXCEPTION;
}

 

I think it's quite easy to reproduce too. This seems like a quite significant bug in Mita... Hopefully it's not a stupid mistake of mine...

0 (0 Voti)
RE: Mita: SD card writing problem
Risposta
31/05/19 8.01 come risposta a Krzysztof Wilczynski.

FIX

Solved: there is a uint16_t variable "writerFilePosition" which limits the file size when appending in the generated C source. I just changed it to uint32_t...

Note do devs: fix it maybe? My github issue doesn't seem to drag too much attention... :(

+2 (2 Voti)
RE: Mita: SD card writing problem
Risposta
07/06/19 18.00 come risposta a Krzysztof Wilczynski.
Krzysztof, I was troubling on the same issue, your solution works perfectly! Now I'm working in create a unique CSV every 1 minute using an SNTP server. Thanks!!!
0 (0 Voti)