[Linux]DMA驱动&&madplay安装

[Linux]DMA驱动&&madplay安装

个人博客https://aeneag.xyz/

艾恩凝

2021/7/9

introduction

今天看了看DMA,主要了解DMA(Direct Memory Access)是干什么的,测试了有了DMA的好处,显而易见,在自己理解看来就是解放了cpu。另外解决了昨天遗留的问题。声卡驱动修改装载后,可以播放也可以录音,当播放mp3的时候需要madplay,编译好之后,发现竟然不能用,这和之前测试nand flash 驱动用flash_eraseall这个一样 command not found,终于搞明白了问题在哪,虽然觉得问题很sd。

DMA

DMA直接存储器访问,直接粘粘代码吧

  1#include <linux/module.h>
  2#include <linux/kernel.h>
  3#include <linux/fs.h>
  4#include <linux/init.h>
  5#include <linux/delay.h>
  6#include <linux/irq.h>
  7#include <asm/uaccess.h>
  8#include <asm/irq.h>
  9#include <asm/io.h>
 10#include <asm/arch/regs-gpio.h>
 11#include <asm/hardware.h>
 12#include <linux/poll.h>
 13#include <linux/dma-mapping.h>
 14
 15#define MEM_CPY_NO_DMA  0
 16#define MEM_CPY_DMA     1
 17
 18#define BUF_SIZE  (512*1024)
 19
 20#define DMA0_BASE_ADDR  0x4B000000
 21#define DMA1_BASE_ADDR  0x4B000040
 22#define DMA2_BASE_ADDR  0x4B000080
 23#define DMA3_BASE_ADDR  0x4B0000C0
 24
 25struct s3c_dma_regs {
 26	unsigned long disrc;
 27	unsigned long disrcc;
 28	unsigned long didst;
 29	unsigned long didstc;
 30	unsigned long dcon;
 31	unsigned long dstat;
 32	unsigned long dcsrc;
 33	unsigned long dcdst;
 34	unsigned long dmasktrig;
 35};
 36
 37
 38static int major = 0;
 39
 40static char *src;
 41static u32 src_phys;
 42
 43static char *dst;
 44static u32 dst_phys;
 45
 46static struct class *cls;
 47
 48static volatile struct s3c_dma_regs *dma_regs;
 49
 50static DECLARE_WAIT_QUEUE_HEAD(dma_waitq);
 51
 52static volatile int ev_dma = 0;
 53
 54static int s3c_dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 55{
 56	int i;
 57
 58	memset(src, 0xAA, BUF_SIZE);
 59	memset(dst, 0x55, BUF_SIZE);
 60
 61	switch (cmd)
 62	{
 63		case MEM_CPY_NO_DMA :
 64		{
 65			for (i = 0; i < BUF_SIZE; i++)
 66				dst[i] = src[i];
 67			if (memcmp(src, dst, BUF_SIZE) == 0)
 68			{
 69				printk("MEM_CPY_NO_DMA OK\n");
 70			}
 71			else
 72			{
 73				printk("MEM_CPY_DMA ERROR\n");
 74			}
 75			break;
 76		}
 77
 78		case MEM_CPY_DMA :
 79		{
 80			ev_dma = 0;
 81	
 82	
 83			dma_regs->disrc      = src_phys;   
 84			dma_regs->disrcc     = (0<<1) | (0<<0); 
 85			dma_regs->didst      = dst_phys;    
 86			dma_regs->didstc     = (0<<2) | (0<<1) | (0<<0); 
 87			dma_regs->dcon       = (1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(0<<20)|(BUF_SIZE<<0); 
 88
 89
 90			dma_regs->dmasktrig  = (1<<1) | (1<<0);
 91
 92
 93			wait_event_interruptible(dma_waitq, ev_dma);
 94
 95			if (memcmp(src, dst, BUF_SIZE) == 0)
 96			{
 97				printk("MEM_CPY_DMA OK\n");
 98			}
 99			else
100			{
101				printk("MEM_CPY_DMA ERROR\n");
102			}
103	
104			break;
105		}
106	}
107
108	return 0;
109}
110
111static struct file_operations dma_fops = {
112	.owner  = THIS_MODULE,
113	.ioctl  = s3c_dma_ioctl,
114};
115
116static irqreturn_t s3c_dma_irq(int irq, void *devid)
117{
118
119	ev_dma = 1;
120    wake_up_interruptible(&dma_waitq);   
121	return IRQ_HANDLED;
122}
123
124static int s3c_dma_init(void)
125{
126	if (request_irq(IRQ_DMA3, s3c_dma_irq, 0, "s3c_dma", 1))
127	{
128		printk("can't request_irq for DMA\n");
129		return -EBUSY;
130	}
131
132	src = dma_alloc_writecombine(NULL, BUF_SIZE, &src_phys, GFP_KERNEL);
133	if (NULL == src)
134	{
135		printk("can't alloc buffer for src\n");
136		free_irq(IRQ_DMA3, 1);
137		return -ENOMEM;
138	}
139
140	dst = dma_alloc_writecombine(NULL, BUF_SIZE, &dst_phys, GFP_KERNEL);
141	if (NULL == dst)
142	{
143		free_irq(IRQ_DMA3, 1);
144		dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
145		printk("can't alloc buffer for dst\n");
146		return -ENOMEM;
147	}
148
149	major = register_chrdev(0, "s3c_dma", &dma_fops);
150
151	cls = class_create(THIS_MODULE, "s3c_dma");
152	class_device_create(cls, NULL, MKDEV(major, 0), NULL, "dma"); /* /dev/dma */
153
154	dma_regs = ioremap(DMA3_BASE_ADDR, sizeof(struct s3c_dma_regs));
155
156	return 0;
157}
158
159static void s3c_dma_exit(void)
160{
161	iounmap(dma_regs);
162	class_device_destroy(cls, MKDEV(major, 0));
163	class_destroy(cls);
164	unregister_chrdev(major, "s3c_dma");
165	dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
166	dma_free_writecombine(NULL, BUF_SIZE, dst, dst_phys);
167	free_irq(IRQ_DMA3, 1);
168}
169
170module_init(s3c_dma_init);
171module_exit(s3c_dma_exit);
172
173MODULE_LICENSE("GPL");

基础的驱动程序,希望最近一个周抓紧搞完,做个项目练练手

madplay

问题描述:编译完成后,放到嵌入式板无法正常使用,这种没有错误的错误让人头痛,当然肯定是不如之前BootLoader的错误更让人头痛,昨天下午上网搜集了这个错误,都说只有两种可能,一种是根文件系统和当前工具编译版本环境不一样,另一种就是该路径没有在环境变量中,首先排除第二种,第一种也肯定是一样的,网上搜了那么多,开始怀疑自己的编译版本,查看了工具编译环境确实不一样

解决方案1:重新构建根文件系统,用新版本编译器编译安装,昨晚失败了,可能与当前内核版本编译有关,挂载不上文件系统

解决方案2:重新编译生成madplay,用低版本编译器编译,这个成功了,成功在板子上播放了告白气球就是破音了

疑问:当前内核版本2.6 编译器4.3.2 可是挂载不上一个编译环境下的根文件系统,倒是能挂载上3版本编译成功的根文件系统,当根文件系统和目前使用的工具是同一个编译器就可以

madplay install

1安装zlib

  • 解压
  • 执行export CC=arm-linux-gcc
  • 执行 export $CC 确认
  • 在解压目录下执行 ./configure --prefix=/home/book/bin_file/026_sound/tmp/
  • 最后执行 make && make install

2安装libid3tag

  • 解压
  • 执行./configure --host=arm-linux --prefix=/home/book/bin_file/026_sound/tmp/
  • 如果不行,执行./configure --host=arm-linux --prefix=/home/book/bin_file/026_sound/tmp/ CPPFLAGS=-I/home/book/bin_file/026_sound/tmp/include LDFLAGS=-L/home/book/bin_file/026_sound/tmp/lib
  • 最后执行 make && make install

3安装libmad

  • 解压
  • 执行./configure --host=arm-linux --prefix=/home/book/bin_file/026_sound/tmp/
  • 最后执行 make && make install

4安装madplay

  • 解压
  • 执行 ./configure --host=arm-linux --prefix=/home/book/bin_file/026_sound/tmp/ LDFLAGS="-L/home/book/bin_file/026_sound/tmp/lib" CFLAGS="-I /home/book/bin_file/026_sound/tmp/include"
  • 最后执行 make && make install

TEST

madplay.png

成功播放了告白气球

end

现在的生活状态还是挺好的,就是没个对象,略微不甜。今天身体太乏,不在状态,提不起兴致,每天搞的东西希望能把blog写的更好一些,简直就是流水账。

艾恩凝

写于大连

2021/7/9

catalogue

[Linux]驱动系列目录


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消