CortexM4 GPIO Toggling very slow

sahilkhan wrote on Thursday, January 31, 2019:

Hi,

I am working on TI CortexM4 microcontroller running FreeRTOS. I am trying to toggle a pin on microcontroller. I have noticed the GPIO port is toggling at very slow speed of 3.9usec, while the micrcontroller is running at 120MHz.

I have tried the same code without FreeRTOS and the toggling becomes very fast i.e. 150nsec.

My project has no interrupts running and here is the code i am running under FreeRTOS;

Please note, I have removed the hash sign infront of includes files as the posting system of sourceforge some how doesnt like it.

include <stdint.h>
include <stdbool.h>
include “main.h”
include “drivers/pinout.h”
include “utils/uartstdio.h”

// TivaWare includes
include “driverlib/sysctl.h”
include “driverlib/debug.h”
include “driverlib/rom.h”
include “driverlib/rom_map.h”
include “driverlib/gpio.h”
include “driverlib/inc/hw_memmap.h”
// FreeRTOS includes
include “FreeRTOSConfig.h”
include “FreeRTOS.h”
include “task.h”
include “queue.h”

define SYSTEM_CLOCK 120000000U

// Demo Task declarations
void demoLEDTask(void *pvParameters);
void demoSerialTask(void *pvParameters);

// Main function
int main(void)
{
// Initialize system clock to 120 MHz
uint32_t output_clock_rate_hz;
output_clock_rate_hz = ROM_SysCtlClockFreqSet(
(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480),
SYSTEM_CLOCK);
ASSERT(output_clock_rate_hz == SYSTEM_CLOCK);

// Initialize the GPIO pins for the Launchpad
PinoutSet(false, false);

ROM_GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_4 | GPIO_PIN_5 );
GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_4 | GPIO_PIN_5, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
// Create demo tasks
xTaskCreate(demoLEDTask, (const portCHAR *)"LEDs",
            configMINIMAL_STACK_SIZE, NULL, 2, NULL);

xTaskCreate(demoSerialTask, (const portCHAR *)"Serial",
            configMINIMAL_STACK_SIZE, NULL, 1, NULL);

vTaskStartScheduler();
return 0;

}

// Flash the LEDs on the launchpad
void demoLEDTask(void *pvParameters)
{

for (;;)

{
    GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_4 |GPIO_PIN_5 ,0);
    //for(i=0;i<1;i++){}
    //SysCtlDelay(1);
    GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_4 | GPIO_PIN_5);

}

}

// Write text over the Stellaris debug interface UART port
void demoSerialTask(void *pvParameters)
{

// Set up the UART which is connected to the virtual COM port
UARTStdioConfig(0, 57600, SYSTEM_CLOCK);


for (;;)
{
    UARTprintf("\r\nHello, world from FreeRTOS 9.0!");
    vTaskDelay(5000 / portTICK_PERIOD_MS);
}

}

/* ASSERT() Error function
*

  • failed ASSERTS() from driverlib/debug.h are executed in this function
    */
    void error(char *pcFilename, uint32_t ui32Line)
    {
    // Place a breakpoint here to capture errors until logging routine is finished
    while (1)
    {
    }
    }

And here is the scope snapshot

heinbali01 wrote on Friday, February 01, 2019:

If you want to include source code in a post, please enclose the code between two lines that contain 3 tilda’s (`````) only, like this:

```
void foo()
{
}
```

In general: code should not run slower under FreeRTOS, but you have to realise that the CPU is being shared with other tasks.
In your example, the kernel ( the idle task ) will be sleeping 99.99% of the time.

Now here is the essence of your code:

    // Create demo tasks
    xTaskCreate(demoLEDTask,    (const portCHAR *)"LEDs",   configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    xTaskCreate(demoSerialTask, (const portCHAR *)"Serial", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

// Flash the LEDs on the launchpad
void demoLEDTask(void *pvParameters)
{
    for (;;)
    {
        GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_4 |GPIO_PIN_5 ,0);
        GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_4 | GPIO_PIN_5);
    }
}

// Write text over the Stellaris debug interface UART port
void demoSerialTask(void *pvParameters)
{
    for (;;)
    {
        UARTprintf("\r\nHello, world from FreeRTOS 9.0!");
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
}

I’d like to say something about your demoLEDTask(): it has an eternal loop that will never block ( or sleep ).
I wonder if your second task demoSerialTask(), which has a lower priority, ever gets CPU time?

If you really want to have a task that never blocks, I recommend you let it run on the Idle priority 0.

heinbali01 wrote on Sunday, February 03, 2019:

Hi Sahil, have you discovered what the problem was?