vTaskSuspendAll/xTaskResumeAll don't work for LPC2368

I using Keil compiler and the port RVDS from GitHub for my project on LPC2368. FreeRTOS works well as long as it doesn’t use critical section.
If I use this block

    vTaskSuspendAll ();
....
    xTaskResumeAll ();

everything is ok, but if I type acording documentation:

    vTaskSuspendAll ();
....
    if (!xTaskResumeAll ()) taskYIELD ();

programm will stoped somewere in taskYIELD
Someone know why it should be happened?

Other question: when program spends too much time in critical section, then program stopped somewhere in ‘xTaskResumeAll’, I think, that it the same error, in xTaskResumeAll FreeRTOS runs taskYIELD.

How can I spend as much time as it takes in critical section? But I think, than answer on first question must decide this problem too.

My FreeRTOSConfig.h:

    #define configUSE_PREEMPTION        1
    #define configUSE_IDLE_HOOK         0
    #define configUSE_TICK_HOOK         0
    #define configCPU_CLOCK_HZ          ( ( unsigned long ) 72000000 )  /* =12.0MHz xtal multiplied by 4 using the PLL. */
    #define configTICK_RATE_HZ          ( ( TickType_t  ) 1000 )
    #define configMAX_PRIORITIES        ( 2 )
    #define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 90 )
    #define configTOTAL_HEAP_SIZE       ( ( size_t ) 6 * 1024 )//( ( size_t ) 13 * 1024 )
    #define configMAX_TASK_NAME_LEN     ( 8 )
    #define configUSE_TRACE_FACILITY    0
    #define configUSE_16_BIT_TICKS      0
    #define configIDLE_SHOULD_YIELD     0

    #define configQUEUE_REGISTRY_SIZE   0

    //#define configSUPPORT_STATIC_ALLOCATION 1
    //#define configSUPPORT_DYNAMIC_ALLOCATION 0

    /* Co-routine definitions. */
    #define configUSE_CO_ROUTINES       0
    #define configMAX_CO_ROUTINE_PRIORITIES ( 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             1
    #define INCLUDE_vTaskCleanUpResources   0
    #define INCLUDE_vTaskSuspend            1
    #define INCLUDE_vTaskDelayUntil         1
    #define INCLUDE_vTaskDelay              1

    // HOOKs
    #define configCHECK_FOR_STACK_OVERFLOW  2
    #define configUSE_MALLOC_FAILED_HOOK    1

Example code:

    void testTask (void *p);
    void testTask3 (void *p);

    int main (void) {
    	Init ();

    	dbgmsg ("start FreeRTOS\n");
        
    	BaseType_t ret;

    	ret = xTaskCreate(testTask, (signed char *)"testTask", configMINIMAL_STACK_SIZE, 0, 0, 0);
    	if (ret != pdPASS) {
    		errmsg ("xTaskCreate: COULD_NOT_ALLOCATE_REQUIRED_MEMORY");
    		goto rtosError;
    	}
        
        ret = xTaskCreate(testTask3, (signed char *)"testTask3", configMINIMAL_STACK_SIZE, 0, 0, 0);
    	if (ret != pdPASS) {
    		errmsg ("xTaskCreate: COULD_NOT_ALLOCATE_REQUIRED_MEMORY");
    		goto rtosError;
    	}

    	vTaskStartScheduler();

    rtosError:
    	while (9)
    	{
    		RED_LED_ON;
    		GREEN_LED_OFF;
            Delay (1000, 0);
    		RED_LED_OFF;
    		GREEN_LED_ON;
            Delay (1000, 0);
    	}
    	return 0;
    }

    // HOOKs
    void 
    vApplicationStackOverflowHook( TaskHandle_t xTask, char * pcTaskName ) {
    	//taskENTER_CRITICAL();
    	//vTaskSuspendAll ();
    	while (true)
    	{
    		dbgmsg ("vApplicationStackOverflowHook at '%s'\n", pcTaskName);
    	}
    	//xTaskResumeAll();
    	//taskEXIT_CRITICAL();
    }

    void
    vApplicationMallocFailedHook() {
        //vTaskSuspendAll ();
    	while (true)
    	{
    		dbgmsg ("vApplicationMallocFailedHook\n");
    	}
        //if (!xTaskResumeAll ()) taskYIELD ();
    }

    #include "Defports.h"
    extern void rtosSleep(uint32_t ms);
    extern volatile bool mainTaskIinitialized ();

    void
    testTask3 (void *p) {
        Delay (500, 0);
    	while (9)
    	{
            dbgmsg ("3");
            
            vTaskSuspendAll ();
    		RED_LED_ON;
    		GREEN_LED_OFF;
            xTaskResumeAll ();
            //if (!xTaskResumeAll ()) taskYIELD ();
            Delay (1000, 0);
            //rtosSleep (1000);
    	}
    }

    void testTask (void *p) {
    	while (1) {
            dbgmsg ("1");
            
            vTaskSuspendAll ();
    		RED_LED_OFF;
    		GREEN_LED_ON;        
            //xTaskResumeAll ();
            if (!xTaskResumeAll ()) taskYIELD ();
            Delay (1000, 0);
    	}
    }

Do you have configASSERT() defined? I don’t see it in your config file.

When the program stops, if you stop the system on the debugger, what is it executing?

I meant that none of the tasks anymore writes anything to the debug port and the diodes don’t blinked. I will try to enable assert and report results.

I added configASSERT() to FreeRTOSConfig.h:
void vAssertCalled(char *file, int line);
#define configASSERT(x) if( ( x ) == 0 ) vAssertCalled( FILE, LINE )

implemeted ‘vAssertCalled’ as
void
vAssertCalled(char *file, int line) {
while (true)
{
dbgmsg (“vAssertCalled ‘%s’:%d\n”, file, line);
}
}
And nothing changed (( ‘vAssertCalled’ doesn’t called.

Seems too small. Would you please increase the stack size of your tasks. Something like:

ret = xTaskCreate(testTask, (signed char *)"testTask", 512, 0, 0, 0);

The symptoms you are having indicate that it may be stack overflow.

Thanks.

512*4 bytes seems too much for stack size… I commented call to taskYeld in portmacro.h and everything had worked fine.

I meant that just as a test. You can fine tune the stack size once the root cause is identified.

If you are changing portmacro.h, it is not the right solution and you are probably just hiding the possible memory corruption (which will manifest itself at a later point).

Thanks.

Would you explain, what does ‘vPortYield’? portASM.s:

vPortYield

	PRESERVE8

	SVC 0
	bx lr

I add some debug to portmacro.h:

#define portYIELD() do{ dbgmsg ("vPortYield\n"); vPortYield();} while(0)

And nothing to call ‘portYIELD’! But, if I do something long in critical section, then taskYIELD runs and programm stoped (it means that none of tasks blinking leds or prints to debug port).
Yes, I tired up stack size up , it hadn’t effect.
ret = xTaskCreate(testTask, (signed char *)"testTask", 1024, 0, 0, 0);

I use this port: FreeRTOS-Kernel/portable/RVDS/ARM7_LPC21xx at main · FreeRTOS/FreeRTOS-Kernel · GitHub

vPortYield() is the port specific implementation of a context switch request. It means that at the next possible occasion, the currently running task may lose its time slice and yield (hence the word) the CPU to another task. This is called in any case when the time slice granularity has expired, but it may be invoked explicitly prior to that (eg by an ISR that has caused a task with a higher priority than the currently running task to be woken up and be ready to run).

EDIT: I would not recommend the changes you made to the macro. This can lead to absolutely unpredictable behavior.

Have you installed SWI interrupt handler correctly? As per this comment, vPortYieldProcessor should be installed as the SWI interrupt handler: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/portable/RVDS/ARM7_LPC21xx/portASM.s#L69

It should be somewhere in your startup code.

Thanks.

Great! Thank you!
I don’t setup SWI_Addr to vPortYieldProcessor in LPC2300.s
SWI_Addr DCD vPortYieldProcessor ;SWI_Handler