summaryrefslogtreecommitdiff
path: root/meta-rtmod1/model_answer
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rtmod1/model_answer')
-rw-r--r--meta-rtmod1/model_answer/files/rt-demo-kmod.c98
-rw-r--r--meta-rtmod1/model_answer/files/rt-sysfs-poll.c52
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[] = {
+ &notify.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);
+}