华清远见嵌入式学习day36——IO模型与GPIO子系统

【1】.复习

    1. 同步互斥
    
        信号量
        互斥体
        
    2. IO模型 
    
        阻塞
            
            1. 定义等待队列头初始化
            2. 定义等待队列项并初始化
            3. 将等待队列项挂在等待队列头上
            4. 设置进程状态 --->>> 睡眠态(S / D)
            5. 调度
            ---------(条件满足唤醒)-----------
            6. 将等待队列项从等待队列头上移除
            7. 设置进程状态 --->>> 运行态(R)
            
        
            wait_event(wq,condition)
            wait_event_interruptible(wq,condition)
        
        非阻塞
        
            O_NONBLOCK & filp -> f_flags

【2】.作业

    01
    02

【一】、IO多路复用

    fs/select.c 
    
    SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,                                     
         fd_set __user *, exp, struct timeval __user *, tvp)
        
        --->>> core_sys_select(n, inp, outp, exp, to);
 
            --->>>  do_select(n, &fds, end_time);
        
                --->>> mask = (*f_op->poll)(file, wait);

    /***********************************************************************
     *返回值:
     *        返回0,代表条件不满足
     *        POLLIN
     *        POLLOUT
     **********************************************************************/
                    
    unsigned int demo_poll(struct file *filp, struct poll_table_struct *wait)
    {
        poll_wait();
        return 0;
    }

    typedef struct poll_table_struct {
        poll_queue_proc _qproc;
        unsigned long _key;
    } poll_table;

    /***********************************************************************************
     *功能:
     *参数:
     *            @filp                file结构体指针 
     *            @wait_address        等待队列头
     *            @p                     poll_table *
     *返回值:void
     **********************************************************************************/
     void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)


【二】、异步通知

    通知机制
    
    条件满足通知(驱动通知应用层进程)
    
    通知  --->>>  信号 
    
    #include <signal.h>

    typedef void (*sighandler_t)(int);

    sighandler_t signal(int signum, sighandler_t handler);
    
    --------------------------------------------------------------
    
    开启异步通知功能:
    
    
    int fcntl(int fd,int cmd, ... /* arg */ );

    异步通知开关(flags):FASYNC
    
    F_GETFL
    F_SETFL
    F_SETOWN
    
    --------------------------------------------------------------
    
    fcntl(fd,F_SETFL,FASYNC | fcntl(fd,F_GETFL));
    
    fcntl(fd,F_SETOWN,getpid());
    
    
    --->>> SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
    
        --->>> do_fcntl(fd, cmd, arg, filp);
            
            --->>> err = setfl(fd, filp, arg);
            
            --->>> 
            
     if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op &&filp->f_op->fasync) {
            error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);                                               
            if (error < 0)
                goto out;
            if (error > 0)
                error = 0;
     }

     int (*fasync) (int, struct file *, int);  //开启异步通知功能
 
 
------------------------------------------------------------------------------------------

     int demo_fasync(int fd, struct file *filp, int on)
     {
        
        return 0;
     }
        
    /***********************************************************************************
     *功能: 初始化异步通知结构体,并插入到异步通知队列中
     *参数:
     *            @fd        文件描述符
     *            @filp   file结构体指针 
     *            @on        异步通知开关
     *            @fapp    异步通知结构体
     *返回值:失败返回负数错误码 , 成功返回0
     **********************************************************************************/
     int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
    
     POLL_IN / POLL_OUT 
    
     29) SIGIO    
    
     void kill_fasync(struct fasync_struct **fp, int signal, int band)
    
    
【三】、GPIO子系统

    LED --->> 控制灯
    KEY --->> 读取按键值
    
    <linux/gpio.h>
     
    GPIOF_DIR_OUT     
    GPIOF_DIR_IN     

    GPIOF_INIT_LOW     
    GPIOF_INIT_HIGH         
    
    GPIOF_OUT_INIT_LOW
    GPIOF_OUT_INIT_HIGH
        
    struct gpio {
        unsigned    gpio;            //gpio 号
        unsigned long    flags;        //标志
        const char    *label;            //gpio名字
    };
        
    gpio编号:

    为GPIO统一编号:

    GPIOA0 ~ GPIOA31    (0  ~ 31)
    GPIOB0 ~ GPIOB31    (32 ~ 63)
    ...    
    
    /***********************************************************
     *请求一个指定的GPIO,如果该gpio没有其他驱动使用,返回真,
     *如果有其他驱动使用该GPIO,返回负数错误码
     **********************************************************/
     int gpio_request(unsigned gpio, const char *label)
     void gpio_free(unsigned gpio)
     
    /* 请求gpio ,并设置flags */
     int gpio_request_one(unsigned gpio,unsigned long flags, const char *label)
    
    /**************************************************************
        *功能:请求一组gpio 
     *参数: 
     *            @array 结构体数组
     *            @num   结构体数组元素个数
     *************************************************************/
     int gpio_request_array(const struct gpio *array, size_t num)
     void gpio_free_array(const struct gpio *array, size_t num)
     
     int gpio_direction_input(unsigned gpio) //设置gpio输入模式
     int gpio_direction_output(unsigned gpio, int value) //设置gpio输出模式,并设置输出值
     
     int gpio_get_value(unsigned gpio)                  //获取gpio引脚值
     void gpio_set_value(unsigned gpio, int value)     //设置gpio引脚值
    
     int gpio_to_irq(unsigned gpio)   //根据GPIO号获取中断号 

     红灯    GPIOA28            --->>>          (0*32 + 28)
     绿灯    GPIOE13            --->>>          (4*32 + 13)
     蓝灯   GPIOB12            --->>>          (1*32 + 12)

   
     
     

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值