xTaskCreate();

Hello!
I’m having a problem right now!
As the pictures below the first picture is I initialize the task control of 2 programs dk_task and dk_task_1! And figure 2 is the control part! However I can only get the condition at dk_task and can’t execute the condition at dk_task_1! Does anyone know what the problem is!
Please help me!
Thank you guys!

I don’t understand why my program does only one task, dk_task!

I don’t know what the exact problem is. Are all tasks created successfully or not ?
If xTaskCreate fails there is not enough heap to do so as documented.
Also you call cyhal_gpio_init with the same parameters from 2 tasks. This is redundant at least, but in general it might be a problem accessing the same HW peripheral from multiple tasks without protection (mutex, critical section).
Why not calling cyhal_gpio_init before the tasks using the GPIO peripheral are created ?
Only if interrupts are involved and you’re using for instance task notifications I’d enable the corresponding interrupts from the tasks which handle the notifications (signaled from the ISR) because the initialized task handles are needed before an interrupt kicks in.

The problem I had before was !
Start xTaskCreate(); can work when I change the priority between the 2 tasks dk_task() and dk_task_1, however they cannot work together.
I mean if the condition in dk_task doesn’t match it will move to the condition in dk_task_1!
I’ll try moving my GPIO init somewhere else!

Changing cyhal_gpio_init didn’t work!

My biggest problem is just using a quest first!
For example, I use priority 1 for the task of surveying the value of temperature and priority 2 for the task of surveying the value of humidity. My returns only appear in temperature!
On the contrary, I change the mission value priority to 1 in humidity and 2 in temperature, the result performs in humidity!
Where is the reason?

Moving the common GPIO init outside the tasks is a better solution, I think.
Reading the code again I see that you’re also accessing the same GPIO peripheral and pin from both tasks. How should this work reliably ? Is there a (mutex) protection inside cyhal_gpio_write ? Otherwise when you write to the same GPIO (pin) from multiple tasks the resulting behavior will be random somehow.
And what’s your expected result and what’s the real behavior ? I still don’t understand what you try to achieve :thinking:

Edit: Where are the global (and hopefully volatile) variables adc_percent and notify_temperature set ?

I am doing work reading DHT11 sensor and soil moisture sensor from there using temperature, humidity, soil moisture data to control motor.
As you can see in the code if
adc_precent < 50 will activate pin P10_6 of PSoC 6 to activate the motor.
notify_templates > 35 will trigger pin P10_6 of PSoC 6 to activate the engine.
notify_humidity < 60 will trigger pin P10_6 of PSoC 6 to activate motor.
All requirements are to evaluate the value of the sensor to activate the motor set at pin P10_6.
The functions adc_precent and notify_Temp are declared as global variables and they are for calculating the value of the sensor variable.
I’ve tried putting the reflow functions in the same dk_task subroutine. However, they don’t work, until I separate us they start working

I’d use just 1 task (as already proposed as far as I remember) checking the global variables and controlling the motor pin. On any change or measurement of the sensors values simply notify the motor control task. There is no need for an extra task delay there. It’s notified when there is something to check or to do.
I guess the measurement tasks run periodically (for instance with an appropriate delay between measurements) and notify the motor control task on measurement value change.
And better make global, shared variables volatile also as already mentioned, the code might not work when using optimization. It tells the compiler that a variable can be changed from outside.
(And you should post code as code and not screenshots.)
BTW I don’t understand the topic of the posting. xTaskCreate seems completely unrelated to your questions…

I apologize for the wrong title of this question

I tried to do as you said write them together in 1 task but they can’t handle the condition!

I still don’t get what you mean “When there is any change or measurement of the sensor values, just notify the machine control task. No need to further delay the task there. It is notified. Notify when something needs to be checked or done.
I predict running measurement tasks periodically (e.g. there is a match between measurements) and notify the motor control tasks of the measurement value change.
And it’s better to make the variables generic, global volatile as well as mentioned, the code can’t work when using optimization. It tells the compiler that a variable can be changed from the outside.” What is it? how to implement them!

Did you mean like this!

Exactly. And on the measurement side I’d save/remember the last measured value and only notify the dk_task in case the current measured value is different. Because if it’s the same value dk_task would do exactly the same as the last time which is useless.
Hint: When posting code just enclose the text by 3 tildes ‘~’ or alternatively 3 backticks ‘`’.

I tried to do it this way. However, when entering the program, P10_6 started continuously without being able to consider the specific condition of both.

I use Bluetooth for this case! This is my Bluetooth transmission code and in the dk_task section I made a command to wait for data from Bluetooth then execute the dk_task command.

This is bluetooth code of me!

	{
		wiced_result_t wiced_result = WICED_BT_SUCCESS;
	
		/* Configure platform specific settings for the BT device */
		cybt_platform_config_init(&cybsp_bt_platform_cfg);
	
		/* Register call back and configuration with stack */
		wiced_result = wiced_bt_stack_init (app_bt_management_callback, &wiced_bt_cfg_settings);
	
		/* Check if stack initialization was successful */
		if( WICED_BT_SUCCESS == wiced_result)
		{
			printf("Bluetooth Stack Initialization Successful \n");
		}
		else
		{
			printf("Bluetooth Stack Initialization failed !! \n");
		}
	
		for(;;)
		{
			ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
	
			if(char_notification_enabled == true)
			{
				/* Sample input voltage at channel 0 */
				adc_single_channel_process();
	
				adc_send_notification();
			}
			if(humidity_notification_enabled == true)
			{
				humidity_send_notification();
				printf("\r\nHumidity = %.2f\r\n",DHT_read.humidity);
			}
	
			if(temperature_notification_enabled == true)
			{
				temperature_send_notification();
				printf("\r\nTemperature = %.2f\r\n",DHT_read.temperature);
			}
			vTaskDelay(200);
		}
	}

This is the int main function that initializes the tasks!

/******************************************************************************
 * File Name: main.c
 *
 * Description: This is the source code for the FreeRTOS
 *              BLE ADC Server Example for ModusToolbox.
 *
 * Related Document: See README.md
 *
 *******************************************************************************
 * $ Copyright 2023-YEAR Cypress Semiconductor $
 *******************************************************************************/

/*******************************************************************************
 * Header Files
 *******************************************************************************/
#include "cybsp.h"
#include "cy_retarget_io.h"
#include <FreeRTOS.h>
#include <task.h>
#include "timers.h"
#include "GeneratedSource/cycfg_bt_settings.h"
#include "wiced_bt_stack.h"
#include "cybsp_bt_config.h"
#include "cybt_platform_config.h"
#include "cy_pdl.h"
#include "cyhal.h"
#include <ble_adc.h>
#include <queue.h>
#ifdef ENABLE_BT_SPY_LOG
#include "cybt_debug_uart.h"
#endif

/*******************************************************************************
 *        Macro Definitions
 *******************************************************************************/
#define BLE_TASK_STACK_SIZE                 ((configMINIMAL_STACK_SIZE * 4 ))
#define BLE_TASK_PRIORITY                   ((configMAX_PRIORITIES - 2 ))

#define UART_TASK_STACK_SIZE                ((configMINIMAL_STACK_SIZE * 4 ))
#define UART_TASK_PRIORITY                  ((configMAX_PRIORITIES - 3 ))

#define DK_TASK_STACK_SIZE                 ((configMINIMAL_STACK_SIZE * 4))
#define DK_TASK_PRIORITY                   ((configMAX_PRIORITIES - 4 ))


/*******************************************************************************
 * Variable Definitions
 *******************************************************************************/
TaskHandle_t uart_handle;
TaskHandle_t dk_task_handle;
TaskHandle_t control_task_handle;
TaskHandle_t dieukhien_task_handle;
TaskHandle_t ble_task_handle;
QueueHandle_t print_queue;

/******************************************************************************
 * Function Definitions
 ******************************************************************************/

/*******************************************************************************
 * Function Name : main
 * *****************************************************************************
 * Summary :
 *   Entry point to the application. Set device configuration and start BT
 *  stack initialization.  The actual application initialization will happen
 *  when stack reports that BT device is ready.
 *
 * Parameters:
 *    None
 *
 * Return:
 *    None
 ******************************************************************************/
int main()
{
	cy_rslt_t cy_result;
	BaseType_t rtos_api_result = pdPASS;


#if defined (CY_DEVICE_SECURE)
    cyhal_wdt_t wdt_obj;

    /* Clear watchdog timer so that it doesn't trigger a reset */
    result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
    CY_ASSERT(CY_RSLT_SUCCESS == result);
    cyhal_wdt_free(&wdt_obj);
#endif

	/* Initialize the board support package */
	cy_result = cybsp_init();

	if (CY_RSLT_SUCCESS != cy_result)
	{
		CY_ASSERT(0);
	}
    cy_result = cyhal_gpio_init(DATA_PIN, CYHAL_GPIO_DIR_BIDIRECTIONAL, CYHAL_GPIO_DRIVE_PULLUP, 1);
    cy_result = cyhal_gpio_init(P6_3, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, 1);
    cy_result = cyhal_gpio_init(P10_6, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, false);

	/* Enable global interrupts */
	__enable_irq();

#ifdef ENABLE_BT_SPY_LOG
	{
		cybt_debug_uart_config_t config = {
				.uart_tx_pin = CYBSP_DEBUG_UART_TX,
				.uart_rx_pin = CYBSP_DEBUG_UART_RX,
				.uart_cts_pin = CYBSP_DEBUG_UART_CTS,
				.uart_rts_pin = CYBSP_DEBUG_UART_RTS,
				.baud_rate = DEBUG_UART_BAUDRATE,
				.flow_control = TRUE};
		cybt_debug_uart_init(&config, NULL);
	}
#else
{
	/* Initialize retarget-io to use the debug UART port */
	cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
}
#endif //ENABLE_BT_SPY_LOG

printf("***************BTSTACK FreeRTOS Example *********************\n");
printf("****************** PSoC 6 BLE ADC DHT11 ********************\n");

print_queue = xQueueCreate(10, sizeof(struct read));
if(print_queue == NULL)
{
	CY_ASSERT(0);
}

xTaskCreate(DHT_Task, "DHT Task", 4*configMINIMAL_STACK_SIZE, (void*) print_queue, (configMAX_PRIORITIES - 1 ), NULL);
xTaskCreate(Print_Task, "Print Task", 4*configMINIMAL_STACK_SIZE, (void*) print_queue, 1, NULL);

/* Create a Button Task */
//rtos_api_result |=xTaskCreate(uart_task, "Uart", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIORITY, &uart_handle);

rtos_api_result |=xTaskCreate(ble_task, "BLE", BLE_TASK_STACK_SIZE, NULL, 1, &(ble_task_handle));

rtos_api_result |=xTaskCreate(dk_task, "DK", DK_TASK_STACK_SIZE, NULL, 1, &(dk_task_handle));

if (pdPASS  == rtos_api_result)
{
	/* Start the RTOS scheduler. This function should never return */
	vTaskStartScheduler();

	/* Program should never reach here! */
	printf("[Error]   : FreeRTOS scheduler failed to start \r\n");
}
else
{
	printf("[Error]   : FreeRTOS failed to create task \r\n");
}

printf("PSoC 063 BLE read DHT11 using Modus Toolbox 3.0");

/* Should never get here */
CY_ASSERT(0);
}

/* END OF FILE [] */

So the BLE task is also notified by a task ?
If you just want to periodically measure some sensors you can do it with a simple loop and a delay as you did it (without the ulTaskNotifyTake) or if a task triggers the measurement with a notification then again the delay should not be needed.
At least for testing I’d omit the ulTaskNotifyTake in the BLE task and let the measurement loop run with a delay and verify that the dk_task controls the pin as desired. Mean’s check that the conditions / the limit checks are correct.
Later on for instance In the send_notification functions I’d add a test if the currently measured value has changed and only in this case notify the dk_task as already proposed.
And I’d simplify the code in dk_task by checking all conditions and set the GPIO once analog to this pseudo code:

bool value = (sensor1 > limit1) || (sensor2 < limit2) …;
cyhal_gpio_write(…, value);

This should work. It doesn’t seem too complicated.
With a debugger attached you can simply set some breakpoints e.g. in the dk_task at the condition check and step through the code. You’ll quickly see what’s wrong.

That’s right at the beginning of the question in figure 1 is to start the BLE task!
When I omit ulTaskNotifyTake from the BLE task, the BLE task is not executed, it goes directly through the dk_task. And the condition part just turns on the engine and doesn’t do anything else.
When the BLE task is inactive we cannot tell if the values are changing or not!
I will try to put all the conditions into the same variable!
And I don’t understand your statement “With the debugger attached you can simply put some breakpoints e.g. in dk_task when checking the condition and go through the code step by step. You will quickly see what’s wrong.”
Thank you!