嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx

上传人:b****7 文档编号:22703754 上传时间:2023-02-05 格式:DOCX 页数:17 大小:19.16KB
下载 相关 举报
嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx_第1页
第1页 / 共17页
嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx_第2页
第2页 / 共17页
嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx_第3页
第3页 / 共17页
嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx_第4页
第4页 / 共17页
嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx

《嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。

嵌入式Linux下LED报警灯驱动设计及编程Word文档格式.docx

LED6-------GPM5

LED7-------GPQ0

LED8-------GPQ1

得出结论:

8个LED灯使用到的硬件控制器分别为GPM和GPQ两个硬件控制器

(2)在芯片手册中找到相应的硬件控制器部分,重心是看懂端口寄存器

本实验要求完成LED流水灯设计,所以需要设置控制器中端口寄存器:

GPMCON----设置相应位为输出口

GPMDAT-----控制相应位输出高电平-----点亮LED灯

输出低电平-----熄灭LED灯

(3)linux内核中相关寄存器读写函数

读寄存器函数

readl(寄存器虚地址);

写寄存器函数

writel(值(无符号整型),寄存器虚地址);

具体端口寄存器地址宏定义在/opt/FriendlyARM/linux-2.6.38/arch/arm/mach-s3c64xx/include/mach文件夹下的文件中,如端口M寄存器在gpio-bank-m.h文件中有定义:

#defineS3C64XX_GPMCON(S3C64XX_GPM_BASE+0x00)

#defineS3C64XX_GPMDAT(S3C64XX_GPM_BASE+0x04)

5.2LED报警灯驱动设计s3c6410_leddrv.c

(1)头文件包含和相关宏定义

#include<

linux/miscdevice.h>

linux/delay.h>

asm/irq.h>

//#include<

mach/regs-gpio.h>

mach/hardware.h>

linux/kernel.h>

linux/module.h>

linux/init.h>

linux/mm.h>

linux/fs.h>

linux/types.h>

linux/moduleparam.h>

linux/slab.h>

linux/errno.h>

linux/ioctl.h>

linux/cdev.h>

linux/string.h>

linux/list.h>

linux/pci.h>

asm/uaccess.h>

asm/atomic.h>

asm/unistd.h>

mach/map.h>

mach/regs-clock.h>

plat/gpio-cfg.h>

mach/gpio-bank-e.h>

mach/gpio-bank-k.h>

#defineON1

#defineOFF0

(2)编写驱动接口函数

/*

功能:

配置GPM0~5/GPQ0~1为输出口

参数:

返回值:

*/

voidLedConfig(void)

{

//读出端口M控制寄存器(S3C64XX_GPMCON)值,修改并写回相关端口寄存器

//addyourcode

unsignedinttmp;

tmp=readl(S3C64XX_GPMCON);

tmp&

=~((0XF<

<

0X0)|(0XF<

0X4)|(0XF<

0X8)|(0XF<

0XC)|(0XF<

0X10)|(0XF<

0X14));

tmp|=(0X1<

0X0)|(0X1<

0X4)|(0X1<

0X8)|(0X1<

0XC)|(0X1<

0X10)|(0X1<

0X14);

writel(tmp,S3C64XX_GPMCON);

}

/*

点亮第i个LED灯

无符号整型变量iLed,表示第i个LED灯

voidiLedOn(unsignedintiLed)

//读出端口M数据寄存器(S3C64XX_GPKDAT)值,修改并写回相关端口寄存器

//addyourcodehere

tmp=readl(S3C64XX_GPMDAT);

=~((0X1<

0X1)|(0X1<

0X2)|(0X1<

0X3)|(0X1<

0X5));

writel(tmp,S3C64XX_GPMDAT);

}

熄灭第i个LED灯

voidiLedOff(unsignedintiLed)

0X5);

(2)和文件系统接口对接

staticints3c6410_led_open(structinode*inode,structfile*filp)

{

//把之前的端口K控制寄存器值读出来保存起来

//调用LedConfig函数,把GPIO口配置成输出口

//addyourcode

old_gpmcon_val=readl(S3C64XX_GPMCON);

LedConfig();

renturn0;

}

staticints3c6410_led_release(structinode*inode,structfile*filp)

//恢复之前的端口K控制寄存器初始值

writel(old_gpmcon_val,S3C64XX_GPMCON);

renturn0;

staticlongs3c6410_led_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg)

switch(cmd)

caseON:

//点亮所有LED灯

//addyourcode

iLedOn();

break;

caseOFF:

//熄灭所有LED灯

iLedOff();

structfile_operationsled_fops=

.open=___s3c6410_led_open______,

.release=___s3c6410_led_release______,

.unlocked_ioctl=___s3c6410_led_ioctl____,

};

(3)添加模块标记代码

staticint__initled_dev_init(void)

intret;

ret=_____register_chrdev(0,"

leddev"

&

led_fops)_____________;

//注册设备

printk(DEVICE_NAME"

\tinitialized\n"

);

returnret;

staticvoid__exitled_dev_exit(void)

//注销设备

____unregister_chrdev(leddevNo,"

)_;

__________________

module_init(led_dev_init);

module_exit(led_dev_exit);

MODULE_LICENSE("

GPL"

MODULE_AUTHOR("

lic@njupt."

5.2编写Makefile并加载到内核

(1)编写Makefile如下:

obj-m:

=_______leddrv.o____________________

all:

make–C_/opt/FriendlyARM/linux-2.6.38_SUBDIRS=$(shellpwd)modules

clean:

rm-rf*.ko*.o

(3)编译

使用命令编译:

_____#make_____________________________

编译完成后生成驱动文件_____leddrv.ko__________________。

(3)加载驱动

使用命令进行驱动加载____#insmodleddrv.ko___________________。

(4)创建设备文件,将驱动设备号和设备文件名关联

相关命令为:

_____#mknod/dev/leddevc2530___________________________。

5.3编写应用程序

任务:

要求每5秒点亮所有的LED灯,然后熄灭,过5秒再点亮LED灯

stdio.h>

sys/types.h>

sys/stat.h>

fcntl.h>

sys/ioctl.h>

voidmain()

fd=open(___”/dev/leddev”___,O_RDWR);

if(fd<

0)

exit

(1);

while

(1)

//点亮LED灯

ioctl(fd,ON);

sleep(5);

//熄灭LED灯

__ioctl(fd,OFF);

_____

close(fd);

5.4按照现在的驱动设计,假设要完成LED跑马灯实验,请问是否可行___B___[A.可行B.不可行]。

如果不可行的话,应该怎样改造驱动代码和应用程序。

驱动代码修改部分:

应用程序修改部分:

六.实验5.2步骤

6.1实验预备知识

(1)相关硬件

看门狗硬件主要用于监控系统软件或者应用软件是否发生故障,如发生故障则可以通过发出硬件复位信号,使得系统能够重启,如果再配合相关自动加载应用程序等措施,则可以保证应用程序在发生故障后能够自恢复和重启。

看门狗硬件由看门狗控制器组成,位于S3C6410处理器内部,无须处理器外其它硬件配合,因此仅需直接编程端口寄存器,并封装成文件系统接口即可。

(2)端口寄存器及相关操作

在内核代码文件中已经定义好看门狗相关端口寄存器对应的虚地址,见/opt/FriendlyARM/linux-2.6.38/arch/arm/plat-samsung/include/plat/regs-watchdog.h,如下:

#defineS3C2410_WTCONS3C_WDOGREG(0x00)

#defineS3C2410_WTDATS3C_WDOGREG(0x04)

#defineS3C2410_WTCNTS3C_WDOGREG(0x08)

6.2看门狗驱动代码(s3c6410_wdtdrv.c)设计

(1)头文件包含和相关宏定义

linux/timer.h>

linux/watchdog.h>

linux/platform_device.h>

linux/interrupt.h>

linux/clk.h>

linux/uaccess.h>

linux/io.h>

linux/cpufreq.h>

#undefS3C_VA_WATCHDOG

#defineS3C_VA_WATCHDOG(0)

plat/regs-watchdog.h>

打开看门狗,允许复位,禁止看门狗中断,并设置看门狗最长看门时间

voidWdtConfig(void)

//读出看门狗控制寄存器S3C2410_WTCON,保存原值,并按照要求修改

//最后写回看门狗端口控制寄存器S3C2410_WTCON

tmp=(0XFF<

8)|(0X0<

6)|(0X1<

5)|(0X2<

3)|(0XFF<

2)|(0X1<

1)|(0XFF<

8)|(0X1<

0);

writel(tmp,S3C2410_WTCON);

(2)和文件系统接口对接

staticints3c6410_wdt_open(structinode*inode,structfile*filp)

//打开看门狗,允许复位,禁止看门狗中断,并设置看门狗最长看门时间

old_wdtcon_val=readl(S3C2410_WTCON);

WdtConfig();

staticssize_ts3c6410_wdt_write(structfile*file,constchar__user*data,size_tlen,loff_t*ppos)

//把data指针所指向的用户空间值更新到看门狗计数寄存器S3C2410_WTCNT中

unsignedintval;

copy_from_user(&

val,data,4);

writel(val,S3C2410_WTCNT);

return0;

staticints3c6410_wdt_release(structinode*inode,structfile*filp)

//恢复之前的看门狗端口控制寄存器的原始值

writel(old_wdtcon_val,S3C2410_WTCON);

structfile_operationswdt_fops=

.open=_s3c6410_wdt_open__,

.release=_s3c6410_wdt_release_,

.write=_s3c6410_wdt_write_,

staticint__initwdt_dev_init(void)

ret=__register_chrdev(0,"

wdtdev"

wdt_fops)_____;

staticvoid__exitwdt_dev_exit(void)

___unregister_chrdev(wdtdevNo,"

_____

module_init(wdt_dev_init);

module_exit(wdt_dev_exit);

=_______wdtdrv.o______

make–C___/opt/FriendlyARM/linux-2.6.38___SUBDIRS=$(shellpwd)modules

________#make_______________

编译完成后生成驱动文件______wdtdrv.ko_______。

使用命令进行驱动加载___#insmodwdtdrv.ko____________________。

_______#mknod/dev/leddevc2520___________________________。

要求每5秒点亮所有的LED灯,然后熄灭,过5秒再点亮LED灯,要求能够添加看门狗支持

pthread.h>

void*wdt_thrd_func(void*arg);

pthread_twdt_thd;

fd1=open(__"

/dev/leddev"

___,O_RDWR);

//打开LED设备

if(fd1<

fd2=open(__"

/dev/wdtdev"

//打开看门狗设备

if(fd2<

//创建看门狗喂狗线程

if(pthread_create(&

wdt_thd,NULL,wdt_thrd_func,NULL)!

=0)

printf("

Createwatchdogthreaderror!

\n"

exit

(1);

_ioctl(leddev_fd,OFF);

____

void*wdt_thrd_func(void*arg)

//每隔10秒喂狗一次

unsignedintwdt_val=0XFFFF;

//喂狗

write(fd2,&

wdt_val,sizeof(int));

sleep(10);

return;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 生物学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1