0

I'm trying to log data to SD card using Teensy 3.2. I've taken the code from Arduino Examples SD > ReadWrite.ino and modified it slightly to run it with FreeRTOS - no changes in the header libraries were made.

The code works fine when uploaded from Arduino IDE to Teensy 3.2. However, the code doesn't work when executed from a FreeRTOS task; I get the following output.

Initializing SD card... initialization done. 0 Error opening test.txt 2009 3009 4009

So, the SD is initialized, but then the code fails somewhere. When I plug the SD card to my PC, it appears the file is created, but with 0 B size.

Interestingly, if I simply move the code to setup() part (keeping all else intact), it runs just fine. This has left me scratching my head for a few hours now and I still can't figure out why this is happening.

Here's the code.

/*
SD card read/write

This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11, pin 7 on Teensy with audio board
** MISO - pin 12
** CLK - pin 13, pin 14 on Teensy with audio board
** CS - Select suitable pin

created   Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe

This example code is in the public domain.

*/

#include <FreeRTOS.h>
#include <task.h>
#include <timers.h>
#include <SD.h>
#include <SPI.h>

#define LOGFILE_NAME "test.txt"

// Enable to print received data to console (Serial)
#define DEBUG_PRINT_TO_CONSOLE 1

TaskHandle_t logger_taskhandle = NULL;

// change this to match your SD shield or module;
const int chipSelect = 10;

void setup()
{
    //UNCOMMENT THESE TWO LINES FOR TEENSY AUDIO BOARD:
    //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
    //SPI.setSCK(14);  // Audio shield has SCK on pin 14

    // Open serial communications and wait for port to open:
    Serial.begin(115200);

    xTaskCreate(logger_task, "logger", configMINIMAL_STACK_SIZE + 4096, NULL, tskIDLE_PRIORITY + 2, &logger_taskhandle);

    vTaskStartScheduler();

    while (true);
}

void logger_task(void *pvParameters)
{
    vTaskDelay(pdMS_TO_TICKS(2000));
    //while (!Serial) {}

    Serial.print("Initializing SD card... ");

    if (!SD.begin(chipSelect))
    {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    File myFile = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
    Serial.println(myFile, HEX);
    if (myFile)
    {
        Serial.printf("Writing to %s...\r\n", LOGFILE_NAME);
        myFile.println("testing 1, 2, 3.");
        //myFile.flush();
         //close the file:
        myFile.close();
        Serial.println("done.");
    }
    else
    {
        // if the file didn't open, print an error:
        Serial.printf("Error opening %s\r\n", LOGFILE_NAME);
        //return;
    }

    //// re-open the file for reading:
    //myFile = SD.open("test.txt");
    //if (myFile) 
    //{
    //  Serial.println("opened test.txt:");

    //  // read from the file until there's nothing else in it:
    //  while (myFile.available()) {
    //      Serial.write(myFile.read());
    //  }
    //  // close the file:
    //  myFile.close();
    //}
    //else {
    //  // if the file didn't open, print an error:
    //  Serial.println("error opening test.txt");
    //}

    while (true)
    {
        Serial.println(xTaskGetTickCount());
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void loop(){}

It doesn't seem to be a problem with the stack size as I've already allocated 4096 words. Task priority doesn't seem to be an issue since logger_task is the only task running. I've also tried changing the SPI speed in SD.cpp > SD.begin() method from SPI_HALF_SPEED to SPI_FULL_SPEED and SPI_QUARTER_SPEED to no avail.

The hardware setup is fairly straightforward: SD card breakout board is connected to Teensy 3.2 over SPI lines (Teensy 3.2 pins 10, 11, 12, and 13) - Chip Detect (CD) pin on the breakout board is connected to the board, but not actually utilized. I'm using a SanDisk Ultra 8GB Class10 SD card.

I've logged to SD card in the same setup using SDFat library in the past, but it's very curious to me as why SD library fails to create a file within a FreeRTOS task.

Any help is appreciated! Cheers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.