From dcf30472717f02a4857426e9ebdea30ae53622cb Mon Sep 17 00:00:00 2001 From: "david.maul" <david.maul@informatik.hs-fulda.de> Date: Thu, 13 Feb 2025 21:18:37 +0100 Subject: [PATCH] fix: prepare message only once for sending --- kernel/kmod.c | 72 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/kernel/kmod.c b/kernel/kmod.c index 387109c..7dfff87 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -17,7 +17,7 @@ #define SLOTS 4 #define SLOT_INTERVAL_NS 10000000 -#define MAX_VALUES 16 +#define MAX_MEASUREMENTS 16 #define BAUD_RATE 9600 #define BIT_TIME_US (1000000 / BAUD_RATE) @@ -28,6 +28,7 @@ static struct class *class = NULL; static struct cdev mycdev; typedef struct packet { + uint8_t magic; data_t data; uint32_t crc; } packet_t; @@ -42,19 +43,48 @@ static struct task_struct *timed_thread; static DECLARE_WAIT_QUEUE_HEAD(wq); static atomic_t wake_counter = ATOMIC_INIT(0); +#define SEND_BUFFER_SIZE 4096 + +static uint8_t send_buffer[SEND_BUFFER_SIZE]; +static size_t send_buffer_size = 0; + static int slot = 0; static int device_open(struct inode *inode, struct file *file) { return 0; } static int device_release(struct inode *inode, struct file *file) { return 0; } -static uint32_t calculate_crc32(const data_t *data) { - uint32_t crc = crc32(0, (void *)&data->sender_id, sizeof(uint8_t)); - crc = crc32(crc, (void *)&data->count, sizeof(uint8_t)); - crc = crc32(crc, (void *)&data->measurements, sizeof(measurement_t) * data->count); +static uint32_t calculate_crc32(const packet_t *packet) { + uint32_t crc = crc32(0, (void *)&packet->data.sender_id, sizeof(uint8_t)); + crc = crc32(crc, (void *)&packet->data.count, sizeof(uint8_t)); + crc = crc32(crc, (void *)&packet->data.measurements, + sizeof(measurement_t) * packet->data.count); return crc; } +static void prepare_for_sending(void) { + packet->crc = calculate_crc32(packet); + + send_buffer[0] = packet->magic; + send_buffer[1] = packet->data.sender_id; + send_buffer[2] = packet->data.count; + + uint8_t *bytes = (uint8_t *)packet->data.measurements; + + for (size_t i = 0; i < sizeof(measurement_t) * packet->data.count; i++) { + send_buffer[bytes[3 + i]] = bytes[i]; + } + + bytes = (uint8_t *)&packet->crc; + + for (size_t i = 0; i < sizeof(uint32_t); i++) { + send_buffer[3 + sizeof(measurement_t) * packet->data.count + i] = bytes[i]; + } + + send_buffer_size = + 3 + sizeof(measurement_t) * packet->data.count + sizeof(uint32_t); +} + static ssize_t device_write(struct file *filp, const char *input, size_t length, loff_t *offset) { if (length != sizeof(data_t)) { @@ -62,8 +92,8 @@ static ssize_t device_write(struct file *filp, const char *input, size_t length, return -EFAULT; } - if (((data_t *)input)->count >= MAX_VALUES) { - printk(KERN_ALERT "lkm: Tried to write more messages than allowed\n"); + if (((data_t *)input)->count >= MAX_MEASUREMENTS) { + printk(KERN_ALERT "lkm: Tried to write more measurements than allowed\n"); return -EFAULT; } @@ -84,7 +114,7 @@ static ssize_t device_write(struct file *filp, const char *input, size_t length, return -EFAULT; } - packet->crc = calculate_crc32(&packet->data); + prepare_for_sending(); printk(KERN_INFO "lkm: received write of size %zu\n", length); @@ -123,23 +153,9 @@ static inline void send_byte(uint8_t byte) { } static void send_data(const packet_t *packet) { - send_byte(0xAA); - /* -send_byte(packet->data.sensor_id); -send_byte(packet->data.count); - -uint8_t *bytes = (uint8_t *)packet->data.values; - -for (size_t i = 0; i < sizeof(message_t) * packet->data.count; i++) { - send_byte(bytes[i]); -} - -bytes = (uint8_t *)&packet->crc; - -for (size_t i = 0; i < sizeof(uint32_t); i++) { - send_byte(bytes[i]); -} -*/ + for (size_t i = 0; i < send_buffer_size; i++) { + send_byte(send_buffer[i]); + } } static int timed_thread_fn(void *args) { @@ -166,16 +182,20 @@ static int __init lkm_init(void) { return -EFAULT; } + packet->magic = 0xAA; packet->data.sender_id = SENDER_ID; packet->data.count = 0; - packet->data.measurements = (measurement_t *)vmalloc(sizeof(measurement_t) * MAX_VALUES); + packet->data.measurements = + (measurement_t *)vmalloc(sizeof(measurement_t) * MAX_MEASUREMENTS); if (packet->data.measurements == NULL) { vfree(packet); return -EFAULT; } + prepare_for_sending(); + // Dynamically allocate major number if (alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME) < 0) { vfree(packet->data.measurements); -- GitLab