当前位置: 首页 > news >正文

网站地图格式超酷个人网站欣赏

网站地图格式,超酷个人网站欣赏,属于网页制作工具,建设主管部门门户网站目录 1、项目背景 2、驱动程序 2.1 三层架构 2.2 驱动三要素 2.3 字符设备驱动 2.3.1 驱动模块 2.3.2 应用层 3、设计实现 3.1 项目设计 3.2 项目实现 3.2.1 驱动模块代码 3.2.2 用户层代码 4、功能特性 5、技术分析 6. 总结与未来展望 1、项目背景 养老院的老人…

目录

1、项目背景

2、驱动程序

2.1 三层架构

2.2 驱动三要素

2.3 字符设备驱动

 2.3.1 驱动模块

2.3.2 应用层

3、设计实现

3.1 项目设计

3.2 项目实现

3.2.1 驱动模块代码

3.2.2 用户层代码 

4、功能特性

5、技术分析 

6. 总结与未来展望


1、项目背景

        养老院的老人在生活中难免有所不方便,为了便捷老年人的生活,使用字符设备驱动编写了一个自助饮水机项目。该饮水机与普通饮水机的区别在于拥有更复杂的功能;饮水机拥有可以自行输入金额,然后程序开始运行。运行期间常亮绿灯,可以点击按钮暂停,灯颜色改变;一直到余额不足,然后蜂鸣器提示用户。

        提示:该项目的基础是在”系统移植“之上,对于系统移植步骤及说明:

        http://t.csdnimg.cn/O1uMi

 

2、驱动程序

2.1 三层架构

图2-1 结构框图

         对于三层的说明,想必大家都不陌生。内核层既需要去通过转换地址映射到内核,使得内核可以通过虚拟地址去操作底层的硬件设备;也需要使用虚拟文件系统向上层提供一个用户能够操作的文件设备。内核层作为中间枢纽,能提供如此的功能,归功于驱动程序,见图2-2。

 

2.2 驱动三要素

//驱动模块三要素 入口、出口、许可证
#include <linux/init.h>
#include <linux/module.h>
//入口
static int hello_init(void)
{return 0;
}
//出口
static void hello_exit(void)
{
}
module_init(hello_init);
module_exit(hello_exit);
//许可证
MODULE_LICENSE("GPL");//一个最简单、最基本的驱动程序

 

2.3 字符设备驱动

图2-2 字符设备驱动框图

 

 2.3.1 驱动模块

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/fs.h>
unsigned int major=0;
#define CNAME "hello"
ssize_t mycdev_read (struct file *file, char __user *ch, size_t len, loff_t *lodd)
{printk("this is read\n");return 0;
}
ssize_t mycdev_write (struct file *file, const char __user *buf, size_t len, loff_t *lodd)
{printk("this is write\n");return 0;
}
int mycdev_open (struct inode *ino, struct file *file)
{printk("this is open\n");return 0;
}
int mycdev_release (struct inode *ino, struct file *file)
{printk("this is close\n");return 0;
}
const struct file_operations fops=
{.read=mycdev_read,.write=mycdev_write,.open=mycdev_open,.release=mycdev_release,
};//该结构体主要用于像上层的用户层,提供调用的接口函数
static int __init hello_init(void)
{major=register_chrdev(major,CNAME,&fops);//注册一个字符设备驱动if(major<0){printk("register chrdev error\n");return major;}return 0;
}
static void __exit hello_exit(void)
{unregister_chrdev(major,CNAME);printk("bai bai\n");
}
module_init(hello_init);//入口
module_exit(hello_exit);//出口
MODULE_LICENSE("GPL");//返回值

 

2.3.2 应用层

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
char buf[128]={0};
int main(int argc,const char *argv[])
{int fd;fd=open("./hello",O_RDWR);if(fd==-1){perror("open error");return -1;}write(fd,buf,sizeof(buf));//对应着设备驱动模块的mycdev_write read(fd,buf,sizeof(buf));//对应着设备驱动模块的mycdev_readclose(fd);return 0;
}

         所以,具体应用层所能干的,就是调用接口,而接口函数里面做的事情,则由我们驱动开发人员去编写,当然,此驱动模块还没有去操作实际的硬件设备,对于想要操作底层的硬件设备,则需要去看板子的原理图,查看外设的地址映射等。(以上驱动模块并未自动创建设备文件,执行完还需自行mknod,命令格式如下:sudo mknod hello c/b(c 代表字符设备 b代表块设备)主设备号 次设备号)

3、设计实现

3.1 项目设计

        对于该项目组成,同样是上述组成,不过更加复杂,具体的我就不再引出了。如果有任何问题,可以联系博主。

图3-1 驱动模块的作用

3.2 项目实现

3.2.1 驱动模块代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>#define CNAME "NEW_C"
unsigned int major=0;
struct class *cls;
struct device *dvs;
char kbuf[64]={0};
int money=0;
int devlen=0;#define RED_BASE 0xC001A000
#define GRE_BASE 0xC001E000
#define BLU_BASE 0xC001B000
#define BEEP_BASE 0xC001C000
unsigned int *red_base=NULL;
unsigned int *gre_base=NULL;
unsigned int *blu_base=NULL;
unsigned int *beep_base=NULL;#define GPIONO(m,n) m*32+n  //计算gpio号
#define GPIO_B8  (GPIONO(1,8))//计算按键gpio号
#define GPIO_B16  (GPIONO(1,16)) //计算gpio号
struct timer_list mytimer;//声明结构体
struct timer_list mytimer1;
struct timer_list mytimer2;
int gpiono[] = {GPIO_B8,GPIO_B16};//数组内存入两个按键的软中断号
char *irqname[] = {"interrupt-b8","interrupt-b16"};//中断的名字
void key_irq_timer_handle(unsigned long data)//定时器中断处理函数
{int status_b8  = gpio_get_value(GPIO_B8);//读取gpiob8数值int status_b16 = gpio_get_value(GPIO_B16);//读取gpiob16数值if(status_b8 == 0){//如果等于0表示按下,执行打印函数*blu_base |= 1<<12;mod_timer(&mytimer1,jiffies+1000);printk("left  button down............\n");}if(status_b16 == 0){//如果等于0表示按下,执行打印函数*blu_base &= ~(1<<12);del_timer(&mytimer1);printk("right button down#############\n");}
}void key_irq_timer_handle1(unsigned long data)//定时器中断处理函数
{kbuf[11]=kbuf[11]-1;if(kbuf[11]=='/'){kbuf[10]=kbuf[10]-1;kbuf[11]=kbuf[11]+10;}mod_timer(&mytimer1, jiffies + 1000);
}void key_irq_timer_handle2(unsigned long data)//定时器中断处理函数
{*beep_base &= ~(1<<14);
}
irqreturn_t farsight_irq_handle(int num, void *dev)//按键产生的中断处理函数
{mod_timer(&mytimer,jiffies+10);//开启定时器。只要触发就重新赋值,用来消抖return IRQ_HANDLED; 
}ssize_t my_dev_read(struct file *file, char __user *ubuf, size_t len, loff_t *loff)
{if(len >sizeof(kbuf)){len =sizeof(kbuf);}printk("%c %c\n",kbuf[10],kbuf[11]);devlen = copy_to_user(ubuf,kbuf,len);if(devlen){printk("copy to user is err\n");return devlen;}return 0;
}ssize_t my_dev_write(struct file *file, const char __user *ubuf, size_t len, loff_t *loff)
{if(len > sizeof (kbuf)){len=sizeof(kbuf);}devlen = copy_from_user(kbuf,ubuf,len);if(devlen){printk("copy from user is err\n");return devlen;}money=(kbuf[10]-48)*10+(kbuf[11]-48);printk("This is my char_dev_write %d\n",money);return 0;
}int my_dev_open(struct inode *inode, struct file *file)
{return 0;
}int my_dev_release(struct inode *inode, struct file *file)
{*beep_base |= 1<<14;mod_timer(&mytimer2, jiffies + 1000);return 0;
}const struct file_operations fops=
{.read=my_dev_read,.write=my_dev_write,.open=my_dev_open,.release=my_dev_release,// .unlocked_ioctl=my_unlocked_ioctl,
};static int __init hello_init(void)
{major=register_chrdev(major,CNAME,&fops);if(major<0){printk("register_chrdev is error\n");return major;}red_base=ioremap(RED_BASE,36);gre_base=ioremap(GRE_BASE,36);blu_base=ioremap(BLU_BASE,36);beep_base=ioremap(BEEP_BASE,36);if(red_base==NULL || gre_base==NULL){printk("ioremap is err\n");return -ENOMEM;}*red_base &=~(1<<28);*(red_base+1) |=1<<28;*(red_base+9) &=~(3<<24);*gre_base &= ~(1<<13);*(gre_base+1) |= (1<<13);*(gre_base+8) &=~(3<<26);*(blu_base+1) |= 1<<12;*(blu_base+8) |=(2<<24);*beep_base &= ~(1<<14);*(beep_base+1) |= 1<<14;*(beep_base+8) &= ~(1<<29);*(beep_base+8) |= 1<<28;cls = class_create(THIS_MODULE, CNAME);if(IS_ERR(cls)){printk("class create is err\n");return PTR_ERR(cls);}dvs=device_create(cls, NULL, MKDEV(major,0), NULL, CNAME);if(IS_ERR(dvs)){printk("device create is err\n");return PTR_ERR(dvs);}int ret,i;mytimer.expires = jiffies + 10;//时间mytimer.function = key_irq_timer_handle;//定时器中断处理函数mytimer.data = 0;//参数init_timer(&mytimer);//将定时器信息写入进行初始化add_timer(&mytimer);//开启一次定时器mytimer1.expires = jiffies + 1000;//时间mytimer1.function = key_irq_timer_handle1;//定时器中断处理函数mytimer1.data = 0;//参数init_timer(&mytimer1);//将定时器信息写入进行初始化add_timer(&mytimer1);//开启一次定时器mytimer2.expires = jiffies + 1000;//时间mytimer2.function = key_irq_timer_handle2;//定时器中断处理函数mytimer2.data = 0;//参数init_timer(&mytimer2);//将定时器信息写入进行初始化add_timer(&mytimer2);//开启一次定时器for(i=0;i<ARRAY_SIZE(gpiono); i++){//这里用for主要目的之申请两个中断ret = request_irq(gpio_to_irq(gpiono[i]),farsight_irq_handle,IRQF_TRIGGER_FALLING,irqname[i],NULL);//中断申请 参数:软中断号  中断执行函数  下降沿触发 中断的名字if(ret){printk("request irq%d error\n",gpio_to_irq(gpiono[i]));//申请失败提示return ret;}}return 0;
}static void __exit hello_exit(void)
{int i;for(i=0;i<ARRAY_SIZE(gpiono); i++){//注销掉中断free_irq(gpio_to_irq(gpiono[i]),NULL);}del_timer(&mytimer);//注销掉定时器del_timer(&mytimer1);//注销掉定时器del_timer(&mytimer2);//注销掉定时器class_destroy(cls);device_destroy(cls,MKDEV(major,0));iounmap(red_base);iounmap(gre_base);iounmap(blu_base);iounmap(beep_base);unregister_chrdev(major,CNAME);}module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

3.2.2 用户层代码 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <time.h>#include "head.h"char buf[64] ={0};
char buff[128]={0};
struct tm *tp;
time_t t;
int main(int argc, char *argv[])
{int fd = open("/dev/NEW_C", O_RDWR);if (fd < 0){perror("open NEW_C err\n");return -1;}int fds=open("./history.txt",O_APPEND|O_CREAT|O_WRONLY,0666);if(fds<0){perror("open history err\n");return -1;}sprintf(buf,"0X55%s%s0XFF",argv[1],argv[2]);write(fd,buf,sizeof(buf));int readlen=0;while(1){time(&t);tp = localtime(&t);if((buf[10]=='0') && buf[11]=='0'){goto loop;}readlen = read(fd,buf,sizeof(buf));sprintf(buff,"%4d-%02d-%02d %02d:%02d:%02d : 账户:%c%c\t剩余金额:%c%c\n",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec,buf[6],buf[7],buf[10],buf[11]);write(fds,buff,strlen(buff));printf("账户:%c%c\t剩余金额:%c%c\n",buf[6],buf[7],buf[10],buf[11]);sleep(1);}
loop:close(fd);return 0;
}

 

4、功能特性

上述项目的功能大体如下:

        用户可自行输入金额。

        金额定时减少,出水时亮绿灯

        用户可点击按钮实现暂停接水,并且余额不会减少。

        余额归零,代表出水完毕,蜂鸣器响提示用户。

        本地日志会记录用户的购买记录及详细信息。

 

5、技术分析 

        字符设备驱动编写:向上提供接口,向下控制硬件。

        定时器使用:按键消抖,水量控制,蜂鸣器控制。

        中断使用:按键触发中断。

        文件io:保存用户消费日志。

 

6. 总结与未来展望

        字符设备驱动是操作系统中的一种设备驱动程序,用于管理和控制字符设备。在Linux系统中,字符设备驱动通常使用字符设备接口进行开发。驱动程序需要定义设备结构体、注册设备、实现文件操作函数等,以提供稳定高效的设备访问接口。除了基本的功能,驱动程序还可以实现多个进程访问同一个设备、内存映射、虚拟文件系统、设备驱动模块化、调试信息输出等特性。

        字符设备驱动技术在计算机领域有着重要的意义和影响。首先,它为应用程序提供了访问字符设备的标准接口,使得应用程序能够方便地与设备进行数据交互,从而促进了各种应用软件的开发和推广。其次,字符设备驱动技术也支持多种设备类型和多种操作系统平台,使得设备之间的互通性得到了提升,为设备互联和智能化提供了先决条件。

        未来,随着物联网技术的不断发展和普及,字符设备驱动技术将会得到更广泛的应用和推广。特别是在智能家居、工业自动化、医疗健康等领域,字符设备驱动技术将发挥更大的作用和贡献。同时,随着技术的不断进步和创新,字符设备驱动技术也将会不断完善和优化,以满足日益增长的设备互联需求和应用场景。

        感谢大家的阅读,欢迎留言指教。

http://www.yayakq.cn/news/344654/

相关文章:

  • 建立wordpress网站吗建筑人才网与厦门人才网的中级工程师证书的区别
  • 微网站自己怎么做的吗南昌中企动力做的网站怎么样
  • 网站群建设技术方案微信微商城平台
  • 企业网站多少钱建立免费网站
  • 杭州富阳网站建设公司百度一下网页版浏览器百度
  • 哈尔滨网络宣传与网站建设如何在微信上开发小程序
  • 潍坊网站制作多少钱怎么做网站优化 site
  • 一家只做t恤的网站怎么申请公司
  • 胶州国际网站建设效果北京网页公司制作
  • 网站开发教程pdf设计官网公司
  • 百度新网站提交入口建设电动车官网
  • 阿里巴巴吧网站建设企业标志设计公司
  • 新蔡县城乡建设局网站购物网站素材
  • 做网站有哪些软件有专门做网站的公司
  • 国外创意网站设计欣赏如何让网站自适应屏幕
  • 网站建设与网页设计专业网站设计规划书怎么写
  • ASP.NET网站建设实战企业网站建设网站制作
  • 哪里有免费的网站自己做影视公司宣传片
  • 如何在百度上建网站网站做301跳转的方法
  • 自己做网站推广需要多少钱自已电脑做网站
  • 佛山品牌网站建设金华规划局网站开发区
  • 山东外贸网站是什么意思制作网页首页教程
  • 网站的建站方案网上最好的网站模块
  • 建设银行网站注册用户便宜电商网站建设
  • 浦江建设局网站厦门网站设计公司找哪家厦门电商系统
  • 网站制作公司 哪家好做网站怎么调用栏目
  • 网站icp备案认证怎么做十大著名企业文化
  • 电子商务网站推广的方法有哪些asp. net 做网站
  • 做网站网页需要多久正规营销型网站定制
  • 网站开发应用技术专业计算机软件开发工资高吗