FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [January 2017 Threads] configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F PortPosted 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 PortPosted 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 PortPosted by edwards3 on January 25, 2017
configASSERT( ( xTimeIncrement > 0U ) ); Problem on PIC24F PortPosted 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 PortPosted 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 PortPosted 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 PortPosted 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
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|