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

网站设计培训班老师网络营销软件条件

网站设计培训班老师,网络营销软件条件,网站建设准备,方维制网站一、IO多路复用--epoll实现 1.核心: 红黑树、一张表以及三个接口、 2.实现过程及API 1)创建epoll句柄/创建红黑树根节点 int epfdepoll_create(int size--无意义,>0即可)----------成功:返回根节点对应文件描述符&#xf…

一、IO多路复用--epoll实现

1.核心:

红黑树、一张表以及三个接口、

2.实现过程及API

1)创建epoll句柄/创建红黑树根节点

int epfd=epoll_create(int size--无意义,>0即可)----------成功:返回根节点对应文件描述符,失败:-1

2)将要监测的文件描述符挂载到红黑树上

a.struct epoll_event event;定义事件结构体

b.struct epoll_event events[10];定义存放就绪事件描述符的数组

c.添加准备就绪事件进入epoll,如:

event.events = EPOLLIN; // 读事件

event.data.fd = fd1;

epoll_ctl(epfd, EPOLL_CTL_ADD---控制方法, fd1, &event)

3)监听事件是否发生,阻塞等待准备好的文件描述符

epoll_wait(epfd, events, 10, -1--不关心是否超时);

返回值:

>0:准备好的文件描述符的个数

=0:超时

<0:失败

4)遍历数组,做事件的处理

二、信号驱动IO

异步IO方式,linux预留了一个信号SIGIO用于进行信号驱动IO,当硬件数据准备就绪后会发起一个硬件中断,在中断的处理函数中向当前进程发送一个SIGIO信号。进程收到SIGIO信号后执行信号处理函数,在信号处理函数中将数据读走即可。

1.实现过程及API

应用程序:

1)打开设备文件

2)注册信号的信号处理函数--signal(SIGIO,信号处理函数)

3)回调驱动中的fasync方法,完成发送信号之前的准备工作

        a.获取文件描述符属性

                int flags=fcntl(fd,F_GETFL);

        b.在文件描述符表的flags中添加FASYNC

                fcntl(fd,F_SETFL,flags|FASYNC);

        c.设置fd对应的驱动程序发送SIGIO信号只发送给当前进程

                fcntl(fd,F_SETOWN,getpid());

4)注意:不能让主程序结束

驱动程序:

1)定义一个异步对象指针

        struct fasync_struct *fp;

2)异步操作方法

int mycdev_fasync(int fd, struct file *file, int on) // 异步操作方法

{

        // 完成发送信号之前的准备工作

        fasync_helper(fd, file, on, &fp);

        return 0;

}

需要在操作方法结构体对象中加     .fasync = mycdev_fasync,

3)向进程发送信号

参数: fp:异步对象的二级指针

            sig:要发生的信号 SIGIO

            band:发送信号时添加的事件标志          POLL_IN表述读数据操作

//发送信号

kill_fasync(&fp,SIGIO,POLL_IN);

三、设备树

1.概念

1)设备树(DeviceTree/DT/of)是用来保存设备信息的一种树形结构

2)设备树的源码是独立于linux内核源码存在的

3)设备树上的设备信息在内核启动后被内核解析,加载到内核空间

4)设备树上的节点(包含属性子节点保存设备的设备信息;设备的信息由多个属性(链表形式存在,属性是键值对共同描述.

2.引入设备树的原因

        为了让驱动可以兼容更多硬件,不在驱动中指定设备信息,让驱动中获取设备树上的设备信息,基于这些设备信息完成硬件的控制

设备树linux官方手册:Device Tree Usage - eLinux.org

3.设备树节点结构体struct device_node和属性结构体 struct property

4.设备树节点解析API

1)根据设备树节点的名字解析指定的设备树节点信息

struct device_node *dnode;

dnode=of_find_node_by_name(NULL(默认从根节点解析),"mynode");

返回值:成功返回目标节点首地址,失败返回NULL

测试:

printk("name=%s,value=%s\n",dnode->properties->name,(char *)dnode->properties->value);

2)根据设备树节点路径解析设备树节点信息

3)根据节点的厂商信息解析指定的节点

dnode=of_find_compatible_node(NULL(默认从根节点解析),NULL(设备类型),:compatible值);

4)将大端字节序32位的数据转换成主机字节序

__u32 __be32_to_cpup(const __be32 *p)

printk("name=%s,value=%x %x\n",dnode->properties->next->next->name,

        __be32_to_cpup((u32 *)dnode->properties->next->next->value),

        __be32_to_cpup((u32 *)dnode->properties->next->next->value+1));

5.属性解析API

返回值:成功返回属性对象指针,失败返回NULL

struct property *pr;

int len;

pr=of_find_property(dnode,"uint",&len);

测试:

printk("name=%s value=%x %x\n",pr->name,__be32_to_cpup((u32 *)pr->value),

        __be32_to_cpup((u32 *)pr->value+1)); 

epoll实现IO多路复用的应用程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/epoll.h>
/* According to earlier standards */
#include <sys/time.h>int main(int argc, char const *argv[])
{int fd1, fd2, epfd;struct epoll_event event;      // 用于操作epollstruct epoll_event events[10]; // 存放就绪事件描述符的数组char buf[128] = {0};// 创建epoll句柄epfd = epoll_create(1);if (epfd < 0){printf("epoll_create filed\n");exit(-1);}// 打开设备文件fd1 = open("/dev/input/mouse0", O_RDWR);if (fd1 < 0){printf("打开鼠标设备文件失败\n");exit(-1);}fd2 = open("/dev/mycdev0", O_RDWR);if (fd2 < 0){printf("打开鼠标设备文件失败\n");exit(-1);}// 添加准备就绪事件进入epoll;event.events = EPOLLIN; // 读事件event.data.fd = fd1;if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &event) < 0){printf("epoll_ctl add filed\n");}event.events = EPOLLIN; // 读事件event.data.fd = fd2;if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd2, &event) < 0){printf("epoll_ctl add filed\n");}// 监听事件是否发生while (1){// 如果成功,ret接收返回的事件个数,把就绪的事件放在events数组中int ret = epoll_wait(epfd, events, 10, -1);if (ret < 0){printf("epoll_wait filed\n");exit(-1);}int i;// 循环遍历数组,做事件的处理for (i = 0; i < ret; i++){if (events[i].events & EPOLLIN)//判断发生的事件是不是读事件{read(events[i].data.fd, buf, sizeof(buf));printf("buf:%s\n", buf);}}}close(fd1);close(fd2);return 0;
}

信号驱动IO:

proc1.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/epoll.h>
/* According to earlier standards */
#include <sys/time.h>
int fd; // 存放就绪事件描述符的数组
char buf[128] = {0};
// 定义信号处理函数
void sigio_handler(int sig)
{read(fd, buf, sizeof(buf));printf("buf:%s\n", buf);
}
int main(int argc, char const *argv[])
{// 打开设备文件fd = open("/dev/myled0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}// 注册SIGIO信号的信号处理函数signal(SIGIO, sigio_handler);// 回调驱动中的fasync方法,完成发送信号之前的准备工作int flags = fcntl(fd,F_GETFL);     // 获取文件描述符属性fcntl(fd,F_SETFL,flags|FASYNC); // 在文件描述符表的flags中添加FASYNC,就可以回调fasync方法fcntl(fd,F_SETOWN,getpid());//驱动发送信号只发送给当前进程while(1){printf("aaaaa\n");sleep(1);}close(fd);return 0;
}

proc2.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>int main(int argc, char const *argv[])
{char buf[128] = "hello world";int fd = open("/dev/myled0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}write(fd, buf, sizeof(buf));close(fd);return 0;
}

fasync.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/poll.h>
struct cdev *cdev;
char kbuf[128] = {0};
unsigned int major = 0;
unsigned int minor = 0;
dev_t devno;
module_param(major, uint, 0664); // 方便在命令行传递major的值
struct class *cls;
struct device *dev;
struct fasync_struct *fp; // 定义一个异步对象指针// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{int ret;// 判断IO方式if (file->f_flags & O_NONBLOCK) // 非阻塞{}else // 阻塞{}ret = copy_to_user(ubuf, kbuf, size);if (ret){printk("copy_to_user err\n");return -EIO;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{int ret;// 从用户拷贝数据,模拟硬件数据ret = copy_from_user(kbuf, ubuf, size);if (ret){printk("copy_from_user err\n");return -EIO;}//发送信号(异步对象二级指针,要发生的信号,发送信号时添加事件的标志位)kill_fasync(&fp,SIGIO,POLL_IN);return 0;
}int mycdev_fasync(int fd, struct file *file, int on) // 异步操作方法
{// 完成发送信号之前的准备工作fasync_helper(fd, file, on, &fp);return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
// 定义一个操作方法结构体对象并且初始化
struct file_operations fops = {.open = mycdev_open,.read = mycdev_read,.write = mycdev_write,.fasync = mycdev_fasync,.release = mycdev_close,
};
static int __init mycdev_init(void)
{int ret;// 为字符设备驱动对象申请空间cdev = cdev_alloc();if (cdev == NULL){printk("字符设备驱动对象申请空间失败\n");ret = -EFAULT;goto out1;}printk("申请对象空间成功\n");// 初始化字符设备驱动对象cdev_init(cdev, &fops);// 申请设备号if (major > 0) // 静态指定设备号{ret = register_chrdev_region(MKDEV(major, minor), 3, "myled");if (ret){printk("静态申请设备号失败\n");goto out2;}}else if (major == 0) // 动态申请设备号{ret = alloc_chrdev_region(&devno, minor, 3, "myled");if (ret){printk("动态申请设备号失败\n");goto out2;}major = MAJOR(devno); // 获取主设备号minor = MINOR(devno); // 获取次设备号}printk("申请设备号成功\n");// 注册字符设备驱动对象ret = cdev_add(cdev, MKDEV(major, minor), 3);if (ret){printk("注册字符设备驱动对象失败\n");goto out3;}printk("注册字符设备驱动对象成功\n");// 向上提交目录信息cls = class_create(THIS_MODULE, "myled");if (IS_ERR(cls)){printk("向上提交目录失败\n");ret = -PTR_ERR(cls);goto out4;}printk("向上提交目录成功\n");// 向上提交设备节点信息int i;for (i = 0; i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");ret = -PTR_ERR(dev);goto out5;}}printk("向上提交设备信息成功\n");return 0;
out5:// 释放前一次提交成功的设备信息for (--i; i >= 0; i--){device_destroy(cls, MKDEV(major, i));}class_destroy(cls); // 释放目录
out4:cdev_del(cdev);
out3:unregister_chrdev_region(MKDEV(major, minor), 3);
out2:kfree(cdev);
out1:return ret;
}
static void __exit mycdev_exit(void)
{// 释放节点信息int i;for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}// 销毁目录class_destroy(cls);// 注销驱动对象cdev_del(cdev);// 释放设备号unregister_chrdev_region(MKDEV(major, minor), 3);// 释放对象空间kfree(cdev);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

http://www.ritt.cn/news/18224.html

相关文章:

  • 东莞路桥总公司电话网站优化的方法
  • 全国加盟网站建设搜狗搜图
  • javaweb网站开发小项目百度广告运营
  • 网站建设做什么的chrome官方下载
  • 国内优秀网页设计案例武汉seo托管公司
  • 淮安新网站制作怎么把自己的网站发布到网上
  • 编程代码入门教学seo培训网的优点是
  • 盐城网站建设招聘千锋教育培训机构就业率
  • 淘宝 客要推广网站怎么做北京网络营销公司排名
  • 网站域名在哪里注册如何做网站推广
  • 网站建设 日志河南关键词排名顾问
  • 长沙建设企业网站成人短期电脑培训班学费
  • 济南做网站建设成都全网推广哪家专业
  • 网站制作流程网站建设有哪些公司
  • 中国充电网络公司排名seo工作流程图
  • 天津建设网站需要的费用重庆百度推广
  • 贵州建设厅安全员b证考试网站张北网站seo
  • 招商网官网seo流量增加软件
  • 佛山市企业网站seo点击软件刷百度指数
  • 巩义专业网站建设价格百度广告大全
  • 福州公司网站开发方案成都网多多
  • 制作简易网站企业营销策划案例
  • 什么网站可以学做西餐网络营销的成功案例
  • 城投公司企业文化建设关键词优化意见
  • 企业网站建设 网络服务合肥seo排名优化公司
  • 游戏网站外链建设千峰培训可靠吗?
  • 青岛模板网站互联网广告投放公司
  • 网站项目实施方案seo排名优化服务
  • 阿里网站备案营业推广策略有哪些
  • 标准件做网站推广效果怎么样今日最新体育新闻