博文

目前显示的是标签为“iomap”的博文

PC蜂鸣器音乐

有了“使用procfs”、“I/O映射之I/O端口”、“内核读写磁盘文件”这三篇文章的基础后,我们将其结合,实现如下功能的实例: 1.打开传入的音乐谱文件(通过procfs接口); 2.读取音乐谱文件(以“频率”、“延时”、“频率”、“延时”、……这样的格式保存); 3.解析读取的文件; 4.将解析的数据传送去操作8254,让PC蜂鸣器弹奏文件对应的音乐。 好了,基础的内容看开头提及的文章,接下来上代码: #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <asm/uaccess.h> #include <linux/timex.h> #ifndef MAX_PATH #define MAX_PATH 256 #endif #define PACKAGE_SIZE 512 extern void msleep(unsigned int msecs); struct proc_dir_entry * slam_dir = NULL; struct proc_dir_entry * slam_entry = NULL; static char * dir_name = "slam_song"; static char * entry_name = "path"; static void beep(unsigned int freq, unsigned int delay) { unsigned int count; if (freq) count = PIT_TICK_RATE / freq; else count = 20; outb_p(0xB6, 0x43); outb_p(count & 0xff, 0x42); outb((count >> 8) & 0xff, 0x42); ...

I/O映射之I/O端口

图片
对于外设,操作系统会采用端口映射和内存映射两种方式来对其进行控制,其中端口映射就是操作系统规定好一段地址给指定换上设,其与外设的寄存器按顺序一一对应上。 在Linux内核源码include/asm-generic/io.h头文件里有如下我们对I/O port进行操作的函数: static inline u8 inb(unsigned long addr) { return readb(addr + PCI_IOBASE); } static inline u16 inw(unsigned long addr) { return readw(addr + PCI_IOBASE); } static inline u32 inl(unsigned long addr) { return readl(addr + PCI_IOBASE); } static inline void outb(u8 b, unsigned long addr) { writeb(b, addr + PCI_IOBASE); } static inline void outw(u16 b, unsigned long addr) { writew(b, addr + PCI_IOBASE); } static inline void outl(u32 b, unsigned long addr) { writel(b, addr + PCI_IOBASE); } #define inb_p(addr) inb(addr) #define inw_p(addr) inw(addr) #define inl_p(addr) inl(addr) #define outb_p(x, addr) outb((x), (addr)) #define outw_p(x, addr) outw((x), (addr)) #define outl_p(x, addr) outl((x), (addr)) 分别对应对端口进行读取或写入字节、字、双字大小数据的操作。 该头文件中还有其他的操作函数及宏定义,请自行深入了解。 我们可通过读取/proc/ioports文件来了解Linux里I/O端口的映射...