diff options
Diffstat (limited to 'meta-rtmod1/model_answer')
-rw-r--r-- | meta-rtmod1/model_answer/files/rt-demo-kmod.c | 98 | ||||
-rw-r--r-- | meta-rtmod1/model_answer/files/rt-sysfs-poll.c | 52 |
2 files changed, 150 insertions, 0 deletions
diff --git a/meta-rtmod1/model_answer/files/rt-demo-kmod.c b/meta-rtmod1/model_answer/files/rt-demo-kmod.c new file mode 100644 index 0000000000..2342b9c35e --- /dev/null +++ b/meta-rtmod1/model_answer/files/rt-demo-kmod.c @@ -0,0 +1,98 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/slab.h> + +struct demo_attr { + struct attribute attr; + int value; +}; + +static struct demo_attr notify = { + .attr.name="notify", + .attr.mode = 0644, + .value = 0, +}; + +static struct demo_attr trigger = { + .attr.name="trigger", + .attr.mode = 0644, + .value = 0, +}; + +static struct attribute *demoattr[] = { + ¬ify.attr, + &trigger.attr, + NULL +}; + +static struct kobject *demo_kobj; + +static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct demo_attr *a = container_of(attr, struct demo_attr, attr); + + pr_debug("RT demo kmod: show called (%s)\n", a->attr.name); + + return scnprintf(buf, PAGE_SIZE, "%s: %d\n", a->attr.name, a->value); +} + +static ssize_t store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct demo_attr *a = container_of(attr, struct demo_attr, attr); + + if (!strncmp(a->attr.name, "notify", sizeof("notify"))) + return len; + + sscanf(buf, "%d", &a->value); + notify.value = a->value; + pr_debug("RT demo kmod: sysfs_notify store %s = %d\n", a->attr.name, + a->value); + sysfs_notify(demo_kobj, NULL, "notify"); + + return len; +} + +static struct sysfs_ops demoops = { + .show = show, + .store = store, +}; + +static struct kobj_type mytype = { + .sysfs_ops = &demoops, + .default_attrs = demoattr, +}; + +static int __init demo_module_init(void) +{ + int err = -1; + + pr_debug("RT demo kmod: init\n"); + demo_kobj = kzalloc(sizeof(*demo_kobj), GFP_KERNEL); + if (demo_kobj) { + kobject_init(demo_kobj, &mytype); + if (kobject_add(demo_kobj, NULL, "%s", "demo-poll")) { + err = -1; + pr_err("RT demo kmod: kobject_add() failed\n"); + kobject_put(demo_kobj); + demo_kobj = NULL; + } + err = 0; + } + return err; +} + +static void __exit demo_module_exit(void) +{ + if (demo_kobj) { + kobject_put(demo_kobj); + kfree(demo_kobj); + } + pr_debug("RT demo kmod: exit\n"); +} + +module_init(demo_module_init); +module_exit(demo_module_exit); +MODULE_LICENSE("GPL"); diff --git a/meta-rtmod1/model_answer/files/rt-sysfs-poll.c b/meta-rtmod1/model_answer/files/rt-sysfs-poll.c new file mode 100644 index 0000000000..8d0a5314e9 --- /dev/null +++ b/meta-rtmod1/model_answer/files/rt-sysfs-poll.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2021 by Linaro */ +/* Permission to use, copy, modify, and/or distribute this software for any */ +/* purpose with or without fee is hereby granted. */ +/* THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES */ +/* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR */ +/* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ +/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN */ +/* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF */ +/* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <poll.h> + +#define TEST_SYSFS_NOTIFY "/sys/demo-poll/notify" + +int main(void) +{ + int notify_fd, rv, cnt; + char attr_data[100]; + struct pollfd ufds; + + if ((notify_fd = open(TEST_SYSFS_NOTIFY, O_RDWR)) < 0) { + printf("Unable to open %s", TEST_SYSFS_NOTIFY); + exit(1); + } + + cnt = read(notify_fd, attr_data, 100); + lseek(notify_fd, 0, SEEK_SET); + ufds.fd = notify_fd; + ufds.events = POLLPRI | POLLERR; + ufds.revents = 0; + + if ((rv = poll(&ufds, 1, 100000)) < 0) { + perror("poll error"); + } else if (rv == 0) { + printf("Timeout occurred!\n"); + } else if (ufds.revents & (POLLPRI | POLLERR)) { + cnt = read(notify_fd, attr_data, 100); + printf("sysfs_notify() triggered, revents: %08X," + " attribute data[%d] %s", ufds.revents, cnt, attr_data); + } + + close(notify_fd); +} |