调试分析之 imx257中proc下mymsg及myprintk的实现

发布者:AdventureSeeker最新更新时间:2024-08-13 来源: cnblogs关键字:调试分析  proc 手机看文章 扫描二维码
随时随地手机看文章


唤醒的条件是buff不空.当程序被唤醒时,则调用copy_to_user函数将数据拷贝到用户进程中进行打印出来.


8.修改测试驱动程序err_led.c.


首先外部引入myprintk函数,然后将测试驱动程序的printk全部修改为myprintk函数.


1 extern int myprintk(const char *fmt, ...); //引入外部声明

3 static int key_open(struct inode *inode, struct file *file)

4 {

5     myprintk('<0>function open!nn');  //将printk修改未myprintk

6     return 0;

7 }


9.编译测试:


注意加载驱动的顺序.


①加载mymsg.ko驱动程序


②加载test/err_led.ko驱动程序:发现板子上的err_led灯闪烁,等led闪烁完毕


③读取 cat /proc/mymsg: 发现成功的打印出我们err_led要打印的消息,如下图


④卸载test/err_led.ko:发现板子上的err_led等闪烁,等闪烁完毕


⑤读取 cat /proc/mymsg: 再消息最末尾多了一条goodbye的消息,成功


⑥卸载mymsg.ko驱动程序

1c5bffea79d2618b23cf1ce4a4ba0d9f_1U2H2dwpL9AAAAAASUVORK5CYII=.png

附上驱动程序mymsg_4.c


  1 #include

  2 #include

  3 #include

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 

 11 

 12 #define MYLOG_BUF_LEN  1024

 13 

 14 //定义proc的entry结构体

 15 static struct proc_dir_entry *myentry;

 16 static char mylog_buf[MYLOG_BUF_LEN];        //数据缓冲区

 17 static char tmp_buf[MYLOG_BUF_LEN];            //数据缓冲区

 18 static int mylog_r = 0;

 19 static int mylog_w = 0;

 20 

 21 static DECLARE_WAIT_QUEUE_HEAD(mylog_wait);

 22 

 23 //判断是否为空

 24 static int is_mylog_empty(void)

 25 {

 26     return (mylog_r == mylog_w);

 27 }

 28 //判断是否已满

 29 static int is_mylog_full(void)

 30 {

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

 32 }

 33 //写入字符

 34 static void mylog_putc(char c)

 35 {

 36     if(is_mylog_full)

 37     {

 38         //丢弃一个数据

 39         mylog_r = (mylog_r + 1) % MYLOG_BUF_LEN;

 40     }

 41     mylog_buf[mylog_w] = c;

 42     mylog_w = (mylog_w + 1) % MYLOG_BUF_LEN;

 43     

 44     /* 唤醒等待数据的进程 */

 45     wake_up_interruptible(&mylog_wait);

 46 }

 47 //读取字符

 48 static int mylog_getc(char *p)

 49 {

 50     if(is_mylog_empty())

 51         return 0;

 52     *p = mylog_buf[mylog_r];

 53     mylog_r = (mylog_r + 1) %  MYLOG_BUF_LEN;

 54     return 1;

 55 }

 56 

 57 //打印输出  参考vsprintf.c  的 sprintf

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

 59 {

 60     va_list args;

 61     int i,j;

 62     

 63     va_start(args, fmt);

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

 65     va_end(args);

 66     for(j = 0; j 67     {

 68         mylog_putc(tmp_buf[j]);

 69     }

 70     return 1;

 71 }

 72 EXPORT_SYMBOL(myprintk);

 73 

 74 //实现读函数     参考kmsg.c

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

 76 {

 77     int error;

 78     int i = 0;        //所读的数据的个数

 79     char c;

 80     

 81     //以非阻塞打开,并且数据队列为空

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

 83         return -EAGAIN;

 84     

 85     //等待直到队列非空

 86     error = wait_event_interruptible(mylog_wait,!is_mylog_empty());

 87     

 88     /* copy_to_user 若是没错,获取字符串成功 */

 89     while( !error && (mylog_getc(&c)) && i < count ){

 90         error = __put_user(c, buf);            //等同copy_to_user

 91         buf++;

 92         i++;

 93     }

 94     if(!error)

 95         error = i;

 96     return error;

 97 }

 98 

 99 //定义file_operation结构体

100 static struct file_operations proc_mymsg_operations = {

101     .read = mymsg_read,

102 };

103 //入口函数

104 static int mymsg_init(void)

105 {

106     //sprintf(mylog_buf, '%s', 'abcdefghijklmnn');    //模拟伪造buf的数据

107     //创建proc的条目

108     myentry = create_proc_entry('mymsg',S_IRUSR,NULL);    //S_IRUSR:400 只读

109     

110     if(myentry)

111         myentry->proc_fops = &proc_mymsg_operations;

112     

113     

114     return 0;

115 }

116 //出口函数

117 static void mymsg_exit(void)

118 {

119     remove_proc_entry('mymsg', NULL);

120 }

121 

122 module_init(mymsg_init);

123 module_exit(mymsg_exit);

124 

125 MODULE_LICENSE('GPL');

126 MODULE_AUTHOR('Lover雪儿');

127 

128 

129 /*

130 1.环形缓冲区

131     空: R == W

132     写: buf[W] = val;

133         W = (W+1) % 10;

134     读: val = buf[R]

135         R = (R+1) % 10    

136     

137 

138 

139 */


附上测试驱动程序err_led.c:


  1 #include

  2 #include

  3 #include

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 #include

 11 #include

 12 #include

 13 #include

 14 

 15 #define Driver_NAME 'err_led_dev'

 16 #define DEVICE_NAME 'err_led_dev'

 17 

 18 static int major = 0;

 19 

 20 //auto to create device node

 21 static struct class *drv_class = NULL;

 22 static struct class_device *drv_class_dev = NULL;

 23 

 24 //寄存器基址;

 25 static unsigned long base_iomux;      //iomux基址 0X 43FA C000 -  0X 43FA FFFF

 26 static unsigned long base_gpio3;    //gpio3      0X 53FA 4000 -  0X 53FA 7FFF

 27 // MUX_CTL模式选择  配置寄存器

 28 #define MUX_CTL  (*(volatile unsigned long *)(base_iomux + 0x0060))

 29 // PAD_CTL GPIO常用功能设置

 30 #define PAD_CTL  (*(volatile unsigned long *)(base_iomux + 0x0270))

 31 // GPIO DR   数据寄存器  DR

 32 #define DR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0000))

 33 // GPIO GDIR 方向控制寄存器  GDIR

 34 #define GDIR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0004))

 35 

 36 

 37 extern int myprintk(const char *fmt, ...);

 38 

 39 static int key_open(struct inode *inode, struct file *file)

 40 {

 41     myprintk('<0>function open!nn');

 42     return 0;

 43 }

 44 

 45 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

 46 {

 47     return 0;

 48 }

 49 

 50 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

 51 {

 52     myprintk('<0>function write!nn');

 53     return 1;

 54 }

 55 

 56 static int  key_release(struct inode *inode, struct file *filp)

 57 {

 58     myprintk('<0>function write!nn');

 59     return 0;

 60 }

 61 

 62 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)

 63 {

 64     myprintk('<0>function ioctl!nn');

 65     return 0;

 66 }

 67 static struct file_operations key_fops = {

 68     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

 69     .open   =   key_open,

 70     .read   =   key_read,

 71     .write  =   key_write,

 72     .release=   key_release,

 73     .ioctl  =   key_ioctl,

 74 };

 75 

 76 void gpio_addr(void){

 77     myprintk('<0>addr base_iomux : %x n',base_iomux);

 78     myprintk('<0>addr base_gpio3 : %x n',base_gpio3);

 79     myprintk('<0>addr MUX_CTL : %x n',&MUX_CTL);

 80     myprintk('<0>addr PAD_CTL : %x n',&PAD_CTL);

 81     myprintk('<0>addr GDIR_GPIO3 : %x n',&GDIR_GPIO3);

 82     myprintk('<0>addr DR_GPIO3 : %x n',&DR_GPIO3);

 83 }

 84 

 85 void led_on_off(void){

 86     ssleep(1);

 87     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1

 88     ssleep(1);

 89     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零

 90     ssleep(1);

 91     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1

 92     ssleep(1);

 93     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零

[1] [2] [3] [4] [5]
关键字:调试分析  proc 引用地址:调试分析之 imx257中proc下mymsg及myprintk的实现

上一篇:调试分析之 根据内核报错信息PC指针分析错误
下一篇:iMX257引脚配置函数/内存读写函数

推荐阅读最新更新时间:2024-11-13 16:47

iMX257引脚配置函数/内存读写函数
要包含的三个头文件: #include mx257_gpio.h #include mx25_pins.h #include iomux.h 一、GPIO引脚使用 选择引脚模式- 引脚配置- 申请GPIO- 设置引脚输入/输出- 读取GPIO- 释放引脚模式- 释放GPIO 1.选择引脚的模式(ALT0-ALT7) int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) 示例: mxc_request_iomux(GPIO
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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