Skip to content

Commit a06c92d

Browse files
committed
Update
1 parent d947e54 commit a06c92d

File tree

7 files changed

+345
-0
lines changed

7 files changed

+345
-0
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ obj-m += hashtable.o # <linux/hashtable.h>
1010
obj-m += phone_table.o # simple hashtable.h example
1111
obj-m += container_of.o # Now I understand container_macro deeply ..
1212
obj-m += container_of_container_of.o
13+
obj-m += string-9.o # string manipulation
14+
obj-m += kfifo_int.o # simplifed version of /samples/kfifo/inttype-example.c
15+
obj-m += wait_queue.o #
16+
obj-m += wait_queue_proc.o #
1317
#obj-m += cdev.o # complete char device
1418

1519

README.adoc

+3
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ image:images/hashtable.png[alt text]
1414
#### link:../main/phone_table.c[phone_table.c] dmesg
1515
image:images/phone_table.png[alt text]
1616

17+
#### link:../main/wait_queue_proc.c[wait_queue_proc.c] dmesg
18+
image:images/wait_queue_proc.png[alt text]
19+
1720

images/wait_queue_proc.png

80.7 KB
Loading

kfifo_int.c

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Sample kfifo int type implementation
4+
*
5+
* Copyright (C) 2010 Stefani Seibold <[email protected]>
6+
*/
7+
8+
#include <linux/init.h>
9+
#include <linux/module.h>
10+
#include <linux/proc_fs.h>
11+
#include <linux/mutex.h>
12+
#include <linux/kfifo.h>
13+
14+
/*
15+
* This module shows how to create a int type fifo.
16+
*/
17+
18+
/* fifo size in elements (ints) */
19+
#define FIFO_SIZE 32
20+
21+
/* name of the proc entry */
22+
#define PROC_FIFO "int-fifo"
23+
24+
/* lock for procfs read access */
25+
static DEFINE_MUTEX(read_lock);
26+
27+
/* lock for procfs write access */
28+
static DEFINE_MUTEX(write_lock);
29+
30+
/*
31+
* define DYNAMIC in this example for a dynamically allocated fifo.
32+
*
33+
* Otherwise the fifo storage will be a part of the fifo structure.
34+
*/
35+
#if 1
36+
#define DYNAMIC
37+
#endif
38+
39+
#ifdef DYNAMIC
40+
static DECLARE_KFIFO_PTR(test, int);
41+
#else
42+
static DEFINE_KFIFO(test, int, FIFO_SIZE);
43+
#endif
44+
45+
static const int expected_result[FIFO_SIZE] = {
46+
3, 4, 5, 6, 7, 8, 9, 0,
47+
1, 20, 21, 22, 23, 24, 25, 26,
48+
27, 28, 29, 30, 31, 32, 33, 34,
49+
35, 36, 37, 38, 39, 40, 41, 42,
50+
};
51+
52+
static int __init testfunc(void)
53+
{
54+
int buf[6];
55+
int i, j;
56+
unsigned int ret;
57+
58+
printk(KERN_INFO "int fifo test start\n");
59+
60+
/* put values into the fifo */
61+
for (i = 0; i != 10; i++)
62+
kfifo_put(&test, i);
63+
64+
for (i = 0; i != 10; i++)
65+
pr_err("");
66+
67+
/* show the number of used elements */
68+
printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
69+
70+
/* get max of 2 elements from the fifo */
71+
ret = kfifo_out(&test, buf, 2);
72+
printk(KERN_INFO "ret: %d\n", ret);
73+
/* and put it back to the end of the fifo */
74+
ret = kfifo_in(&test, buf, ret);
75+
printk(KERN_INFO "ret: %d\n", ret);
76+
77+
/* skip first element of the fifo */
78+
printk(KERN_INFO "skip 1st element\n");
79+
kfifo_skip(&test);
80+
81+
/* put values into the fifo until is full */
82+
for (i = 20; kfifo_put(&test, i); i++)
83+
;
84+
85+
printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
86+
87+
/* show the first value without removing from the fifo */
88+
if (kfifo_peek(&test, &i))
89+
printk(KERN_INFO "%d\n", i);
90+
91+
/* check the correctness of all values in the fifo */
92+
j = 0;
93+
while (kfifo_get(&test, &i)) {
94+
printk(KERN_INFO "item = %d\n", i);
95+
if (i != expected_result[j++]) {
96+
printk(KERN_WARNING "value mismatch: test failed\n");
97+
return -EIO;
98+
}
99+
}
100+
if (j != ARRAY_SIZE(expected_result)) {
101+
printk(KERN_WARNING "size mismatch: test failed\n");
102+
return -EIO;
103+
}
104+
printk(KERN_INFO "test passed\n");
105+
106+
return 0;
107+
}
108+
109+
static ssize_t fifo_write(struct file *file, const char __user *buf,
110+
size_t count, loff_t *ppos)
111+
{
112+
int ret;
113+
unsigned int copied;
114+
115+
if (mutex_lock_interruptible(&write_lock))
116+
return -ERESTARTSYS;
117+
118+
ret = kfifo_from_user(&test, buf, count, &copied);
119+
120+
mutex_unlock(&write_lock);
121+
122+
return ret ? ret : copied;
123+
}
124+
125+
static ssize_t fifo_read(struct file *file, char __user *buf,
126+
size_t count, loff_t *ppos)
127+
{
128+
int ret;
129+
unsigned int copied;
130+
131+
if (mutex_lock_interruptible(&read_lock))
132+
return -ERESTARTSYS;
133+
134+
ret = kfifo_to_user(&test, buf, count, &copied);
135+
136+
mutex_unlock(&read_lock);
137+
138+
return ret ? ret : copied;
139+
}
140+
141+
static const struct proc_ops fifo_proc_ops = {
142+
.proc_read = fifo_read,
143+
.proc_write = fifo_write,
144+
.proc_lseek = noop_llseek,
145+
};
146+
147+
static int __init example_init(void)
148+
{
149+
#ifdef DYNAMIC
150+
int ret;
151+
152+
ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
153+
if (ret) {
154+
printk(KERN_ERR "error kfifo_alloc\n");
155+
return ret;
156+
}
157+
#endif
158+
if (testfunc() < 0) {
159+
#ifdef DYNAMIC
160+
kfifo_free(&test);
161+
#endif
162+
return -EIO;
163+
}
164+
165+
if (proc_create(PROC_FIFO, 0, NULL, &fifo_proc_ops) == NULL) {
166+
#ifdef DYNAMIC
167+
kfifo_free(&test);
168+
#endif
169+
return -ENOMEM;
170+
}
171+
return 0;
172+
}
173+
174+
static void __exit example_exit(void)
175+
{
176+
remove_proc_entry(PROC_FIFO, NULL);
177+
#ifdef DYNAMIC
178+
kfifo_free(&test);
179+
#endif
180+
}
181+
182+
module_init(example_init);
183+
module_exit(example_exit);
184+
MODULE_LICENSE("GPL");
185+
MODULE_AUTHOR("smalinux");

string-9.c

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <linux/module.h>
2+
#include <linux/kernel.h>
3+
#include <linux/string.h>
4+
MODULE_LICENSE("GPL");
5+
6+
static int hello_init(void)
7+
{
8+
pr_info("sting: module loaded!\n");
9+
10+
char str[20];
11+
strcpy(str, "hi, strcpy");
12+
pr_info("strcpy: %s\n", str);
13+
// ____________________________________________________________________
14+
char str1[10];
15+
strcat(str1, "Con");
16+
strcat(str1, "Cat");
17+
pr_info("strcat: %s\n", str1);
18+
// ____________________________________________________________________
19+
//int x;
20+
//x = strcasecmp("AAAA","aaa");
21+
//pr_info("strcmp: %d", x);
22+
// ____________________________________________________________________
23+
int point = 123;
24+
char *s = "123-";
25+
int out = get_option(&s, &point);
26+
pr_info("get_option %d\n", out);
27+
28+
29+
return 0;
30+
}
31+
32+
static void hello_exit(void)
33+
{
34+
pr_err("Goodbye, cruel world\n");
35+
}
36+
37+
module_init(hello_init);
38+
module_exit(hello_exit);

wait_queue.c

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <linux/module.h>
2+
#include <linux/init.h>
3+
#include <linux/sched.h>
4+
#include <linux/time.h>
5+
#include <linux/delay.h>
6+
#include<linux/workqueue.h>
7+
8+
static DECLARE_WAIT_QUEUE_HEAD(my_wq);
9+
static int condition = 0;
10+
11+
/* declare a work queue*/
12+
static struct work_struct wrk_t;
13+
14+
static void work_handler(struct work_struct *work)
15+
{
16+
printk("Waitqueue module handler %s\n", __FUNCTION__);
17+
msleep(5000);
18+
printk("Wake up the sleeping module\n");
19+
condition = 1;
20+
wake_up_interruptible(&my_wq);
21+
}
22+
23+
static int __init my_init(void)
24+
{
25+
pr_info("wait_queue: module loaded!\n");
26+
27+
INIT_WORK(&wrk_t, work_handler);
28+
schedule_work(&wrk_t);
29+
30+
printk("Going to sleep %s\n", __FUNCTION__);
31+
wait_event_interruptible(my_wq, condition != 0);
32+
33+
pr_info("woken up by the work job\n");
34+
35+
return 0;
36+
}
37+
38+
void my_exit(void)
39+
{
40+
pr_info("waitqueue: exit...\n");
41+
}
42+
43+
module_init(my_init);
44+
module_exit(my_exit);
45+
MODULE_AUTHOR("John Madieu <[email protected]>");
46+
MODULE_LICENSE("GPL");

wait_queue_proc.c

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <linux/module.h>
2+
#include <linux/init.h>
3+
#include <linux/sched.h>
4+
#include <linux/time.h>
5+
#include <linux/delay.h>
6+
#include <linux/workqueue.h>
7+
8+
#include <linux/moduleparam.h>
9+
#include <linux/kernel.h>
10+
#include <linux/proc_fs.h>
11+
#include <asm/uaccess.h>
12+
#define BUFSIZE 100
13+
14+
15+
static DECLARE_WAIT_QUEUE_HEAD(my_wq);
16+
static int condition = 0;
17+
/* declare a proc_fs ent */
18+
static struct proc_dir_entry *ent;
19+
20+
/* declare a work queue */
21+
static struct work_struct wrk_t;
22+
23+
static void work_handler(struct work_struct *work)
24+
{
25+
printk("Waitqueue module handler %s\n", __FUNCTION__);
26+
}
27+
28+
static ssize_t mywrite(struct file *file, const char __user *ubuf,size_t count, loff_t *ppos)
29+
{
30+
if(wq_has_sleeper(&my_wq)) {
31+
printk( KERN_DEBUG "write handler\n");
32+
printk("Wake up the sleeping module\n");
33+
condition = 1;
34+
wake_up_interruptible(&my_wq);
35+
}
36+
return -1;
37+
}
38+
39+
static struct proc_ops myops =
40+
{
41+
.proc_write = mywrite,
42+
};
43+
44+
static int __init my_init(void)
45+
{
46+
pr_info("wait_queue: module loaded!\n");
47+
ent = proc_create("mydev", 0660, NULL, &myops); // create proc_fs
48+
49+
INIT_WORK(&wrk_t, work_handler);
50+
schedule_work(&wrk_t);
51+
52+
printk("Going to sleep %s\n", __FUNCTION__);
53+
wait_event_interruptible(my_wq, condition != 0);
54+
55+
pr_info("woken up by the work job\n");
56+
57+
return 0;
58+
}
59+
60+
void my_exit(void)
61+
{
62+
proc_remove(ent);
63+
pr_info("waitqueue: exit...\n");
64+
}
65+
66+
module_init(my_init);
67+
module_exit(my_exit);
68+
MODULE_AUTHOR("John Madieu <[email protected]>");
69+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)