From 906954a035a26077d4c1e1141613f98a36165183 Mon Sep 17 00:00:00 2001 From: Klagarge Date: Wed, 1 Apr 2026 17:21:01 +0200 Subject: [PATCH] feat(lab02): add code for ex08 --- src/01-skeleton/s02e08-interrupt.c | 83 ++++++++++++++++++++++++++++++ src/01-skeleton/skeleton.c | 72 +++++++++++++++++++------- 2 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 src/01-skeleton/s02e08-interrupt.c diff --git a/src/01-skeleton/s02e08-interrupt.c b/src/01-skeleton/s02e08-interrupt.c new file mode 100644 index 0000000..de0037d --- /dev/null +++ b/src/01-skeleton/s02e08-interrupt.c @@ -0,0 +1,83 @@ +#include // needed by all modules +#include // needed for macros +#include // needed for debugging + +#include +#include +#include "linux/printk.h" + +#define SWITCH_K1 0 +#define SWITCH_K2 2 +#define SWITCH_K3 3 + +struct gpio_nanopi { + int pin; + char* name; +}; +static struct gpio_nanopi switchK1 = {0, "K1: GPIOA.0"}; +static struct gpio_nanopi switchK2 = {0, "K2: GPIOA.2"}; +static struct gpio_nanopi switchK3 = {0, "K3: GPIOA.3"}; + +irqreturn_t isrGPIO(int irq, void* gpio_struct) { + struct gpio_nanopi *gpio = (struct gpio_nanopi *)gpio_struct; + pr_info("GPIO pressed: %s\n", gpio->name); + return IRQ_HANDLED; +} + + +void interrupt_init(void) { + pr_info("Initializing interrupts\n"); + + int status = 0; + + // Switch k1 + if (gpio_request(SWITCH_K1, switchK1.name) == 0) { + status = request_irq( + gpio_to_irq(SWITCH_K1), + isrGPIO, + IRQF_TRIGGER_FALLING | IRQF_SHARED, + switchK1.name, + &switchK1 + ); + } + + // Switch k2 + if (gpio_request(SWITCH_K2, switchK2.name) == 0) { + status = request_irq( + gpio_to_irq(SWITCH_K2), + isrGPIO, + IRQF_TRIGGER_FALLING | IRQF_SHARED, + switchK2.name, + &switchK2 + ); + } + + // Switch k3 + if (gpio_request(SWITCH_K3, switchK3.name) == 0) { + status = request_irq( + gpio_to_irq(SWITCH_K3), + isrGPIO, + IRQF_TRIGGER_FALLING | IRQF_SHARED, + switchK3.name, + &switchK3 + ); + } + + pr_info("Interrupt initialized\n"); +} + +void interrupt_exit(void) { + pr_info("Exiting interrupts\n"); + + gpio_free(SWITCH_K1); + free_irq(gpio_to_irq(SWITCH_K1), &switchK1); + + gpio_free(SWITCH_K2); + free_irq(gpio_to_irq(SWITCH_K2), &switchK2); + + gpio_free(SWITCH_K3); + free_irq(gpio_to_irq(SWITCH_K3), &switchK3); + + pr_info ("Interrupt exited\n"); + +} diff --git a/src/01-skeleton/skeleton.c b/src/01-skeleton/skeleton.c index 0f73338..0c0d303 100644 --- a/src/01-skeleton/skeleton.c +++ b/src/01-skeleton/skeleton.c @@ -3,69 +3,105 @@ #include // needed for macros #include // needed for debugging +#include "linux/printk.h" #include "s02e02-parameters.c" +// #define PARAMETERS + #include "s02e04-dynamic_allocation.c" +// #define DYNAMIC_ALLOCATION + #include "s02e05-io_memory_mapped.c" +// #define IO_MEMORY_MAPPED + #include "s02e06-thread.c" +// #define THREAD + #include "s02e07-sleeping.c" +// #define SLEEPING + +#include "s02e08-interrupt.c" +#define INTERRUPT static int __init skeleton_init(void) { pr_info("Linux module skeleton ex05 loading...\n"); - pr_info("--------------------\n"); // Lab02 - Exercise 2: Parameters - // parameters_print(); - - pr_info("--------------------\n"); + #ifdef PARAMETERS + pr_info("--------------------\n"); + parameters_print(); + #endif // Lab02 - Exercise 4: Dynamic memory allocation and linked list - // dynAlloc_init(); - + #ifdef DYNAMIC_ALLOCATION pr_info("--------------------\n"); + Alloc_init(); + #endif // Lab02 - Exercise 5: Memory-mapped I/O - // ioMemoryMapped_init(); - + #ifdef IO_MEMORY_MAPPED pr_info("--------------------\n"); + ioMemoryMapped_init(); + #endif // Lab02 - Exercise 6: Kernel thread - // thread_init(); - + #ifdef THREAD pr_info("--------------------\n"); + thread_init(); + #endif // Lab02 - Exercise 7: Sleeping + #ifdef SLEEPING + pr_info("--------------------\n"); sleeping_init(); + #endif + + // Lab02 - Exercise 8: Interrupt + #ifdef INTERRUPT + pr_info("--------------------\n"); + interrupt_init(); + #endif pr_info("--------------------\n"); - pr_info("Linux module skeleton loaded\n"); return 0; } static void __exit skeleton_exit(void) { + pr_info("Linux module skeleton unloading...\n"); // Lab02 - Exercise 4: Dynamic memory allocation and linked list - // dynAlloc_exit(); - + #ifdef DYNAMIC_ALLOCATION pr_info("--------------------\n"); + dynAlloc_exit(); + #endif // Lab02 - Exercise 5: Memory-mapped I/O - // ioMemoryMapped_exit(); - + #ifdef IO_MEMORY_MAPPED pr_info("--------------------\n"); + ioMemoryMapped_exit(); + #endif // Lab02 - Exercise 6: Kernel thread - // thread_exit(); - + #ifdef THREAD pr_info("--------------------\n"); + thread_exit(); + #endif // Lab02 - Exercise 7: Sleeping + #ifdef SLEEPING + pr_info("--------------------\n"); sleeping_exit(); + #endif + + // Lab02 - Exercise 8: Interrupt + #ifdef INTERRUPT + pr_info("--------------------\n"); + interrupt_exit(); + #endif pr_info("--------------------\n"); - pr_info ("Linux module skeleton unloaded\n"); }