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

哈尔滨自助建站系统长春做电商网站的公司

哈尔滨自助建站系统,长春做电商网站的公司,一个网站主页开发费用,石家庄p2p网站开发文章目录 目的相关资料参考实验驱动程序-timer_dev.c编译文件-Makefile测试程序-timer.c分析 加载驱动-运行测试程序总结 目的 通过定时器timer_list、字符设备、规避竞争关系-原子操作,综合运用 实现一个程序,加深之前知识的理解。 实现字符设备驱动框…

文章目录

  • 目的
  • 相关资料参考
  • 实验
    • 驱动程序-timer_dev.c
    • 编译文件-Makefile
    • 测试程序-timer.c
      • 分析
  • 加载驱动-运行测试程序
  • 总结


目的

通过定时器timer_list、字符设备、规避竞争关系-原子操作,综合运用 实现一个程序,加深之前知识的理解。

  • 实现字符设备驱动框架, 自动生成设备节点。
  • 根据上一小节学到的知识, 实现秒计时。
  • 通过原子变量来记录递增的秒数, 避免竞争的发生。
  • 通过用户空间和内核空间的数据交换, 将记录的秒数传递到应用空间, 并通过应用程
    序打印出来

相关资料参考

驱动-原子操作
驱动-Linux定时-timer_list

实验

驱动程序-timer_dev.c


#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>struct device_test
{dev_t  dev_num;  //定义dev_t类型变量来表示设备号int major,minor; //定义int 类型的主设备号和次设备号struct cdev cdev_test;   //定义字符设备struct class *class;   //定义结构体变量class 类struct device *device;  // 设备int sec;               //秒};
atomic64_t v = ATOMIC_INIT(0);//定义原子类型变量v,并定义为0struct device_test dev1;  static void function_test(struct timer_list *t);//定义function_test定时功能函数
DEFINE_TIMER(timer_test,function_test);//定义一个定时器
static void function_test(struct timer_list *t)
{atomic64_inc(&v);//原子变量v自增dev1.sec = atomic_read(&v);//将读取到的原子变量v,赋值给secprintk("the sec is %d\n",dev1.sec);mod_timer(&timer_test,jiffies_64 + msecs_to_jiffies(1000));//使用mod_timer函数将定时时间设置为一秒后
}/*打开设备函数*/
static int open_test(struct  inode  *inode,struct file *file){file->private_data=&dev1;//设置私有数据printk("\n this is open_test \n");add_timer(&timer_test);	//添加一个定时器return 0;};static ssize_t read_test(struct file *file, char __user *buf, size_t size, loff_t *off)
{if(copy_to_user(buf,&dev1.sec,sizeof(dev1.sec))){//使用copy_to_user函数将sec传递到应用层printk("copy_to_user error \n");return -1;}return 0;
}static int release_test(struct inode *inode,struct file *file)
{del_timer(&timer_test);//删除一个定时器printk("\nthis is release_test \n");return 0;
}static struct file_operations fops_test = {.owner=THIS_MODULE,//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块.open = open_test,//将open字段指向chrdev_open(...)函数.read = read_test,//将open字段指向chrdev_read(...)函数.release = release_test,//将open字段指向chrdev_release(...)函数
};//定义file_operations结构体类型的变量cdev_test_opsstatic int __init timer_dev_init(void)//驱动入口函数
{if(alloc_chrdev_region(&dev1.dev_num,0,1,"chrdev_name") < 0){printk("alloc_chrdev_region is error\n");}   printk("alloc_chrdev_region is ok\n");dev1.major=MAJOR(dev1.dev_num);//通过MAJOR()函数进行主设备号获取dev1.minor=MINOR(dev1.dev_num);//通过MINOR()函数进行次设备号获取printk("major is %d\n",dev1.major);printk("minor is %d\n",dev1.minor);使用cdev_init()函数初始化cdev_test结构体,并链接到cdev_test_ops结构体cdev_init(&dev1.cdev_test,&fops_test);dev1.cdev_test.owner = THIS_MODULE;//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块 cdev_add(&dev1.cdev_test,dev1.dev_num,1);printk("cdev_add is ok\n");dev1.class  = class_create(THIS_MODULE,"test");//使用class_create进行类的创建,类名称为class_testdevice_create(dev1.class,NULL,dev1.dev_num,NULL,"test");//使用device_create进行设备的创建,设备名称为device_testreturn 0;
}
static void __exit timer_dev_exit(void)//驱动出口函数
{cdev_del(&dev1.cdev_test);//使用cdev_del()函数进行字符设备的删除unregister_chrdev_region(dev1.dev_num,1);//释放字符驱动设备号 device_destroy(dev1.class,dev1.dev_num);//删除创建的设备class_destroy(dev1.class);//删除创建的类printk("module exit \n");}
module_init(timer_dev_init);//注册入口函数
module_exit(timer_dev_exit);//注册出口函数
MODULE_LICENSE("GPL v2");//同意GPL开源协议
MODULE_AUTHOR("wang fang chen "); //作者信息

编译文件-Makefile

#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += timer_dev.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

测试程序-timer.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc,char *argv[]){int fd;//定义int类型的文件描述符fdint count;//定义int类型记录秒数的变量countfd = open("/dev/test",O_RDWR);//使用open()函数以可读可写的方式打开设备文件while(1){	read(fd,&count,sizeof(count));//使用read函数读取内核传递来的秒数sleep(1);printf("num is %d\n",count);}return 0;
}

编译测试程序变成可执行文件:

aarch64-linux-gnu-gcc -o timer timer.c

分析

通过函数 read(fd,&count,sizeof(count)) 调用, 为什么count 值会变化。 有的人会问,count 默认值是0 ,read 读取。

ssize_t read(int fd, void *buf, size_t count);

函数read 参数解释:

  • fd 参数代表文件描述符,是一个整数,用于标识要读取的文件或设备。
  • buf 参数是一个指向缓冲区的指针,read 函数会将读取的数据存储在这个缓冲区中。
  • count 参数指定了最多要读取的字节数。

这里好好思考一下如下,会不会有问题,需要理解清楚,思考清楚。

测试程序每隔1秒读取count值 放到$count 缓冲区, 然后读取;内核端每隔一秒增加sec 值,通过原子操作+1,然后内核层copy_to_user。 用户层在缓冲区读取的值就是内核层每隔一秒通过 buffer 传递过来的。

在这里插入图片描述

加载驱动-运行测试程序

insmod timer_dev.ko./timer

实际返回值,如下:
在这里插入图片描述

总结

这个程序实验,用到了原子操作+定时器timer_list+字符设备操作。 简要了解即可,加深前面知识印象。

http://www.dtcms.com/a/613189.html

相关文章:

  • 做网站要不要35类商标网站构建免费
  • 校园网站的系统建设wordpress如和安装
  • 建设银行网站用户注册不了江宁区建设工程局网站
  • 站长推荐跳转广州社交软件app开发
  • c 网站开发案例wordpress模板是什么意思
  • 网站资料上传教程游戏广告联盟平台
  • 排名好的网站关键词优化企业网站如何做优化推广
  • 还能电子商务网站建设php网站开发编程软件
  • 网站开发有哪几个阶段百度快速收录3元一条
  • 网站免费网站免费优化优化建站之星模板的使用
  • 关于建设殡葬网站的报告范文wordpress开源吗
  • 网站建设成立领导小组许昌网站制作公司
  • 福建建设职业管理中心网站win7优化极致性能
  • 登录建设厅网站的是企业锁吗wordpress第一篇文章id
  • 网站盈利方式天河建网站的公司
  • 郑州 (网站建设宜昌网站建设设计
  • 住房建设厅官方网站html插件代码大全
  • 网站目录命名做营销的网站推广
  • 东莞优化网站建设厦门建网站做优化
  • 建站系统源代码ps模板网站推荐
  • 网站用ps下拉效果怎么做的网站建设项目报告
  • 个人公司网站搭建公司的创建
  • 中国企业网站建设网站风格特点
  • 值得浏览的国外网站怎么搭建网站环境配置文件
  • 如何做网站弹窗在线工具seo
  • 建站技巧成都网站建设需多少钱
  • 钱包网站建设策划wordpress模板上传
  • 网站开发周志微信小程序商家入口
  • 嘉兴网站制作软件青岛营销型网站制作
  • 邢台企业手机网站建设怎么利用源码做网站