Exercise 2

v2.x.x

Controlling an LED through a button (interrupt based)

In this exercise, we will modify the application to use the more power-efficient interrupt-based method, like we explained in GPIO Generic API. Configure the button to generate an interrupt every time it is pressed. Then, inside the interrupt handler (callback function) of the button, we will toggle the LED.

Exercise steps

1. In VS Code, select Add an existing application, like we did in the previous exercise.

2. In the GitHub repository for this course, open the exercise code base for this exercise, found in lesson2/fund_less2_exer2 of whichever version directory you are using (v2.x.x or v1.6.0-v1.9.1).

3. Configure the interrupt on the button’s pin.

Configure an interrupt on the pin associated with the button by calling the function gpio_pin_interrupt_configure_dt().

Search for STEP 3 in main.c and add the following code:  

ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);

4. Define the callback function button_pressed().

Define the callback function that will run when the button is pressed to toggle the LED.

Search for STEP 4 and add the following code:

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    gpio_pin_toggle_dt(&led);
}

5. Define a variable of type static struct gpio_callback.

Search for STEP 5 in main.c and add the line below:

static struct gpio_callback button_cb_data;

6. Initialize the static struct gpio_callback variable.

Initialize the struct gpio_callback button_cb_data by passing this variable, along with the callback function and the bit mask for the GPIO pin button.pin to gpio_init_callback().

Search for STEP 6 and add the following line:

gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); 	

7. Add the callback function by calling gpio_add_callback().

Search for STEP 7 and add the following line:

gpio_add_callback(button.port, &button_cb_data);

8. We will get rid of all the polling code in the main loop and we will keep the call to the function k_msleep() to put the main thread (covered in Lesson 7) to sleep for a very long time.

9. Increase the sleep time in the main function from 100 ms to 10 minutes. This is done by changing the macro SLEEP_TIME_MS value from 100 to 10*60*1000.

More on this (Lesson 7)

In this example, there are no other high-priority threads running. Therefore, the idle thread will be called automatically to put the CPU to sleep. The CPU will wake up whenever the button is pressed, it will call the ISR, which will toggle the LED. Then execution is resumed back to the infinite loop, which will call the sleep function again.

Since the main function does not have any functionality aside from configuring the GPIO and the callback function, we let it yield by calling k_msleep() so the RTOS scheduler can select a ready thread to run. A better method would actually be calling k_yield() in the while-loop.

Lesson 7 will cover the different Zephyr system threads.

10. Build the exercise and flash it to the board. Just like in Exercise 1, observe that when button 1 is pressed, the LED is toggled.

The solution for this exercise can be found in the GitHub repository, lesson2/fund_less2_exer2_solution of whichever version directory you are using (v2.x.x or v1.6.0-v1.9.1).

v1.6.0 – v1.9.1

Controlling an LED through a button (interrupt based)

In this exercise, we will modify the application to use the more power-efficient interrupt-based method, like we explained in GPIO Generic API. Configure the button to generate an interrupt every time it is pressed. Then, inside the interrupt handler (callback function) of the button, we will toggle the LED.

Exercise steps

1. In VS Code, select Add an existing application, like we did in the previous exercise.

2. In the GitHub repository for this course, open the exercise code base for this exercise, found in lesson2/fund_less2_exer2 of whichever version directory you are using (v2.x.x or v1.6.0-v1.9.1).

3. Define a variable of type static struct gpio_callback. Search for STEP 3 in main.c and add the line below:

static struct gpio_callback button_cb_data;

4. Configure the interrupt on the pin by calling the function gpio_pin_interrupt_configure().

Search for STEP 4 in main.c and add the following code:  

    ret = gpio_pin_interrupt_configure(dev, SW0_GPIO_PIN, GPIO_INT_EDGE_TO_ACTIVE | GPIO_INT_DEBOUNCE);

5. Define the callback function button_pressed().

Search for STEP 5 and add the following code:

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    gpio_pin_toggle(dev,PIN);
}

6. Initialize the static struct gpio_callback variable.

Search for STEP 6 and add the following line:

    gpio_init_callback(&button_cb_data, button_pressed, BIT(SW0_GPIO_PIN)); 

7. Add the callback function by calling gpio_add_callback().

Search for STEP 7 and add the following line:

    gpio_add_callback(dev, &button_cb_data);

8. We will get rid of all the polling code in the main loop and we will keep the call to the function k_msleep() to put the main thread (covered in Lesson 7) to sleep for a very long time.

9. Increase the sleep time in the main function from 100 ms to 10 minutes. This is done by changing the macro SLEEP_TIME_MS value from 100 to 10*60*1000.

More on this (Lesson 7)

In this example, there are no other high-priority threads running. Therefore, the idle thread will be called automatically to put the CPU to sleep. The CPU will wake up whenever the button is pressed. It will call the ISR, which will toggle the LED. Then execution is resumed back to the infinite loop, which will call the sleep function again.

Since the main function does not have any functionality aside from configuring the GPIO and the callback function, we let it yield by calling k_msleep() so the RTOS scheduler can select a ready thread to run. A better method would actually be calling k_yield() in the while-loop.

Lesson 7 will cover the different Zephyr system threads.

10. Build the exercise and flash it to the board. Just like in Exercise 1, observe that when button 1 is pressed, the LED is toggled.

The solution for this exercise can be found in the GitHub repository, lesson2/fund_less2_exer2_solution of whichever version directory you are using (v2.x.x or v1.6.0-v1.9.1).

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

Forgot your password?
Enter your email address, and we will send a link to reset your password.