Skip to content
Snippets Groups Projects
Commit 4f989950 authored by Leon Bohnwagner's avatar Leon Bohnwagner :crab:
Browse files

feat: add bit banging raw dogging (¬‿¬)

parent fb2f04ad
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......@@ -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);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment