Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by andrew-ar on January 24, 2017

I have a function which updates the flash memory on a PIC24F device with new data. I have followed Microchip's advice with regard to copying the old flash page to RAM, modifying the RAM copy, erasing the flash page and then writing the modified RAM copy back to the flash. When this routine is run on its own (no RTOS), all is fine and I can see the updated data in the flash.

The problem arises when I call this function from a FreeRTOS task which uses vTaskDelayUntil() to execute itself periodically every 4ms. The kernel tick time is set to 4ms, which is required so that I can have the aforementioned task execute every 4ms. The flash write operation, however, takes 40ms because writing to flash is a slow operation. So lots of ticks will be missed while this takes place. I have the flash algorithm in a critical section. When the program tries to execute vTaskDelayUntil() AFTER data has written back to the flash, configASSERT( ( xTimeIncrement > 0U ) ); triggers. The flash data updates correctly, so the FreeRTOS kernel must have been corrupted somehow. My question is why, and what can I do to fix it. The flash write operation uses Microchip's writeflashword16(prog_addressT dst, int dat) function, which does modify interrupt priorities temporarily, but I don't know if that is likely to cause a problem if it is done inside a critical section.

The code is as follows (I've stripped out some unrelated stuff to make it easier to read).

Task which executes every 4ms void vSystemUSBTask( void pvParameters ) { TickType_t xLastWakeTime; // Initialise xLastWakeTime variable with current tick count. xLastWakeTime = xTaskGetTickCount();

for(;;) {
    USBDeviceTasks(); //Takes care of enumeration and other USB events
    if((USBGetDeviceState() < CONFIGUREDSTATE) ||
       (USBIsDeviceSuspended() == true))
    {
        continue;
    }
    else
    {
        vVendorConfig();
    }

    // Block for 4ms (1 tick period).
    vTaskDelayUntil( &xLastWakeTime, pdMSTOTICKS(4) );
    **configASSERT( (xTimeIncrement > 0U ) ) triggers here, but only after vVendorConfig() has run**
}

vVendorConfig() function void vVendorConfig(void) { ... taskENTERCRITICAL(); ... for(row = 0; row < FLASHROWSINPAGE; row++) { _writeflash16(flashRowAddress, (int )ramAddress); flashRowAddress += FLASHROWINC; // Increment ramBuffer (source) by same amount ramAddress += RAMBUFFERINC; }
taskEXITCRITICAL(); }

I know it is writeflashword16() causing the problem, as commenting it out prevents the configASSERT from being triggered. Furthermore, replacing writeflash16 with a simple for loop time delay of roughly the same time seems to eliminate the problem (obviously at the expense of not writing to the flash), so the problem must be something to do with writeflash16.

Any help as to why configASSERT( (xTimeIncrement > 0U ) ) triggers would be gratefully appreciated.

Many thanks in advance.

Andrew


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by rtel on January 24, 2017

That assert would seem to indicate the second parameter to vTaskDelayUntil() is passed in as zero, but in your code it is passed in as pdMSTOTICKS(4), which would seem to be a constant, so why does it think it is 0?


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by edwards3 on January 25, 2017

Stack overflow?


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by andrew-ar on January 25, 2017

Thanks for the suggestions. If I put a breakpoint on taskEXITCRITICAL(), then step thorugh the code, the correct value is passed into the second parameter of vTaskDelayUntil() - pdMSTOTTICKS, which computes to 1 in this case. However, if I insert the following code into tasks.c (temporary modification), and put a breakpoint on the Nop(), it appears that "0" has been passed into the second parameter of vTaskDelayUntil(). Weird.

void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
{
TickType_t xTimeToWake;
BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;

if( xTimeIncrement == 0) {
    Nop();
}

    configASSERT( pxPreviousWakeTime );
	configASSERT( ( xTimeIncrement > 0U ) );
	configASSERT( uxSchedulerSuspended == 0 );    

    ...
}

I have vApplicationStackOverflowHook() defined and configCHECKFORSTACK_OVERFLOW set to 2, and its not hitting those.

Maybe I am expecting too much to use flash writing calls with FreeRTOS. With some careful thinking I could make this application work without an RTOS, but I would prefer to use it if I can. I will post back here if I make any progress. Any further comments welcome.


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by andrew-ar on January 25, 2017

Update: When the problem occurs, it seems to think the first parameter to vTaskDelayUntil() is zero too.


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by rtel on January 25, 2017

As pointed out, this could be a stack issue. Does the library that writes to flash use a lot of stack, or allocate large buffers?


configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F Port

Posted by andrew-ar on January 27, 2017

Thanks all for the help - I have now located and fixed the problem. Yes, the functions which write to flash use a lot of RAM for buffering (1K's worth), which might have been causing a stack overflow but I doubt it given the memory allocation settings. More serious, however, was that when the relevant flash page was erased during the update procedure, a small amount of program code was erased with it...I admit to this being a stupid mistake on my part for not locating the objects to be updated elsewhere in program memory, well away from program code! Nonetheless, a stack overflow may be an issue as I use up more RAM during development. I have learnt the hard way, but at least I'll not make the same mistake again. Apologies that this turned out not to be a FreeRTOS issue.

Many thanks - FreeRTOS is brilliant piece of engineering and usually makes life much easier!

Andrew


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS