C語言簡單的字符驅動程序介紹
C語言是一種計算機程序設計語言,它既具有高級語言的.特點,又具有彙編語言的特點。以下是小編為大家搜索整理的C語言簡單的字符驅動程序介紹,希望能給大家帶來幫助,更多精彩內容請及時關注我們應屆畢業生考試網!
代碼分為:makefile ,內核態程序 globalmem.c 用户態程序 user.c 功能是把一個數組排序,你也可以使用 read write函數往內存裏寫東西。
運行方法:
make,產生文件, Insmod , 看一下 dmesg -c 是否有提示信息(也可以 lsmod | grep "glo"), 有的話説明加載上了,
然後 mknod /dev globalmem c 254 0 , 看一下 ls /proc/device/ | grep "glo" 有東西沒。
然後運行用户態程序,數組被排序了。dmesg -c 可以看到提示信息, 在模塊中排序了。
上代碼(是帶鎖的代碼,順便練練手)
makefile
1# makefile for kernel 2.6
2ifneq ($(KERNELRELEASE),)
3#mymodule-objs := file1.o file2.o
4obj-m := globalmem.o
5
6else
7PWD := $(shell pwd)
8KVER := $(shell uname -r)
9KDIR := /lib/modules/$(KVER)/build
10all:
11 $(MAKE) -C $(KDIR) M=$(PWD)
12clean:
13 rm -rf .* *.o *.c * _versions
14
15endif
16
內核模塊
1#include
2#include
3#include
4#include
5#include
6#include
7#include
8#include
9#include
10#include
11#include "mem.h"
12
13#define GLOBALMEM_SIZE 0x1000
14#define MEM_CLEAR 0x1
15#define ARRAY_INSTER 0x2
16#define GLOBALMEM_MAJOR 254
17
18static int globalmem_major = GLOBALMEM_MAJOR;
19
20//the struct of global
21typedef struct __globalmem_dev{
22 struct cdev cdev;
23 unsigned char mem[GLOBALMEM_SIZE];
24 //add lock, signal
25 struct semaphore sem;
26 atomic_t ato;
27}globalmem_dev;
28
29globalmem_dev * global;
30
31typedef struct __arithmetic_st{
32 int buf[10];
33 int len;
34}arithmetic_st;
35
36
37
38
39int globalmem_open(struct inode *inode, struct file * filp)
40{
41 filp->private_data = global;
42 //you can only open one file
43 if(!atomic_dec_and_test(&global->ato))
44 {
45 printk( KERN_NOTICE "atomic is lock ");
46 return -EBUSY;
47 }
48 return 0;
49}
50
51int globalmem_release(struct inode * inode, struct file * filp)
52{
53 atomic_inc(&global->ato);
54 return 0;
55}
56
57
58//read
59static ssize_t globalmem_read(struct file * filp, char __user *buf, size_t size, loff_t *ppos)
60{
61 unsigned long p = *ppos;
62 unsigned int count = size;
63 int ret = 0;
64
65 globalmem_dev *dev = filp->private_data;
66
67 if(p > GLOBALMEM_SIZE)
68 return count ? -ENXIO : 0;
69 if(count > GLOBALMEM_SIZE - p)
70 count = GLOBALMEM_SIZE - p;
71//add the lock
72 if(down_interruptible(&dev->sem))
73 {
74 return -ERESTARTSYS;
75 }
76
77
78 if(copy_to_user(buf, (void *)(dev->mem + p), count)){
79 ret = -EFAULT;
80 }else{
81 *ppos += count;
82 ret = count;
83 printk(KERN_INFO "read %d bytes from %u ", count, p);
84 }
85//unlock
86 up(&dev->sem);
87 return ret;
88}
89
90//write
91static ssize_t globalmem_write(struct file * filp, const char __user * buf,
92 size_t size, loff_t *ppos)
93{
94 unsigned long p = *ppos;
95 unsigned int count = size;
96 int ret = 0;
97 globalmem_dev *dev = filp->private_data;
98
99 if(p >= GLOBALMEM_SIZE)
100 return count ? -ENXIO : 0;
101 if(count > GLOBALMEM_SIZE - p)
102 count = GLOBALMEM_SIZE - p;
103//lock
104 if(down_interruptible(&dev->sem)){
105 return -ERESTARTSYS;
106 }
107 if(copy_from_user((dev->mem + p), buf, count))
108 ret = -EFAULT;
109 else{
110 *ppos += count;
111 ret = count;
112 printk( KERN_INFO "written %d bytes from %u ", count , p);
113 }
114//unlock
115 up(&dev->sem);
116 return ret;
117}
118
119//seek
120static loff_t globalmem_llseek(struct file * filp, loff_t offset, int orig)
121{
122 loff_t ret = 0;
123 switch(orig){
124 case 0:
125 if(offset < 0){
126 ret = -EINVAL;
127 break;
128 }
129 if((unsigned int) offset > GLOBALMEM_SIZE){
130 ret = -EINVAL;
131 break;
132 }
133 filp->f_pos = (unsigned int)offset;
134 ret = filp->f_pos;
135 break;
136 case 1:
137 if((filp->f_pos + offset) > GLOBALMEM_SIZE){
138 ret = -EINVAL;
139 break;
140 }
141 if((filp->f_pos + offset) < 0){
142 ret = -EINVAL;
143 break;
144 }
145 filp->f_pos += offset;
146 ret = filp->f_pos;
147 break;
148 default :
149 ret = -EINVAL;
150 break;
151 }
152 return ret;
153}
154static int inster_arithmetic(int * buf, int len)
155{
156 int i;
157 int j;
158 int key;
159
160 if(len < 2){
161 return -1;
162 }
163 for( j = 1; j < len; j++){
164 key = *(buf + j);
165 i = j -1;
166
167 while(i >= 0 && *(buf + i) > key){
168 *(buf + i + 1) = *(buf + i);
169 i = i - 1;
170 }
171 *(buf + i + 1) = key;
172 }
173}
174
175//ioctl
176static int globalmem_ioctl(struct inode * inode, struct file * filp,
177 unsigned int cmd, unsigned long arg)
178{
179 globalmem_dev * dev = filp->private_data;
180 arithmetic_st * p;
181 arithmetic_st * q;
182 int i;
183
184 switch(cmd){
185 case MEM_CLEAR:
186 //lock
187 if(down_interruptible(&dev->sem)){
188 return -ERESTARTSYS;
189 }
190 memset(dev->mem, 0, GLOBALMEM_SIZE);
191 printk(KERN_INFO "glbalmem is set to zero ! ");
192 //unlock
193 up(&dev->sem);
194 break;
195 case ARRAY_INSTER:
196 p = (arithmetic_st *)arg;
197 q = (arithmetic_st *)kmalloc(sizeof(arithmetic_st), GFP_KERNEL);
198 memset(q->buf, 0, 10);
199 if(down_interruptible(&dev->sem)){
200 return -ERESTARTSYS;
201 }
202 if(copy_from_user(q, p, sizeof(arithmetic_st))){
203 return -EFAULT;
204 }
205 if(q->len != 0){
206 inster_arithmetic(q->buf, q->len);
207 if(copy_to_user(p, q, sizeof(arithmetic_st))){
208 return -EFAULT;
209 }
210 for(i = 0; i < q->len; i++){
211 printk(KERN_INFO ">>>>>>>>>>buf%d:%d ! ",i, q->buf[i]);
212 }
213 }else{
214 printk(KERN_INFO ">>>>>>>>>>len is zero [%d] [%s] ! ", __LINE__, __FUNCTION__);
215 }
216 kfree(q);
217 break;
218
219 default:
220 return -EINVAL;
221 }
222 return 0;
223}
224
225static const struct file_operations globalmem_fops =
226{
227 r = THIS_MODULE,
228 ek = globalmem_llseek,
229 = globalmem_read,
230 e = globalmem_write,
231 l = globalmem_ioctl,
232 = globalmem_open,
233 ase = globalmem_release,
234};
235//register cdev
236static void globalmem_setup_cdev(globalmem_dev * dev, int index)
237{
238 int err;
239 int devno = MKDEV(globalmem_major, index);
240
241 cdev_init(&dev->cdev, &globalmem_fops);
242 dev->r = THIS_MODULE;
243// dev-> = &globalmem_fops;
244 err = cdev_add(&dev->cdev, devno, 1);
245 if(err)
246 printk( KERN_NOTICE "error %d adding LED %d" , err, index);
247}
248
249//
250int globalmem_init(void)
251{
252 int result;
253 dev_t devno = MKDEV(globalmem_major, 0);
254
255 if(globalmem_major){
256 result = register_chrdev_region(devno, 1, "globalmem");
257 }else{
258 result = alloc_chrdev_region(&devno, 0, 1, "globalmem");
259 globalmem_major = MAJOR(devno);
260 }
261 if(result < 0)
262 return result;
263 global = kmalloc(sizeof(globalmem_dev), GFP_KERNEL);
264 if(!global){
265 result = -ENOMEM;
266 goto fail_kmalloc;
267 }
268 memset(global, 0, sizeof(globalmem_dev));
269 globalmem_setup_cdev(global, 0);
270 printk( KERN_NOTICE "init over! ");
271 //lock
272 init_MUTEX(&global->sem);
273 atomic_set(&global->ato, 1);
274 printk( KERN_NOTICE "init signl! ");
275 printk( KERN_INFO "the process is %s pid is %i ", current->comm, current->pid);
276 return 0;
277
278fail_kmalloc:
279 unregister_chrdev_region(devno, 1);
280 return result;
281}
282//
283void globalmem_exit(void)
284{
285 cdev_del(&global->cdev);
286 kfree(global);
287 unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);
288 printk( KERN_NOTICE "exit over! ");
289}
290
291MODULE_AUTHOR("xueby");
292MODULE_LICENSE("XBY/GPL");
293module_param(globalmem_major, int , S_IRUGO);
294
295module_init(globalmem_init);
296module_exit(globalmem_exit);
297
用户態
1#include
2#include
3#include
4#include
5#include
6#include
7#include
8
9#define MEM_CLEAR 0x1
10#define ARRAY_INSTER 0x2
11
12typedef struct __arithmetic_st{
13 int buf[10];
14 int len;
15}arithmetic_st;
16
17
18
19int main()
20{
21 int ret;
22 int fd;
23 int buf[10] = {2, 5, 1, 9, 3, 12, 0,15, 11, 23};
24 char rbuf[100] = {0, };
25 arithmetic_st *a;
26
27 a = (arithmetic_st*)malloc(sizeof(arithmetic_st));
28 if(!a)
29 return -1;
30 memcpy(a->buf, buf, sizeof(buf));
31 a->len = 10;
32
33 fd = open("/dev/globalmem", O_RDWR , S_IRWXU);
34 ioctl(fd, ARRAY_INSTER, (unsigned long)a);
35 for(ret = 0; ret < 10; ret++){
36 printf("%d ;",a->buf[ret]);
37 }
38 return 0;
39}
40
41
-
2017年3月計算機二級C語言考試摸底測試題
以下是yjbys考試網小編整理的2017年3月計算機二級C語言考試摸底測試題,希望對大家有所幫助,祝大家計算機二級考試順利通過。一、選擇題(每小題1分。)(1)程序流程圖中帶有箭頭的線段表示的是()。A.圖元關係B.數據流C.控制流D.調用關係(2)結構化程序設計的基本原則...
-
C語言if else語句彙總
對於很多情況,順序結構的代碼是遠遠不夠的,大家都接觸過C語言吧,下面是小編為大家整理的C語言ifelse語句,希望對大家有所幫助。C語言ifelse語句在C語言中,使用if和else關鍵字對條件進行判斷。請先看下面的代碼:#includeintmain(){intage;printf("請輸入你的年齡:");sc...
-
C語言精選面試題詳解
C語言是IT編程中最基礎的語言,在面試中,基本可以忽略又或者格外重要。下面是小編為大家整理的C語言精選面試題詳解,歡迎參考~分析這些面試題,本身包含很強的趣味性;而作為一名研發人員,通過對這些面試題的深入剖析則可進一步增強自身的內功。試題1:以下是引用片段:voi...
-
2017年計算機二級考試C語言備考題及答案
計算機二級對於很多考生來説還是比較有難度的,那麼怎樣順利通過二級考試呢?這就需要大家平時多練習和找方法了。以下是本站小編整理的2017年計算機二級考試C語言備考題及答案,希望對大家有幫助!1.(A)是構成C語言程序的基本單位。A、函數B、過程C、子程序D、子例...