summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknolax <1339802534.kk@gmail.com>2017-12-07 23:23:03 -0500
committerknolax <1339802534.kk@gmail.com>2017-12-07 23:23:03 -0500
commitf1617e325830181323800c1c3d80c79b8e948232 (patch)
treea5c69763027cc37c2247dbc6e478379688a51863
parent4d26093fd63934a5b3b8441bb9740675faff1d96 (diff)
changed the update function from being timer based to thread based so that it can sleep. it may be because of the fact that it couldn't sleep that it was causing kenel panics
-rw-r--r--skey.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/skey.c b/skey.c
index 2d5b4aa..0457cb4 100644
--- a/skey.c
+++ b/skey.c
@@ -2,6 +2,9 @@
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/timer.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
/*
* Unsigned ints containing the BCM pin numbers for the pins used, __initdata
* helps with the loading and unloading of data in memory
@@ -14,35 +17,46 @@ static __initdata unsigned int row_pins[3] = {3, 6, 5};
static __initdata char * clabels[10] = {"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9",};
static __initdata char * rlabels[3] = {"R0", "R1", "R2"};
/*
- * timer period in ms and timer struct
+ * variables for setting up the thread
*/
-static struct timer_list update_timer;
-static int update_period = 5;
+
+struct task_struct *update_task;
/*
*This function is called every timer-period to actually read the keyboard
*/
-static void skey_update (unsigned long unused) {
- printk(KERN_INFO "skey: updated keyboard\n");
- //reads the keyboard
- int row_index = 0;
- int column_index = 0;
- while (column_index < 10) {
- //sets the column pin high for reading
- gpio_set_value(column_pins[column_index], 1);
- //reads with all the rows
- row_index = 0;
- while (row_index < 3) {
- if (gpio_get_value(row_pins[row_index])) {
- printk(KERN_INFO "skey: key pressed at column %d, row %d\n", column_index, row_index);
+int skey_update_thread (void *data) {
+ printk(KERN_INFO "skey: starting update thread\n");
+ //thread stuff
+ const struct sched_param PARAM = { .sched_priority = 45};
+ sched_setscheduler(current, SCHED_FIFO, &PARAM);
+ printk(KERN_INFO "skey: started update thread\n");
+ while (1) {
+ //reads the keyboard
+ int row_index = 0;
+ int column_index = 0;
+ while (column_index < 10) {
+ //sets the column pin high for reading
+ gpio_set_value(column_pins[column_index], 1);
+ //reads with all the rows
+ row_index = 0;
+ while (row_index < 3) {
+ if (gpio_get_value(row_pins[row_index])) {
+ printk(KERN_INFO "skey: key pressed at column %d, row %d\n", column_index, row_index);
+ }
+ row_index++;
}
- row_index++;
+ //sets the row pin low
+ gpio_set_value(column_pins[column_index], 0);
+ column_index++;
+ }
+ //sleep 2000us= 2ms = 0.002 seconds
+ usleep_range(2000, 2000);
+ //for when the thread has to stop
+ if (kthread_should_stop()) {
+ break;
}
- //sets the row pin low
- gpio_set_value(column_pins[column_index], 0);
- column_index++;
}
- //updates the timer
- mod_timer(&update_timer, jiffies + msecs_to_jiffies(update_period));
+ return 0;
}
/*
* This function is called when the module is loaded
@@ -86,12 +100,9 @@ static int __init skey_init (void) {
}
j++;
}
- //sets up timer for keyboard read function
- setup_timer(&update_timer, skey_update, 0);
- if (mod_timer(&update_timer, jiffies + msecs_to_jiffies(update_period))) {
- printk(KERN_ALERT "skey: failed to set up timer\n");
- return -EINVAL;
- }
+ //sets up update thread
+ printk("skey: setting up update thread...\n");
+ update_task = kthread_run(skey_update_thread, NULL, "skey_update_thread");
printk(KERN_INFO "skey: module finished initiating\n");
return 0;
}
@@ -112,8 +123,8 @@ static void __exit skey_exit (void) {
gpio_free(row_pins[j]);
j++;
}
- //deletes update timer
- del_timer(&update_timer);
+ //deletes the thread
+ kthread_stop(update_task);
printk(KERN_INFO "skey: module exited\n");
return;
}