From 4f989950d14deee9e0532aeb633536d1a2025f8d Mon Sep 17 00:00:00 2001
From: "leon.bohnwagner" <leon.bohnwagner@informatik.hs-fulda.de>
Date: Wed, 12 Feb 2025 23:07:15 +0100
Subject: [PATCH] =?UTF-8?q?feat:=20add=20bit=20banging=20raw=20dogging=20(?=
 =?UTF-8?q?=C2=AC=E2=80=BF=C2=AC)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 kernel/kmod.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index d8dd08c..882a939 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -6,6 +6,8 @@
 #include <linux/uaccess.h>
 #include <linux/hrtimer.h>
 #include <linux/kthread.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
 #include "../common/include/message.h"
 
 #define DEVICE_NAME "amogus"
@@ -14,6 +16,8 @@
 #define SLOTS 4
 #define SLOT_INTERVAL_NS 250000
 
+#define GPIO_PIN 12
+
 static int major_number;
 static struct class* class = NULL;
 static struct cdev mycdev;
@@ -44,7 +48,7 @@ static ssize_t device_write(struct file *filp, const char *input,
                            size_t length, loff_t *offset)
 {
     if(length != sizeof(message_t)) {
-        printk(KERN_ALERT "lkm: Tried to to write more bytes than allowed\n");
+        printk(KERN_ALERT "lkm: Tried to write more bytes than allowed\n");
         return -EFAULT;
     }
 
@@ -52,7 +56,7 @@ static ssize_t device_write(struct file *filp, const char *input,
         return -EFAULT;
     }
 
-    printk(KERN_INFO "lkm: received write of size %zu\n",length);
+    printk(KERN_INFO "lkm: received write of size %zu\n", length);
 
     return length;
 }
@@ -71,12 +75,31 @@ static enum hrtimer_restart timer_callback(struct hrtimer *timer) {
     return HRTIMER_RESTART;
 }
 
+static void send_byte(uint8_t byte) {
+    for (int i = 0; i < 8; i++) {
+        int bit = (byte >> (7 - i)) & 1;
+
+        gpio_set_value(GPIO_PIN, bit);
+        udelay(1);
+    }
+}
+
+static void send_data(void *data, size_t length) {
+    uint8_t *bytes = (uint8_t*)data;
+
+    for (size_t i = 0; i < length; i++) {
+        send_byte(bytes[i]);
+    }
+}
+
 static int timed_thread_fn(void *args) {
     while (!kthread_should_stop()) {
         wait_event_interruptible(wq, atomic_read(&wake_counter) > 0);
         atomic_dec(&wake_counter);
 
-        if (slot == 0) {}
+        if (slot == 0) {
+            send_data(&message, sizeof(message));
+        }
 
         slot = (slot + 1) % SLOTS;
     }
@@ -130,10 +153,16 @@ static int __init lkm_init(void)
 
     printk(KERN_INFO "lkm: device created successfully\n");
 
-    interval = ktime_set(0, SLOT_INTERVAL_NS);
-    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-    timer.function = timer_callback;
-    hrtimer_start(&timer, interval, HRTIMER_MODE_REL);
+    if (gpio_request(GPIO_PIN, "GPIO_PIN") < 0) {
+        vfree(message);
+        cdev_del(&mycdev);
+        device_destroy(class, MKDEV(major_number, 0));
+        class_destroy(class);
+        unregister_chrdev_region(MKDEV(major_number, 0), 1);
+        printk(KERN_ALERT "Failed to request GPIO pin\n");
+        return -1;
+    }
+    gpio_direction_output(GPIO_PIN, 0);
 
     timed_thread = kthread_run(timed_thread_fn, NULL, "timed_thread");
     if (IS_ERR(timed_thread)) {
@@ -142,13 +171,15 @@ static int __init lkm_init(void)
         device_destroy(class, MKDEV(major_number, 0));
         class_destroy(class);
         unregister_chrdev_region(MKDEV(major_number, 0), 1);
-
-        hrtimer_cancel(&timer);
-
         printk(KERN_ALERT "Failed to create timed thread\n");
         return -1;
     }
 
+    interval = ktime_set(0, SLOT_INTERVAL_NS);
+    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+    timer.function = timer_callback;
+    hrtimer_start(&timer, interval, HRTIMER_MODE_REL);
+
     return 0;
 }
 
@@ -161,6 +192,13 @@ static void __exit lkm_exit(void)
     unregister_chrdev_region(MKDEV(major_number, 0), 1);
     printk(KERN_INFO "lkm: device removed successfully\n");
 
+    gpio_set_value(GPIO_PIN, 0);
+    gpio_free(GPIO_PIN);
+
+    if(timed_thread) {
+        kthread_stop(timed_thread);
+    }
+
     hrtimer_cancel(&timer);
 }
 
-- 
GitLab