From b1cbff638d3018817b62084f2ecfb00c598d46cf Mon Sep 17 00:00:00 2001 From: vitaliyzhirko Date: Tue, 28 Dec 2021 16:11:12 +0200 Subject: [PATCH 1/2] TASK08: Add task08 IRQ handling, polling Signed-off-by: vitaliyzhirko --- 08_irq_handling/src/Makefile | 44 ++++++++++ 08_irq_handling/src/led_mod.c | 155 ++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 08_irq_handling/src/Makefile create mode 100644 08_irq_handling/src/led_mod.c diff --git a/08_irq_handling/src/Makefile b/08_irq_handling/src/Makefile new file mode 100644 index 0000000..dea0f3f --- /dev/null +++ b/08_irq_handling/src/Makefile @@ -0,0 +1,44 @@ +TARGET = led_module + +ifneq ($(KERNELRELEASE),) + +obj-m := $(TARGET).o +$(TARGET)-objs := led_mod.o + +else + + +ifneq ($(QUEMU),) +BUILD_KERNEL=~/projects/LinuxKernelCoursePro/kernel/buildroot-2021.02.7/output/build/linux-5.10.10/ +$(info 1 $(QUEMU)) +else +BUILD_KERNEL=/lib/modules/$(shell uname -r)/build +$(info 2 $(QUEMU)) +endif + + +KERNELDIR := $(BUILD_KERNEL) + +.PHONY: all clean + +all: + $(MAKE) -C $(KERNELDIR) M=$(CURDIR) modules +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURDIR) clean +install: + sudo insmod ./$(TARGET).ko + #- lsmod | grep head -n +remove: + sudo rmmod $(TARGET) + #- lsmod | grep head -n +test: + #sudo dmesg -C + sudo insmod $(TARGET).ko + sudo rmmod $(TARGET) + +check: + - $(BUILD_KERNEL)/scripts/checkpatch.pl -f --no-tree --fix ./main.c + +endif + + diff --git a/08_irq_handling/src/led_mod.c b/08_irq_handling/src/led_mod.c new file mode 100644 index 0000000..e3c9782 --- /dev/null +++ b/08_irq_handling/src/led_mod.c @@ -0,0 +1,155 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ + +#include +#include +#include +#include + +#define GPIO_NUMBER(port, bit) (32 * (port) + (bit)) + +/* https://linux-sunxi.org/Xunlong_Orange_Pi_PC#LEDs + * Board config for OPI-PC: + * LED GREEN (PL10): GPIO_11_10 + * LED RED (PA15): GPIO_0_15 + * BUTTON (PG7) : GPIO_6_7 + * + * https://linux-sunxi.org/Xunlong_Orange_Pi_Zero#LEDs + * Board config for OPI-Zero: + * LED GREEN (PL10): GPIO_11_10 + * LED RED (PA17): GPIO_0_17 + * BUTTON (PG7) : GPIO_6_7 + * + */ + +#define LED_GREEN GPIO_NUMBER(11, 10) +#define LED_RED GPIO_NUMBER(0, 17) +//#define BUTTON GPIO_NUMBER(6, 7) +#define BUTTON GPIO_NUMBER(0, 1) //Activate PA1 + +#define TIMER_ENABLE 1 + +static int ledg_gpio = -1; +static int ledr_gpio = -1; +static int button_gpio = -1; +static int button_state = -1; +static int button_cnt = -1; + +#ifdef TIMER_ENABLE +static ktime_t timer_period; +struct hrtimer button_timer; + +static enum hrtimer_restart timer_callback(struct hrtimer *timer) +{ + int cur_button_state; + + cur_button_state = gpio_get_value(button_gpio); + button_cnt = (cur_button_state == button_state) ? (button_cnt + 1) : 0; + button_state = cur_button_state; + gpio_set_value(ledr_gpio, ((button_cnt == 20) ? 1 : 0)); + if (button_cnt >= 20) + gpio_set_value(ledg_gpio, !button_state); + hrtimer_forward(timer, timer->base->get_time(), timer_period); + return HRTIMER_RESTART; //restart timer +} +#endif + +static int led_gpio_init(int gpio, int *led_gpio) +{ + int res; + + res = gpio_direction_output(gpio, 0); + if (res != 0) + return res; + + *led_gpio = gpio; + return 0; +} + +static int button_gpio_init(int gpio) +{ + int res; + + res = gpio_request(gpio, "Onboard user button"); + if (res != 0) + return res; + + res = gpio_direction_input(gpio); + if (res != 0) + goto err_input; + + button_gpio = gpio; + pr_info("Init GPIO%d OK\n", button_gpio); + button_state = gpio_get_value(button_gpio); + button_cnt = 0; + + return 0; + +err_input: + gpio_free(gpio); + return res; +} + +static void button_gpio_deinit(void) +{ + if (button_gpio >= 0) { + gpio_free(button_gpio); + pr_info("Deinit GPIO%d\n", button_gpio); + } +} + +/* Module entry/exit points */ +static int __init gpio_poll_init(void) +{ + int res; + pr_info("GPIO Init\n"); + + res = button_gpio_init(BUTTON); + if (res != 0) { + pr_err("Can't set GPIO%d for button\n", BUTTON); + return res; + } +#ifdef TIMER_ENABLE + timer_period = ktime_set(0, 1000000); /*1 msec*/ + hrtimer_init(&button_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_start(&button_timer, timer_period, HRTIMER_MODE_REL); + button_timer.function = timer_callback; +#endif + res = led_gpio_init(LED_GREEN, &ledg_gpio); + if (res != 0) { + pr_err("Can't set GPIO%d for output\n", LED_GREEN); + goto err_led; + } + + gpio_set_value(ledg_gpio, 0); + + res = led_gpio_init(LED_RED, &ledr_gpio); + if (res != 0) { + pr_err("Can't set GPIO%d for output\n", LED_RED); + goto err_led; + } + gpio_set_value(ledr_gpio, 1); + + return 0; + +err_led: + button_gpio_deinit(); + return res; +} + +static void __exit gpio_poll_exit(void) +{ + gpio_set_value(ledg_gpio, 1); + gpio_set_value(ledr_gpio, 0); + button_gpio_deinit(); +#ifdef TIMER_ENABLE + hrtimer_cancel(&button_timer); +#endif +} + +module_init(gpio_poll_init); +module_exit(gpio_poll_exit); + +MODULE_AUTHOR("Vitaliy Zhyrko vitaliyzh@gmail.com>"); +MODULE_DESCRIPTION("LED Test"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); From 5ff2da20bf4e0b65fefebf91f101a1c998f5e1aa Mon Sep 17 00:00:00 2001 From: vitaliyzhirko Date: Tue, 11 Jan 2022 10:30:58 +0200 Subject: [PATCH 2/2] Add task08 lesson08: irq hadlinng --- 08_irq_handling/src/led_mod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/08_irq_handling/src/led_mod.c b/08_irq_handling/src/led_mod.c index e3c9782..a9ed858 100644 --- a/08_irq_handling/src/led_mod.c +++ b/08_irq_handling/src/led_mod.c @@ -26,7 +26,8 @@ //#define BUTTON GPIO_NUMBER(6, 7) #define BUTTON GPIO_NUMBER(0, 1) //Activate PA1 -#define TIMER_ENABLE 1 +//#define TIMER_ENABLE 1 +#define IRQ_ENABLE 1 static int ledg_gpio = -1; static int ledr_gpio = -1;