<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 自定義print函數(shù)緩存打印數(shù)據(jù)到環(huán)形緩沖區(qū)

          自定義print函數(shù)緩存打印數(shù)據(jù)到環(huán)形緩沖區(qū)

          作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          驅(qū)動程序:
          #include "linux/module.h"
          #include "linux/kernel.h"
          #include "linux/fs.h"
          #include "linux/init.h"
          #include "linux/delay.h"
          #include "asm/uaccess.h"
          #include "asm/irq.h""
          #include "asm/io.h"
          #include "asm/arch/regs-gpio.h"
          #include ""asm/hardware.h"
          #include "linux/proc_fs.h"
          #define MYLOG_BUF_LEN 1024
          struct proc_dir_entry *myentry;
          static char mylog_buf[MYLOG_BUF_LEN];
          static char tmp_buf[MYLOG_BUF_LEN];
          static int mylog_r = 0;
          static int mylog_r_for_read = 0;
          static int mylog_w = 0;
          static DECLARE_WAIT_QUEUE_HEAD(mymsg_waitq);
          static int is_mylog_empty(void)
          {
          return (mylog_r == mylog_w);
          }
          static int is_mylog_empty_for_read(void)
          {
          return (mylog_r_for_read == mylog_w);
          }
          static int is_mylog_full(void)
          {
          return ((mylog_w + 1)% MYLOG_BUF_LEN == mylog_r);
          }
          static void mylog_putc(char c)
          {
          if (is_mylog_full())
          {
          // 丟棄一個數(shù)據(jù) //
          mylog_r = (mylog_r + 1) % MYLOG_BUF_LEN;
          if ((mylog_r_for_read + 1) % MYLOG_BUF_LEN == mylog_r)
          {
          mylog_r_for_read = mylog_r;
          }
          }
          mylog_buf[mylog_w] = c;
          mylog_w = (mylog_w + 1) % MYLOG_BUF_LEN;
          // 喚醒等待數(shù)據(jù)的進程 //
          wake_up_interruptible(&mymsg_waitq); // 喚醒休眠的進程 //
          }
          static int mylog_getc(char *p)
          {
          if (is_mylog_empty())
          {
          return 0;
          }
          *p = mylog_buf[mylog_r];
          mylog_r = (mylog_r + 1) % MYLOG_BUF_LEN;
          return 1;
          }
          static int mylog_getc_for_read(char *p)
          {
          if (is_mylog_empty_for_read())
          {
          return 0;
          }
          *p = mylog_buf[mylog_r_for_read];
          mylog_r_for_read = (mylog_r_for_read + 1) % MYLOG_BUF_LEN;
          return 1;
          }
          int myprintk(const char *fmt, ...)
          {
          va_list args;
          int i;
          int j;
          va_start(args, fmt);
          i = vsnprintf(tmp_buf, INT_MAX, fmt, args);
          va_end(args);
          for (j = 0; j < i; j++)
          mylog_putc(tmp_buf[j]);
          return i;
          }
          static ssize_t mymsg_read(struct file *file, char __user *buf,
          size_t count, loff_t *ppos)
          {
          int error = 0;
          int i = 0;
          char c;
          // 把mylog_buf的數(shù)據(jù)copy_to_user, return //
          if ((file->f_flags & O_NONBLOCK) && is_mylog_empty_for_read())
          return -EAGAIN;
          //printk("%s %dn", __FUNCTION__, __LINE__);
          //printk("count = %dn", count);
          //printk("mylog_r = %dn", mylog_r);
          //printk("mylog_w = %dn", mylog_w);
          error = wait_event_interruptible(mymsg_waitq, !is_mylog_empty_for_read());
          //printk("%s %dn", __FUNCTION__, __LINE__);
          //printk("count = %dn", count);
          //printk("mylog_r = %dn", mylog_r);
          //printk("mylog_w = %dn", mylog_w);
          while (!error && (mylog_getc_for_read(&c)) && i < count) {
          error = __put_user(c, buf);
          buf++;
          i++;
          }
          if (!error)
          error = i;
          return error;
          }
          static int mymsg_open(struct inode *inode, struct file *file)
          {
          mylog_r_for_read = mylog_r;
          return 0;
          }
          const struct file_operations proc_mymsg_operations = {
          .open = mymsg_open,
          .read = mymsg_read,
          };
          static int mymsg_init(void)
          {
          myentry = create_proc_entry("mymsg", S_IRUSR, &proc_root);
          if (myentry)
          myentry->proc_fops = &proc_mymsg_operations;
          return 0;
          }
          static void mymsg_exit(void)
          {
          remove_proc_entry("mymsg", &proc_root);
          }
          module_init(mymsg_init);
          module_exit(mymsg_exit);
          EXPORT_SYMBOL(myprintk);
          MODULE_LICENSE("GPL");
          ===============================================================
          解析:
          當其他驅(qū)動程序調(diào)用自定義的myprintk函數(shù)打印數(shù)據(jù)時不會立即把數(shù)據(jù)打印在前臺顯示,而是把數(shù)據(jù)放在mylog_buf環(huán)形緩沖區(qū)中保存,當應(yīng)用程序查看proc/mymsg時,即執(zhí)行:cat /proc/mymsg時會調(diào)用mymsg_read函數(shù)讀取環(huán)型緩沖區(qū),如果緩沖區(qū)中有數(shù)據(jù)會調(diào)用__put_user返回,如果沒有數(shù)據(jù)系統(tǒng)會休眠。


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();