S3C2440内核蜂鸣器驱动解读

发布者:WhisperingWaves最新更新时间:2024-08-21 来源: cnblogs关键字:S3C2440  内核  蜂鸣器驱动 手机看文章 扫描二维码
随时随地手机看文章

首先介绍需要的一些头文件的位置


linux-2.6.32.内核重要文件目录:

linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/regs-gpio.h

linux-2.6.32.2/arch/arm/plat-s3c24xx/gpio.c

linux-2.6.32.2/linux/asm-generic/io.h

linux-2.6.32.2/include/linux/wait.h

asm -- linux-2.6.32.2/linux/asm-generic

mach -- linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach

plat -- linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat

-- linux-2.6.32.2/arch/arm/plat/include/plat


1、2440蜂鸣器内核驱动

展示内核驱动


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#include

#include

#include

#include

#include

 

#include

#include


static int beep_major = 0;

module_param(beep_major, int, 0);//传参函数,并在模块目录下会生成parameter目录及参数文件

/*

MODULE_AUTHOR ( 声明谁编写了模块 ),

MODULE_DESCRIPION( 一个人可读的关于模块做什么的声明 ),

MODULE_VERSION ( 一个代码修订版本号; 看 的注释以便知道创建版本字串使用的惯例),

MODULE_ALIAS ( 模块为人所知的另一个名字 ), 以及 MODULE_DEVICE_TABLE ( 来告知用户空间, 模块支持那些设备 ). 

MODULE_LICENSE(“GPL”);

内核认识的特定许可有, “GPL”( 适用 GNU 通用公共许可的任何版本 ), “GPL v2”( 只适用 GPL 版本 2 ), “GPL and additional rights”, “Dual BSD/GPL”, “Dual MPL/GPL”, 和 “Proprietary”. 除非你的模块明确标识是在内核认识的一个自由许可下, 否则就假定它是私有的

*/

MODULE_AUTHOR('All');

MODULE_LICENSE('Dual BSD/GPL');


#define BEEP_MAGIC 'b'

#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)//使用内核函数库提供的_IO函数,最后参考文献详细查看

#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)


/*

 * Open the device; in fact, there's nothing to do here.

 */

int beep_open (struct inode *inode, struct file *filp)

{

return 0;

}


ssize_t beep_read(struct file *file, char __user *buff, size_t count, loff_t *offp)

{

return 0;

}


ssize_t beep_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)

{

return 0;

}

//一般像read、write一般这些函数不会写什么内容,open有时候会放入初始化函数


/*

使用s3c2410_gpio_cfgpin函数初始化端口,设置为输出,s3c2410_gpio_setpin设置端口输出高低电压,对着开发手册进行设置自己所需要的输出电压。s3c2410_gpio_pullup控制上拉电阻

*/

void beep_stop( void )

{

//set GPB0 as output

s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);

s3c2410_gpio_setpin(S3C2410_GPB(0),0);

}


void beep_start( void )

{

//set GPB0 as output

s3c2410_gpio_pullup(S3C2410_GPB(0),1);

s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);

s3c2410_gpio_setpin(S3C2410_GPB(0),1);

}


/*函数调用,使用ioctl可以通过不同的cmd数,选择所调用的内核函数*/

static int beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

//add your src HERE!!!

switch ( cmd ) {

case BEEP_START_CMD: {

beep_start(); break;

}

case BEEP_STOP_CMD: {

beep_stop(); break;

}

default: {

break;

}

}

return 0;


}


static int beep_release(struct inode *node, struct file *file)

{

return 0;

}


/*

 * Set up the cdev structure for a device.

 */

static void beep_setup_cdev(struct cdev *dev, int minor,

struct file_operations *fops)

{

int err, devno = MKDEV(beep_major, minor);

    

cdev_init(dev, fops);

    //注册设备,或者应该说是初始化

dev->owner = THIS_MODULE;

dev->ops = fops;

err = cdev_add (dev, devno, 1);

    //向内核添加设备失败,linux-2.6之后使用者两个函数进行注册和添加

if (err)

printk (KERN_NOTICE 'Error %d adding beep%d', err, minor);

}


 /*

 file_operations结构体

 Linux使用file_operations结构访问驱动程序的函数,这个结构的每一个成员的名字都对应着一个函数调用。

  用户进程利用在对设备文件进行诸如read/write操作的时候,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数,这是Linux的设备驱动程序工作的基本原理。

  struct module *owner

  第一个 file_operations 成员根本不是一个操作,它是一个指向拥有这个结构的模块的指针。这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏.这个宏比较复杂,在进行简单学习操作的时候,一般初始化为THIS_MODULE。

https://blog.csdn.net/zqixiao_09/article/details/50850475

*/

static struct file_operations beep_remap_ops = {

.owner   = THIS_MODULE,

.open    = beep_open,

.release = beep_release,

.read    = beep_read,

.write   = beep_write,

.ioctl   = beep_ioctl,

};


/*

 * There's no need for us to maintain any

 * special housekeeping info, so we just deal with raw cdevs.

 */

static struct cdev BeepDevs;


/*

 * Module housekeeping.

 */

/*beep_init函数主要用于获取设备号,用于内核识别*/

static int beep_init(void)

{

int result;

dev_t dev = MKDEV(beep_major, 0);

    //格式转换,beep_major是主设备号,这里是靠调用驱动时的传参,默认为0 

char dev_name[]='beep';


/* Figure out our device number. */

if (beep_major)

result = register_chrdev_region(dev, 1, dev_name);

    //手动分配注册设备号,如果之前没有分配设备号,beep_major为0因此调用动态分配设备号进行注册,但是内核分配后beep_major不为0,就会调用该函数,也就是说知道主设备号才来使用该函数

else {

result = alloc_chrdev_region(&dev, 0, 1, dev_name);

beep_major = MAJOR(dev);

    //动态分配注册设备号,并更新主设备号,详细查看https://blog.csdn.net/welbell_uplooking/article/details/83654312

}

if (result < 0) {

printk(KERN_WARNING 'beep: unable to get major %dn', beep_major);

return result;

}

if (beep_major == 0)

beep_major = result;


/* Now set up cdev. */

beep_setup_cdev(&BeepDevs, 0, &beep_remap_ops);

printk('beep device installed, with major %dn', beep_major);

printk('The device name is: %sn', dev_name);

return 0;

}



static void beep_cleanup(void)

{

cdev_del(&BeepDevs);

    //注销设备,删除一个cdev

unregister_chrdev_region(MKDEV(beep_major, 0), 1);

    //释放注销的所占用的设备号

printk('beep device uninstalledn');

}



module_init(beep_init);

module_exit(beep_cleanup);

//驱动加载系统传参

EXPORT_SYMBOL(beep_major);



加载驱动模块


insmod beep_dev.ko


创建dev下面beep设备文件与我们的beep_dev驱动绑定


mknod /dev/beep c 251 0


原命令形式:mknod /dev/node_name c major minor


只有创建了beep文件用户才能通过open之类的操作访问或者调用内核驱动函数


2、2440蜂鸣器用户函数

其次是蜂鸣器内核外的应用层函数


#include

#include

#include

#include

#include


#define BEEP_MAGIC 'b'

#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)

#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)




int main()

{

int i = 0;

int dev_fd;

dev_fd = open('/dev/beep',O_RDWR | O_NONBLOCK);

if ( dev_fd == -1 ) {

printf('Cann't open file /dev/beepn');

exit(1);

}

printf('Start beepn');

ioctl (dev_fd, BEEP_START_CMD,0);

getchar();

ioctl (dev_fd, BEEP_STOP_CMD,0);

printf('Stop beep and Close devicen');

close(dev_fd);

return 0;

}



关系大概如下:

image-20230613190752929


关键字:S3C2440  内核  蜂鸣器驱动 引用地址:S3C2440内核蜂鸣器驱动解读

上一篇:TQ2440--nandflash(K9F2G08U0A)驱动编写
下一篇:S3C2440 SPI驱动框架

推荐阅读最新更新时间:2024-11-17 03:00

s3c2440为例讲解arm芯片的启动过程
arm 嵌入式芯片的启动过程对于嵌入式菜鸟来说其实是很复杂的,很多人都是一知半解,存在很多误区。在笔者看来,要想真正了解这一启动过程必须要首先了解存储器的区别与联系,参考文章:各种主流半导体存储器的区别与联系。还需要了解程序是如何编译链接和执行的。 本文将以s3c2440为例详细讲述 arm 芯片的启动过程。s3c2440支持两种启动模式:NAND FLASH 启动和非 NAND FLASH 启动(一般是NOR FLASH 启动,并且可以配置数据宽度),通过 OM1、OM0 两个管脚来控制。 NAND FLASH启动过程 当 OM1、OM0 两个管脚都为低电平时,CPU 就被配置成了 NAND FLASH 启动。此时 CP
[单片机]
以<font color='red'>s3c2440</font>为例讲解arm芯片的启动过程
S3C2440裸机实战 之一 创建初始工程
好几年没玩S3C2440,从单片机玩到嵌入式,就记得这个是我入门嵌入式比较早的一款芯片。 S3C2440是带MMU的,可以上WinCE/Linux这些操作系统,适合做嵌入式开发,做单片机开发的话,总感觉有点浪费,但如果只是玩玩应该没问题。 最近业余时间想把S3C2440拿来当单片机玩玩。 废话少说,直接入主题。 第一步当然是创建初始工程。 既然是裸机实战,想玩点什么特色,看来汇编是不能少的了。ARM9汇编支持的好一点的当然是MDK,IAR的汇编语法和ARM官方的有一些区别,还是算了。 gcc 语法和ARM官方是差不多,不过编译出来的代码质量比不过MDK。这里就选用MDK5.1 单片机的helloworl
[单片机]
05-S3C2440学习之内核(移植)linux3.4.2移植(2) yffs2文件系统移植+内核裁剪+内核制作补丁
一、移植YFFS2文件系统 yffs文件系统更加支持nand设备 上节移植了jffs2文件系统(点击查看)到移植的内核中,这节我们将yffs2文件系统移植到刚移植好的内核中。 (1)获取源码并解压 git clone git://www.aleph1.co.uk/yaffs2 tar xjf yaffs2.tar.bz2 (2)给内核打上yffs2补丁 ./patch-ker.sh c m /home/book/linux-3.4.2 (3) 配置内核支持YAFFS 1. ls fs/yaffs2 (4)编译、生成uImage 出错,制作yffs2 source工程. (
[单片机]
05-S3C2440学习之<font color='red'>内核</font>(移植)linux3.4.2移植(2) yffs2文件系统移植+<font color='red'>内核</font>裁剪+<font color='red'>内核</font>制作补丁
WinCE内核裁减(中文字体)及字库和内核的分离(转)
每次定制中文系统时,NK总是比英文大10M左右,启动时在bootloader中将内核Copy到内存时也花时间,同时也占用了很多内存,留给系统和应用的内存就少了10M左右,真是浪费呀,看到都心痛!本人研究了一下,同时也参考了网上的资料,现总结如下,如何减少中文字库大小和将字库放到外部存贮器上。核心思想是将默认选择的中文字体SimSun & NSimSun (SYSGEN_FONTS_SIMSUN)替换成SimSun & NSimSun (Subset 2_50) (SYSGEN_FONTS_SIMSUN_2_50)达到体积的缩小。在注册表中 和 改变字库simsun.ac3或simsun.ttc的存贮位置。 一、减少中文字库大小
[嵌入式]
S3C2440 OpenJtag
C:UsersAdministratorDesktop oflash.exe leds.bin +---------------------------------------------------------+ | Flash Programmer v1.5.4 for OpenJTAG of www.100ask.net | | OpenJTAG is a USB to JTAG & RS232 tool based FT2232 | | This programmer supports both of S3C24X0 & S3C6410 | | Author: Email/MSN(thisway.diy@1
[单片机]
I2S音频总线学习(三)S3C2440的I2S控制器
一、I2S控制器结构框图 S3C2440A的Inter-IC Sound (IIS)总线接口作为一个编解码接口连接外部8/16位立体声音频解码IC用于迷你碟机和可携式应用。IIS总线接口支持IIS总线数据格式和MSB-justified数据格式。该接口对FIFO的访问采用了DMA模式取代了中断。它可以在同一时间接收和发送数据。 图1 结构框图 总线接口,寄存器组和状态机(BRFC):总线接口逻辑和FIFO 访问由状态机控制。 5 位双预定标器(IPSR):一个预定标器用于IIS 总线接口的主时钟发生器,另外一个用作外部编解码时钟发生器。 64 位FIFO(TxFIFO 和RxFIFO):在发送数据传输时,数据写到T
[单片机]
S3C2440-中断体系架构
1.ARM的体系与架构 1.1.ARM体系的CPU有以下其中工作模式: 用户模式 (usr) 快速中断模式 (fiq) 中断模式 (irq) 管理模式 (svc) 数据访问终止模式 (abt) 系统模式 (sys) 未定义指令终止模式 (und) 1.2.ARM寄存器: 31个通用寄存器 : R0~R7(未备份寄存器) , R8~R14(备份寄存器) , R15( 程序计数器PC ) 6个状态寄存器 : CPSR( 当前程序状态寄存器) , SPSR(备份程序状态寄存器) 2.ARM状态下当异常发生时, 处理器将切换进相应的模式: 2.1. 当异常发生时, 处理器将自动完成以
[单片机]
S3C2440-中断体系架构
Linux内核异常处理体系结构详解(一)
【首先来区分一下两个概念:中断(Interrupt)和异常(Exception)。中断属于异常的一种,就拿2440开发板来说,他有60多种中断源,例如来自DMA控制器、UART、IIC和外部中断等。2440有一个专门的中断控制器来处理这些中断,中断控制器在接收到这些中断信号之后就需要ARM920T进入IRQ或FIQ模式进行处理,这两种模式也是中断异常的仅有模式。而异常的概念要广的多,它包括复位、未定义指令、软中断、IRQ等等。还有一点知识就是,中断这种异常在响应之前到来之前是需要程序员进行什么优先级、是否要屏蔽信号之类的初始化的,而其他比如未定义指令是不用的,只要发生了就跳到异常向量入口取址执行。因此下面初始化内容中的第(2)点是
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved