From ce3b308d6d8f4a5541fff3ba1cec521cb7c1a7ae Mon Sep 17 00:00:00 2001 From: fastium Date: Fri, 5 Jun 2026 11:46:39 +0200 Subject: [PATCH] feat(MP/kernel): add temperature API - init and exit fonction for the module - read_temp(), to get the temperature --- src/06-mini-project/kernel/Makefile | 13 ++- src/06-mini-project/kernel/main.c | 34 +++++++- src/06-mini-project/kernel/temperature/temp.c | 83 +++++++++++++++++++ src/06-mini-project/kernel/temperature/temp.h | 27 ++++++ 4 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 src/06-mini-project/kernel/temperature/temp.c create mode 100644 src/06-mini-project/kernel/temperature/temp.h diff --git a/src/06-mini-project/kernel/Makefile b/src/06-mini-project/kernel/Makefile index 05692bc..103b424 100644 --- a/src/06-mini-project/kernel/Makefile +++ b/src/06-mini-project/kernel/Makefile @@ -11,7 +11,15 @@ SOURCE := main ifneq ($(KERNELRELEASE),) obj-m += $(MODULE).o ## name of the generated module -$(MODULE)-objs := $(SOURCE).o ## list of objects needed for that module +# add folder sources +SOURCES_C := $(wildcard $(src)/*.c) +# add temperature sources +SOURCES_C += $(wildcard $(src)/temperature/*.c) + + +$(MODULE)-objs := $(patsubst $(src)/%.c, %.o, $(SOURCES_C)) + +# $(MODULE)-objs := $(SOURCE).o ## list of objects needed for that module CFLAGS_$(SOURCE).o := -DDEBUG # Part executed when called from standard make in module source directory: @@ -28,7 +36,6 @@ clean: install: $(MAKE) -C $(KDIR) M=$(PWD) INSTALL_MOD_PATH=$(MODPATH) modules_install - install -D -m 0644 $(MODULE).conf $(MODPATH)/etc/modprobe.d/$(MODULE).conf + # install -D -m 0644 $(MODULE).conf $(MODPATH)/etc/modprobe.d/$(MODULE).conf endif - diff --git a/src/06-mini-project/kernel/main.c b/src/06-mini-project/kernel/main.c index 8b1cff4..647b01c 100644 --- a/src/06-mini-project/kernel/main.c +++ b/src/06-mini-project/kernel/main.c @@ -2,13 +2,41 @@ #include // needed by all modules #include // needed for macros #include // needed for debugging +#include +#include +#include #include "linux/printk.h" +#include "temperature/temp.h" + +static struct task_struct *temp_thread = NULL; + +/* Thread function that runs in the background */ +static int temp_thread_fn(void *data) { + pr_info("temp_regulator: Background thread started\n"); + + while (!kthread_should_stop()) { + read_temp(); + /* Wait 1 second (1000 milliseconds) */ + msleep(1000); + } + + pr_info("temp_regulator: Background thread stopping\n"); + return 0; +} + static int __init temp_regulator_init(void) { pr_info("Linux module temp_regulator loading...\n"); - + int ret; + + /* Initialize temperature sensor API */ + ret = temp_init(); + if (ret != 0) { + pr_err("temp_regulator: Initialization failed with error %d\n", ret); + return ret; + } pr_info("Linux module temp_regulator loaded\n"); return 0; @@ -18,7 +46,9 @@ static void __exit temp_regulator_exit(void) { pr_info("Linux module temp_regulator unloading...\n"); - + /* Release sensor resources */ + temp_exit(); + pr_info("Linux module temp_regulator unloaded\n"); } diff --git a/src/06-mini-project/kernel/temperature/temp.c b/src/06-mini-project/kernel/temperature/temp.c new file mode 100644 index 0000000..f42413d --- /dev/null +++ b/src/06-mini-project/kernel/temperature/temp.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include + +#include "temp.h" + +#define TEMPERATURE_SENSOR_BASE_ADDR 0x01C25000 +#define TEMPERATURE_SENSOR_REG_SIZE 0x1000 +#define TEMPERATURE_REG_OFFSET 0x80 + +static struct resource *temp_res = NULL; +static void __iomem *temp_reg = NULL; + +int temp_init(void) { + /* Request physical memory region */ + temp_res = request_mem_region(TEMPERATURE_SENSOR_BASE_ADDR, + TEMPERATURE_SENSOR_REG_SIZE, + "nanopi - temperature sensor"); + if (temp_res == NULL) { + pr_warn("temp_regulator: Failed to reserve physical memory region\n"); + } + + /* Map the physical memory to virtual kernel memory */ + temp_reg = ioremap(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE); + if (temp_reg == NULL) { + pr_err("temp_regulator: Failed to ioremap registers\n"); + /* Clean up previously requested region */ + release_mem_region(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE); + temp_res = NULL; + return -ENOMEM; + } + + pr_info("temp_regulator: Temperature sensor memory successfully mapped\n"); + return 0; +} + +uint32_t read_temp(void) { + uint32_t temperature = 0; + uint32_t raw_val = 0; + + if (temp_reg == NULL) { + pr_warn("temp_regulator: Cannot read temperature, sensor not initialized\n"); + return 0; + } + + /* Read the raw register value from THS0_DATA (offset 0x80) */ + raw_val = ioread32(temp_reg + TEMPERATURE_REG_OFFSET); + + /* Choose the correct formula according to the datasheet */ + if (raw_val > 0x500) { + /* Temperature is lower than 70°C */ + temperature = -1191 * (int32_t)raw_val / 10 + 223000; + } else { + /* Temperature is higher than or equal to 70°C */ + temperature = -1452 * (int32_t)raw_val / 10 + 259000; + } + + pr_info("temp_regulator: Temperature=%u.%03u C (register raw value: %u)\n", + temperature / 1000, + temperature % 1000, + raw_val); + + return temperature; +} + +void temp_exit(void) { + /* Unmap virtual address space */ + if (temp_reg != NULL) { + iounmap(temp_reg); + temp_reg = NULL; + } + + /* Release physical memory region */ + if (temp_res != NULL) { + release_mem_region(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE); + temp_res = NULL; + } + + pr_info("temp_regulator: Temperature sensor resources released\n"); +} diff --git a/src/06-mini-project/kernel/temperature/temp.h b/src/06-mini-project/kernel/temperature/temp.h new file mode 100644 index 0000000..096805c --- /dev/null +++ b/src/06-mini-project/kernel/temperature/temp.h @@ -0,0 +1,27 @@ +#ifndef TEMP_H +#define TEMP_H + +#include + +/** + * temp_init() - Request physical memory and map it into kernel virtual memory. + * + * Return: 0 on success, or a negative error code on failure. + */ +int temp_init(void); + +/** + * read_temp() - Read the current CPU temperature from the mapped registers. + * To convert it in degrees Celsius, divide by 1000.0 + * + * Return: The calculated temperature value. + */ +uint32_t read_temp(void); + + +/** + * temp_exit() - Unmap the virtual memory and release the requested physical memory region. + */ +void temp_exit(void); + +#endif /* TEMP_H */