嵌入式linux学习记录十三

嵌入式linux学习记录十三
  1. 这是 Linux 驱动开发中利用原子变量(Atomic Variable)实现“互斥锁(设备只能被一个进程打开)”的经典逻辑。
    /* 通过判断原子变量的值来检查LED 有没有被别的应用使用 */

    if (!atomic_dec_and_test(&gpioled.lock)) {

    atomic_inc(&gpioled.lock);/* 小于0 的话就加1,使其原子变量等于0 */

    return -EBUSY; /* LED 被使用,返回忙 */

    }
    /* 执行需要保护的资源 */
    /* 完成对资源操作后,把锁加1,恢复成资源可以使用的状态 */
    atomic_inc(&gpioled.lock);

  2. 这展示了在 Linux 驱动开发中,利用自旋锁(Spinlock)+ 普通变量(dev_stats)实现设备互斥访问(只允许一个进程打开)的另一种标准写法。
    spin_lock_irqsave(&gpioled.lock, flags); /* 上锁 */

    if (gpioled.dev_stats)

    { /* 如果设备被使用了 */

    spin_unlock_irqrestore(&gpioled.lock, flags); /* 解锁 */

    return -EBUSY;

    }

    gpioled.dev_stats++; /* 如果设备没有打开,那么就标记已经打开了 */

    spin_unlock_irqrestore(&gpioled.lock, flags); /* 解锁 */
    /* 对受保护资源进行操作 */
    /* 资源操作完成后,需要把普通变量(dev_stats)变成0,以恢复资源可操作性 */

    spin_lock_irqsave(&gpioled.lock, flags); /* 上锁 */

    if (gpioled.dev_stats) {

    gpioled.dev_stats--;

    }

    spin_unlock_irqrestore(&gpioled.lock, flags);/* 解锁 */


    解释:

    1. 自旋锁的角色(保镖):它的任务非常短命。它的存在仅仅是为了保护if (gpioled.dev_stats)dev_stats++这两行代码在多核并行时不被打扰。它就像一个保镖,护送进程安全地完成“检查并登记”这个动作。

    2. dev_stats的角色(登记簿):它的任务非常长命。一旦被写成1,它就会一直保持为1,直到用户层主动调用close()关闭设备。它负责长达几小时、甚至几天的硬件资源占有标记。