Electronic – FreeRTOS: Task Creation Problem

cfreertosmicrocontrollerpic

I am creating 2 tasks, one controls a keypad the other a temperature sensor. Each task works individually. However when I try to create both task it does not seem to create the task, it keeps looping in main (discovered while debugging, the task was not being created because there was not enough memory allocated to the heap).
There is an LCD output which flickers when running. However the correct output is displaced when a single task is created. Code below.

main.c

    /*HEADER FILES*/
#include    "FreeRTOS.h"
#include    "task.h"
#include    "xlcd_GpE.h"
#include    "Keypad.h"
#include    "TempSensor.h"
#include    "timers.h"
#include    <p18f452.h>

/*PIC18 CONFIGURATION SETTINGS*/
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#define XTAL_FREQ 4000000

/*VARIABLES*/

/*FUNCTION PROTOTYPES*/
void keypadTask (void *pvParameter);
void tempTask (void *pvParameter);
void keypadISR (void);

void main (void)
{
    INTCONbits.GIE = 0;

    configKeypad();
    InitLCD();
    xTaskCreate( tempTask, "TempTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
    xTaskCreate( keypadTask, "keypadTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

    vTaskStartScheduler();
}

temperature function in tempTask.c

    void tempTask(void *pvParameter) {

    for (;;) {


             if (xSemaphoreTake(tempSem, (TickType_t) 3000) == pdTRUE) {
            char tempLSB, tempMSB;
            char get[10];
            int k;

            if (owInit() == 1) {
                writeByte(0xCC);
                writeByte(0x44);
                Delay10TCYx(10);
                Nop();
                Nop();
                Nop();
                Nop();
                Nop();
            }
            if (owInit() == 1) {
                writeByte(0xCC);
                writeByte(0xBE);
                for (k = 0; k < 9; k++) {
                    get[k] = readByte();
                }
            }

            tempMSB = get[1];
            tempLSB = get[0];
            if (tempMSB <= 0x80) {
                tempLSB = (tempLSB / 2);
            }
            tempMSB = tempMSB & 0x80;
            if (tempMSB >= 0x80) {
                tempLSB = (~tempLSB) + 1;
            }
            if (tempMSB >= 0x80) {
                tempLSB = (tempLSB / 2);
            }
            if (tempMSB >= 0x80) {
                tempLSB = ((-1) * tempLSB);
            }
            while (BusyXLCD());
            SetDDRamAddr(0x00);
            while (BusyXLCD());
            putsXLCD(tempLSB);
            while (BusyXLCD());

        } else {
            while (BusyXLCD());
            SetDDRamAddr(0x40);
            while (BusyXLCD());
            putrsXLCD("DNG Temp Sem!");
            while (BusyXLCD());
        }
    }
}

keypad function in keypad.c

    void keypadTask(void *pvParameter) {

    keypadSem = xSemaphoreCreateCounting(1, 0);
    tempSem = xSemaphoreCreateCounting(1, 0);

    for (;;) {
        //vTaskDelay(10);
        if (xSemaphoreTake(keypadSem, (TickType_t) 2500) == pdTRUE) {
            int key = (BIT0 * 1 + BIT1 * 2 + BIT2 * 4 + BIT3 * 8);
            SetDDRamAddr(0x00);
            while (BusyXLCD());
            putrsXLCD("                ");
            switch (key) {
                case 0:
                    xSemaphoreGive(tempSem);
                    break;
                case 1:
                    while (BusyXLCD());
                    SetDDRamAddr(0x01);
                    while (BusyXLCD());
                    putrsXLCD("2");
                    while (BusyXLCD());
                    break;
                case 2:
                    while (BusyXLCD());
                    SetDDRamAddr(0x02);
                    while (BusyXLCD());
                    putrsXLCD("3");
                    while (BusyXLCD());
                    break;
                case 3:
                    while (BusyXLCD());
                    SetDDRamAddr(0x03);
                    while (BusyXLCD());
                    putrsXLCD("A");
                    while (BusyXLCD());
                    break;
                case (4):
                    while (BusyXLCD());
                    SetDDRamAddr(0x00);
                    while (BusyXLCD());
                    putrsXLCD("4");
                    while (BusyXLCD());
                    break;
                case (5):
                    while (BusyXLCD());
                    SetDDRamAddr(0x01);
                    while (BusyXLCD());
                    putrsXLCD("5");
                    while (BusyXLCD());
                    break;
                case (6):
                    while (BusyXLCD());
                    SetDDRamAddr(0x02);
                    while (BusyXLCD());
                    putrsXLCD("6");
                    while (BusyXLCD());
                    break;
                case (7):
                    while (BusyXLCD());
                    SetDDRamAddr(0x03);
                    while (BusyXLCD());
                    putrsXLCD("B");
                    while (BusyXLCD());
                    break;
                case (8):
                    while (BusyXLCD());
                    SetDDRamAddr(0x00);
                    while (BusyXLCD());
                    putrsXLCD("7");
                    while (BusyXLCD());
                    break;
                case (9):
                    while (BusyXLCD());
                    SetDDRamAddr(0x01);
                    while (BusyXLCD());
                    putrsXLCD("8");
                    while (BusyXLCD());
                    break;
                case (10):
                    while (BusyXLCD());
                    SetDDRamAddr(0x02);
                    while (BusyXLCD());
                    putrsXLCD("9");
                    while (BusyXLCD());
                    break;
                case (11):
                    while (BusyXLCD());
                    SetDDRamAddr(0x03);
                    while (BusyXLCD());
                    putrsXLCD("C");
                    while (BusyXLCD());
                    break;
                case (12):
                    while (BusyXLCD());
                    SetDDRamAddr(0x00);
                    while (BusyXLCD());
                    putrsXLCD("0");
                    while (BusyXLCD());
                    break;
                case (13):
                    while (BusyXLCD());
                    SetDDRamAddr(0x01);
                    while (BusyXLCD());
                    putrsXLCD("F");
                    while (BusyXLCD());
                    break;
                case (14):
                    while (BusyXLCD());
                    SetDDRamAddr(0x02);
                    while (BusyXLCD());
                    putrsXLCD("E");
                    while (BusyXLCD());
                    break;
                case (15):
                    while (BusyXLCD());
                    SetDDRamAddr(0x03);
                    while (BusyXLCD());
                    putrsXLCD("D");
                    while (BusyXLCD());
                    break;
                default:
                    while (BusyXLCD());
                    SetDDRamAddr(0x00);
                    while (BusyXLCD());
                    putrsXLCD("An Error!");
                    while (BusyXLCD());
                    break;
            }
        } else {
            while (BusyXLCD());
            SetDDRamAddr(0x00);
            while (BusyXLCD());
            putrsXLCD("DNG Keypad Sem!");
            while (BusyXLCD());
            INTCONbits.INT0F = 0;
        }
    }
    }

Best Answer

Confirming the task was actually being created by using the pdPASS was a great tool, from there, the answer was found in the FreeRTOS Reference Manual, under the vTaskCreate example. Problem was solved by changing configTOTAL_HEAP_SIZE from 512 to 1024, in the FreeRTOSconfig.h (for the PIC18f452)

    /* Define a structure called xStruct and a variable of type xStruct. These are just used to
demonstrate a parameter being passed into a task function. */
typedef struct A_STRUCT
{
 char cStructMember1;
 char cStructMember2;
} xStruct;

/* Define a variable of the type xStruct to pass as the task parameter. */
xStruct xParameter = { 1, 2 };

/* Define the task that will be created. Note the name of the function that implements the task
is used as the first parameter in the call to xTaskCreate() below. */
void vTaskCode( void * pvParameters )
{
xStruct *pxParameters;

 /* Cast the void * parameter back to the required type. */
 pxParameters = ( xStruct * ) pvParameters;

 /* The parameter can now be accessed as expected. */
 if( pxParameters->cStructMember1 != 1 )
 {
 /* Etc. */
 }

 /* Enter an infinite loop to perform the task processing. */
 for( ;; )
 {
 /* Task code goes here. */
 }
}
/* Define a function that creates a task. This could be called either before or after the
scheduler has been started. */
void vAnotherFunction( void )
{
TaskHandle_t xHandle;

 /* Create the task. */
 if( xTaskCreate(
 vTaskCode,                   /* Pointer to the function that implements the task. */
 "Demo task",                 /* Text name given to the task. */
 STACK_SIZE,                  /* The size of the stack that should be created for the task.
                              This is defined in words, not bytes. */
 (void*) &xParameter,        /* A reference to xParameters is used as the task parameter.
                              This is cast to a void * to prevent compiler warnings. */
 TASK_PRIORITY,              /* The priority to assign to the newly created task. */
 &xHandle                    /* The handle to the task being created will be placed in
 xHandle.                     */
 ) != pdPASS )
 {
 /* The task could not be created as there was insufficient heap memory remaining. If
 heap_1.c, heap_2.c or heap_4.c are included in the project then this situation can be
 trapped using the vApplicationMallocFailedHook() callback (or ‘hook’) function, and the
 amount of FreeRTOS heap memory that remains unallocated can be queried using the
 xPortGetFreeHeapSize() API function.*/
 }
 else
 {
 /* The task was created successfully. The handle can now be used in other API functions,
 for example to change the priority of the task.*/
 vTaskPrioritySet( xHandle, 2 );
 }
}
Related Topic