1:内核里
将一段DMA内存里的数据打印到/tmp/LogFile中,用hexdump打开这个文件就可以看到这段内存里的数据了。
DMA操作的是物理地址,往文件里写数据,需要的是数据的虚拟地址。还好,分配DMA内存的时候,已经将DMA内存的物理地址对应了虚拟地址。下面是分配的音频DMA buff,在播放音乐时,buff里的值是不停更新的。
int * tmp;
389 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
390 &buf->addr, GFP_KERNEL);
391 if (!buf->area)
392 return -ENOMEM;
393 tmp = buf->area;
通过下面方式,将tmp地址开始的,dma_size大小的数据块保存到/tmp/LogFile文件中。 用16进制的方法(hexdump) 打开这个文件,就可以看到数据块里的值了。
133 struct file *file=NULL;
134 mm_segment_t old_fs;
135
136 //file = filp_open("/tmp/LogFile", O_RDWR | O_APPEND | O_CREAT, 0644);
137 file = filp_open("/tmp/LogFile", O_RDWR | O_CREAT, 0644);
138 if (IS_ERR(file))
139 printk("filp_open error\n");
140 old_fs = get_fs();
141 set_fs(KERNEL_DS);
142 file->f_op->write(file, tmp, dma_size, &file->f_pos);
143 set_fs(old_fs);
144 filp_close(file, NULL);
2:应用层读取底层寄存器的值,将值保存到文件里。
在调试48K S24_3LE格式数据的播放时,为了对比SPDIF tx shift register里的值是不是原始的音频数据,需要将这个寄存器里的值打印出来和原始值进行对比,但是这个寄存器是一秒钟更新48k次,如果用printk或printf将其直接打印出来时不可能的。同样,需要将其保存到文件里。
用mmap的方式将这个寄存器的地址映射到应用层,应用层将这个地址里的值保存到文件里。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <sys/mman.h>
6
7 static int dev_fd;
8 static unsigned int map_base;
9 int main()
10 {
11 FILE *file;
12
13 dev_fd = open("/dev/mem", O_RDWR | O_NDELAY);
14 if (dev_fd < 0) {
15 printf("open /dev/mem error\n");
16 return -1;
17 }
18
19 map_base = (void *)mmap(0, 0x29d+0x800, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0xd80ed000);
注意:mmap中第一和最后一个参数相加是要mmap的起始寄存器地址,最后一个参数必须要是page_size(4k)的整数倍。我要mmap的寄存器起始地址是0xd80ed800,因为它不是4096的整数倍,而离0xd80ed800最近的4096整数倍值是0xd80ed000,所以我将最后一个值写成0xd80ed000,同时将第二个参数length改为0x29d+0x800。
20
21 file = fopen("/tmp/temp", "a+"); //a+的意思是写进去的新值紧接着原来的值,不覆盖。
22
23 while(1) {
24 fwrite(map_base + 0xc4 + 0x800, sizeof(0x12345678), 1, file);
//0xd80ed8c4这个寄存器是32bit的,所以用sizeof(0x12345678)也就是32bit,播放24bit数据时,32bit里面有8位是为0,也就是只有24bit有效。
25 }
26
27 fclose(file);
28
29 return 0;
30 }
下面代码主要是用来说明,int转字符型可以用sprintf,字符型转int型可以用atoi。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <sys/mman.h>
6
7 static int dev_fd;
8 static unsigned int map_base;
9 int main()
10 {
11 FILE *file;
12
13 char buffer[14];
14 int a;
15
16 dev_fd = open("/dev/mem", O_RDWR | O_NDELAY);
17 if (dev_fd < 0) {
18 printf("open /dev/mem error\n");
19 return -1;
20 }
21
22 map_base = (void *)mmap(0, 0x29d+0x800, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0xd80ed000);
23
24 file = fopen("/tmp/temp", "a+");
25 while(1) {
26 a = *(volatile unsigned int *)(map_base + 0xc4 + 0x800);
27 sprintf(buffer, "C4:%x,", a);
28 fwrite(&buffer, sizeof(buffer), 1, file);
29 }
30 fclose(file);
31
32 return 0;
33 }