zoukankan      html  css  js  c++  java
  • linux内核debug的一种方式:procfs

      1 #include <linux/module.h>
      2 
      3 #include <linux/compat.h>
      4 #include <linux/types.h>
      5 #include <linux/errno.h>
      6 #include <linux/kernel.h>
      7 #include <linux/major.h>
      8 #include <linux/slab.h>
      9 #include <linux/mm.h>
     10 #include <linux/mman.h>
     11 #include <linux/vt.h>
     12 #include <linux/init.h>
     13 #include <linux/linux_logo.h>
     14 #include <linux/proc_fs.h>
     15 #include <linux/seq_file.h>
     16 #include <linux/console.h>
     17 #include <linux/kmod.h>
     18 #include <linux/err.h>
     19 #include <linux/device.h>
     20 #include <linux/efi.h>
     21 #include <linux/fb.h>
     22 #include <linux/delay.h>
     23 #include <linux/version.h>
     24 #include <linux/kthread.h>
     25 #include <linux/poll.h>
     26 
     27 /*Proc based contron intertace*/
     28 #define AUDIO_DEBUG_PROC_DIR "audio"
     29 #define AUDIO_DEBUG_PROC_INFO "debuginfo"
     30 #define MAX_BUF_WT_LEN 200 //do not bigger than one page size 1024 bytes
     31 #define MAX_BUF_RD_LEN 2048
     32 
     33 static struct proc_dir_entry *audio_proc_dir = NULL;
     34 static struct proc_dir_entry *audio_proc_dbginfo_file = NULL;
     35 
     36 static struct deca_device *audio_deca_dev=NULL;
     37 static struct snd_device *audio_snd_dev=NULL;
     38 
     39 static char *audio_info_buffer = NULL;
     40 static __u32 g_dbg_show_en = 0;
     41 static __u32 g_dbg_show_interval = 1;
     42 static     struct mutex audio_dbg_mutex;
     43 wait_queue_head_t audio_dbg_wq;
     44 static     struct task_struct *audio_dbg_show_thread_ptr;
     45 
     46 static char *audio_state(unsigned long state)
     47 {
     48     char *ret = NULL;
     49     switch(state)
     50     {
     51         case 0:
     52             ret="DETACH";
     53             break;
     54         case 1:
     55             ret="ATTACH";
     56             break;
     57         case 2:
     58             ret="IDLE";
     59             break;
     60         case 4:
     61             ret="PLAY";
     62             break;
     63         case 8:
     64             ret="PAUSE";
     65             break;
     66         default:
     67             ret="UNKNOWN";
     68             break;
     69     }
     70     return ret;
     71 }
     72 static char *audio_sub_state(unsigned long state)
     73 {
     74     char *ret = NULL;
     75     switch(state)
     76     {
     77         case 0:
     78             ret="IDLE";
     79             break;
     80         case 1:
     81             ret="NORMAL";
     82             break;
     83         case 2:
     84             ret="NO DATA";
     85             break;
     86         case 4:
     87             ret="NO BUFF";
     88             break;
     89         default:
     90             ret="UNKNOWN";
     91             break;
     92     }
     93     return ret;
     94 }
     95 static int audio_read_debug_info(char * buffer)
     96 {
     97     int len = 0;
     98     unsigned long len_max = MAX_BUF_RD_LEN - 100;
     99     struct audio_dbg_info dbg_info;
    100 
    101     if(!audio_deca_dev || !audio_snd_dev)
    102     {
    103         return -EUNATCH;
    104     }
    105 
    106     if (RET_SUCCESS == deca_io_control(audio_deca_dev, DECA_GET_DBG_INFO, (UINT32)(&dbg_info)))
    107     {
    108         len += sprintf(&buffer[len],"
    desc enable    : %s
    ", (1==dbg_info.snd.ad_en)?"yes":"no");
    109         if (len_max <= len)
    110             goto out;
    111 
    112         len += sprintf(&buffer[len],"deca state     : %s(%d)
    ", audio_state(dbg_info.deca.state), (int)dbg_info.deca.state);
    113         if (len_max <= len)
    114             goto out;
    115 
    116         len += sprintf(&buffer[len],"deca sub state : %s(%d)
    ", audio_sub_state(dbg_info.deca.sub_state), (int)dbg_info.deca.sub_state);
    117         if (len_max <= len)
    118             goto out;
    119 
    120         len += sprintf(&buffer[len],"snd  state     : %s(%d)
    ", audio_state(dbg_info.snd.state), (int)dbg_info.snd.state);
    121         if (len_max <= len)
    122             goto out;
    123 
    124         len += sprintf(&buffer[len],"snd  sub state : %s(%d)
    ", audio_sub_state(dbg_info.snd.sub_state), (int)dbg_info.snd.sub_state);
    125         if (len_max <= len)
    126             goto out;
    127 
    128         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    ");
    129         if (len_max <= len)
    130             goto out;
    131         len += sprintf(&buffer[len],"|BUFF |PCM(HEX BYTE)     |DESC(HEX BYTE)    |DD(HEX BYTE)      |DDP(HEX BYTE)     |
    ");
    132         if (len_max <= len)
    133             goto out;
    134 
    135         /* deca buff info */
    136         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    ");
    137         if (len_max <= len)
    138             goto out;
    139         len += sprintf(&buffer[len],"|BS   |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |                  |                  |
    ",
    140             (int)((dbg_info.deca.prog_bs_buff_rm*100)/(dbg_info.deca.prog_bs_buff_len)),
    141             (unsigned int)dbg_info.deca.prog_bs_buff_rm, (unsigned int)dbg_info.deca.prog_bs_buff_len,
    142             (int)((dbg_info.deca.desc_bs_buff_rm*100)/(dbg_info.deca.desc_bs_buff_len)),
    143             (unsigned int)dbg_info.deca.desc_bs_buff_rm, (unsigned int)dbg_info.deca.desc_bs_buff_len);
    144         if (len_max <= len)
    145             goto out;
    146         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    ");
    147         if (len_max <= len)
    148             goto out;
    149         len += sprintf(&buffer[len],"|CB   |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |                  |                  |
    ",
    150             (int)((dbg_info.deca.prog_cb_buff_rm*100)/(dbg_info.deca.prog_cb_buff_len)),
    151             (unsigned int)dbg_info.deca.prog_cb_buff_rm, (unsigned int)dbg_info.deca.prog_cb_buff_len,
    152             (int)((dbg_info.deca.desc_cb_buff_rm*100)/(dbg_info.deca.desc_cb_buff_len)),
    153             (unsigned int)dbg_info.deca.desc_cb_buff_rm, (unsigned int)dbg_info.deca.desc_cb_buff_len);
    154         if (len_max <= len)
    155             goto out;
    156 
    157         /* snd buff info */
    158         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    ");
    159         if (len_max <= len)
    160             goto out;
    161         len += sprintf(&buffer[len],"|SYNC |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |
    ",
    162             (int)((dbg_info.snd.sync_buff_pcm_rm*100)/(dbg_info.snd.sync_buff_pcm_len)),
    163             (unsigned int)dbg_info.snd.sync_buff_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_pcm_len,
    164             (int)((dbg_info.snd.sync_buff_desc_pcm_rm*100)/(dbg_info.snd.sync_buff_desc_pcm_len)),
    165             (unsigned int)dbg_info.snd.sync_buff_desc_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_desc_pcm_len,
    166             (int)((dbg_info.snd.sync_buff_dd_rm*100)/(dbg_info.snd.sync_buff_dd_len)),
    167             (unsigned int)dbg_info.snd.sync_buff_dd_rm, (unsigned int)dbg_info.snd.sync_buff_dd_len,
    168             (int)((dbg_info.snd.sync_buff_ddp_rm*100)/(dbg_info.snd.sync_buff_ddp_len)),
    169             (unsigned int)dbg_info.snd.sync_buff_ddp_rm, (unsigned int)dbg_info.snd.sync_buff_ddp_len        );
    170         if (len_max <= len)
    171             goto out;
    172         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    ");
    173         if (len_max <= len)
    174             goto out;
    175         len += sprintf(&buffer[len],"|DMA  |%03d%%(%05x/%05x) |                  |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |
    ",
    176             (int)((dbg_info.snd.dma_buff_pcm_rm*100)/(dbg_info.snd.dma_buff_pcm_len)),
    177             (unsigned int)dbg_info.snd.dma_buff_pcm_rm, (unsigned int)dbg_info.snd.dma_buff_pcm_len,
    178             (int)((dbg_info.snd.dma_buff_dd_rm*100)/(dbg_info.snd.dma_buff_dd_len)),
    179             (unsigned int)dbg_info.snd.dma_buff_dd_rm, (unsigned int)dbg_info.snd.dma_buff_dd_len,
    180             (int)((dbg_info.snd.dma_buff_ddp_rm*100)/(dbg_info.snd.dma_buff_ddp_len)),
    181             (unsigned int)dbg_info.snd.dma_buff_ddp_rm, (unsigned int)dbg_info.snd.dma_buff_ddp_len        );
    182         if (len_max <= len)
    183             goto out;
    184 
    185         len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+
    
    ");
    186         if (len_max <= len)
    187             goto out;
    188     }
    189 
    190 out:
    191     return len;
    192 }
    193 
    194 static int audio_show_debug_info(void)
    195 {
    196     struct audio_dbg_info dbg_info;
    197 
    198     if(!audio_deca_dev || !audio_snd_dev)
    199     {
    200         return -EUNATCH;
    201     }
    202 
    203     if (RET_SUCCESS == deca_io_control(audio_deca_dev, DECA_GET_DBG_INFO, (UINT32)(&dbg_info)))
    204     {
    205         printk( "
    desc enable    : %s
    ", (1==dbg_info.snd.ad_en)?"yes":"no");
    206         printk( "deca state     : %s(%d)
    ", audio_state(dbg_info.deca.state), (int)dbg_info.deca.state);
    207         printk( "deca sub state : %s(%d)
    ", audio_sub_state(dbg_info.deca.sub_state), (int)dbg_info.deca.sub_state);
    208         printk( "snd  state     : %s(%d)
    ", audio_state(dbg_info.snd.state), (int)dbg_info.snd.state);
    209         printk( "snd  sub state : %s(%d)
    ", audio_sub_state(dbg_info.snd.sub_state), (int)dbg_info.snd.sub_state);
    210 
    211         printk( "+-----+------------------+------------------+------------------+------------------+
    ");
    212         printk( "|BUFF |PCM(HEX BYTE)     |DESC(HEX BYTE)    |DD(HEX BYTE)      |DDP(HEX BYTE)     |
    ");
    213 
    214         /* deca buff info */
    215         printk( "+-----+------------------+------------------+------------------+------------------+
    ");
    216         printk( "|BS   |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |                  |                  |
    ",
    217             (int)((dbg_info.deca.prog_bs_buff_rm*100)/(dbg_info.deca.prog_bs_buff_len)),
    218             (unsigned int)dbg_info.deca.prog_bs_buff_rm, (unsigned int)dbg_info.deca.prog_bs_buff_len,
    219             (int)((dbg_info.deca.desc_bs_buff_rm*100)/(dbg_info.deca.desc_bs_buff_len)),
    220             (unsigned int)dbg_info.deca.desc_bs_buff_rm, (unsigned int)dbg_info.deca.desc_bs_buff_len);
    221         printk( "+-----+------------------+------------------+------------------+------------------+
    ");
    222         printk( "|CB   |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |                  |                  |
    ",
    223             (int)((dbg_info.deca.prog_cb_buff_rm*100)/(dbg_info.deca.prog_cb_buff_len)),
    224             (unsigned int)dbg_info.deca.prog_cb_buff_rm, (unsigned int)dbg_info.deca.prog_cb_buff_len,
    225             (int)((dbg_info.deca.desc_cb_buff_rm*100)/(dbg_info.deca.desc_cb_buff_len)),
    226             (unsigned int)dbg_info.deca.desc_cb_buff_rm, (unsigned int)dbg_info.deca.desc_cb_buff_len);
    227 
    228         /* snd buff info */
    229         printk( "+-----+------------------+------------------+------------------+------------------+
    ");
    230         printk( "|SYNC |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |
    ",
    231             (int)((dbg_info.snd.sync_buff_pcm_rm*100)/(dbg_info.snd.sync_buff_pcm_len)),
    232             (unsigned int)dbg_info.snd.sync_buff_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_pcm_len,
    233             (int)((dbg_info.snd.sync_buff_desc_pcm_rm*100)/(dbg_info.snd.sync_buff_desc_pcm_len)),
    234             (unsigned int)dbg_info.snd.sync_buff_desc_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_desc_pcm_len,
    235             (int)((dbg_info.snd.sync_buff_dd_rm*100)/(dbg_info.snd.sync_buff_dd_len)),
    236             (unsigned int)dbg_info.snd.sync_buff_dd_rm, (unsigned int)dbg_info.snd.sync_buff_dd_len,
    237             (int)((dbg_info.snd.sync_buff_ddp_rm*100)/(dbg_info.snd.sync_buff_ddp_len)),
    238             (unsigned int)dbg_info.snd.sync_buff_ddp_rm, (unsigned int)dbg_info.snd.sync_buff_ddp_len        );
    239         printk( "+-----+------------------+------------------+------------------+------------------+
    ");
    240         printk( "|DMA  |%03d%%(%05x/%05x) |                  |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |
    ",
    241             (int)((dbg_info.snd.dma_buff_pcm_rm*100)/(dbg_info.snd.dma_buff_pcm_len)),
    242             (unsigned int)dbg_info.snd.dma_buff_pcm_rm, (unsigned int)dbg_info.snd.dma_buff_pcm_len,
    243             (int)((dbg_info.snd.dma_buff_dd_rm*100)/(dbg_info.snd.dma_buff_dd_len)),
    244             (unsigned int)dbg_info.snd.dma_buff_dd_rm, (unsigned int)dbg_info.snd.dma_buff_dd_len,
    245             (int)((dbg_info.snd.dma_buff_ddp_rm*100)/(dbg_info.snd.dma_buff_ddp_len)),
    246             (unsigned int)dbg_info.snd.dma_buff_ddp_rm, (unsigned int)dbg_info.snd.dma_buff_ddp_len        );
    247 
    248         printk( "+-----+------------------+------------------+------------------+------------------+
    
    ");
    249     }
    250 
    251     return 0;
    252 }
    253 
    254 /*Process debug info*/
    255 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
    256 static ssize_t audio_dbginfo_procfile_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos)
    257 {
    258     int len = 0;
    259     ssize_t ret_len = 0;
    260 
    261     if(audio_info_buffer)
    262     {
    263         memset(audio_info_buffer, 0, MAX_BUF_RD_LEN);
    264         len = audio_read_debug_info(audio_info_buffer);
    265         ret_len = simple_read_from_buffer(ubuf, size, ppos, audio_info_buffer, len);
    266     }
    267 
    268     return ret_len;
    269 }
    270 
    271 
    272 static ssize_t audio_dbginfo_procfile_write(struct file *file, const char __user * buffer, size_t count, loff_t *ppos)
    273 {
    274     char            buf[MAX_BUF_WT_LEN] = {0};
    275     char            *eq_ch = NULL;
    276     char            *endp = NULL;
    277     unsigned long   value = 0;
    278 
    279     if ((0>=count) || (MAX_BUF_WT_LEN<count))
    280         return 0;
    281 
    282     if (copy_from_user(buf, buffer, count))
    283         return -EFAULT;
    284 
    285     eq_ch = strstr(buf, "=");
    286     if (NULL == eq_ch)
    287     {
    288         printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    289         return -EINVAL;
    290     }
    291 
    292     value = simple_strtoul((char *)(eq_ch+1), &endp, 0);
    293     if ((eq_ch+1) == endp || value >= INT_MAX)
    294     {
    295         printk(KERN_ERR "param error: incorrect value: "%s"
    ", (eq_ch+1));
    296         return -EINVAL;
    297     }
    298 
    299     switch(*buf)
    300     {
    301         case 'a':
    302         {
    303             if (strstr(buf, "ad_en"))
    304             {
    305                 if (0==value || 1==value)
    306                 {
    307                     if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (UINT32)value))
    308                     {
    309                         printk("33[40;31m%s->%s.%u, set ad_en(%d) fail!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, (int)value);
    310                         return -EFAULT;
    311                     }
    312                 }
    313                 else
    314                 {
    315                     printk(KERN_ERR "param error: incorrect value: "%d"
    ", (int)value);
    316                     return -EINVAL;
    317                 }
    318             }
    319             else
    320             {
    321                 printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    322                 return -EINVAL;
    323             }
    324             break;
    325         }
    326         case 'm':
    327         {
    328             if (strstr(buf, "monitor"))
    329             {
    330                 if (0==value || 1==value)
    331                 {
    332                     g_dbg_show_en = value;
    333                     if (g_dbg_show_en)
    334                     {
    335                         if (mutex_lock_interruptible(&audio_dbg_mutex))
    336                         {
    337                             return(-ERESTARTSYS);
    338                         }
    339                         wake_up_interruptible(&audio_dbg_wq);
    340                         mutex_unlock(&audio_dbg_mutex);
    341                     }
    342                 }
    343                 else
    344                 {
    345                     printk(KERN_ERR "param error: incorrect value: "%d"
    ", (int)value);
    346                     return -EINVAL;
    347                 }
    348             }
    349             else
    350             {
    351                 printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    352                 return -EINVAL;
    353             }
    354             break;
    355         }
    356         case 'i':
    357         {
    358             if (strstr(buf, "interval"))
    359             {
    360                 if (0<value && 100>value)
    361                 {
    362                     g_dbg_show_interval = value;
    363                 }
    364                 else
    365                 {
    366                     printk(KERN_ERR "param error: incorrect value: "%d"
    ", (int)value);
    367                     return -EINVAL;
    368                 }
    369             }
    370             else
    371             {
    372                 printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    373                 return -EINVAL;
    374             }
    375             break;
    376         }
    377         default:
    378             printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    379             return -EINVAL;
    380     }
    381 
    382 
    383     #if 0 /* Modified by William.Zeng on 2016-10-14 18:57 */
    384     if ((1 != sscanf(buf, "ad_en=%d", &ad_en)) && (0==ad_en || 1==ad_en))
    385     {
    386         return 0;
    387     }
    388     if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (enum adec_desc_channel_enable)ad_en))
    389     {
    390         printk("33[40;31m%s->%s.%u, set ad_en(%d) fail!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, ad_en);
    391         return 0;
    392     }
    393     printk("33[40;31m%s->%s.%u, set ad_en(%d) success!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, ad_en);
    394     #endif /* #if 0, End of Modified by William.Zeng on 2016-10-14 18:57 */
    395 
    396     return count;
    397 }
    398 #else
    399 static int audio_dbginfo_procfile_read(char*buffer, char**buffer_localation, off_t offset,int buffer_length,int* eof, void *data )
    400 {
    401     int len = 0;
    402     len =  audio_read_debug_info(buffer);
    403     *eof = 1;
    404     return len;
    405 }
    406 
    407 static int audio_dbginfo_procfile_write(struct file *filp, const char *buffer,unsigned long count,void *data)
    408 {
    409     char            buf[MAX_BUF_WT_LEN] = {0};
    410     char            *eq_ch = NULL;
    411     char            *endp = NULL;
    412     unsigned long   value = 0;
    413 
    414     if ((0>=count) || (MAX_BUF_WT_LEN<count))
    415         return 0;
    416 
    417     if (copy_from_user(buf, buffer, count))
    418         return -EFAULT;
    419 
    420     eq_ch = strstr(buf, "=");
    421     if (NULL == eq_ch)
    422     {
    423         printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    424         return -EINVAL;
    425     }
    426 
    427     value = simple_strtoul((char *)(eq_ch+1), &endp, 0);
    428     if ((eq_ch+1) == endp || value >= INT_MAX)
    429     {
    430         printk(KERN_ERR "param error: incorrect value: "%s"
    ", (eq_ch+1));
    431         return -EINVAL;
    432     }
    433 
    434     switch(*buf)
    435     {
    436         case 'a':
    437             if (strstr(buf, "ad_en"))
    438             {
    439                 if (0==value || 1==value)
    440                 {
    441                     if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (UINT32)value))
    442                     {
    443                         printk("33[40;31m%s->%s.%u, set ad_en(%d) fail!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, (int)value);
    444                         return -EFAULT;
    445                     }
    446                 }
    447                 else
    448                 {
    449                     printk(KERN_ERR "param error: incorrect value: "%d"
    ", (int)value);
    450                     return -EINVAL;
    451                 }
    452             }
    453             else
    454             {
    455                 printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    456                 return -EINVAL;
    457             }
    458             break;
    459         case 'm':
    460             if (strstr(buf, "monitor"))
    461             {
    462                 if (0==value || 1==value)
    463                 {
    464                     g_dbg_show_en = value;
    465                     if (g_dbg_show_en)
    466                     {
    467                         if (mutex_lock_interruptible(&audio_dbg_mutex))
    468                         {
    469                             return(-ERESTARTSYS);
    470                         }
    471                         wake_up_interruptible(&audio_dbg_wq);
    472                         mutex_unlock(&audio_dbg_mutex);
    473                     }
    474                 }
    475                 else
    476                 {
    477                     printk(KERN_ERR "param error: incorrect value: "%d"
    ", (int)value);
    478                     return -EINVAL;
    479                 }
    480             }
    481             else
    482             {
    483                 printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    484                 return -EINVAL;
    485             }
    486             break;
    487         default:
    488             printk(KERN_ERR "param error: incorrect value: "%s"
    ", buf);
    489             return -EINVAL;
    490     }
    491 
    492 
    493 #if 0 /* Modified by William.Zeng on 2016-10-14 18:57 */
    494     if ((1 != sscanf(buf, "ad_en=%d", &ad_en)) && (0==ad_en || 1==ad_en))
    495     {
    496         return 0;
    497     }
    498     if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (enum adec_desc_channel_enable)ad_en))
    499     {
    500         printk("33[40;31m%s->%s.%u, set ad_en(%d) fail!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, ad_en);
    501         return 0;
    502     }
    503     printk("33[40;31m%s->%s.%u, set ad_en(%d) success!33[0m
    ", __FILE__, __FUNCTION__, __LINE__, ad_en);
    504 #endif /* #if 0, End of Modified by William.Zeng on 2016-10-14 18:57 */
    505 
    506     return count;
    507 }
    508 
    509 
    510 #endif
    511 
    512 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
    513 static const struct file_operations audio_debuginfo_fops = {
    514     .read = audio_dbginfo_procfile_read,
    515     .write = audio_dbginfo_procfile_write,
    516     .llseek = default_llseek,
    517 };
    518 #endif
    519 
    520 static int audio_dbg_show_thread(void *param)
    521 {
    522     __s32 ret;
    523 
    524     for(;;)
    525     {
    526         if (mutex_lock_interruptible(&audio_dbg_mutex))
    527         {
    528             return(-ERESTARTSYS);
    529         }
    530 
    531         /* Wait until we are allowed to show debug info.
    532         */
    533         while (g_dbg_show_en == 0)
    534         {
    535             mutex_unlock(&audio_dbg_mutex);
    536             if (wait_event_interruptible(audio_dbg_wq, (1==g_dbg_show_en)))
    537             {
    538                 return(-ERESTARTSYS);
    539             }
    540             if (mutex_lock_interruptible(&audio_dbg_mutex))
    541             {
    542                 return(-ERESTARTSYS);
    543             }
    544         }
    545 
    546         ret = audio_show_debug_info();
    547 
    548         if (ret < 0)
    549         {
    550             g_dbg_show_en = 0;
    551             printk("33[40;31m%s->%s.%u, audio_show_debug_info failed!.33[0m
    ", __FILE__, __FUNCTION__, __LINE__);
    552         }
    553         mutex_unlock(&audio_dbg_mutex);
    554 
    555         msleep(g_dbg_show_interval*1000);
    556     }
    557 
    558     return(0);
    559 }
    560 
    561 int  audio_debug_procfs_init(void)
    562 {
    563     audio_info_buffer = kmalloc(MAX_BUF_RD_LEN, GFP_KERNEL);
    564     if (NULL == audio_info_buffer)
    565     {
    566         printk("kmall audio_info_buffer %d failed!!
    ", MAX_BUF_RD_LEN);
    567         return -1;
    568     }
    569     mutex_init(&audio_dbg_mutex);
    570     init_waitqueue_head(&audio_dbg_wq);
    571 
    572     audio_proc_dir = proc_mkdir(AUDIO_DEBUG_PROC_DIR, NULL);
    573     if (audio_proc_dir == NULL) {
    574         printk("audio_debug_procfs_init create dir audio failed!!
    ");
    575         kfree(audio_info_buffer);
    576         return -1;
    577     }
    578 
    579 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0))
    580     /*For Debug info*/
    581     audio_proc_dbginfo_file = proc_create(AUDIO_DEBUG_PROC_INFO,0644,audio_proc_dir, &audio_debuginfo_fops);
    582 #else
    583     /*For Debug info*/
    584     audio_proc_dbginfo_file = create_proc_entry(AUDIO_DEBUG_PROC_INFO,0644,audio_proc_dir);
    585 #endif
    586     if(audio_proc_dbginfo_file == NULL)
    587     {
    588         remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL);
    589         kfree(audio_info_buffer);
    590         printk("Error:could not initialize /proc/%s/%s
    ", AUDIO_DEBUG_PROC_DIR, AUDIO_DEBUG_PROC_INFO);
    591         return -1;
    592     }
    593 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
    594     audio_proc_dbginfo_file->read_proc = audio_dbginfo_procfile_read;
    595     audio_proc_dbginfo_file->write_proc = audio_dbginfo_procfile_write;
    596 #endif
    597 
    598     audio_deca_dev=(struct deca_device*)hld_dev_get_by_type(NULL, HLD_DEV_TYPE_DECA);
    599     audio_snd_dev=(struct snd_device*)hld_dev_get_by_type(NULL, HLD_DEV_TYPE_SND);
    600 
    601     audio_dbg_show_thread_ptr = kthread_create(audio_dbg_show_thread, NULL, "audio_dbg");
    602 
    603     if (IS_ERR(audio_dbg_show_thread_ptr))
    604     {
    605         printk("%s,%d
    ", __FUNCTION__, __LINE__);
    606         remove_proc_entry(AUDIO_DEBUG_PROC_INFO, audio_proc_dir);
    607         remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL);
    608         kfree(audio_info_buffer);
    609         return(PTR_ERR(audio_dbg_show_thread_ptr));
    610     }
    611 
    612     wake_up_process(audio_dbg_show_thread_ptr);
    613 
    614     return 0;
    615 }
    616 
    617 
    618 void  audio_debug_procfs_exit(void)
    619 {
    620     remove_proc_entry(AUDIO_DEBUG_PROC_INFO, audio_proc_dir);
    621     remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL);
    622 
    623     if (audio_info_buffer)
    624         kfree(audio_info_buffer);
    625 
    626     return ;
    627 }
    View Code

    今天刚好加了一个procfs的目录,用于调试自己的驱动,使用方法如下:

    目前支持如下几个命令:
    cat /proc/audio/debuginfo --》查看audio信息
    echo "ad_en=1" > /proc/audio/debuginfo --》动态打开/关闭audio desc,ad_en参数只能为0或1
    echo "monitor=1" > /proc/audio/debuginfo --》wake up内核线程audio_dbg,默认每秒打印一次audio信息,monitor参数只能为0或1
    echo "interval=5" > /proc/audio/debuginfo --》设置monitor打印的时间间隔(单位:秒),interval参数范围为[1,100]

    audio打印信息如下:(其中表格记录的是audio各个buff的使用情况:剩余数据量百分比(剩余数据量/buff总大小),主要用于debug buff堵住的情况)

    # cat /proc/audio/debuginfo
    
    desc enable : no
    deca state : IDLE(2)
    deca sub state : IDLE(0)
    snd state : IDLE(2)
    snd sub state : IDLE(0)
    +-----+------------------+------------------+------------------+------------------+
    |BUFF |PCM(HEX BYTE)     |DESC(HEX BYTE)    |DD(HEX BYTE)      |DDP(HEX BYTE)     |
    +-----+------------------+------------------+------------------+------------------+
    |BS   |000%(00000/0c800) |000%(00000/0c800) |                  |                  |
    +-----+------------------+------------------+------------------+------------------+
    |CB   |000%(00000/000c8) |000%(00000/000c8) |                  |                  |
    +-----+------------------+------------------+------------------+------------------+
    |SYNC |000%(00000/60300) |000%(00000/60300) |000%(00000/60300) |000%(00000/60300) |
    +-----+------------------+------------------+------------------+------------------+
    |DMA  |000%(00000/20100) |                  |000%(00000/20100) |000%(00000/20100) |
    +-----+------------------+------------------+------------------+------------------+
  • 相关阅读:
    angularJs中ngModel的坑
    Angular中ngModel的$render的详解
    typescript中的工具 tsd
    angula组件-通过键盘实现多选(原创)
    angular指令系列---多行文本框自动高度
    微信公众号系列 --- ionic在IOS的键盘弹出问题
    angular Jsonp的坑
    关于js的一些基本知识(类,闭包,变量)
    介绍Angular的注入服务
    2019 SDN大作业
  • 原文地址:https://www.cnblogs.com/zengjianrong/p/5965218.html
Copyright © 2011-2022 走看看