#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. c++和java的一些debug方法

    就上面那个绿色的小瓢虫,点了就进了debug模式. 好尴尬啊,就说一句话. 而且,要加断点,不然就一下debug完了.

  2. 纯C语言实现循环双向链表创建,插入和删除

    #include <stdio.h> #include <stdlib.h> typedef int ElemType; typedef struct DLNode{ Elem ...

  3. Java学习——单元测试JUnit

    Java学习——单元测试JUnit 摘要:本文主要介绍了什么是单元测试以及怎么进行单元测试. 部分内容来自以下博客: https://www.cnblogs.com/wxisme/p/4779193. ...

  4. 把本地项目提交到GIT上

    1.init之前 1.1 新建.gitignore文件 在提交之前.gitignore文件会把文件里面包含的内容都忽略掉 node_modules // webstorm里面的配置,别人不一定用 .i ...

  5. vue 开发系列(九) VUE 动态组件的应用

    业务场景 我们在开发表单的过程中会遇到这样的问题,我们选择一个控件进行配置,控件有很多中类型,比如文本框,下来框等,这些配置都不同,因此需要不同的配置组件来实现. 较常规的方法是使用v-if 来实现, ...

  6. TEE(Trusted Execution Environment)简介【转】

    转自:https://blog.csdn.net/fengbingchun/article/details/78657188 TEE(Trusted Execution Environment),可信 ...

  7. 如何在Etherscan.io 部署ETH以太坊智能合约 如何在15分钟内创建你的加密货币

    一.概述 ETH 网络这里就不介绍了,这篇文章主要记录在以太坊主网和测试网络部署一个智能合约,也就是如何发币. 二.部署合约需要的生产工具      准备工具前,建议大家准备个VPN,因为会访问国外网 ...

  8. linux基础-ssh服务

    SSH ssh 服务是实现管路服务器的一种方式: 本地管理(安装系统,故障修复),ssh 远程连接 linux 可以是实现远程连接的方式:ssh 命令 windows 可以实现远程连接方式: xshe ...

  9. Python中print用法里面% ,"%s 和 % d" 代表的意思

    Python 编程 里面% . "%s 和 % d" 代表的意思 %s,表示格化式一个对象为字符 %d,整数 "Hello, %s"%"zhang3& ...

  10. 201871010109-胡欢欢《面向对象程序设计(java)》第十三周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...