PSoC5LP RTOS
Lab 03 — Task Control: Suspend & Resume

FreeRTOS on PSoC 5LP · Lab Series. Platform: CY8CKIT-059 (PSoC 5LP, Cortex-M3) · PSoC Creator 4.4 · FreeRTOS Kernel V11. Pairs with Chapter 3 — Task Control (and Chapter 1 — Tasks).


1. Introduction & Objectives

So far, tasks have only paused themselves with vTaskDelay. This lab introduces control from one task over another: a button task pauses and resumes a blinking LED task through the blink task's handle, using vTaskSuspend and vTaskResume. Along the way, you see the difference between Blocked, Suspended, and Deleted.

After this lab you can:

  • Keep a task handle from xTaskCreate and use it to control that task later.
  • Suspend and resume a task with vTaskSuspend / vTaskResume.
  • Explain why suspend/resume are not counted, and track your own paused flag.
  • Tell Blocked (automatic, self-clearing) from Suspended (manual, no timeout) from Deleted (permanent).
  • Debounce a button so one press = one action.

2. Prerequisites

Hardware: CY8CKIT-059 PSoC 5LP Prototyping Kit; RobotSoC Kit 1× LED + 220 Ω, 1× push button.

Software: PSoC Creator 4.4 with the FreeRTOS V11 BaseProject.

Chapters (sync progress): Required — Chapter 3 (Task Control: handle, suspend/resume, states), builds on Chapter 1 (tasks); Peripheral prerequisite — basic GPIO (LED/switch) is covered in the separate (non-FreeRTOS) Lab 01–02.

3. Reading Materials / References

  • Chapter 3 slides — Task Control (suspend/resume, handle, Blocked vs Suspended vs Deleted).
  • FreeRTOS API: vTaskSuspend, vTaskResume, xTaskResumeFromISR, eTaskGetState, vTaskDelete.

4. Background & Theory of Operation

Handles. xTaskCreate(..., &hTask) writes a handle — a reference to the created task — into hTask. Any task that holds the handle can act on that task: suspend it, resume it, query its state, change its priority, or delete it. In this lab the control task holds hBlink so it can pause the blink task.

Suspend vs delay. vTaskDelay is a timed pause the task asks for itself; it ends on its own. vTaskSuspend(hTask) is an open-ended stop another task applies: the task is taken off the scheduler and stays off — no timeout — until something calls vTaskResume(hTask). A suspended task uses no CPU, just like a blocked one, but it will never wake on its own.

The three states to keep straight.

  • Blocked — automatic: waiting on a delay or an event; clears itself on timeout/event; the task stays alive.
  • Suspended — manual: vTaskSuspend took it off the scheduler; only vTaskResume returns it; the task stays alive.
  • Deleted — manual: vTaskDelete removes it permanently and frees its memory; it cannot be resumed.

Suspend/resume are not counted. Two vTaskSuspend calls still need only one vTaskResume. So you cannot rely on call-counting; keep your own paused flag and flip it on each press. eTaskGetState(hTask) lets you confirm the task reads eSuspended while paused and eBlocked while delaying.

From an ISR. vTaskResume is task-context only. If a resume comes from an interrupt, use xTaskResumeFromISR instead (introduced with interrupts later). This lab polls the button in a task, so vTaskResume is correct here.

Debounce. A mechanical button bounces: one press can read as many. Add a short delay after acting (or require a release) so one physical press produces one suspend/resume.

5. RTOS Task Architecture & State Model

TWO TASKS, ONE HANDLE Control (Button) Task priority 2 · polls the button (debounced) each press flips paused/running owns hBlink, the blink task's handle Blink Task priority 1 · toggles the LED every 200 ms vTaskDelay between toggles target of suspend / resume vTaskSuspend (hBlink) vTaskResume (hBlink) TASK STATES RUNNING READY BLOCKED vTaskDelay / wait SUSPENDED manual, no timeout DELETED scheduled block event/timeout vTaskSuspend vTaskResume vTaskDelete Blocked is automatic and clears itself (timeout/event). Suspended is manual with no timeout — only vTaskResume returns it. Suspend/resume are not counted: two suspends need only one resume, so track your own paused flag. Deleted is permanent. ​

Left — the two tasks: the Control (Button) Task (priority 2) owns hBlink and calls vTaskSuspend / vTaskResume on the Blink Task (priority 1). Right — the state model: the blink task moves Running ⇄ Ready ⇄ Blocked on its own, but only an explicit vTaskSuspend/vTaskResume crosses into and out of Suspended, and vTaskDelete is one-way to Deleted.

6. Suspend / Resume Over Time

Suspend/resume a blink (button-controlled) the LED toggles every 200 ms; a press suspends the blink task, the next press resumes it 0 200 400 600 800 1000 1200 1400 1600 1800 time (ms) SUSPENDED (LED frozen) PRESS suspend resume LED Conceptual / idealized. During SUSPENDED, the blink task is off the scheduler, so the LED holds its level; resume continues the toggling. Measure on hardware. ​

The LED toggles every 200 ms. The first press suspends the blink task, so the LED freezes at whatever level it was at — the task is off the scheduler and does no further toggling. The next press resumes it and the toggling continues. Nothing happens to the LED during the suspended band because a suspended task simply does not run.

7. Schematic Circuit & Pin Configuration

  • LED → GPIO + 220 Ω → GND.
  • BTN → push button to GND, internal pull-up (active-low: pressed reads 0).
  • Assign both in <project>.cydwr → Pins.

8. FreeRTOS API Reference

APIPurpose
xTaskCreate(..., &handle) Create a task and capture its handle for later control.
vTaskSuspend(h) Take a task h off the scheduler; NULL suspends the caller. No timeout.
vTaskResume(h) Resume a suspended task (task context only).
xTaskResumeFromISR(h) ISR-safe resume; returns whether a context switch is needed.
eTaskGetState(h) Query a task's state (Running/Ready/Blocked/Suspended).
vTaskDelete(h) Remove a task permanently; NULL deletes the caller.

9. Provided Template

You are given Lab03_Template_main.c:

  • Given: all includes (note #include "FreeRTOS_PSoC.h"), both handles, and a complete main() that creates the blink task first (so hBlink is valid before the control task runs), then the control task. Both task functions have a placeholder so the project builds and runs.
  • You write: the bodies of vBlinkTask() and vControlTask(), per the TODO(Exp01) comments — including a paused flag and a debounce.
  • Do not change the boot sequence in main().
static void vControlTask(void *arg)
{
    /* bool paused = false; */
    for (;;)
    {
        /* TODO(Exp01): if (BTN_Read()==0) { paused=!paused;
         *   paused ? vTaskSuspend(hBlink) : vTaskResume(hBlink);
         *   vTaskDelay(pdMS_TO_TICKS(250)); }
         * vTaskDelay(pdMS_TO_TICKS(10)); */
        vTaskDelay(pdMS_TO_TICKS(10));   /* placeholder */
    }
}

10. Lab Experiments

Exp01 — Basic: pause & resume a blink. Write both task bodies. One press pauses the blink (the LED freezes); the next resumes it. Use a paused flag and debounce so one press = one toggle. Expected: the LED freezes and continues cleanly, one press at a time.

Exp02 — Advanced: watch the states. In the control task, read eTaskGetState(hBlink) and print it over UART. Confirm the blink task reads eBlocked while it is delaying and eSuspended while paused. Then call vTaskSuspend(hBlink) twice in a row and show that a single vTaskResume still brings it back — proof that suspends are not counted. Expected: a short UART log of the state across a press cycle.

Exp03 — Challenge: delete vs suspend (and a third task). Add a third task (e.g. a 500 ms LED or a 1 s UART status). Then compare: after vTaskSuspend you can resume; after vTaskDelete(hBlink) the task is gone and a later resume does nothing (and hBlink is stale). Expected: you can state why suspend is reversible and delete is not, and the other tasks keep running throughout.

11. Testing & Verification

#Pass condition
Exp01 One press pauses the blink (LED frozen), next press resumes; one press = one toggle.
Exp02 UART shows eBlocked/eSuspended; two suspends + one resume still resumes.
Exp03 Suspend is reversible; after delete, the task is gone; other tasks unaffected.

Submit: your two task bodies, the Exp02 state log, and a one-line suspend-vs-delete explanation.

12. Q&A & Troubleshooting

  • One press toggles several times → button bounce; add a debounce delay or require a release.
  • LED never resumes → you suspended twice but resumed once, or lost track of paused; keep the flag.
  • HardFault on resume → hBlink is stale (task was deleted), or you resumed before the task was created.
  • Whole system freezes → you suspended a task that holds a shared resource, or suspended the control task itself.
  • Must resume from an ISR → use xTaskResumeFromISR, not vTaskResume.

13. Analysis Questions & Lab Report

  1. What is a task handle, and what can another task do with it?
  2. Compare Blocked, Suspended, and Deleted: who causes each, and how does the task leave that state?
  3. Why are suspend/resume "not counted," and what does that force you to do in code?
  4. When must you use xTaskResumeFromISR instead of vTaskResume?

Your report should include your task bodies, the Exp02 log, and answers to the four questions.

© 2026 Air Supply Information Center (Air Supply BBS)