From 0b617454fcda8c4c33217e776e597bf98672448e Mon Sep 17 00:00:00 2001 From: Maryna Malakhova Date: Wed, 24 Mar 2021 14:54:18 +0200 Subject: [PATCH 1/2] TIME06HW: Create basic module to store time in sysfs Add a module to store absolute time of last reading in sysfs. Also the relative passed time is stored there Signed-off-by: Maryna Malakhova --- 06_timers/time_module/Makefile | 7 ++ 06_timers/time_module/get_time_module.c | 121 ++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 06_timers/time_module/Makefile create mode 100644 06_timers/time_module/get_time_module.c diff --git a/06_timers/time_module/Makefile b/06_timers/time_module/Makefile new file mode 100644 index 00000000..78c7b7b5 --- /dev/null +++ b/06_timers/time_module/Makefile @@ -0,0 +1,7 @@ +TARGET = get_time_module +obj-m+=$(TARGET).o +default: + $(MAKE) -C $(BUILD_KERNEL) M=$(CURDIR) modules + +clean: + $(MAKE) -C $(BUILD_KERNEL) M=$(CURDIR) clean diff --git a/06_timers/time_module/get_time_module.c b/06_timers/time_module/get_time_module.c new file mode 100644 index 00000000..652607aa --- /dev/null +++ b/06_timers/time_module/get_time_module.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-3.0 +/**/ + +#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME +#include +#include +#include +#include +#include +#include + +#define LEN_STR 160 + +static char buf_str[LEN_STR + 1]; +static struct timespec64 r_last_time; +static struct timespec64 a_last_time; +static bool first_read = 1; + +struct timespec64 delta_time(struct timespec64 start, struct timespec64 stop) +{ + struct timespec64 delta; + + delta.tv_sec = stop.tv_sec-start.tv_sec; + delta.tv_nsec = stop.tv_nsec-start.tv_nsec; + if (delta.tv_nsec < 0) + delta.tv_nsec += 1000000000; + return delta; +} + +static ssize_t relation_delay_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int ret = 0; + struct timespec64 r_new_time, delta; + + if (first_read) { + ret = scnprintf(buf, PAGE_SIZE, + "RELATION DELAY FROM LAST READING \t 0s\n"); + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_new_time); + first_read = 0; + return ret; + } + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_new_time); + delta = delta_time(r_last_time, r_new_time); + ret = scnprintf(buf, PAGE_SIZE, + "RELATION DELAY FROM LAST READING \t %lld.%09lds\n", + (s64)delta.tv_sec, delta.tv_nsec); + r_last_time = r_new_time; + return ret; +} + +static ssize_t absolute_delay_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int ret = 0; + + if (first_read) { + ret = scnprintf(buf, PAGE_SIZE, + "ABSOLUTE TIME OF LAST READING \t 0s\n"); + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_last_time); + first_read = 0; + return ret; + } + ktime_get_ts64(&r_last_time); + ret = scnprintf(buf, PAGE_SIZE, + "ABSOLUTE TIME OF LAST READING \t %lld.%09lds\n", + (s64)a_last_time.tv_sec, a_last_time.tv_nsec); + ktime_get_real_ts64(&a_last_time); + return ret; +} + +static struct kobj_attribute relation_delay_attribute = + __ATTR(relation_delay, 0444, relation_delay_show, NULL); + +static struct kobj_attribute absolute_delay_attribute = + __ATTR(absolute_delay, 0444, absolute_delay_show, NULL); + +static struct attribute *attrs[] = { + &relation_delay_attribute.attr, + &absolute_delay_attribute.attr, + NULL, +}; + +static struct attribute_group attr_group = { + .attrs = attrs, +}; + +static struct kobject *store_delay_kobj; + +static int __init store_delay_module_init(void) +{ + int retval; + + memset(buf_str, '\0', LEN_STR+1); + pr_debug("loading started\n"); + store_delay_kobj = kobject_create_and_add("PASSED_DELAY", kernel_kobj); + if (!store_delay_kobj) + return -ENOMEM; + retval = sysfs_create_group(store_delay_kobj, &attr_group); + if (retval) + kobject_put(store_delay_kobj); + + return retval; +} + +static void __exit store_delay_module_exit(void) +{ + kobject_put(store_delay_kobj); + pr_info("module exited\n"); +} + +module_init(store_delay_module_init); +module_exit(store_delay_module_exit); + +MODULE_AUTHOR("Malakhova.Maryna "); +MODULE_DESCRIPTION("Store time delay module"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); From 1ad8ed2ccf3b1ac5f8a66fe782eae4a695280603 Mon Sep 17 00:00:00 2001 From: Maryna Malakhova Date: Thu, 25 Mar 2021 17:12:55 +0200 Subject: [PATCH 2/2] TIME06HW: Create user space app to get abs time Create use space app to get absolute time with nsec resolution Signed-off-by: Maryna Malakhova --- 06_timers/Makefile | 7 +++++++ 06_timers/main.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 06_timers/Makefile create mode 100644 06_timers/main.c diff --git a/06_timers/Makefile b/06_timers/Makefile new file mode 100644 index 00000000..f4b14761 --- /dev/null +++ b/06_timers/Makefile @@ -0,0 +1,7 @@ +CC=gcc +SOURCES=main.c +EXECUTABLE=user_abs_time + +all: $(SOURCES) + $(CC) $(SOURCES) -o $(EXECUTABLE) + diff --git a/06_timers/main.c b/06_timers/main.c new file mode 100644 index 00000000..f4a0c818 --- /dev/null +++ b/06_timers/main.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0 +/**/ +#include +#include +#include +#include +#include + +int print_clock_gettime(clockid_t clock) +{ + const int bufsize = 50; + char buf[bufsize]; + struct timespec now; + struct tm ts; + + memset(buf, '\0', bufsize); + if (clock_gettime(clock, &now) == -1) { + perror("clock_gettime failure"); + exit(EXIT_FAILURE); + } + gmtime_r(&now.tv_sec, &ts); + strftime(buf, bufsize, "%Y-%m-%d Time: %H:%M:%S.", &ts); + sprintf(buf, "%s%09lu", buf, now.tv_nsec); + printf("%s\n", buf); + if (clock_getres(clock, &now) == -1) { + perror("clock_getres failure"); + exit(EXIT_FAILURE); + } + printf(" resolution: %10jd.%09ld\n\n", + (intmax_t) now.tv_sec, now.tv_nsec); + return 0; +} + +int main(void) +{ + printf("=============================\n"); + printf("CLOCK_REALTIME time: "); + print_clock_gettime(CLOCK_REALTIME); + #ifdef CLOCK_TAI + printf("=============================\n"); + printf("CLOCK_TAI time: "); + print_clock_gettime(CLOCK_TAI); + #endif + return 0; +} +