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

网站建设怎么跑业务一级域名与二级域名有啥区别

网站建设怎么跑业务,一级域名与二级域名有啥区别,小说关键词自动生成器,wordpress模板安装完没有导航栏以下内容源于朱有鹏嵌入式课程的学习与整理#xff0c;如有其侵权请告知删除。 前言 由misc类设备驱动1——misc类设备的简介可知#xff0c;misc类设备驱动框架包括以下两部分#xff1a; 1、内核开发者实现的部分 drivers/char/misc.c文件主要包括2个关键点#xff1a;类…以下内容源于朱有鹏嵌入式课程的学习与整理如有其侵权请告知删除。 前言 由misc类设备驱动1——misc类设备的简介可知misc类设备驱动框架包括以下两部分 1、内核开发者实现的部分 drivers/char/misc.c文件主要包括2个关键点类的创建、开放给驱动开发者的接口。 2、驱动工程师实现的部分 比如蜂鸣器驱动x210_kernel\drivers\char\buzzer\x210-buzzer.c文件。 下面将对misc.c文件、x210-buzzer.c文件进行分析。 一、驱动核心层misc.c文件的分析 1、misc_init()函数 misc类设备驱动框架本身也是一个模块这意味着可裁剪内核启动时自动加载。 subsys_initcall(misc_init);misc_init()函数内容如下 static int __init misc_init(void) {int err;#ifdef CONFIG_PROC_FSproc_create(misc, 0, NULL, misc_proc_fops); #endifmisc_class class_create(THIS_MODULE, misc);//注册/sys/class/misc类err PTR_ERR(misc_class);if (IS_ERR(misc_class))goto fail_remove;err -EIO; //10 使用老接口注册字符设备驱动主设备号10if (register_chrdev(MISC_MAJOR,misc,misc_fops))goto fail_printk;misc_class-devnode misc_devnode;return 0;fail_printk:printk(unable to get major %d for misc devices\n, MISC_MAJOR);class_destroy(misc_class); fail_remove:remove_proc_entry(misc, NULL);return err; } subsys_initcall(misc_init);1该函数的主要工作内容 使用class_create()函数注册了misc类因此可以在/sys/class/目录下找到misc目录。 使用register_chrdev()这个老接口字符设备驱动注册函数注册了主设备号为10的字符设备驱动。因此cat /proc/devices时字符设备列表处显示有“10 misc”。 存疑/dev/buzzer这个设备文件是在哪里在什么时候创建的这个设备文件在x210-buzzer.c文件中的misc_register()函数中创建。 2misc_fops变量的定义 使用register_chrdev()这个老接口字符设备驱动注册函数时参数中有misc_fops这个变量其定义如下。其中misc_open()函数的分析下文。 static const struct file_operations misc_fops {.owner THIS_MODULE,.open misc_open,//分析见下文 }; 2、misc_register()函数 驱动框架设计了杂散设备的注册接口misc_register()。驱动工程师借助misc类设备驱动框架编写驱动时只需要调用misc_register()函数注册自己的设备即可其余均不用管。 misc_register()函数内容如下 int misc_register(struct miscdevice * misc) {struct miscdevice *c;dev_t dev;int err 0;INIT_LIST_HEAD(misc-list);//(1)misc_list链表的作用mutex_lock(misc_mtx);//遍历内核链表查看该次设备号是否已经被占用list_for_each_entry(c, misc_list, list) {if (c-minor misc-minor) {//次设备号已经被占用mutex_unlock(misc_mtx);return -EBUSY;}}if (misc-minor MISC_DYNAMIC_MINOR) {//这个表示自动分配次设备号int i find_first_zero_bit(misc_minors, DYNAMIC_MINORS);if (i DYNAMIC_MINORS) {mutex_unlock(misc_mtx);return -EBUSY;}misc-minor DYNAMIC_MINORS - i - 1;set_bit(i, misc_minors);//这个表示我要占用此次设备号}dev MKDEV(MISC_MAJOR, misc-minor);//合成设备号misc-this_device device_create(misc_class, misc-parent, dev,misc, %s, misc-name);//创建设备文件if (IS_ERR(misc-this_device)) {int i DYNAMIC_MINORS - misc-minor - 1;if (i DYNAMIC_MINORS i 0)clear_bit(i, misc_minors);err PTR_ERR(misc-this_device);goto out;}/** Add it to the front, so that later devices can override* earlier defaults*/list_add(misc-list, misc_list);out:mutex_unlock(misc_mtx);return err; } 1struct miscdevice 结构体 该结构体是对一个杂散设备的抽象或者说该结构体的变量表示一个杂散设备。 此结构体定义在x210_kernel\include\linux\miscdevice.h文件中内容如下 struct miscdevice {int minor; //杂散设备的主设备号规定为10可变的仅有次设备号const char *name; //杂散设备的名字const struct file_operations *fops;//文件操作函数指针struct list_head list;struct device *parent;struct device *this_device;const char *nodename;mode_t mode; }; 2misc_list链表的作用 在misc.c文件开头处定义了一个misc_list链表即“ static LIST_HEAD(misc_list); ”用来记录所有内核中注册了的杂散类设备P.s. 之前的字符设备是固定大小255的数组。 当我们向内核注册一个misc类设备时内核就会向misc_list链表中插入一个节点。当使用cat /proc/misc打印出信息时其实就是遍历此链表。 static LIST_HEAD(misc_list);/* #define LIST_HEAD_INIT(name) { (name), (name) } #define LIST_HEAD(name) struct list_head name LIST_HEAD_INIT(name)因此上面式子展开后等价于 static struct list_head misc_list { (misc_list), (misc_list) }*/ 3主设备号和次设备号的作用和区分 主设备号表示类次设备号表示某具体设备。 3、misc_open()函数 之前说到misc_fops这个变量中的成员open函数指向misc_open()函数。 static const struct file_operations misc_fops {.owner THIS_MODULE,.open misc_open,//分析见下文 }; misc_open()函数代码如下 static int misc_open(struct inode * inode, struct file * file) { //文件在硬盘的路径 //设备文件的路径int minor iminor(inode);struct miscdevice *c;int err -ENODEV;const struct file_operations *old_fops, *new_fops NULL;mutex_lock(misc_mtx);list_for_each_entry(c, misc_list, list) {if (c-minor minor) {new_fops fops_get(c-fops);//用次设备号寻找设备break;}}if (!new_fops) {mutex_unlock(misc_mtx);request_module(char-major-%d-%d, MISC_MAJOR, minor);mutex_lock(misc_mtx);list_for_each_entry(c, misc_list, list) {if (c-minor minor) {new_fops fops_get(c-fops);break;}}if (!new_fops)goto fail;}err 0;old_fops file-f_op;file-f_op new_fops;if (file-f_op-open) {file-private_data c;errfile-f_op-open(inode,file);//主要的if (err) {fops_put(file-f_op);file-f_op fops_get(old_fops);}}fops_put(old_fops); fail:mutex_unlock(misc_mtx);return err; } misc_open()函数最终映射到x210_buzzer.c中的open函数。 4、misc设备在proc文件系统下的展现 通过cat /proc/devices时字符设备列表处显示有“10 misc”。如下所示。 [rootxjh proc]# cat devices Character devices:1 mem //省略部分代码7 vcs10 misc //这里出现主设备号为10名字为misc的字符设备13 input //省略部分代码Block devices: //省略部分代码 254 device-mapper 5、内核互斥锁 1内核用于防止竞争状态的手段包括原子访问、自旋锁、互斥锁、信号量。 关于这些手段的介绍可见博客内核中防止竞争状态的手段 - 涛少 - 博客园 2static DEFINE_MUTEX(misc_mtx); 在misc.c文件开头处有如下代码 static DEFINE_MUTEX(misc_mtx); DEFINE_MUTEX这个宏包含在x210_kernel\include\linux\mutex.h文件中如下 #define DEFINE_MUTEX(mutexname) \struct mutex mutexname __MUTEX_INITIALIZER(mutexname)/* #define __MUTEX_INITIALIZER(lockname) \{ .count ATOMIC_INIT(1) \, .wait_lock __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \, .wait_list LIST_HEAD_INIT(lockname.wait_list) \__DEBUG_MUTEX_INITIALIZER(lockname) \__DEP_MAP_MUTEX_INITIALIZER(lockname) } */所以static DEFINE_MUTEX(misc_mtx);展开后成为 struct mutex misc_mtx  {        .count ATOMIC_INIT(1) ,.wait_lock __SPIN_LOCK_UNLOCKED(misc_mtx.wait_lock) ,.wait_list LIST_HEAD_INIT(misc_mtx.wait_list) ,   }; 3上锁mutex_lock和解锁mutex_unlock 要访问某资源时要给该资源上锁使用完后要解锁。当某进程想访问已经被上锁的资源时会休眠直到其他进程解锁后此进程才能访问该资源。 三、具体操作层x210-buzzer.c文件的分析 1、dev_init()函数 蜂鸣器归类为杂项字符设备其驱动文件是x210-buzzer.c它也属于模块化设计。 module_init(dev_init); 该函数的内容如下 static int __init dev_init(void) {int ret;init_MUTEX(lock);ret misc_register(misc);//接下来对硬件即蜂鸣器进行初始化//向gpiolib申请gpio并设置成上拉、输出模式输出值为0 /* GPD0_2 (PWMTOUT2) *///由原理图得知蜂鸣器的接口是GPD0_2ret gpio_request(S5PV210_GPD0(2), GPD0);//向gpiolib申请gpioif(ret)printk(buzzer-x210: request gpio GPD0(2) fail);s3c_gpio_setpull(S5PV210_GPD0(2), S3C_GPIO_PULL_UP);//设置成上拉s3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(1));//设置成输出模式gpio_set_value(S5PV210_GPD0(2), 0);//设置输出值为0 printk (x210 DEVICE_NAME initialized\n);return ret; } 1互斥锁初始化init_MUTEX(lock) 互斥锁其实就是计数值为1的信号量所以sema_init(sem, 1)中参数设为1。 有待深入。open和release函数里面也有互斥锁。 init_MUTEX(lock);/* #define init_MUTEX(sem)   sema_init(sem, 1) //这里参数为1static inline void sema_init(struct semaphore *sem, int val) {static struct lock_class_key __key;*sem (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);lockdep_init_map(sem-lock.dep_map, semaphore-lock, __key, 0); } */ 2 misc_register(misc)中的变量misc 变量misc的数据类型是struct miscdevice该变量定义如下。 static struct miscdevice misc {.minor MISC_DYNAMIC_MINOR,//其值为255表示自动分配次设备号.name DEVICE_NAME,.fops dev_fops, };3gpio_request 4printk 2、x210_pwm_ioctl()函数 该函数的内容如下 // PWM:GPF14-PWM0 static int x210_pwm_ioctl(struct inode *inode, struct file *file, \unsigned int cmd, unsigned long arg) {switch (cmd) {case PWM_IOCTL_SET_FREQ:printk(PWM_IOCTL_SET_FREQ:\r\n);if (arg 0)return -EINVAL;PWM_Set_Freq(arg);break;case PWM_IOCTL_STOP:default:printk(PWM_IOCTL_STOP:\r\n);PWM_Stop();break;}return 0; } //上面这两个宏按理定义在头文件中然后让应用程序包含 //但是这个文件却直接定义在开头了不规范 1为什么会有ioctl这个函数 ioctl函数是对设备进行输入与输出既然如此为何不用read和write函数呢其实只有read和write函数也是可以的之前的驱动没有ioctl函数也可以工作。但read和write函数会导致应用层和驱动层的交互麻烦。比如写驱动的人在驱动中定义亮灭应用层的人怎么知道呢使用ioctr后通过命令码的名字就可以明确知道命令码含义。 2ioctl的使用方法 在应用层编写代码见misc类设备驱动0——板载蜂鸣器驱动测试 3、硬件操作有关的代码 硬件操作有关的代码是指PWM_Set_Freq()函数、PWM_Stop()函数。 PWM_Set_Freq()函数 // TCFG0在Uboot中设置这里不再重复设置 // Timer0输入频率Finputpclk/(prescaler11)/MUX1 // 66M/16/16 // TCFG0 tcnt (pclk/16/16)/freq; // PWM0输出频率Foutput Finput/TCFG0 freq static void PWM_Set_Freq( unsigned long freq ) {unsigned long tcon;unsigned long tcnt;unsigned long tcfg1;struct clk *clk_p;unsigned long pclk;//unsigned tmp;//设置GPD0_2为PWM输出s3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(2));tcon __raw_readl(S3C2410_TCON);tcfg1 __raw_readl(S3C2410_TCFG1);//mux 1/16tcfg1 ~(0xf8);tcfg1 | (0x48);__raw_writel(tcfg1, S3C2410_TCFG1);clk_p clk_get(NULL, pclk);pclk clk_get_rate(clk_p);tcnt (pclk/16/16)/freq;__raw_writel(tcnt, S3C2410_TCNTB(2));__raw_writel(tcnt/2, S3C2410_TCMPB(2));//占空比为50%tcon ~(0xf12);tcon | (0xb12); //disable deadzone, auto-reload, inv-off, //update TCNTB0TCMPB0, start timer 0__raw_writel(tcon, S3C2410_TCON);tcon ~(212); //clear manual update bit__raw_writel(tcon, S3C2410_TCON); } 1此函数用于打开蜂鸣器并设置想要的频率。 2蜂鸣器分为有源蜂鸣器无源蜂鸣器。有源蜂鸣器可以用PWM信号驱动并改变频率无源蜂鸣器好像不可以这里是有源蜂鸣器。 PWM_Stop()函数 void PWM_Stop( void ) {//将GPD0_2设置为inputs3c_gpio_cfgpin(S5PV210_GPD0(2), S3C_GPIO_SFN(0)); } 1此函数用于关闭蜂鸣器。
http://www.zqtcl.cn/news/29267/

相关文章:

  • 视频网站自己怎么做深圳十大建筑设计院
  • 青岛专业做网站的手机网站做适配
  • 可以入侵的网站手机做简单的网站
  • 聊天室网站开发wordpress 转繁体
  • 万家灯火网站建设centos部署wordpress
  • 国内网站服务器济南城乡建设官方网站
  • 电子商务网站策划ppt如何使用ftp上传网站
  • 广州做包包的网站有什么好的网站设计思想的博客
  • 重庆网站制作一般多少钱建网站免费吗
  • 建站公司怎么拓客循环视频做网站背景
  • 做网站属于技术开发吗重庆游戏网站开发
  • 想学习网站建设中石油技术开发公司网站
  • 微网站 .net前程无忧做一年网站多钱
  • 做网站运营经理的要求昆明网站建设哪家最好
  • 做一个综合性的网站多少钱招聘网站建设维护人员
  • 安陆市网站长沙优化网站推广
  • 网站开发的概要设计模板大学校园门户网站建设方案
  • 内蒙古兴安盟建设局网站专业网站设计软件工具
  • 网站建设预算明细表上海网站建设加q.479185700
  • 微网站的优点小程序建设
  • 统一门户网站上海健康证查询网址
  • 做网站用什么数据库好用网站 建设 现状
  • 网站文字模板邢台信息网123
  • 西安网站建设的费用网站响应式好吗
  • 湖南做网站 就问磐石网络专业外加工订单网
  • 网站301了不知道在哪做的企业网站策划应该怎么做
  • 安卓网站开发平台新颖的网站策划
  • 网页设计工作室网站在线制作网站免费
  • 博客网站首页设计网络规划设计师含金量高吗
  • 威海网站建设公司排名百度网站官网网址