The application must execute 2 tasks, one of them always will run, the other one must be blocked by a semaphore, this task must blink an LED when is enabled, to unlock the task a button must be pressed.

Code Example:

#include "bsp.h"

void vPeriodicTask( void *pvParameters );   /* Function of task Run normally */
void vHandlerTask( void *pvParameters );    /* Funtion of task to be triggered */

SemaphoreHandle_t xBinSemaphore;            /* Handler of binary Semaphore */

int main( void )
{
    HAL_Init();

    SEGGER_SYSVIEW_Conf();
    SEGGER_SYSVIEW_Start();

    xBinSemaphore = xSemaphoreCreateBinary();                           /* Create binary semaphore */

    HAL_NVIC_SetPriority( EXTI4_15_IRQn, 2, 0  );                       /* Set the priority of external interrupt */
    HAL_NVIC_EnableIRQ( EXTI4_15_IRQn );                                /* Enable External interrupt */

    xTaskCreate( vPeriodicTask, "NormalTask", 240, NULL, 1, NULL );     /* Register Task */
    xTaskCreate( vHandlerTask, "TriggeredTask", 240, NULL, 2, NULL );   /* Register Task */

    vTaskStartScheduler();                                              /* Run Kernel */

    return 0;
}

void vPeriodicTask( void *pvParameters )
{
    for(;;)
    {
        vTaskDelay( 500 / portTICK_PERIOD_MS );
        SEGGER_SYSVIEW_PrintfHost( "Normal Task msg" );     /* Print msg concurrently */
    }
}

void vHandlerTask( void *pvParameters )
{

    for(;;)
    {
        xSemaphoreTake( xBinSemaphore, portMAX_DELAY );     /* If semaphore is available continues execution if not block task */
        SEGGER_SYSVIEW_PrintfHost( "BlinkLed" );            /* Print a message if task run */
        HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_0 );            /* Change Led Status */
        xSemaphoreGive(xBinSemaphore);                      /* Give the semaphore to run again */

        vTaskDelay(500);                                    /* add task concurrency every 500ms */
    }
}

void HAL_GPIO_EXTI_Rising_Callback( uint16_t GPIO_Pin )                     /* Callback of interrupt */
{
    SEGGER_SYSVIEW_RecordEnterISR();                                        /* Record enter of IRS on SytemView timeline */
    BaseType_t xTaskWoken = pdFALSE;                        

    /* Conditional to check if task is blocked or not */
    if ( xSemaphoreGiveFromISR( xBinSemaphore,  &xTaskWoken ) != pdPASS )   /* if Task vPeriodicTask is unblocked */
    {
        xSemaphoreTakeFromISR( xBinSemaphore, &xTaskWoken );                /* Block Task */
    }
    
    SEGGER_SYSVIEW_RecordExitISR();                                         /* Record exit of IRS on SytemView timeline */
    portEND_SWITCHING_ISR( xTaskWoken );                                    /* Change context */
}

Task vPeriodicTask is executed normally, for each 500 ticks the task must print a message on the terminal, and the task vHandlerTask is blocked by default. This task must blink an LED to know that the task is running. The task can be unlocked when a button is pressed which activates an interrupt to give the binary semaphore, if the button is pressed again the interruption callback must block the task again.

SystemView Output

Terminal shows the vPeriodicTask execution at the init, when the button is pressed the other task vHandlerTask now executed concurrently until a button is pressed again.

Document

Timeline:

Document

When the button is pressed an interruption is generated, observe the “ISR 23“ section that runs at the init of the timeline.
After, task vHandlerTask is unlocked and can be blinked the LED and print on Terminal that led is blinking.

If the button is pressed again, the task will be blocked again, observe that in the timeline the interruption is generated again.
The terminal shows the behavior of the task, "vHandlerTask" stops running, compares the times between timeline ISR execution and the last message on the terminal of “BlinkLed“.