Can't get scheduler to run anymore

moto95 wrote on Tuesday, April 23, 2013:

OK, I am stumped. I’ve had a FreeRTOS application nicely ticking over. Made new additions in the course of development and now the scheduler refuses to run. Tasks get successfully created, but vTaskStartScheduler seems to fail somewhere in xPortStartScheduler. I can trace it to there.

So, I’ve reduced it a very simple main loop and one task. The highly reduced code now is:
#include <stdio.h>
#include <stdlib.h>
#include “main.h”

void vTest (void *pvParameters)
{
    for(;:wink:
    {
        PORTToggleBits (OC4);
        vTaskDelay (500);
    }
}

int main(void) {   
    // Configure the processor for maximum performance.
    SYSTEMConfigPerformance(configCPU_CLOCK_HZ);
   
    // Initialise the system hardware.
    DIG_IO_config();
    AN_IO_config();

    while (TRUE)
    {
        // For testing, turn on an LED if the task gets created successfully.
        if (xTaskCreate(vTest, “test”, 240, NULL, 1, NULL))
            {PORTSetBits(OC5);}
       
        // Now start the RTOS scheduler.
        vTaskStartScheduler();

        // This is just for debug. We should never get here.
        for (;:wink: {PORTSetBits(OC4);};
    }
}

I’ve searched on here and found references to heap and stack size.  My settings are:
#define configTOTAL_HEAP_SIZE                       ( ( size_t ) 8000 )
I am using heap_1.c

I’ve tried increasing the heap size and tried different heap_x.c files. It’s made no difference.

I am using an PIC32MX575 with MPLAB-X and XC-32 compiler.

This ran with far more code than the above with multiple tasks,etc. Now, I can’t even get this simple example to work. There are no compile errors, btw.

Any suggestions on how to get this working again would be greatly appreciated.

edwards3 wrote on Tuesday, April 23, 2013:

What new additions did you make? Additions to the Kernel or to your app code? Check nothing In the FreeRTOS source directory has been edited.

How far does it get in the start scheduler function - Where does it crash and what happens when it crashes?

moto95 wrote on Tuesday, April 23, 2013:

Too many changes to list here but all app code additions as I added functionality. But, the above is a test to make it as small as possible. I have not edited any FreeRTOS files, I’ve even reinstalled the 7.4.0 files.

It gets to the xPortStartScheduler but can’t delve into that as it’s a priviledged function. That’s all I know at the moment.

rtel wrote on Wednesday, April 24, 2013:

It gets to the xPortStartScheduler but can’t delve into that as it’s a priviledged function. That’s all I know at the moment.

I don’t understand that statement.  All code in that port is privileged, so you should be able to step into the function just like you can any other function.  If you step through the function at some point, near the end, it will start executing assembly instructions but even then you should be able to step through it.  If you can step through it, let me know at which point it goes wrong - if you can step through all the code until you get to that function but can’t step through that function then something must have already gone wrong.

Regards.

moto95 wrote on Wednesday, April 24, 2013:

Not sure if this is better or worse, but after starting with a fresh copy of FreeRTOS 7.4.0, I now get the following error:

In file included from ../FreeRTOSV7.4.0/FreeRTOS/Source/portable/MPLAB/PIC32MX/port_asm.S:77:0:
../FreeRTOSV7.4.0/FreeRTOS/Source/portable/MPLAB/PIC32MX/ISR_Support.h:75:28: fatal error: FreeRTOSConfig.h: No such file or directory

This is perplexing since the FreeRTOSconfig.h file definitely there and the project directory is definitely included in the include paths of both comiler and assembler:

-g -I"F:/MPLABXProjects/DIS-5_Development_System" -I"F:/MPLABXProjects/FreeRTOSV7.4.0/FreeRTOS/Source/include" -I"F:/MPLABXProjects/FreeRTOSV7.4.0/FreeRTOS/Source/portable/MPLAB/PIC32MX" -I"F:/MPLABXProjects/DIS-5_Development_System"

Please help!

moto95 wrote on Wednesday, April 24, 2013:

Further update. I got past the previous file reference error temporarily by hard coding the file paths. This isn’t right but at least let’s debug the original problem.

So, I’ve stepped through the functions, and I get to xPortStartScheduler(), as before. When I step into that function, it opens file port.c and shows the xPortStartScheduler function as expected, but the code is greyed out. Scrolling to the top of the file, I find this:

#ifndef __XC__
    #error This port is designed to work with XC32.  Please update your C compiler version.
#endif

How can this be? The error directive never gets printed out during compilation.

moto95 wrote on Wednesday, April 24, 2013:

And yet a further update. Stepping through the same code as in post 1, I get to portYIELD_WITHIN_API() in prvProcessTimerOrBlockTask.

I can’t step into portYIELD_WITHIN_API, but the it seems to be defined as:

#ifndef portYIELD_WITHIN_API
	#define portYIELD_WITHIN_API portYIELD
#endif

I am pretty much lost at this point, I hate to admit.

moto95 wrote on Wednesday, April 24, 2013:

Please ignore post 5. Silly mistake (what else is new!).

Post 6 & 7 are still valid, though.

moto95 wrote on Wednesday, April 24, 2013:

So, with a fresh installation of MPLAB-X V1.7 and FreeRTOS V7.4.0, I’ve created a new project with the required RTOS files, and a small main.c file. Here are the FreeRTOSConfig.h and main.c files:

#define configUSE_PREEMPTION                        1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION     1
#define configUSE_IDLE_HOOK                         0
#define configUSE_TICK_HOOK                         1
#define configTICK_RATE_HZ                          ( ( portTickType ) 200 )
#define configCPU_CLOCK_HZ                          ( 48000000UL )
#define configPERIPHERAL_CLOCK_HZ                   ( 48000000UL )
#define configMAX_PRIORITIES                        ( 5UL )
#define configMINIMAL_STACK_SIZE                    ( 190 )
#define configISR_STACK_SIZE                        ( 400 )
#define configTOTAL_HEAP_SIZE                       ( ( size_t ) 28000 )
#define configMAX_TASK_NAME_LEN                     ( 8 )
#define configUSE_TRACE_FACILITY                    0
#define configUSE_16_BIT_TICKS                      0
#define configIDLE_SHOULD_YIELD                     1
#define configUSE_MUTEXES                           0
#define configCHECK_FOR_STACK_OVERFLOW              0
#define configQUEUE_REGISTRY_SIZE                   0
#define configUSE_RECURSIVE_MUTEXES                 0
#define configUSE_MALLOC_FAILED_HOOK                0
#define configUSE_APPLICATION_TASK_TAG              0
#define configUSE_COUNTING_SEMAPHORES               0
#define configGENERATE_RUN_TIME_STATS               0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES                       0
#define configMAX_CO_ROUTINE_PRIORITIES             ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS                            1
#define configTIMER_TASK_PRIORITY                   ( 2 )
#define configTIMER_QUEUE_LENGTH                    5
#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet		1
#define INCLUDE_uxTaskPriorityGet		1
#define INCLUDE_vTaskDelete			0
#define INCLUDE_vTaskCleanUpResources		0
#define INCLUDE_vTaskSuspend			1
#define INCLUDE_vTaskDelayUntil			1
#define INCLUDE_vTaskDelay			1
#define INCLUDE_uxTaskGetStackHighWaterMark	1
/* The priority at which the tick interrupt runs.  This should probably be
kept at 1. */
#define configKERNEL_INTERRUPT_PRIORITY		0x01
/* The maximum interrupt priority from which FreeRTOS.org API functions can
be called.  Only API functions that end in ...FromISR() can be used within
interrupts. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY	0x03




#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
// FreeRTOS includes
#include "FreeRTOS.h"
#include "task.h"
#pragma config FNOSC = FRCPLL, FPLLIDIV = DIV_2, FPLLMUL = MUL_24, FPLLODIV = DIV_2
#pragma config FSOSCEN = OFF, OSCIOFNC = OFF
#pragma config FWDTEN = OFF, WDTPS = PS4096
#pragma config DEBUG = ON, ICESEL = ICS_PGx1
void vTask1 (void *pvParameters)
{
    for (;;)
    {
        mPORTDToggleBits(BIT_1);
        vTaskDelay (200);
    }
}
void vApplicationTickHook (void)
{
    mPORTDToggleBits(BIT_1);
}
int main(int argc, char** argv) {
    TRISGbits.TRISG12 = 0;
    mPORTGSetBits(BIT_12);   // Turn off active low output.
    TRISDbits.TRISD1 = 0;
    mPORTDClearBits(BIT_1); // Turn off active high ouput.
    while (1)
    {
        // Create a task, turn on LED if successfully created.
        if (xTaskCreate (vTask1, "Test Task", 240, NULL, 1, NULL))
        {
                mPORTGToggleBits(BIT_12);
        }
        
        // Now start scheduler
        vTaskStartScheduler();
    }
    // We should never get here!
    for ( ;; )
    {
        mPORTGToggleBits(BIT_12);
    }
    return (EXIT_SUCCESS);
}

The result is the same as in post 1, i.e. the single task (in this case) never runs, the tick hook function never runs either.

I’ve also (seemingly) confirmed the previous results using the debugger. Setting a breakpoint, I get to the following function inside the scheduler.

prvTimerTask
        prvProcessTimerOrBlockTask
                portYIELD_WITHIN_API

If I set the breakpoint on the next instruction which is prvProcessReceivedCommands inside prvTimerTask, it seems to crash. The debugger reports:
“Target halted due to Software Breakpoint in user code”, which apparently indicates a crash.

I hope this sheds further light on my problem and any help would be greatly appreciated.

rtel wrote on Wednesday, April 24, 2013:

Are you using the XC compiler?  One of your previous posts seemed to indicate not because you expected to hit the #error during compilation, but your original post states you are.  If you are not using XC, but the older MPLAB PIC32 C compiler, then you would have to use FreeRTOS V7.3.0.

I presuming you didn’t change chips, compiler version, or FreeRTOS version between having a working application and having a non-working application.

From your last post it would seem that your code is not getting stuck in vTaskStartScheduler() after all, but that when the scheduler starts it is selecting the Timer task to run first and that something is happening in the timer task.

The timer task is just a task as any other, but as you are not actually using it you could try setting configUSE_TIMERS to 0 in FreeRTOSConfig.h.

As the message says you are halted on a breakpoint then two things come to mind:

1) There actually is a break point there, but if it is on an assembler instruction that falls between two C instructions you might not be able to see it.  Try opening up the breakpoints window in MPLAB and click the “delete/remove all” option to ensure no breakpoints are set.  Or….

2) You have hit an exception that is not being handled.  If this is the case, when the code stops open the disassembly window and see if you can work out where you are.  If you are in a catch all exception handler then you will have to look up the exception cause from the CAUSE register (internal MIPS CPU register).  That would require the MIPS manual or (I think) the MCU section of the PIC32 Family Reference Manual.  The following code inserted into the exception handler (might) help decode the cause and address at which the exception occurred (although you should be able to determine the address by stepping through the assembly instructions).

asm volatile("mfc0 %0,$13" : "=r" (_excep_code));
asm volatile("mfc0 %0,$14" : "=r" (_excep_addr));
_excep_code = (_excep_code & 0x0000007C) >> 2;

Regards.

moto95 wrote on Wednesday, April 24, 2013:

Many thanks for your help, Richard. Yes, I am using XC32 but port.c doesn’t seem to recognise this. Is it even worth doing anything else until that problem is fixed? Where should __XC__ be defined? I’ve tried to comment out the ifndef condition to force port.c to compile the code. Strangely, it seems to make no difference to the behaviour of the code.

And, yes, I have not changed compilers, chip, nor versions of FreeRTOS and MPLAB-X.

The following is all done on the simplified code eaxctly as shown in post 9 above, with no changes. No breakpoints other than those mentioned specifically are set. I’ve confirmed this.

Update:
1. If I disable the use of timers, the code gets to the test task and stops at the breakpoint set (first line inside the for loop)
2. If I reenable timers, it doesn’t get to that breakpoint.
3. If I let the debugger run from that breakpoint, the code crashes before it hits the same breakpoint again. However, if I single step through the code I get back to the same breakpoint. I can do this repeatedly by single stepping, but as soon as I let it run (with the same breakpoint still set), it crashes. So, it seems to crash somewhere inside vTaskDelay.

Once the code has crashed (so called Software Breakpoint), the disassembly window doesn’t give any clues. It just stays at the last program counter.

Does that give any clues?

rtel wrote on Thursday, April 25, 2013:

Many thanks for your help, Richard. Yes, I am using XC32 but port.c doesn’t seem to recognise this. Is it even worth doing anything else until that problem is fixed? Where should __XC__ be defined? I’ve tried to comment out the ifndef condition to force port.c to compile the code. Strangely, it seems to make no difference to the behaviour of the code.

Is it a case that the code will not compile because #error is stopping it as __XC__ is not defined, or is it just that when viewed in the editor it appears as if the #error will get triggered because it is not grayed out?  In the latter case - ignore it as editors are not aware of compiler defined macros.

__XC__ should be defined by the compiler itself - you will not see it defined in any header file.  This is like things like __FILE__ and __LINE__ being defined and interpreted by the compiler.

Does that give any clues?

Unfortunately not.  Let me consult a PIC32 hardware expert and see if he can shed any light.

Regards.

rtel wrote on Thursday, April 25, 2013:

…just wondering if it could be something to do with the software interrupt not being installed correctly.  The software interrupt is used for yielding.

Regards.

moto95 wrote on Thursday, April 25, 2013:

…or is it just that when viewed in the editor it appears as if the #error will get triggered because it is not grayed out?

Yes. I’ll ignore it, especially as the error never gets triggered, i.e. no message gets printed, during compile time.

When I get a chance a little later, I will hook up another PIC32 development system and test the same code to eliminate the hardware.

moto95 wrote on Thursday, April 25, 2013:

…just wondering if it could be something to do with the software interrupt not being installed correctly. The software interrupt is used for yielding.

How do I check/test this?

moto95 wrote on Thursday, April 25, 2013:

OK, had a chance to run the same code on different hardware: Standard MicroStick-II with PIC32MX250F128B. The only modifications to the above code is change of I/O pins to reflect the MicroStick-II hardware. The result is that is behaves the same way. So, I am pretty much convinced that it’s not the hardware.

Unfortunately, the built-in debugger on the MicroStick-II is a bit braindead, it shows the same behaviour where you can single step OK, but even “stepping over” functions, it crashes at various places.

The first function is crashes if I don’t single step through it is vPortStartFirstTask().
If I step into that function it crashes at vTaskDelay().
If I step into that function,  it crashes at  vTaskSuspendAll().
If I step into that function, I can single step throught it, return to the calling function vTaskDelay
It then crashes at uxListRemove().
If I step into that function, I can single step throught it, return to the calling function vTaskDelay().
It then crashes at prvAddCurrentTaskToDelayedList().
And on it goes…

In every case, the reported call stack says: No source code lines were found at current PC 0x9d003958, which presumably just means it crashed.

rtel wrote on Thursday, April 25, 2013:

I am using an PIC32MX575 with MPLAB-X and XC-32 compiler.

Please provide:
- Part number (MX575, are there any other markings)
- IDE version/revision
- Compiler version/revision

Software breakpoints are supported by these tools and are implemented using sdbpp instructions.  Are you able to determine if you see any sdbpp in the assembly listing output by the compiler (or in the disassemble window at any time other than when there is genuinely a breakpoint set on a line)?

Regards.

moto95 wrote on Thursday, April 25, 2013:

PIC32MX575F512L
MPLAB-X V1.7.0
C compiler XC-32 V1.20

Windows 7, 64-bit

Software breakpoints are disabled, and there are none in the assembly listing. The MicroStickII in-built debugger does not support software break points. I searched the entire assembly listing. There are no sdbpp. I’d be happy to email it to you.

moto95 wrote on Friday, April 26, 2013:

Out of desparation, I decided to start fresh on a different PC from scratch. That PC has MPLAB-X V1.51, XC32 compiler V1.11, and FreeRTOS V7.2.0 installed. I then took the following steps:
1. Created a new project for the MicroStickII with a PIC32MX250F128B processor
2. Wrote the simplest of main function (from scratch, no cut-and-pasting) to blink the LED on the MicroStick-II - This worked as expected.
3. Added task.c, queue.c, list.c, port.c and port_asm.S (from PICMX32 directory), and heap_1.c to the project source files
4. Copied FreeRTOSConfig.h from the FreeRTOS demo directory and adapted it to suit, i.e. clock rate, no hook functions.
5. Compiled and ran the project but still the simple main function to blink the LED (no FreeRTOS calls or includes) - Worked as expected.
6. Changed the main function to use FreeRTOS to:

#include <FreeRTOS.h>
#include <task.h>
//	Function Prototypes
int main(void);
void MyTask (void *pvParameters)
{
    for( ;; )
    {
        mPORTAToggleBits(BIT_0);
        vTaskDelay(500/portTICK_RATE_MS);
    }
}
int main(void) {
    TRISAbits.TRISA0 = 0;
    mPORTAClearBits(BIT_0);
    if(xTaskCreate(MyTask, "MyTask", 240, NULL, 1, NULL))
        mPORTASetBits(BIT_0);
    vTaskStartScheduler();
    while (1)
    {
        mPORTAClearBits(BIT_0);
    };
}

This resulted in the same behaviour as previously reported. It seems to get into the task once, because the LED gets turned off after the if clause on xTaskCreate() turns it on. The code then crashes. I can verify this with the debugger, and again, if I single step through every line, it gets back into the task and I can repeatedly make the LED toggle.

Really pulling my hair out here with project deadline looming large. Anyone willing to help me to get out this very odd predicament would be truly appreciated.

travfrog wrote on Friday, April 26, 2013:

Moto95,

Where are your interrupts set up?

Your rtos configuration file has use_tick_hook set - do you actually have the hook function in your code?

Is the simple file above ‘all’ of your code?