linux驱动程序设计方案实例 .docx

上传人:C****o 文档编号:13057466 上传时间:2022-04-27 格式:DOCX 页数:22 大小:94.25KB
返回 下载 相关 举报
linux驱动程序设计方案实例 .docx_第1页
第1页 / 共22页
linux驱动程序设计方案实例 .docx_第2页
第2页 / 共22页
点击查看更多>>
资源描述

《linux驱动程序设计方案实例 .docx》由会员分享,可在线阅读,更多相关《linux驱动程序设计方案实例 .docx(22页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精品名师归纳总结封面可编辑资料 - - - 欢迎下载精品名师归纳总结作者: PanHongliang仅供个人学习AT91SAM9G20 驱动程序设计开发环境: Vmware + ubuntu10.04硬件平台: AT91SAM9G20可编辑资料 - - - 欢迎下载精品名师归纳总结Linux 版本: linux2.6.27一: led 驱动说明:由于设计的开发板上没有led 灯,便通过 PC0 来演示,通过示波器来观看引脚端的电平变化。1.驱动程序: my_led.c#include #include #include #include #include #include #include #

2、define MY_LED_MAJOR250/定义主设备号#define LED_ON0#define LED_OFF 1 struct global_devstruct cdev cdev。 。/定义设备结构体struct global_dev *global_devp 。/定义一个指向设备结构体的指针static int my_led_openstruct inode *inode, struct file *filpfilp-private_data = global_devp 。return 0。static int my_led_releasestruct inode *inode,

3、 struct file *filereturn 0。static int my_led_ioctlstruct inode *inode, struct file *filp, unsigned int cmd, unsigned long dataswitchcmdcase LED_ON:at91_set_gpio_valueA T91_PIN_PC0, 0 。/将 PC0 引脚置低break。case LED_OFF:at91_set_gpio_valueA T91_PIN_PC0, 1 。/将 PC1 引脚置高break。可编辑资料 - - - 欢迎下载精品名师归纳总结default:

4、printkno valid cmd input.n。break。可编辑资料 - - - 欢迎下载精品名师归纳总结return 0。struct file_operations my_led_ctl_ops =可编辑资料 - - - 欢迎下载精品名师归纳总结.owner = THIS_MODULE,.open = my_led_open,.release = my_led_release,.ioctl = my_led_ioctl, 。/* 初始化设备结构体 */static void my_led_setupstruct global_dev *dev, int indexint err 。

5、int devno = MKDEVMY_LED_MAJOR, index。cdev_init&dev-cdev, &my_led_ctl_ops。dev-cdev.owner = THIS_MODULE。dev-cdev.ops = &my_led_ctl_ops 。err = cdev_add&dev-cdev, devno, 1 。iferrprintkadd my led setup failed.n。static int my_led_initvoidint ret 。dev_t devno = MKDEVMY_LED_MAJOR, 0。 / 创建设备号printkmy first d

6、river-led.n。at91_set_GPIO_periphA T91_PIN_PC0, 1 。at91_set_gpio_outputA T91_PIN_PC0, 1 。/对 PC0 引脚的初始化ret = register_chrdev_regiondevno, 1, my_led。/申请设备号if ret cdev 。/删除设备kfreeglobal_devp 。/释放内存unregister_chrdev_regionMKDEVMY_LED_MAJOR, 0, 1。/释放设备号MODULE_LICENSEMYGPL。MODULE_AUTHORFANY。module_initmy_l

7、ed_init。 /注册设备module_exitmy_led_cleanup 。/卸载设备2:如何将驱动驱动程序编译成模块在 drivers 目录下新建 led 目录,并在该目录下添加 Kconfig ,可编辑资料 - - - 欢迎下载精品名师归纳总结Makefile 文件。Kconfig :Menu My driver support ConfigTrisate led driver. HelpLed driverEndmenu:Makefile :Obj-$CONFIG_MY_LED+= my_led.o修改 linux/drivers 目录下的 Kconfig , Makefile 文

8、件Kconfig:Source drivers/led/Kconfig Makefile:Obj-y+= my_led/修改体系结构目录 arch/arm 目录下的 Kconfig 文件,否就在配置菜单中将无法看到 led 的配置选项。(假如是在 drivers 目录下新建一文件夹,并在其中添加驱动程序,必需相应的体系结构目录下添加配置选项)。Kconfig:Source driver/led/Kconfig3.测试程序: my_led_test.c#include #include #include #include #include #define DEVICE_NAME /dev/my_

9、led #define LED_ON0#define LED_OFF1int mainvoidint fd 。int ret 。int i 。printfmy_led_driver test.n 。fd = openDEVICE_NAME, O_RDONLY 。iffd = -1printfopen device %s error.n, DEVICE_NAME。fori = 0 。 i 50 。 i+可编辑资料 - - - 欢迎下载精品名师归纳总结ioctlfd, LED_OFF 。sleep1。ioctlfd, LED_ON 。sleep1。ret = closefd 。printfret

10、= %dn, ret 。printfclose my_led_driver.n。return 0。将测试程序编译成目标平台的可执行文件,并下载到开发板GCC=/home/zzq/9G20/arm-2007q1/bin/arm-none-linux-gnueabi-gcc # 交叉编译器的路径My_led_test:my_led_test.c$GCC -o my_led_test my_led_test.c clean:rm -f my_led_test学习总结:熟识驱动程序的架构,如何将驱动程序添加到内核即如何写测试程序。二:按键驱动设计1. 硬件部分: PC4 接按键。2. 驱动程序:#in

11、clude #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUTTON_MAJOR245#define DEVICE_NAME/dev/button static volatile int ev_press = 0 。static struct cdev button_cdev。static void button_do_

12、taskletunsigned long n 。可编辑资料 - - - 欢迎下载精品名师归纳总结DECLARE_TASKLETbutton_tasklet, button_do_tasklet, 0。/定义 tasklet 并与处理函数关联起来static DECLARE_WAIT_QUEUE_HEADbutton_waitq。/ 静态的初始化一个等待队列struct button_irq_desc int irq 。int irq_type 。int pin 。int number。char *name。 。staticstructbutton_irq_descbutton_irq1=A T

13、91_PIN_PB22,AT91_AIC_SRCTYPE_LOW,AT91_PIN_PB22, 0, KEY0 。static int key_values1=0。/中断处理底半部static void button_do_taskletunsigned long nwake_up_interruptible&button_waitq。/唤醒队列printkbutton press.n 。/中断处理顶半部static irqreturn_t button_interruptint irq, void *dev_id, struct pt_regs *regsint up 。static int

14、 press_down。up = gpio_get_valuebutton_irq0.pin 。printkirqn 。/* 按键消抖 */ifuppress_down = 1。 /当按键没有按下 ,置标志位为 1. if.up & press_down = 1 press_down = 0。 / 当按键按下 ,置标志位为 0. ev_press = 1。at91_set_gpio_valuebutton_irq0.pin, 1 。key_valuesbutton_irq0.number = .up 。tasklet_schedule&button_tasklet 。return IRQ_RE

15、TV ALIRQ_HANDLED。static int button_openstruct inode *inode, struct file *filpreturn 0。static int button_releasestruct inode *inode, struct file *filpreturn 0。static int button_readstruct file *filp, charuser *buff, size_t count, loff_t *offpint ret 。if.ev_press /当按键没有按下时,读进程挂起,知道按键按下。wait_event_inte

16、rruptiblebutton_waitq, ev_press 。ev_press = 0。ret = copy_to_userbuff, const void *key_values, minsizeofkey_values, count。可编辑资料 - - - 欢迎下载精品名师归纳总结memsetvoiduser *key_values, 0, sizeofkey_values 。return ret . -EFAULT:minsizeofkey_values, count 。static struct file_operations button_fops = .owner = THIS

17、_MODULE,.open = button_open,.release = button_release,.read = button_read, 。static int irq_initvoidint err 。at91_set_gpio_inputbutton_irq0.pin, 1 。at91_set_deglitchbutton_irq0.pin, 1 。/ 将 PC0 设置为中断功能set_irq_typebutton_irq0.irq, button_irq0.irq_type。/设置中断类型at91_set_gpio_valuebutton_irq0.pin, 1 。err =

18、 request_irq button_irq0.irq, button_interrupt, IRQF_DISABLED, button_irq0.name, void *&button_irq0。/申请中断可编辑资料 - - - 欢迎下载精品名师归纳总结if err disable_irqbutton_irq0.irq 。free_irqbutton_irq0.irq, void *&button_irq0。return -EBUSY 。可编辑资料 - - - 欢迎下载精品名师归纳总结return 0。static intinit button_initvoidint ret, err 。

19、ret = register_chrdev_regionMKDEVBUTTON_MAJOR, 0, 1, DEVICE_NAME。ifret 0 printkbutton init failed with %dn, ret。return ret 。cdev_init&button_cdev, &button_fops 。button_cdev.owner = THIS_MODULE 。button_cdev.ops = &button_fops 。err = cdev_add&button_cdev, MKDEVBUTTON_MAJOR, 0, 1。if err0 printkkey add

20、failedn 。return err。irq_init 。printkkey driver add success.n 。return 0。static voidexit button_exitvoidcdev_del&button_cdev 。unregister_chrdev_regionMKDEVBUTTON_MAJOR, 0, 1。disable_irqbutton_irq0.irq 。free_irqbutton_irq0.irq, void *&button_irq0。printkunregister key driver.n。可编辑资料 - - - 欢迎下载精品名师归纳总结mo

21、dule_initbutton_init 。module_exitbutton_exit 。MODULE_AUTHORfany。MODULE_DESCRIPTIONAtmel9g20 key Driver。MODULE_LICENSEGPL。3. 测试程序:#include #include #include #include #include #include #define DEVICE_NAME /dev/button int mainvoidint fd,i 。int ret 。int key_value1 。printfkey test.n 。fd = openDEVICE_NAME

22、, O_RDWR。iffd 0可编辑资料 - - - 欢迎下载精品名师归纳总结else while1 printfopen device %s error.n, DEVICE_NAME。printfopen device success.n 。ret = readfd, key_value, 1 。if .ret 可编辑资料 - - - 欢迎下载精品名师归纳总结elseprintfbutton not press.n 。printfbutton press.n 。可编辑资料 - - - 欢迎下载精品名师归纳总结printfkey_value %dn, key_value 。closefd。pr

23、intfclose key driver.n。return 0。4. 学习总结:在 linux 设备驱动程序中,中断处理程序通常分为两部分:上半部和下半部。上半部处理比较紧急的的硬件操作,比如简洁的读取寄存器中的状态并清除中断标志后,进行登记中断的工作。剩下的工作就由下半部来实现。对堵塞与非堵塞进程的懂得,堵塞:在执行设备操作时,如不能可编辑资料 - - - 欢迎下载精品名师归纳总结猎取设备资源就挂起,直到中意可操作的条件后再进行操作。非堵塞操作:在执行设备操作时,如不能猎取设备资源就马上返回。 三:总线驱动AT91SAM9G20 储备器映射图 截取部分 ,片选 4 接外设,利用总线对外设进行

24、拜望。但是在 linux 驱动,不能对物理的址进行操作,可通过内存拜望的机制实现对物理的址的拜望。将一段物理的址空间映射到虚拟的 址空间中,然后对虚拟的址的操作即是对物理的址的操作。3.1 :总线驱动#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include atmel9g20_liu.h struct gr_liu_info void iomem *virtbase

25、。void iomem *regbase。struct resource *res。u32 flags。 。static struct gr_liu_info liu_info 。static struct cdev atmel9g20_liu_cdev 。unsigned short liu_readunsigned addraddr &= A TMEL9G20_LIU_MASK。addr = addr 1 。可编辑资料 - - - 欢迎下载精品名师归纳总结addr += unsigned longliu_info.regbase 。printkread the virtual addr i

26、s 0x%xn, addr 。return readwaddr & 0xff 。 /读 IO 内存。EXPORT_SYMBOLliu_read。int liu_writeunsigned addr, unsigned valaddr &= A TMEL9G20_LIU_MASK。addr = addr num_resources .= 1 ret = -ENODEV 。goto err1。/IO 内存的申请liu_info.res=request_mem_regionpdev-resource0.start,pdev-resource0.end-pdev-resource0.start + 1

27、, 9g20-liu 。if .liu_info.res printkliu: cant get request mem region 。ret = -ENOMEM 。goto err1。/IO 内存的映射可编辑资料 - - - 欢迎下载精品名师归纳总结1。liu_info.regbase = ioremappdev-resource0.start, pdev-resource0.end - pdev-resource0.start +printkrequest virtual addr liu_info.regbase=0x%xn,unsigned intliu_info.regbase。i

28、f liu_info.regbase = NULL printkliu: cant get ioremap memn 。ret = -ENOMEM 。goto err2。可编辑资料 - - - 欢迎下载精品名师归纳总结dev_set_drvdata&pdev-dev, &liu_info。printkLIU probe done.n。return 0。err2:release_mem_regionpdev-resource0.start, pdev-resource0.end - pdev-resource0.start + 1 。err1:return ret 。static int liu

29、_removestruct platform_device *pdev可编辑资料 - - - 欢迎下载精品名师归纳总结释放内存struct gr_liu_info *fi 。fi = pdev-dev.driver_data 。iounmapfi-regbase 。/解除映射,release_mem_regionpdev-resource0.start, pdev-resource0.end - pdev-resource0.start + 1。/fi-flags = 0x0 。return 0。可编辑资料 - - - 欢迎下载精品名师归纳总结static struct platform_dr

30、iver liu_driver = .probe = liu_probe,.remove = liu_remove,.driver = .name = 9g20-liu,.owner = THIS_MODULE, 。/设置 SMC 寄存器static void cs4_initvoid可编辑资料 - - - 欢迎下载精品名师归纳总结at91_sys_writeAT91_MA TRIX_EBICSA,at91_sys_readAT91_MATRIX_EBICSA| AT91_MA TRIX_CS4A_SMC 。/* Configure SMC CS4 */ at91_sys_writeAT91_

31、SMC_SETUP4,AT91_SMC_NWESETUP_2 | AT91_SMC_NCS_WRSETUP_2 | AT91_SMC_NRDSETUP_2 | AT91_SMC_NCS_RDSETUP_2。at91_sys_writeAT91_SMC_PULSE4,AT91_SMC_NWEPULSE_12 | AT91_SMC_NCS_WRPULSE_10 | AT91_SMC_NRDPULSE_12 | AT91_SMC_NCS_RDPULSE_10。at91_sys_writeAT91_SMC_CYCLE4,AT91_SMC_NWECYCLE_16 | AT91_SMC_NRDCYCLE_

32、16。at91_sys_writeAT91_SMC_MODE4,AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_DBW_16 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_3。at91_sys_writeAT91_PMC_PCER, 1 A T91SAM9260_ID_PIOC 。/* Enable CS4 */at91_set_A_periphA T91_PIN_PC8, 1 。printk*at91sam9g20ek_ebibus_cs4_init*n。static intinit atmel9g2

33、0_liu_initvoidint ret,err 。ret = register_chrdev_regionMKDEVLIU_MAJOR, 0, 1, /dev/liu。if ret 0 printkLIU init_module failed with %dn, ret。return ret 。cdev_init&atmel9g20_liu_cdev, &atmel9g20_liu_fops。atmel9g20_liu_cdev.owner = THIS_MODULE。atmel9g20_liu_cdev.ops = &atmel9g20_liu_fops 。err = cdev_add&

34、atmel9g20_liu_cdev, MKDEVLIU_MAJOR, 0, 1。if err0 printkliu add failedn 。return err。cs4_init 。return platform_driver_register&liu_driver。/注册平台设备。static voidexit atmel9g20_liu_cleanupvoidprintkatmel 9g20 liu exitn。cdev_del&atmel9g20_liu_cdev 。unregister_chrdev_regionMKDEVLIU_MAJOR, 0, 1。platform_driver_unregister&liu_driver。modu

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁