个人做网站 用什么语言公司网站设计哪家好

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

个人做网站 用什么语言,公司网站设计哪家好,android wordpress 源码,公司免费网站制作1、字符设备传统开发模板 字符设备驱动框架#xff0c;首先我们需要去用module_init这个宏去修饰整个驱动的入口函数#xff0c;用module_exit去修饰整个驱动的出口函数#xff0c;然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设…1、字符设备传统开发模板 字符设备驱动框架首先我们需要去用module_init这个宏去修饰整个驱动的入口函数用module_exit去修饰整个驱动的出口函数然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设备使用register_chrdev()注册字符设备使用class_create来注册区分一个类在用device_create来为这个类创造一个设备节点供我们在linux根目录下的dev目录下给应用层程序访问。在register_chrdev注册时最重要的是要提供字符设备的结构体file_operations,这个结构体启动了内核和应用层交互数据的功能。需要实现file_operations结构体的open,write,read,release函数对应于应用层的open,write,readclose #include asm-generic/errno-base.h #include asm-generic/gpio.h #include asm/uaccess.h #include linux/module.h #include linux/poll.h #include linux/fs.h #include linux/errno.h #include linux/miscdevice.h #include linux/kernel.h #include linux/major.h #include linux/mutex.h #include linux/proc_fs.h #include linux/seq_file.h #include linux/stat.h #include linux/init.h #include linux/device.h #include linux/tty.h #include linux/kmod.h #include linux/gfp.h #include linux/gpio/consumer.h #include linux/platform_device.h #include linux/of_gpio.h #include linux/of_irq.h #include linux/interrupt.h #include linux/irq.h #include linux/slab.h #include linux/fcntl.h #include linux/timer.hstruct gpios {int gpio;int irq;char *name; };static gpois gpios_s[2]{{115,0,sr51}, };static int major0; static struct class *clsNULL;static ssize_t sr51_read(struct file *file, char __user *buf, size_t size, loff_t * loff) {char ker_buf[2]{0};int err0;errcopy_from_user(ker_buf, buf, 1);if(err){return -EINVAL;}ker_buf[1]gpio_get_value(gpios_s[0].gpio);copy_to_user(buf, ker_buf,2)return 2; }static int sr51_release(struct inode *node, struct file *file) {printk(%s %s line %d\n, FILE, FUNCTION, LINE);printk(fd close\n);return 0;}static int sr51_open(struct inode *node, struct file *file) {printk(%s %s line %d\n,FILE,FUNCTION,LINE);return 0; }ssize_t sr51_write(struct file *file, const char user *buf , size_t size , loff_t * loff) {printk(%s %s line %d\n,FILE,FUNCTION,LINE__);return 0; }static struct file_operations sr51_driver{.ownerTHIS_MODULE,.opensr51_open,.writesr51_write,.readsr51_read,.releasesr51_release, };static int __init sr51_driver_init(void) {int err;errgpio_request(gpios_s[0].gpio, gpios[0].name);if (err 0) {printk(can not request gpio %s %d\n, gpios_s[0].gpio, gpios[0].name);return -ENODEV;}gpio_direction_output(gpios[0].gpio, 1);majorregister_chrdev(0, sr51,sr51_driver);clsclass_create(THIS_MODULE,sr51_class);if(IS_ERR(cls)){printk(%s %s line %d\n, FILE, FUNCTION, LINE);unregister_chrdev(major,sr51);return PTR_ERR(cls);}device_create(cls, NULL, MKDEV(major, 0), NULL, sr51);return 0; }static void __exit sr51_driver_exit(void) {device_destroy(cls, MKDEV(major, 0));unregister_chrdev(major,sr51);class_destroy(cls);gpio_free(gpios_s[0].gpio); }module_init(sr51_driver_init); module_exit(sr51_driver_exit); MODULE_LICENSE(GPL);2、不使用register_chrdev的另外一类驱动的注册方法 register_chrdev其实是cdev封装好的一个函数他其实也会调用cdev_init(),cdev_add(), 初始化设备号的另一种方法 1、int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name); 1、dev_t *dev 这个参数是一个指向 dev_t 类型的指针。dev_t 是一个在 sys/types.h 中定义的数据类型用于表示设备号。在调用 alloc_chrdev_region() 函数时你需要传递一个 dev_t 类型的变量的地址给这个函数。如果函数成功地为你的字符设备驱动程序分配了一个设备号那么它会将这个设备号存储在 dev 指针所指向的变量中。 2、unsigned baseminor次设备号 3、unsigned count几个次设备号 4、const char *name设备名称 2、void cdev_init(struct cdev *cdev, const struct file_operations *fops); cdev设备号 fops字符设备结构体 3、int cdev_add(struct cdev *p, dev_t num, unsigned int count); struct cdev *p指向已经初始化的cdev结构体的指针。 dev_t num分配给这个字符设备的设备号。这通常是通过alloc_chrdev_region()函数获得的。 unsigned int count通常设置为1除非你的字符设备支持多个次设备号。 3、当下用的最多的驱动开发设备树加platform总线模型 设备树的作用用于描述硬件的具体的功能。像gpio控制器ii2c控制器io多路复用控制器spi控制器中断控制器gic都需要使用设备树去描述这个硬件。 platform总线模型他是一个虚拟的总线模型内核里面使用bus_type这个结构体来描述这个虚拟总线这个虚拟中心又分为左边一部分和右边一部分左边一部分使用platform_device来描述这个结构体它可以由程序员编写也可以直接使用设备树自动生成目前使用的是这个而右边是使用的是platform_driver这个是由当下的驱动程序员来编写的虚拟总线的功能就是让这两个设备相匹配如果匹配到了那么驱动就会被加载进内核当中。 3.1他们是怎么匹配到然后加载进入内核的详细过程 1、设备树通常在系统引导阶段由引导加载器如U-Boot从预定义的配置文件加载并传递给内核它包含了硬件的层次结构和属性如内存地址、中断号和GPIO配置等。 2、设备树中的节点会被映射到内核中的platform_device结构体实例。每个设备节点通常包含compatible属性此属性用于标识设备类型和需要加载的驱动。第一次会比对 3、设备通过platform_device_register函数在内核中注册。这个过程会为设备创建一个platform_device实例并将其添加到platform_bus_type所代表的总线上。 设备注册后内核会使用platform_bus_type中的.match函数来查找和该设备兼容的驱动程序。 4、驱动程序使用platform_driver_register函数注册自己并提供一个platform_driver结构体其中包含驱动程序的名称、匹配表、以及回调函数如.probe和.remove。 .match回调函数确定一个驱动程序是否适用于某个特定的设备这通常是基于设备的compatible属性进行匹配的。 5、当设备和驱动成功匹配时驱动的.probe函数被调用这是驱动初始化设备的地方。例如驱动可能会配置设备使用的GPIO引脚设置初始状态或注册更高层的服务如输入设备或网络接口。 4、设备树的使用 设备树的常见属性 compatible:用于在驱动匹配时使用的匹配字符串。 #address-cells常见于父节点中用于规定子节点使用多少字长来描述硬件的起始地址。 #size-cells常见于父节点中用于规定子节点使用多少字长来描述硬件的地址长度。 / { #address-cells 1; #size-cells 1; memory { reg 0x80000000 0x20000000; }; };status:表示这个设备的状态 reg 节点的本意是 register用来表示寄存器地址。 但是在设备树里它可以用来描述一段空间。反正对于 ARM 系统寄存器和 内存是统一编址的即访问寄存器时用某块地址访问内存时用某块地址在访 问方法上没有区别 chosen 节点可以通过设备树文件给内核传入一些参数。