1
\$\begingroup\$

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;
        }
    }
    }
\$\endgroup\$
  • 1
    \$\begingroup\$ You should be confirming that xTaskCreate returns pdPASS. Right now you have no idea if it creates the tasks or not. \$\endgroup\$ – Ron Beyer Nov 8 '19 at 15:51
  • \$\begingroup\$ What is configUSE_PREEMPTION set to?? (Look in FreeRTOSConfig.h.) \$\endgroup\$ – jonk Nov 8 '19 at 15:56
  • 1
    \$\begingroup\$ configUSE_PREEMPTION is set to 1, so I'm using preemption. @Ron Beyer, will add that in actually will help with the debugging! \$\endgroup\$ – Simeon R Nov 8 '19 at 16:07
  • 1
    \$\begingroup\$ @SimeonR Great to hear! Coincidentally, I can go into intimate details about how to structure and write an O/S (which varies on what you consider to be the most fundamental abstractions at its core.) I worked on the Unix v6 kernel and, before that, created timeshared BASIC and assembly code on an HP 21xx back in 1975. Later, I taught operating system design at a 4yr university and I've been doing O/S work almost every year since. So it's old hat. But that doesn't mean I have a magic wand to wave. It just means some ideas are familiar to me and that I can imagine a little more than some. \$\endgroup\$ – jonk Nov 8 '19 at 17:31
  • 1
    \$\begingroup\$ @SimeonR My smaller configurable O/S is designed to sit very well with C to minimize the assembly I need to write when retargeting. It allows heap, but only a global heap, for example. (There is no per-process heap allocator as that would mean more work, more code, more data, and less reliance on the compiler vendor's library system and it doesn't pay for itself well for the application spaces I address.) If you ever get a chance, I recommend you read (for joy, only) Douglas Comer's original red-cover "XINU" book (1983, I think?) It is a joy to read and clear as a bell. Worth the time. \$\endgroup\$ – jonk Nov 8 '19 at 17:37
2
\$\begingroup\$

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 );
 }
}
| improve this answer | |
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.