Lesson Watch Dogs


Watchdog is a timer which can continuously check if there is any malfunction in the system operation and perform certain actions to restore normal operation. Watchdogs are commonly found in embedded system devices and provides self reliance to the system. It can take timely action to a critical failure in the system thereby restoring the system to a safe state.


Operation of a standard watchdog timer

There are hardware and software watchdogs. Hardware watchdog awaits a signal/pulse from a resource in the system during its timer period. If it receives the signal, it will reset itself and restart the timer. This continues till the system operations are normal and stable. If the resource fails or there is any fault in the system, the watchdog receives no indication during its timer period. Once the timer period elapses, it can take certain actions to bring the system back to stable state. The action could be resetting the system or any other action which restores normal operation.

Software watchdog is a task which monitors other tasks. Each task will report to the watchdog about its normal operation. If any of the tasks misbehave, then the watchdog can alert the user/system or take corrective action to get the task back to normal state.

Ref: https://e2e.ti.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-03-59/1538.fig2.PNG


Task Resuming & Suspending

A freeRTOS task that is currently running can be suspended by another task or by its own task. A suspended task will not get any processing time from the micro-controller. Once suspended, it can only be resumed by another task.

API which can suspend a single task is:

void vTaskSuspend( TaskHandle_t xTaskToSuspend );

Refer this link to explore more details on the API. https://www.freertos.org/a00130.html

API to suspend the scheduler is:

void vTaskSuspendAll( void );
API to resume a single task:
void vTaskResume( TaskHandle_t xTaskToResume );
API to resume the scheduler:
BaseType_t xTaskResumeAll( void );



Event group APIs can be used to monitor a set of tasks. A software watchdog in an embedded system can make use of event groups for a group of tasks and notify/alert the user if any of the task misbehaves.

Each task uses an event bit. After every successful iteration of the task, the bit can be set by the task to mark completion. The event bits are then checked in the watchdog task to see if all the tasks are running successfully. If any of the bits are not set, then watchdog task can alert about the task to the user.

Below are the APIs that can be used. Refer to each of the API to understand how to use them in your application.

Lab Assignment: Watchdogs


  • Learn File I/O API to read and write data to the SD card
    • This requires a micro SD card that is formatted with FAT32
  • Design a simple application that communicates over the RTOS queue
  • Implement a "Software" Watchdog through FreeRTOS EventGroups API


Prerequisite Knowledge
File I/O

You will be using a "file system" API to read (or write) a file. This is a third-party library and is not part of the standard C library, and it is connected to the SD card using the SPI bus.

Please read this page for API details; here is the overall data flow which allows you to use high-level API to read and write a file.



  • A "watchdog timer" is a hardware timer
  • It can count up or count down based on the implementation
  • The objective is that when it reaches a ceiling, then it will trigger CPU reset
void main(void) {

  while (true) {
    // If this function does not run within 100ms, the CPU will reset



Part 0: Setup Producer and Consumer Task
  1. Create a producer task that reads a sensor value every 1ms.
    • The sensor can be any input type, such as a light sensor, or an acceleration sensor
    • After collecting 100 samples (after 100ms), compute the average
    • Write average value every 100ms (avg. of 100 samples) to the sensor queue
    • Use medium priority for this task
  2. Create a consumer task that pulls the data off the sensor queue
    • Use infinite timeout value during xQueueReceive API
    • Open a file (i.e.: sensor.txt), and append the data to an output file on the SD card
    • Save the data in this format: sprintf("%i, %i\n", time, light)"
    • Note that you can get the time using xTaskGetTickCount()
      • The sensor type is your choice (such as light or acceleration)
    • Note that if you write and close a file every 100ms, it may be very inefficient, so try to come up with a better method such that the file is only written once a second or so...
      • Also, note that periodically you may have to "flush" the file (or close it) otherwise data on the SD card may be cached and the file may not get written
    • Use medium priority for this task


  •  By configuration, fatfs only support FAT32. Thus, any MicroSD larger than 32 GB needs to be reformatted to FAT32.
  • Alternatively, you can modify the ffconfig.h to enable exFAT support.
#include "ff.h"
#include <string.h>

// Sample code to write a file to the SD Card
void write_file_using_fatfs_pi(void) {
  const char *filename = "file.txt";
  FIL file; // File handle
  UINT bytes_written = 0;
  FRESULT result = f_open(&file, filename, (FA_WRITE | FA_CREATE_ALWAYS));

  if (FR_OK == result) {
    char string[64];
    sprintf(string, "Value,%i\n", 123);
    if (FR_OK == f_write(&file, string, strlen(string), &bytes_written)) {
    } else {
      printf("ERROR: Failed to write data to file\n");
  } else {
    printf("ERROR: Failed to open: %s\n", filename);


Part 1: Use FreeRTOS EventGroup API

What you are designing is a software check-in system and thus emulating a "Software Watchdog".



  1. At the end of the loop of each task, set a bit using FreeRTOS event group API.
    • At the end of each loop of the tasks, set a bit using the xEventGroupSetBits()
    • producer task should set bit1, consumer task should set bit2 etc.
    • You are expected to read about the FreeRTOS Event Group API yourself
  2. Create a watchdog task that monitors the operation of the two tasks.
    • Use high priority for this task.
    • Use a task delay of 1 second, and wait for all the bits to set. If there are two tasks, wait for bit1, and bit2 etc.
    • If you fail to detect the bits are set, that means that the other tasks did not reach the end of the loop.
      • Print a message when the Watchdog task is able to verify the check-in of other tasks
      • Print an error message clearly indicating which task failed to check-in with the RTOS Event Groups API
void producer_task(void *params) {
  while(1) { // Assume 100ms loop - vTaskDelay(100)
    // Sample code:
    // 1. get_sensor_value()
    // 2. xQueueSend(&handle, &sensor_value, 0);
    // 3. xEventGroupSetBits(checkin)
    // 4. vTaskDelay(100)

void consumer_task(void *params) {
  while(1) { // Assume 100ms loop
    // No need to use vTaskDelay() because the consumer will consume as fast as production rate
    // because we should block on xQueueReceive(&handle, &item, portMAX_DELAY);
    // Sample code:
    // 1. xQueueReceive(&handle, &sensor_value, portMAX_DELAY); // Wait forever for an item
    // 2. xEventGroupSetBits(checkin)

void watchdog_task(void *params) {
  while(1) {
    // ...
    // vTaskDelay(200);
    // We either should vTaskDelay, but for better robustness, we should
    // block on xEventGroupWaitBits() for slightly more than 100ms because
    // of the expected production rate of the producer() task and its check-in
    if (xEventGroupWaitBits(...)) { // TODO
      // TODO


Part 2: Thoroughly test the Application
  1. Create a CLI to "suspend" and "resume" a task by name.
    • "task suspend task1" should suspend a task named "task1"
    • "task resume task2" should suspend a task named "task2"
  2. Run the system, and under normal operation, you will see a file being saved with sensor data values.
    • Collect the data over several seconds, and then verify by inserting the micro-SD card to your computer
    • Plot the file data in Excel to demonstrate.
  3. Suspend the producer task
    • The watchdog task should display a message and save relevant info to the SD card.
  4. Observe the CPU utilization while your file is being saved
    • You should observe that the SD card task should utilize more CPU

What you created is a "software watchdog". This means that in an event when a task is stuck, or a task is frozen, you can save relevant information such that you can debug at a later time.

You may use any built-in libraries for this lab assignment such as a sensor API



What to turn in
  • Positive test case scenario with serial terminal indicating tasks are running normally
  • Suspension of a task, and then negative test case scenario with serial terminal indicating which task failed to check-in
  • Data plot as mentioned in Part 2
  • All relevant source code (compiled and tested)
FreeRTOS Trace

Please use TraceAlyzer to open this trace and inspect what is going on. The company offers "Academic License" to view the attached file (click on the link above).