一个新的注册设备号方法

//Makefile

#内核路径
KERNEL_DIR=/home/me/farsight/linux-3.0.8
#驱动程序代码所在的路径
CUR_DIR=$(shell pwd)
#驱动程序的名称
DRV_NAME1 = led_drv
APP_NAME = led_app

all:
        make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
        arm-none-linux-gnueabi-gcc -o $(APP_NAME) $(APP_NAME).c

clean:
        make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
        rm -rf $(APP_NAME)

install:
        cp -raf *.ko $(APP_NAME) /opt/rootfs/drv_module

#到底要把哪个.c编译成模块
obj-m = $(DRV_NAME1).o

//应用层代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <asm-generic/ioctl.h>

#define ALL_LED_ON   _IO('A',0x01)
#define ALL_LED_OFF  _IO('A',0x02)
#define SEL_LED_ON   _IOW('S',0x01,int)
#define SEL_LED_OFF  _IOW('S',0x02,int)

#define SEL_LED1 0x01
#define SEL_LED2 0x02

int main(void)
{
    int fd;
    int led_cmd;
    fd = open("/dev/led_drv",O_RDWR);
    if(fd < 0)
    {
        perror("open");
        exit(1);
    }
    while(1)
    {
           ioctl(fd, ALL_LED_ON);
        sleep(1);
        ioctl(fd, ALL_LED_OFF);
        sleep(1);
        ioctl(fd, SEL_LED_ON, SEL_LED1);
        sleep(1);
        ioctl(fd, SEL_LED_OFF, SEL_LED1);
        sleep(1);
        ioctl(fd, SEL_LED_ON, SEL_LED2);
        sleep(1);
        ioctl(fd, SEL_LED_OFF, SEL_LED2);
        sleep(1);
    }
    close(fd);
    return 0;
}

//内核驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm-generic/ioctl.h>
#include <linux/cdev.h>

#define ALL_LED_ON   _IO('A',0x01)
#define ALL_LED_OFF  _IO('A',0x02)
#define SEL_LED_ON   _IOW('S',0x01,int)
#define SEL_LED_OFF  _IOW('S',0x02,int)

#define SEL_LED1 0x01
#define SEL_LED2 0x02


struct fs210_led{
    dev_t dev_no;
    struct cdev * c_dev;
    struct class * clazz;
    struct device *dev;
    void * GPC0_CON;
    void * GPC0_DAT;
};

struct fs210_led * fs210_led;

long led_drv_ioctl(struct file * filp, unsigned int cmd, unsigned long args)
{
    int reg_value;
    switch(cmd)
    {
        case ALL_LED_ON:
        {
           reg_value = __raw_readl(fs210_led->GPC0_DAT);
           reg_value |= (0x03 << 3);
           __raw_writel(reg_value, fs210_led->GPC0_DAT);
        }
            break;
        case ALL_LED_OFF:
        {
           reg_value = __raw_readl(fs210_led->GPC0_DAT);
           reg_value &= ~(0x03 << 3);
           __raw_writel(reg_value, fs210_led->GPC0_DAT);
        }
            break;
        case SEL_LED_ON:
        {
           if(args == SEL_LED1)
           {
                reg_value = __raw_readl(fs210_led->GPC0_DAT);
                reg_value |= (0x01 << 3);
                __raw_writel(reg_value, fs210_led->GPC0_DAT);
           }
           else
           {
                reg_value = __raw_readl(fs210_led->GPC0_DAT);
                reg_value |= (0x01 << 4);
                __raw_writel(reg_value, fs210_led->GPC0_DAT);
           }
        }
            break;
        case SEL_LED_OFF:
        {
           if(args == SEL_LED1)
           {
               reg_value = __raw_readl(fs210_led->GPC0_DAT);
               reg_value &= ~(0x01 << 3);
               __raw_writel(reg_value, fs210_led->GPC0_DAT);
           }
           else
           {
               reg_value = __raw_readl(fs210_led->GPC0_DAT);
               reg_value &= ~(0x01 << 4);
               __raw_writel(reg_value, fs210_led->GPC0_DAT);
           }
        }
            break;
        default:
            break;
    }
    return 0;
}
    
const struct file_operations fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = led_drv_ioctl,
};

static int __init led_drv_init(void)
{
   int ret;
   int reg_value;
   // 0.初始化全局的结构体对象
   fs210_led = kzalloc(sizeof(struct fs210_led), GFP_KERNEL);
   if(fs210_led == NULL)
   {
        printk("kzalloc error\n");
        return -ENOMEM;
   }
   
   // 1.申请/注册设备号(新方法)
   #if 0
   //注册设备号
   fs210_led->dev_no = MKDEV(250, 0);
   ret = register_chrdev_region(fs210_led->dev_no, 1, "led_drv");
   if(ret < 0)
   {
        printk("register_chrdev_region error\n");
        goto kzalloc_err;
   }
   #endif
   //申请设备号
   ret = alloc_chrdev_region(&fs210_led->dev_no, 0, 1, "led_drv");
   if(ret < 0)
   {
        printk("alloc_chrdev_region error\n");
        goto kzalloc_err;
   }
   
   //创建一个cdev对象
   fs210_led->c_dev = cdev_alloc();
   if(IS_ERR(fs210_led->c_dev))
   {
        printk("cdev_alloc error\n");
        ret = PTR_ERR(fs210_led->c_dev);
        goto register_chrdev_region_err;
   }
   cdev_init(fs210_led->c_dev, &fops);
   cdev_add(fs210_led->c_dev, fs210_led->dev_no, 1);

   // 2.创建类
   // 创建类
   //参数1:当前模块
   //参数2:类描述(自定义)
   fs210_led->clazz = class_create(THIS_MODULE, "led_class");
   if(IS_ERR(fs210_led->clazz))
   {
        printk("register_chrdev error\n");
        ret = PTR_ERR(fs210_led->clazz);
        goto cdev_alloc_err;
   }

   // 3.创建设备节点
   // mknod /dev/xxx  c  major  minor
   // 创建设备结点
   // 参数1: 类对象
   // 参数2: 父类
   // 参数3: 设备号
   // 参数4: 私有数据
   // 参数5: 设备节点名称
   fs210_led->dev = device_create(fs210_led->clazz, NULL, fs210_led->dev_no, NULL, "led_drv");
   if(IS_ERR(fs210_led->dev))
   {
        printk("device_create error\n");
        ret = PTR_ERR(fs210_led->dev);
        goto class_create_err;
   }

   // 4.硬件初始化
   fs210_led->GPC0_CON = ioremap(0xE0200060, 8);
   fs210_led->GPC0_DAT = fs210_led->GPC0_CON + 4;
   
   reg_value = readl(fs210_led->GPC0_CON);
   reg_value &= ~(0xff << 12);
   reg_value |= (0x11 << 12);
   writel(reg_value, fs210_led->GPC0_CON);

   reg_value = __raw_readl(fs210_led->GPC0_DAT);
   reg_value &= ~(0x03 << 3);
   __raw_writel(reg_value, fs210_led->GPC0_DAT);
   
   return 0;

   class_create_err:
           class_destroy(fs210_led->clazz);
   cdev_alloc_err:
           cdev_del(fs210_led->c_dev);
   register_chrdev_region_err:
           unregister_chrdev_region(fs210_led->dev_no, 1);
   kzalloc_err:
           kfree(fs210_led);
        
   return ret;
}

static void __exit led_drv_exit(void)
{
    iounmap(fs210_led->GPC0_CON);
    device_destroy(fs210_led->clazz, fs210_led->dev_no);
    class_destroy(fs210_led->clazz);
    cdev_del(fs210_led->c_dev);
    unregister_chrdev_region(fs210_led->dev_no, 1);
    kfree(fs210_led);
}

module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 使用H5编写一个手机注册界面需要以下步骤: 1. 创建一个HTML文件,并设置DOCTYPE为HTML5。 2. 在<body>标签中创建一个<form>标签,用于包裹注册表单。 3. 在<form>标签内部,创建一个<input>标签,用于接收用户输入的手机码。 4. 设置<input>标签的type属性为"tel",以确保用户只能输入数字。 5. 设置<input>标签的name属性为"phone",以便后续在服务器端读取用户输入数据。 6. 添加一个<label>标签,用于标识输入框的用途。例如,可以设置<label>标签的for属性为"phone",并在<label>标签内部添加文本内容,如"手机"。 7. 在<form>标签内部添加一个<button>标签,用于提交表单。 8. 设置<button>标签的type属性为"submit",以便用户点击按钮时触发表单提交。 9. 在<button>标签内部添加文本内容,如"注册"。 10. 在form标签上添加一个action属性,指定表单提交的目标URL。 11. 在form标签上添加一个method属性,设置为"POST",以便将用户输入的数据发送到服务器。 12. 编写一个服务器端脚本来接收表单数据,并进行验证和处理。 以上步骤是编写一个基本的手机注册页面的主要步骤,可以根据具体需求进行扩展和优化,例如添加短信验证码功能、输入格式验证等等。 ### 回答2: 使用HTML5编写一个手机注册页面非常简单。下面是一个简单的示例代码: ``` <!DOCTYPE html> <html> <head> <title>手机注册</title> </head> <body> <h2>手机注册</h2> <form action="submit.php" method="post"> <label for="phone">手机:</label> <input type="tel" id="phone" name="phone" pattern="[0-9]{11}" required> <button type="submit">注册</button> </form> </body> </html> ``` 以上代码中,`<form>` 标签用于创建一个表单,`action` 属性指定了表单提交的目标页面(在示例中为 `submit.php`),`method` 属性指定了提交的 HTTP 方法,这里是 `post`。 手机通过 `<input>` 标签的 `type` 属性设置为 `tel`,这表示输入的内容应该是一个电话码。`pattern` 属性用于限制输入的手机必须是11位数字,`required` 属性表示该字段为必填项。 在用户填写完手机后,可以点击注册按钮提交表单数据到 `submit.php` 页面进行后续处理。 注意:以上仅为一个简单的示例代码,实际开发中可能还需要进行进一步的验证和处理,确保数据的安全性和合法性。 ### 回答3: 使用HTML5可以编写一个手机注册表单,以下是一个简单的示例: ```html <!DOCTYPE html> <html> <head> <title>手机注册</title> </head> <body> <h2>手机注册</h2> <form id="registrationForm" action="/submit-registration" method="post"> <label for="phone">手机码:</label> <input type="tel" id="phone" name="phone" placeholder="请输入手机" required> <br><br> <input type="submit" value="注册"> </form> </body> </html> ``` 在这个示例中,我们使用`form`元素包裹表单内容,并指定了表单的提交地址和请求方法。手机字段通过`input`元素的`type`属性设置为`tel`,以便在移动设备上调用默认的数字键盘。`name`属性指定了字段的名称,方便后续在服务器上处理提交的数据。 我们还通过`required`属性设置了手机字段为必填项,这样在用户提交表单时,如果未填写手机,浏览器会提示用户进行填写。 当用户点击注册按钮后,表单将被提交到`/submit-registration`地址,并使用POST方法发送请求,你可以将这个地址替换为你自己的服务器端处理注册请求的接口地址。 此示例只是一个简单的手机注册表单,你可以根据自己的需求以及后端处理逻辑进行相应的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Lewis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值