Debugging and analysis of the implementation of mymsg and myprintk under proc in imx257

Publisher:AdventureSeekerLatest update time:2024-08-13 Source: cnblogsKeywords:proc Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Create file entries under /proc


1. Define the proc_dir_entry structure and the file_operations structure


1 //Define the entry structure of proc

2 static struct proc_dir_entry *myentry;

3

4 static struct file_operations proc_mymsg_operations = {

5 };


2. Create a proc entry in the entry function and associate it with the file_operations structure


1 static int mymsg_init(void)

2 {

3 //Create the proc directory

4 myentry = create_proc_entry("mymsg",S_IRUSR,NULL); //S_IRUSR:400 read only

5

6 if(myentry)

7 myentry->proc_fops = &proc_mymsg_operations;

8

9 return 0;

10 }


3. In the export function, it is natural to delete the entry


1 static void mymsg_exit(void)

2 {

3 remove_proc_entry("mymsg", NULL);

4 }

4. Compile the test code and create a file mymsg in the /proc directory

7e480d720fd506e199d8838e8cb188e0_Et5PLyBNqQj5E8dGcGtZVoQ5WCvUwmn+adTHys6qppXRczV6tuk5OU3T9GWksaC5RXJhf2nzfuxe5wYo4r5axIq3YDXwW7bA4iLncBTTa0x9+ v+BJ8FWtcyUCAAAAABJRU5ErkJggg==.png

Attach the driver mymsg_1.c


1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9

10 //Define the entry structure of proc

11 static struct proc_dir_entry *myentry;

12

13 static struct file_operations proc_mymsg_operations = {

14 };

15

16 static int mymsg_init(void)

17 {

18 //Create a proc directory

19 myentry = create_proc_entry("mymsg",S_IRUSR,NULL); //S_IRUSR:400 read only

20

21 if(myentry)

22 myentry->proc_fops = &proc_mymsg_operations;

twenty three

24 return 0;

25 }

26

27 static void mymsg_exit(void)

28 {

29 remove_proc_entry("mymsg", NULL);

30 }

31

32 module_init(mymsg_init);

33 module_exit(mymsg_exit);

34

35 MODULE_LICENSE("GPL");

36 MODULE_AUTHOR("Lover Cher");


2. Implement read and write functions


Since our file_operations structure is empty, we naturally cannot read /proc/mymsg. Here we add a read function.


1 static ssize_t mymsg_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

2 {

3 printk("mymsg_read n");

4 return 0;

5 }

6

7 static struct file_operations proc_mymsg_operations = {

8. read = mymsg_read,

9 };


After the compilation and loading is completed, we use the cat command to align and read. The result is as follows: It means that we have successfully entered the mymsg_read function.

4df7f62580e947d22b336a773780a698_h90WZmOMWo6LAAAAABJRU5ErkJggg==.png

Attach the driver mymsg_2.c


1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9

10 //Define the entry structure of proc

11 static struct proc_dir_entry *myentry;

12

13

14 static ssize_t mymsg_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

15 {

16 printk("mymsg_read n");

17 return 0;

18 }

19

20

21 static struct file_operations proc_mymsg_operations = {

22. read = mymsg_read,

twenty three };

twenty four

25 static int mymsg_init(void)

26 {

27 //Create a proc directory

28 myentry = create_proc_entry("mymsg",S_IRUSR,NULL); //S_IRUSR:400 read only

29

30 if(myentry)

31 myentry->proc_fops = &proc_mymsg_operations;

32

33

34 return 0;

35 }

36

37 static void mymsg_exit(void)

38 {

39 remove_proc_entry("mymsg", NULL);

40 }

41

42 module_init(mymsg_init);

43 module_exit(mymsg_exit);

44

45 MODULE_LICENSE("GPL");

46 MODULE_AUTHOR("Lover Cher");


3. Simulate memory data reading


Since we need to read, we naturally need to copy and print the data. Here we use the array to simulate the buff of the data, and then format the data in the init function to simulate writing data.


Then we read it in the mymsg_read function to see if the data can be read successfully.


1. Define a memory buff array


1 //Define the entry structure of proc

2 static struct proc_dir_entry *myentry;

3 static char mylog_buf[1024]; //data buffer

2. Format the string in the init function to simulate writing data


1 static int mymsg_init(void)

2 {

3 sprintf(mylog_buf, "%s", "abcdefghijklmnn"); //Simulate the data of forged buf

4 //Create a proc directory

5 myentry = create_proc_entry("mymsg",S_IRUSR,NULL); //S_IRUSR:400 read only

6

7 if(myentry)

8 myentry->proc_fops = &proc_mymsg_operations;

9

10 return 0;

11 }


3. Read it in the mymsg_read function


1 //Implement the read function

2 static ssize_t mymsg_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

3 {

4 if(copy_to_user(buf, mylog_buf, 10));

5 return 10;

6 }

4. Compile test: It is found that the data is read successfully.

b0f56e35d7dae278067df7739bcd876b_ACP2VBHeQAvGAAAAAElFTkSuQmCC.png

Attach the driver mymsg_3.c

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9

10 //Define the entry structure of proc

11 static struct proc_dir_entry *myentry;

12 static char mylog_buf[1024]; //data buffer

13

14 //Implement the read function

15 static ssize_t mymsg_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

16 {

17 //int cnt;

18 //printk("mymsg_read n");

19 // copy_to_user the data in mylog_buf, return

20 //cnt = min(1024,count);

21 if(copy_to_user(buf, mylog_buf, 10));

twenty two

23 return 10;

twenty four }

25

26 //Define file_operation structure

27 static struct file_operations proc_mymsg_operations = {

28. read = mymsg_read,

29 };

30

31 static int mymsg_init(void)

32 {

33 sprintf(mylog_buf, "%s", "abcdefghijklmnn"); //Simulate the data of forged buf

34 //Create a proc directory

35 myentry = create_proc_entry("mymsg",S_IRUSR,NULL); //S_IRUSR:400 read only

36

37 if(myentry)

38 myentry->proc_fops = &proc_mymsg_operations;

39

40 return 0;

41 }

42

43 static void mymsg_exit(void)

44 {

45 remove_proc_entry("mymsg", NULL);

46 }

47

48 module_init(mymsg_init);

49 module_exit(mymsg_exit);

50

51 MODULE_LICENSE("GPL");

52 MODULE_AUTHOR("Lover Cher");

53

54

55 /*

56 1. Ring Buffer

57 Empty: R == W

58 write: buf[W] = val;

59 W = (W+1) % 10;

60 Read: val = buf[R]

61 R = (R+1) % 10

62 2.

63

64

65

66

67

68

69

70

71

72

73 */


4. Refer to the printk function, which can be used to print and save messages


Now let's write a myprintk function similar to printk, so that other drivers can call myprintk to output all the print information to /proc/mymsg.


It is convenient to debug the driver's printing information in a unified manner without being interfered by other printing information.


For the test driver, we use the previous imx257 LED driver:


Blog article address: http://www.cnblogs.com/lihaiyan/p/4297923.html


Of course, the same applies to other drivers. Just declare the myprintk function externally and then replace all printk with myprintk.


1. Define two data buffs, read and write pointers, and a waiting queue


1 //Define the entry structure of proc

2 static struct proc_dir_entry *myentry;

3 static char mylog_buf[MYLOG_BUF_LEN]; //data buffer

4 static char tmp_buf[MYLOG_BUF_LEN]; //data buffer

5 static int mylog_r = 0;

6 static int mylog_w = ​​0;

7

8 static DECLARE_WAIT_QUEUE_HEAD(mylog_wait);


2. Implement a function to determine if buff is empty


1 //Judge whether it is empty

2 static int is_mylog_empty(void)

3 {

4 return (mylog_r == mylog_w);

5 }

3. Implement a function to determine whether the buff is full


1 //Judge whether it is full

2 static int is_mylog_full(void)

3 {

4 return (((mylog_w + 1) % MYLOG_BUF_LEN) == mylog_r);

5 }

4. Implement the function of writing characters to buff


1 //Write characters

2 static void mylog_putc(char c)

3 {

4 if(is_mylog_full)

5 {

6 //Discard a data

7 mylog_r = (mylog_r + 1) % MYLOG_BUF_LEN;

8 }

9 mylog_buf[mylog_w] = c;

10 mylog_w = ​​(mylog_w + 1) % MYLOG_BUF_LEN;

11

12 /* Wake up the process waiting for data */

13 wake_up_interruptible(&mylog_wait);

14 }


In addition to writing to buff, the function also has an important task of waking up the process so that the data can be printed out in the read function.


5. Implement the function to read buff characters


1 //Read characters

2 static int mylog_getc(char *p)

3 {

4 if(is_mylog_empty())

5 return 0;

6 *p = mylog_buf[mylog_r];

7 mylog_r = (mylog_r + 1) % MYLOG_BUF_LEN;

8 return 1;

9 }


6. Refer to the sprinf function of vsprintf.c in the kernel code, implement the myprintk function, and export the myprintk function for use by other programs


//Print output Refer to sprintf in vsprintf.c

int myprintk(const char *fmt, ...)

{

va_list args;

int i,j;

va_start(args, fmt);

i = vsnprintf(tmp_buf, INT_MAX, fmt, args);

va_end(args);

for(j = 0; j

{

mylog_putc(tmp_buf[j]);

}

return 1;

}

EXPORT_SYMBOL(myprintk);


7. Improve the read function


//Realize the read function, refer to kmsg.c

static ssize_t mymsg_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

{

int error;

int i = 0; //The number of data read

char c;

//Open with non-blocking mode and the data queue is empty

if ((file->f_flags & O_NONBLOCK) && is_mylog_empty())

return -EAGAIN;

//Wait until the queue is not empty

[1] [2] [3] [4]
Keywords:proc Reference address:Debugging and analysis of the implementation of mymsg and myprintk under proc in imx257

Previous article:Debug analysis: PC pointer analysis error based on kernel error information
Next article:iMX257 pin configuration function/memory read and write function

Recommended ReadingLatest update time:2024-11-14 15:22

IMX257 LED driver implementation
Since I didn't understand the address allocation of IMX257 yesterday, I could only use the s3c24xx driver to understand the working principles of ioremap and other IO ports. However, after a careful review of the IMX257 chip last night, I read the chip information of IMX257 again this morning and finally succee
[Microcontroller]
IMX257 LED driver implementation
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号