[Linux]DMA驱动&&madplay安装
[Linux]DMA驱动&&madplay安装
艾恩凝
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
成功播放了告白气球
end
现在的生活状态还是挺好的,就是没个对象,略微不甜。今天身体太乏,不在状态,提不起兴致,每天搞的东西希望能把blog写的更好一些,简直就是流水账。
艾恩凝
写于大连
2021/7/9
catalogue
[Linux]驱动系列目录
![个人公众号](https://pic.aeneag.xyz/qrcode_for_gh_6991d24e23e2_344-91ebc4df.jpg)
![个人微信](https://pic.aeneag.xyz/WechatIMG91-dc5e5be8.jpeg)
则移山填海之难,
终有成功之日!
——孙文
![](https://ftp.stackoverflow.wiki/bolo/background/butterfly/comment.png)