vTaskStartScheduler() only run one task

zhoubowei008 wrote on Friday, October 11, 2019:

hi please help, not sure why only task2 is excuted.
I am using STM32G071RB

Thank you

#include “stm32g0xx.h”
#include “stm32g0xx_nucleo.h”
#include “FreeRTOSConfig.h”
#include “task.h”
#include <stdio.h>
#include <stdint.h>

TaskHandle_t xTaskHandle1 = NULL;
TaskHandle_t xTaskHandle2 = NULL;

//task function prototypes
void vTask1_handler(void *params);
void vTask2_handler(void *params);

// used for semihosting
extern void initialise_monitor_handles();

int main(void)
{
initialise_monitor_handles();

// printf(“first code\n”);
printf(“System clock is %d\n”,SystemCoreClock);
// turn off PLL and HSE, turn ON HSI
HAL_RCC_DeInit();
// update system clock variables
SystemCoreClockUpdate();
// Create two tasks
xTaskCreate(vTask1_handler,“Task-1”,configMINIMAL_STACK_SIZE,NULL,1,&xTaskHandle1);
xTaskCreate(vTask2_handler,“Task-2”,configMINIMAL_STACK_SIZE,NULL,1,&xTaskHandle2);

//Create scheduler to run tasks
vTaskStartScheduler();

for(;;);

}

vTask1_handler(void *params)
{
while(1)
{
printf(“task1 is running\n”);
}
// printf(“task1”);

}

vTask2_handler(void *params)
{
while(1)
{
printf(“task2 is running\n”);
}
// printf(“task2”);

}

my FreeTTOSConfig.h

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------

  • Application specific definitions.
  • These definitions should be adjusted for your particular hardware and
  • application requirements.
  • THESE PARAMETERS ARE DESCRIBED WITHIN THE ‘CONFIGURATION’ SECTION OF THE
  • FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
  • See http://www.freertos.org/a00110.html
    ----------------------------------------------------------/

extern uint32_t SystemCoreClock;

#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
//#define configCPU_CLOCK_HZ ( ( unsigned long ) 16000000 )
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 )
//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16 * 1024 ) )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

#define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
// to define the stack overflow check mechanism
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configGENERATE_RUN_TIME_STATS 0

/* 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

/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 0 (1?) (highest). /
#define configKERNEL_INTERRUPT_PRIORITY 255
/
!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. /
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /
equivalent to 0xb0, or priority 11. */

/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15. This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15

/*-----------------------------------------------------------

  • UART configuration.
    -----------------------------------------------------------/
    #define configCOM0_RX_BUFFER_LENGTH 128
    #define configCOM0_TX_BUFFER_LENGTH 128
    #define configCOM1_RX_BUFFER_LENGTH 128
    #define configCOM1_TX_BUFFER_LENGTH 128

#endif /* FREERTOS_CONFIG_H */

heinbali01 wrote on Friday, October 11, 2019:

Your post is hard to read because the C code is not put literally. It is easier if you can attach a source file.

Or, another way of including literal code in a post is as follows:

```
	while(1)
	{
		printf("task2 is running\n");
	}
```

note the two lines that only contain 3 tildas.

vTask1_handler(void *params)
{
	while(1)
	{
		printf("task1 is running\n");
	}
	// printf("task1");
}

vTask2_handler(void *params)
{
	while(1)
	{
		printf("task2 is running\n");
	}
	// printf("task2");
}

printf can be problematic, maybe it is not suitable for re-entrance.

zhoubowei008 wrote on Friday, October 11, 2019:

Hi I attached the C code.

Is any one can help? Thank you

rtel wrote on Friday, October 11, 2019:

Your tasks are running at the same priority and neither therefore:

  1. If configUSE_PREEMPTION is set to 0 only one task will run. Default
    is 1 if left undefined.
  2. If configUSE_TIME_SLICING is set to 0 only one task will run.
    Default is 1 if left undefined.

Assuming both the above are set to 1, and the tick interrupt is
executing (view the xTickCount variable in the debugger to see if it is
incrementing - if it is then the tick interrupt is running), then I
suspect the implementation of printf() will be the cause of your
problem. Is it thread safe? Does it use a mutex? If it does use a
mutex then for reasons described in the book you can get scenarios where
only one task appears to run as you will only switch to the other if a
tick interrupt happens to occur between one task releasing the mutex and
then taking it again.

heinbali01 wrote on Saturday, October 12, 2019:

Follow up: Richard describes the possible scenarios. In your case you have defined :

#define configUSE_PREEMPTION    1
#define configUSE_TIME_SLICING  1  /* by default */

This means that in your case each task should run for 1 clock-tick, unless a yield is done before the end of a clock-tick period. Waiting for a mutex may lead to a yield.

But please try to find out if your printf() is thread-safe.

What output do you see? Constantly “task1 is running”?

Another test that you can do is to assign a LED to each of the tasks and have it blink. Setting a GPIO is normally implemented thread-safe.

zhoubowei008 wrote on Tuesday, October 15, 2019:

in my case, only task2 is running.

zhoubowei008 wrote on Tuesday, October 15, 2019:

hi Tiboshch

in my case, only task2 is running. :frowning:

can the problem be “unable to match requested speed 800KHz using 4000 KHz”?

Info : Unable to match requested speed 8000 kHz, using 4000 kHz
adapter speed: 4000 kHz
Info : Device id = 0x20006460
Info : STM32L4xx flash size is 128kb, base address is 0x8000000
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20008000
semihosting is enabled

Thank you