#include <linux/module.h>

 #include <linux/compat.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/vt.h>
#include <linux/init.h>
#include <linux/linux_logo.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/console.h>
#include <linux/kmod.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/efi.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/version.h>
#include <linux/kthread.h>
#include <linux/poll.h> /*Proc based contron intertace*/
#define AUDIO_DEBUG_PROC_DIR "audio"
#define AUDIO_DEBUG_PROC_INFO "debuginfo"
#define MAX_BUF_WT_LEN 200 //do not bigger than one page size 1024 bytes
#define MAX_BUF_RD_LEN 2048 static struct proc_dir_entry *audio_proc_dir = NULL;
static struct proc_dir_entry *audio_proc_dbginfo_file = NULL; static struct deca_device *audio_deca_dev=NULL;
static struct snd_device *audio_snd_dev=NULL; static char *audio_info_buffer = NULL;
static __u32 g_dbg_show_en = ;
static __u32 g_dbg_show_interval = ;
static struct mutex audio_dbg_mutex;
wait_queue_head_t audio_dbg_wq;
static struct task_struct *audio_dbg_show_thread_ptr; static char *audio_state(unsigned long state)
{
char *ret = NULL;
switch(state)
{
case :
ret="DETACH";
break;
case :
ret="ATTACH";
break;
case :
ret="IDLE";
break;
case :
ret="PLAY";
break;
case :
ret="PAUSE";
break;
default:
ret="UNKNOWN";
break;
}
return ret;
}
static char *audio_sub_state(unsigned long state)
{
char *ret = NULL;
switch(state)
{
case :
ret="IDLE";
break;
case :
ret="NORMAL";
break;
case :
ret="NO DATA";
break;
case :
ret="NO BUFF";
break;
default:
ret="UNKNOWN";
break;
}
return ret;
}
static int audio_read_debug_info(char * buffer)
{
int len = ;
unsigned long len_max = MAX_BUF_RD_LEN - ;
struct audio_dbg_info dbg_info; if(!audio_deca_dev || !audio_snd_dev)
{
return -EUNATCH;
} if (RET_SUCCESS == deca_io_control(audio_deca_dev, DECA_GET_DBG_INFO, (UINT32)(&dbg_info)))
{
len += sprintf(&buffer[len],"\ndesc enable : %s\n", (==dbg_info.snd.ad_en)?"yes":"no");
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"deca state : %s(%d)\n", audio_state(dbg_info.deca.state), (int)dbg_info.deca.state);
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"deca sub state : %s(%d)\n", audio_sub_state(dbg_info.deca.sub_state), (int)dbg_info.deca.sub_state);
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"snd state : %s(%d)\n", audio_state(dbg_info.snd.state), (int)dbg_info.snd.state);
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"snd sub state : %s(%d)\n", audio_sub_state(dbg_info.snd.sub_state), (int)dbg_info.snd.sub_state);
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n");
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"|BUFF |PCM(HEX BYTE) |DESC(HEX BYTE) |DD(HEX BYTE) |DDP(HEX BYTE) |\n");
if (len_max <= len)
goto out; /* deca buff info */
len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n");
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"|BS |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) | | |\n",
(int)((dbg_info.deca.prog_bs_buff_rm*)/(dbg_info.deca.prog_bs_buff_len)),
(unsigned int)dbg_info.deca.prog_bs_buff_rm, (unsigned int)dbg_info.deca.prog_bs_buff_len,
(int)((dbg_info.deca.desc_bs_buff_rm*)/(dbg_info.deca.desc_bs_buff_len)),
(unsigned int)dbg_info.deca.desc_bs_buff_rm, (unsigned int)dbg_info.deca.desc_bs_buff_len);
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n");
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"|CB |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) | | |\n",
(int)((dbg_info.deca.prog_cb_buff_rm*)/(dbg_info.deca.prog_cb_buff_len)),
(unsigned int)dbg_info.deca.prog_cb_buff_rm, (unsigned int)dbg_info.deca.prog_cb_buff_len,
(int)((dbg_info.deca.desc_cb_buff_rm*)/(dbg_info.deca.desc_cb_buff_len)),
(unsigned int)dbg_info.deca.desc_cb_buff_rm, (unsigned int)dbg_info.deca.desc_cb_buff_len);
if (len_max <= len)
goto out; /* snd buff info */
len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n");
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"|SYNC |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |\n",
(int)((dbg_info.snd.sync_buff_pcm_rm*)/(dbg_info.snd.sync_buff_pcm_len)),
(unsigned int)dbg_info.snd.sync_buff_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_pcm_len,
(int)((dbg_info.snd.sync_buff_desc_pcm_rm*)/(dbg_info.snd.sync_buff_desc_pcm_len)),
(unsigned int)dbg_info.snd.sync_buff_desc_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_desc_pcm_len,
(int)((dbg_info.snd.sync_buff_dd_rm*)/(dbg_info.snd.sync_buff_dd_len)),
(unsigned int)dbg_info.snd.sync_buff_dd_rm, (unsigned int)dbg_info.snd.sync_buff_dd_len,
(int)((dbg_info.snd.sync_buff_ddp_rm*)/(dbg_info.snd.sync_buff_ddp_len)),
(unsigned int)dbg_info.snd.sync_buff_ddp_rm, (unsigned int)dbg_info.snd.sync_buff_ddp_len );
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n");
if (len_max <= len)
goto out;
len += sprintf(&buffer[len],"|DMA |%03d%%(%05x/%05x) | |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |\n",
(int)((dbg_info.snd.dma_buff_pcm_rm*)/(dbg_info.snd.dma_buff_pcm_len)),
(unsigned int)dbg_info.snd.dma_buff_pcm_rm, (unsigned int)dbg_info.snd.dma_buff_pcm_len,
(int)((dbg_info.snd.dma_buff_dd_rm*)/(dbg_info.snd.dma_buff_dd_len)),
(unsigned int)dbg_info.snd.dma_buff_dd_rm, (unsigned int)dbg_info.snd.dma_buff_dd_len,
(int)((dbg_info.snd.dma_buff_ddp_rm*)/(dbg_info.snd.dma_buff_ddp_len)),
(unsigned int)dbg_info.snd.dma_buff_ddp_rm, (unsigned int)dbg_info.snd.dma_buff_ddp_len );
if (len_max <= len)
goto out; len += sprintf(&buffer[len],"+-----+------------------+------------------+------------------+------------------+\n\n");
if (len_max <= len)
goto out;
} out:
return len;
} static int audio_show_debug_info(void)
{
struct audio_dbg_info dbg_info; if(!audio_deca_dev || !audio_snd_dev)
{
return -EUNATCH;
} if (RET_SUCCESS == deca_io_control(audio_deca_dev, DECA_GET_DBG_INFO, (UINT32)(&dbg_info)))
{
printk( "\ndesc enable : %s\n", (==dbg_info.snd.ad_en)?"yes":"no");
printk( "deca state : %s(%d)\n", audio_state(dbg_info.deca.state), (int)dbg_info.deca.state);
printk( "deca sub state : %s(%d)\n", audio_sub_state(dbg_info.deca.sub_state), (int)dbg_info.deca.sub_state);
printk( "snd state : %s(%d)\n", audio_state(dbg_info.snd.state), (int)dbg_info.snd.state);
printk( "snd sub state : %s(%d)\n", audio_sub_state(dbg_info.snd.sub_state), (int)dbg_info.snd.sub_state); printk( "+-----+------------------+------------------+------------------+------------------+\n");
printk( "|BUFF |PCM(HEX BYTE) |DESC(HEX BYTE) |DD(HEX BYTE) |DDP(HEX BYTE) |\n"); /* deca buff info */
printk( "+-----+------------------+------------------+------------------+------------------+\n");
printk( "|BS |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) | | |\n",
(int)((dbg_info.deca.prog_bs_buff_rm*)/(dbg_info.deca.prog_bs_buff_len)),
(unsigned int)dbg_info.deca.prog_bs_buff_rm, (unsigned int)dbg_info.deca.prog_bs_buff_len,
(int)((dbg_info.deca.desc_bs_buff_rm*)/(dbg_info.deca.desc_bs_buff_len)),
(unsigned int)dbg_info.deca.desc_bs_buff_rm, (unsigned int)dbg_info.deca.desc_bs_buff_len);
printk( "+-----+------------------+------------------+------------------+------------------+\n");
printk( "|CB |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) | | |\n",
(int)((dbg_info.deca.prog_cb_buff_rm*)/(dbg_info.deca.prog_cb_buff_len)),
(unsigned int)dbg_info.deca.prog_cb_buff_rm, (unsigned int)dbg_info.deca.prog_cb_buff_len,
(int)((dbg_info.deca.desc_cb_buff_rm*)/(dbg_info.deca.desc_cb_buff_len)),
(unsigned int)dbg_info.deca.desc_cb_buff_rm, (unsigned int)dbg_info.deca.desc_cb_buff_len); /* snd buff info */
printk( "+-----+------------------+------------------+------------------+------------------+\n");
printk( "|SYNC |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |\n",
(int)((dbg_info.snd.sync_buff_pcm_rm*)/(dbg_info.snd.sync_buff_pcm_len)),
(unsigned int)dbg_info.snd.sync_buff_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_pcm_len,
(int)((dbg_info.snd.sync_buff_desc_pcm_rm*)/(dbg_info.snd.sync_buff_desc_pcm_len)),
(unsigned int)dbg_info.snd.sync_buff_desc_pcm_rm, (unsigned int)dbg_info.snd.sync_buff_desc_pcm_len,
(int)((dbg_info.snd.sync_buff_dd_rm*)/(dbg_info.snd.sync_buff_dd_len)),
(unsigned int)dbg_info.snd.sync_buff_dd_rm, (unsigned int)dbg_info.snd.sync_buff_dd_len,
(int)((dbg_info.snd.sync_buff_ddp_rm*)/(dbg_info.snd.sync_buff_ddp_len)),
(unsigned int)dbg_info.snd.sync_buff_ddp_rm, (unsigned int)dbg_info.snd.sync_buff_ddp_len );
printk( "+-----+------------------+------------------+------------------+------------------+\n");
printk( "|DMA |%03d%%(%05x/%05x) | |%03d%%(%05x/%05x) |%03d%%(%05x/%05x) |\n",
(int)((dbg_info.snd.dma_buff_pcm_rm*)/(dbg_info.snd.dma_buff_pcm_len)),
(unsigned int)dbg_info.snd.dma_buff_pcm_rm, (unsigned int)dbg_info.snd.dma_buff_pcm_len,
(int)((dbg_info.snd.dma_buff_dd_rm*)/(dbg_info.snd.dma_buff_dd_len)),
(unsigned int)dbg_info.snd.dma_buff_dd_rm, (unsigned int)dbg_info.snd.dma_buff_dd_len,
(int)((dbg_info.snd.dma_buff_ddp_rm*)/(dbg_info.snd.dma_buff_ddp_len)),
(unsigned int)dbg_info.snd.dma_buff_ddp_rm, (unsigned int)dbg_info.snd.dma_buff_ddp_len ); printk( "+-----+------------------+------------------+------------------+------------------+\n\n");
} return ;
} /*Process debug info*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
static ssize_t audio_dbginfo_procfile_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos)
{
int len = ;
ssize_t ret_len = ; if(audio_info_buffer)
{
memset(audio_info_buffer, , MAX_BUF_RD_LEN);
len = audio_read_debug_info(audio_info_buffer);
ret_len = simple_read_from_buffer(ubuf, size, ppos, audio_info_buffer, len);
} return ret_len;
} static ssize_t audio_dbginfo_procfile_write(struct file *file, const char __user * buffer, size_t count, loff_t *ppos)
{
char buf[MAX_BUF_WT_LEN] = {};
char *eq_ch = NULL;
char *endp = NULL;
unsigned long value = ; if ((>=count) || (MAX_BUF_WT_LEN<count))
return ; if (copy_from_user(buf, buffer, count))
return -EFAULT; eq_ch = strstr(buf, "=");
if (NULL == eq_ch)
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
} value = simple_strtoul((char *)(eq_ch+), &endp, );
if ((eq_ch+) == endp || value >= INT_MAX)
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", (eq_ch+));
return -EINVAL;
} switch(*buf)
{
case 'a':
{
if (strstr(buf, "ad_en"))
{
if (==value || ==value)
{
if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (UINT32)value))
{
printk("\033[40;31m%s->%s.%u, set ad_en(%d) fail!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, (int)value);
return -EFAULT;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%d\"\n", (int)value);
return -EINVAL;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
}
break;
}
case 'm':
{
if (strstr(buf, "monitor"))
{
if (==value || ==value)
{
g_dbg_show_en = value;
if (g_dbg_show_en)
{
if (mutex_lock_interruptible(&audio_dbg_mutex))
{
return(-ERESTARTSYS);
}
wake_up_interruptible(&audio_dbg_wq);
mutex_unlock(&audio_dbg_mutex);
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%d\"\n", (int)value);
return -EINVAL;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
}
break;
}
case 'i':
{
if (strstr(buf, "interval"))
{
if (<value && >value)
{
g_dbg_show_interval = value;
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%d\"\n", (int)value);
return -EINVAL;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
}
break;
}
default:
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
} #if 0 /* Modified by William.Zeng on 2016-10-14 18:57 */
if (( != sscanf(buf, "ad_en=%d", &ad_en)) && (==ad_en || ==ad_en))
{
return ;
}
if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (enum adec_desc_channel_enable)ad_en))
{
printk("\033[40;31m%s->%s.%u, set ad_en(%d) fail!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, ad_en);
return ;
}
printk("\033[40;31m%s->%s.%u, set ad_en(%d) success!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, ad_en);
#endif /* #if 0, End of Modified by William.Zeng on 2016-10-14 18:57 */ return count;
}
#else
static int audio_dbginfo_procfile_read(char*buffer, char**buffer_localation, off_t offset,int buffer_length,int* eof, void *data )
{
int len = ;
len = audio_read_debug_info(buffer);
*eof = ;
return len;
} static int audio_dbginfo_procfile_write(struct file *filp, const char *buffer,unsigned long count,void *data)
{
char buf[MAX_BUF_WT_LEN] = {};
char *eq_ch = NULL;
char *endp = NULL;
unsigned long value = ; if ((>=count) || (MAX_BUF_WT_LEN<count))
return ; if (copy_from_user(buf, buffer, count))
return -EFAULT; eq_ch = strstr(buf, "=");
if (NULL == eq_ch)
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
} value = simple_strtoul((char *)(eq_ch+), &endp, );
if ((eq_ch+) == endp || value >= INT_MAX)
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", (eq_ch+));
return -EINVAL;
} switch(*buf)
{
case 'a':
if (strstr(buf, "ad_en"))
{
if (==value || ==value)
{
if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (UINT32)value))
{
printk("\033[40;31m%s->%s.%u, set ad_en(%d) fail!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, (int)value);
return -EFAULT;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%d\"\n", (int)value);
return -EINVAL;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
}
break;
case 'm':
if (strstr(buf, "monitor"))
{
if (==value || ==value)
{
g_dbg_show_en = value;
if (g_dbg_show_en)
{
if (mutex_lock_interruptible(&audio_dbg_mutex))
{
return(-ERESTARTSYS);
}
wake_up_interruptible(&audio_dbg_wq);
mutex_unlock(&audio_dbg_mutex);
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%d\"\n", (int)value);
return -EINVAL;
}
}
else
{
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
}
break;
default:
printk(KERN_ERR "param error: incorrect value: \"%s\"\n", buf);
return -EINVAL;
} #if 0 /* Modified by William.Zeng on 2016-10-14 18:57 */
if (( != sscanf(buf, "ad_en=%d", &ad_en)) && (==ad_en || ==ad_en))
{
return ;
}
if (RET_SUCCESS != snd_io_control(audio_snd_dev, SND_SET_AD_DYNAMIC_EN, (enum adec_desc_channel_enable)ad_en))
{
printk("\033[40;31m%s->%s.%u, set ad_en(%d) fail!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, ad_en);
return ;
}
printk("\033[40;31m%s->%s.%u, set ad_en(%d) success!\033[0m\n", __FILE__, __FUNCTION__, __LINE__, ad_en);
#endif /* #if 0, End of Modified by William.Zeng on 2016-10-14 18:57 */ return count;
} #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
static const struct file_operations audio_debuginfo_fops = {
.read = audio_dbginfo_procfile_read,
.write = audio_dbginfo_procfile_write,
.llseek = default_llseek,
};
#endif static int audio_dbg_show_thread(void *param)
{
__s32 ret; for(;;)
{
if (mutex_lock_interruptible(&audio_dbg_mutex))
{
return(-ERESTARTSYS);
} /* Wait until we are allowed to show debug info.
*/
while (g_dbg_show_en == )
{
mutex_unlock(&audio_dbg_mutex);
if (wait_event_interruptible(audio_dbg_wq, (==g_dbg_show_en)))
{
return(-ERESTARTSYS);
}
if (mutex_lock_interruptible(&audio_dbg_mutex))
{
return(-ERESTARTSYS);
}
} ret = audio_show_debug_info(); if (ret < )
{
g_dbg_show_en = ;
printk("\033[40;31m%s->%s.%u, audio_show_debug_info failed!.\033[0m\n", __FILE__, __FUNCTION__, __LINE__);
}
mutex_unlock(&audio_dbg_mutex); msleep(g_dbg_show_interval*);
} return();
} int audio_debug_procfs_init(void)
{
audio_info_buffer = kmalloc(MAX_BUF_RD_LEN, GFP_KERNEL);
if (NULL == audio_info_buffer)
{
printk("kmall audio_info_buffer %d failed!!\n", MAX_BUF_RD_LEN);
return -;
}
mutex_init(&audio_dbg_mutex);
init_waitqueue_head(&audio_dbg_wq); audio_proc_dir = proc_mkdir(AUDIO_DEBUG_PROC_DIR, NULL);
if (audio_proc_dir == NULL) {
printk("audio_debug_procfs_init create dir audio failed!!\n");
kfree(audio_info_buffer);
return -;
} #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0))
/*For Debug info*/
audio_proc_dbginfo_file = proc_create(AUDIO_DEBUG_PROC_INFO,,audio_proc_dir, &audio_debuginfo_fops);
#else
/*For Debug info*/
audio_proc_dbginfo_file = create_proc_entry(AUDIO_DEBUG_PROC_INFO,,audio_proc_dir);
#endif
if(audio_proc_dbginfo_file == NULL)
{
remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL);
kfree(audio_info_buffer);
printk("Error:could not initialize /proc/%s/%s\n", AUDIO_DEBUG_PROC_DIR, AUDIO_DEBUG_PROC_INFO);
return -;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
audio_proc_dbginfo_file->read_proc = audio_dbginfo_procfile_read;
audio_proc_dbginfo_file->write_proc = audio_dbginfo_procfile_write;
#endif audio_deca_dev=(struct deca_device*)hld_dev_get_by_type(NULL, HLD_DEV_TYPE_DECA);
audio_snd_dev=(struct snd_device*)hld_dev_get_by_type(NULL, HLD_DEV_TYPE_SND); audio_dbg_show_thread_ptr = kthread_create(audio_dbg_show_thread, NULL, "audio_dbg"); if (IS_ERR(audio_dbg_show_thread_ptr))
{
printk("%s,%d\n", __FUNCTION__, __LINE__);
remove_proc_entry(AUDIO_DEBUG_PROC_INFO, audio_proc_dir);
remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL);
kfree(audio_info_buffer);
return(PTR_ERR(audio_dbg_show_thread_ptr));
} wake_up_process(audio_dbg_show_thread_ptr); return ;
} void audio_debug_procfs_exit(void)
{
remove_proc_entry(AUDIO_DEBUG_PROC_INFO, audio_proc_dir);
remove_proc_entry(AUDIO_DEBUG_PROC_DIR, NULL); if (audio_info_buffer)
kfree(audio_info_buffer); return ;
}

今天刚好加了一个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()
deca sub state : IDLE()
snd state : IDLE()
snd sub state : IDLE()
+-----+------------------+------------------+------------------+------------------+
|BUFF |PCM(HEX BYTE) |DESC(HEX BYTE) |DD(HEX BYTE) |DDP(HEX BYTE) |
+-----+------------------+------------------+------------------+------------------+
|BS |%(/0c800) |%(/0c800) | | |
+-----+------------------+------------------+------------------+------------------+
|CB |%(/000c8) |%(/000c8) | | |
+-----+------------------+------------------+------------------+------------------+
|SYNC |%(/) |%(/) |%(/) |%(/) |
+-----+------------------+------------------+------------------+------------------+
|DMA |%(/) | |%(/) |%(/) |
+-----+------------------+------------------+------------------+------------------+

linux内核debug的一种方式:procfs的更多相关文章

  1. Linux 内核睡眠的几种方式

    译至:http://geeki.wordpress.com/2010/10/30/ways-of-sleeping-in-linux-kernel/ 在Linux中睡眠有2-3种不同的方法. 睡眠的第 ...

  2. 设置 Linux 下打印机的几种方式

    设置 Linux 下打印机的几种方式 一.使用 cups 进行设置 如若遇到 cups 也没有驱动的话可以前往 openprinting.org 找寻对应驱动. 二.前往 official 下载驱动 ...

  3. linux创建文件的四种方式(其实是两种,强行4种)

    linux创建文件的四种方式: 1.vi newfilename->i->编辑文件->ESC->:wq! 2.touch newfilename 3.cp sourcePath ...

  4. Linux 软件安装的三种方式

    Linux 软件安装的三种方式 1.yum ​ 语法格式: ​ yum -y install package.name ​ -y yes # 遇到提示自动输入yes ​ 案例: 安装ifconfig命 ...

  5. Linux 安装 Nodejs 的两种方式

    Linux 安装 Nodejs 的两种方式 目录 Linux 安装 Nodejs 的两种方式 一.压缩包安装 Nodejs 二.源码编译安装 Nodejs 一.压缩包安装 Nodejs 下载 Node ...

  6. Linux下定时执行任务的几种方式

    如果说我说如果,你的某一个目录下会经常的生成一些垃圾文件,比如访问日志.错误日志.core文件,而你又不想过几分钟就去手动检查一下,那么可以使用定时执行任务的方式来解决.目前我所知道的可以执行定时任务 ...

  7. linux异步IO的两种方式【转】

    转自:https://blog.csdn.net/shixin_0125/article/details/78898146 知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个C ...

  8. Linux内核替换的一种简单方法

    前言 使用现有centos的镜像,在海光机器上出现了无法运行的情况,grub引导后就只剩下光标一直在闪,无任何字符输出.这种情况大概率是因为Linux的内核无法运行在海光的CPU上所导致的. 已得知L ...

  9. Linux进程通信的几种方式总结

    进程通信的目的 数据传输 一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间 共享数据 多个进程想要操作共享数据,一个进程对共享数据 通知事 一个进程需要向另一个或一组进程发 ...

随机推荐

  1. Appium基于PO模型的自动化测试(Python)

    基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...

  2. jsonHelper帮助类

    使用前,需引用开源项目类using Newtonsoft.Json 链接:https://pan.baidu.com/s/1htK784XyRCl2XaGGM7RtEg 提取码:gs2n using ...

  3. Linux搭建www,mail,ftp三大DNS服务器

    ##############################-----服务器端----###############################1. 安装bind# yum install bin ...

  4. 【转载】Visual Studio2017如何设置打包发布的WinForm应用程序的版本号

    在Visual Studio 2017集成开发工具中,打包发布Winform窗体应用程序的时候,支持设置此次打包发布的Winform窗体应用程序对应的版本号信息,并且支持一次设置后,后续的所有发布版本 ...

  5. Spring登录实例

    Spring登录实例 项目结构 首先看一下整个项目的目录结构,如下: 导入Jar包 工欲善必先利其器,导入一下Jar包 配置文件 web.xml 配置 web.xml配置文件,如下: xmlns:xs ...

  6. JAVA中为什么要配置环境变量?怎么配置环境变量?

    1.为什么要配置环境变量? 答:为了让javac命令(编译命令)和Java命令(运行命令)能在任何文件夹都能运行. 2.怎么配置环境变量? JAVA_HOME : D:\develop\Java\jd ...

  7. github 分支管理

    github 分支管理 最近有同事问我git 如何管理分支,这里我以github为例,做下工作中常用的分支管理操作. 分支管理 作用:假设你准备开发一个新功能,但需要两周才能完成,第一周写了60%,如 ...

  8. 设计模式小议:state【转】

    转自:https://blog.csdn.net/goodboy1881/article/details/635963 这个模式使得软件可以在不同的state下面呈现出完全不同的特征 不同的theme ...

  9. 如何下载Youtube的4K视频?这里有4款软件, 哪个适合你?

    数字电影的最新分辨率标准是4k,4K分辨率的视频具有高图像清晰度质量.更好的快速动作.更大的投影表面可见度和更详细的图像质量等优点,受到了广大视频爱好者的好评.作为当前最火热的视频分享网站,YouTu ...

  10. Revit 2019 下载链接

    [安装环境]:win7/win8/win10 [64位下载] 百度网盘链接:pan.baidu.com/s/1Vq5Cnyj1G-oMNup_sXvxfQ  提取码:d6xd