火拼是什么意思| 心超是检查什么的| 骨密度增高是什么意思| 熟络是什么意思| 皮肤过敏有什么好办法| 一视同仁什么意思| 喝酸梅汤有什么好处| 腹部胀疼是什么原因| 南瓜什么季节成熟| 流汗多是什么原因| 身上发痒是什么原因| 苕皮是什么| 喝什么水减肥最快| 心电轴右偏是什么意思| 一月十号是什么星座| zara中文叫什么| 酸菜鱼用什么鱼| 头发染什么颜色显皮肤白显年轻| 初一不能做什么| 山代表什么动物| 补办医保卡需要什么资料| 喉咙痰多吃什么药最好| 喝茶水对身体有什么好处| 1961年属什么| 上不来气是什么原因| 晚上睡觉经常醒是什么原因| 肺部有阴影一般是什么病| 木耳和什么不能一起吃| 坐阵是什么意思| 醋纤是什么面料| 尿液发白是什么原因| 为什么会长粉刺| nuxe是什么牌子| 1025是什么星座| 胳膊出汗是什么原因| 湖北有什么好吃的| 血脂高挂什么科| 胃左边疼是什么原因| 莳花弄草是什么意思| 10.30什么星座| 白带多用什么药| 释迦牟尼是什么意思| 男性阴囊潮湿是什么病| 八月十一号是什么星座| 鲨鱼吃什么| 大校相当于政府什么官| 脾肾两虚吃什么中成药| 如花是什么意思| 十二星座什么第一名| 梦到发洪水是什么征兆| 安抚奶嘴什么时候开始用| 胆固醇高是什么引起的| 上海市委书记什么级别| 拉肚子是什么原因导致的| 醒酒喝什么饮料| 草莓是什么植物| 低压高有什么危险| 宫颈lsil是什么意思| 孕晚期吃什么好| 淋巴炎吃什么药效果好| 网友见面叫什么| 蜂蜜水什么时间喝最好| 经常咳嗽是什么原因| 瘁是什么意思| 治妇科炎症用什么药好| 电子烟有什么危害| 大连是什么海| 汕头市花是什么花| 小孩喉咙发炎吃什么药好| 所不欲勿施于人是什么意思| 胎心胎芽是什么意思| 昏厥是什么意思| 咳嗽吃什么好的快| robot什么意思| 张飞的兵器是什么| 零星是什么意思| 酸菜是什么菜做的| 慈禧和光绪是什么关系| 金鱼可以和什么鱼混养| 点痣去医院挂什么科| 喝酒不能吃什么东西| 我要控制我自己是什么歌| 手指甲出现竖纹是什么原因| 伤口愈合慢是什么原因| 流产用什么药最快| 西游记告诉我们什么道理| 绯闻是什么意思| 18k金和24k金有什么区别| 刺青是什么意思| gas是什么意思| 死精是什么样的颜色| 佛度有缘人是什么意思| 喝什么茶降血压最好最快| 突然勃不起来是什么原因造成的| 外阴苔癣是一种什么病| 阑尾炎吃什么水果| 经期吃什么| 桃花眼的女人什么命| 解落三秋叶的解是什么意思| 过敏性皮肤用什么护肤品比较好| 真空是什么意思| dia什么意思| 骞是什么意思| 潘多拉魔盒是什么意思| 种牙和假牙有什么区别| 眼睛痒是怎么回事用什么药| 阿戈美拉汀片是什么药| 单于是什么意思| 什么动物三只爪| 口香糖是什么材料做的| 传销是什么意思| 每天吃一个西红柿有什么好处| 棱角分明是什么意思| 吃饭出虚汗是什么原因| 老花眼有什么办法可以恢复| 筷子什么材质最好| 麾下什么意思| 卡介苗是预防什么的| 双脚麻木是什么病的前兆| 什么水果对胃好更养胃| 来月经属于什么期| 女娲补天是什么生肖| 空调自动关机是什么原因| c4是什么| 老年人腿脚无力是什么原因| 嘴唇发麻是什么病兆| 劲旅是什么意思| 体力不支是什么意思| 生理盐水是什么| 神母是什么病| 一级亲属指的是什么| 男士背心什么牌子好| 看病人送什么水果| 沉香是什么味道| 梦见好多西瓜是什么意思| 面色少华是什么意思| 黄瓜不能和什么食物一起吃| 吃什么能降血压最有效| 排骨汤什么时候放盐最好| mb是什么意思| 品学兼优是什么意思| 子宫内膜增厚是什么意思| 心电图st段改变什么意思| 什么是三公经费| 孕囊小是什么原因| 91年羊是什么命| 狗狗为什么会得细小| 乙肝病毒核心抗体阳性是什么意思| 采耳是什么意思| 手抖吃什么药| 胆囊肿是什么病严重吗| 急性肠胃炎吃什么药效果好| 测幽门螺旋杆菌挂什么科| 狗狗产后吃什么下奶多| 狗取什么名字好| 尿酸高适合吃什么食物| 姜黄粉是什么| 母亲节送母亲什么礼物| 熬夜到什么程度会猝死| 磁共振是做什么的| 列席人员什么意思| 受凉胃疼吃什么药| 核黄素是什么| scc什么意思| 眼睛充血是什么原因造成的| 暗代表什么生肖| 神经性耳鸣吃什么药| 什么叫宫腔粘连| 狂躁症吃什么药| 灵芝与什么相克| 深邃是什么意思| 女生被操是什么感觉| 后背发痒是什么原因| 寿司用什么米做好吃| 马卡龙是什么| 民兵是干什么的| 屎壳郎长什么样| catl是什么意思| 什么是象声词| 韭菜有什么功效| c反应蛋白偏高是什么原因| 狗为什么不能吃洋葱| 搬新家有什么讲究和准备的| 新生儿甲状腺偏高有什么影响| 六月六是什么节| 冰糖里面为什么有白线| 尚公主是什么意思| 白敬亭原名叫什么| 热狗为什么叫热狗| 发痧用什么方法好得快| 1月什么星座| 左眼皮上有痣代表什么| 西安有什么美食| qid医学上是什么意思| 空蝶鞍是什么意思| 孩子张嘴睡觉是什么原因| 增大摩擦力的方法有什么| 黄芪加陈皮有什么功效| 长白班是什么意思| 手关节疼痛是什么原因| 精神心理科主要治疗什么疾病| 潮宏基是什么档次的| 头发爱出油是什么原因| 一般什么人戴江诗丹顿| 狗狗感冒了是什么症状| 血小板偏高有什么危害| 什么是热病| 汽车abs是什么意思| 处暑是什么节气| 甚微是什么意思| 楚国是现在的什么地方| 梦见舅舅是什么意思| 什么中不足成语| 黄瓜又什么又什么| 眼睛充血是什么原因引起的| 人体乳头瘤病毒是什么| pu什么意思| 汉语拼音什么时候发明的| 树根有什么作用| 笑点低是什么意思| 反射弧太长是什么意思| 什么是三净肉| 一周不排便是什么原因| 口干舌燥什么原因| 经常射精有什么危害| 根管治疗后要注意什么| 涂素颜霜之前要涂什么| mice是什么意思| 地奥心血康软胶囊主治什么病| 狗上皮过敏是什么意思| 牛和什么生肖最配| 鼻塞是什么原因| 7.14什么情人节| 增生期子宫内膜是什么意思| 喝山楂水有什么好处和坏处| 什么药止咳最好| legacy什么意思| 白芷有什么作用与功效| 什么的石榴| 四五月份是什么星座| 什么是钙化点| 甲减是什么原因引起的| 侏儒症是缺乏什么元素| 变爻是什么意思| 姐姐的儿子叫什么| 欧舒丹属于什么档次| 胃炎吃什么消炎药| 产厄是什么意思| 什么人不适合喝骆驼奶| 恶心是什么原因| 云是什么意思| 超声科是什么科室| 吃什么东西对眼睛好| 阳虚吃什么| bbd是什么意思| 月经为什么来了一点又不来了| 男女之间的吸引靠什么| 拉肚子是什么原因引起的怎么办| 挚肘是什么意思| 11月17号是什么星座| 皮卡丘站起来变成了什么| 围棋九段是什么水平| 乔其纱是什么面料| 今年什么时候暑伏| 百度
这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 ? 论坛首页 ? 嵌入式开发 ? 软件与操作系统 ? rtthread sensor V2 框架分析

共1条 1/1 1 跳转至

rtthread sensor V2 框架分析

高工
2025-08-04 22:03:26     打赏
百度 按照总书记重要指示精神,韩正书记和上海市委高度重视、迅速跟进、靠前指挥、亲力亲为、抓早动实,牵头制定了“人才20条”和升级版的“人才30条”,推出了一系列创新性的制度机制,形成人才改革的“四梁八柱”,有效激发了人才的创新创业活力。

       rtthread的sensor框架存在两个版本,其中V2版的框架号称是为了解决V1对多传感器共用一颗IC的场景支持问题而设计的(之前PR群内沟通迭代计划时提到的)。

源码解析

源码路径

components\drivers\sensor\v2\sensor.c

注册入口

/**
 *                 Sensor mode
 *              rt_uint16_t mode
 *   0000   |    0000    |   0000   |    0000
 *  unused     accuracy      power     fetch data
 */
#define RT_SENSOR_MODE_ACCURACY_BIT_OFFSET    (8)
#define RT_SENSOR_MODE_POWER_BIT_OFFSET       (4)
#define RT_SENSOR_MODE_FETCH_BIT_OFFSET       (0)

#define RT_SENSOR_MODE_GET_ACCURACY(mode)     (rt_uint8_t)((mode >> RT_SENSOR_MODE_ACCURACY_BIT_OFFSET) & 0x0F)
#define RT_SENSOR_MODE_GET_POWER(mode)        (rt_uint8_t)((mode >> RT_SENSOR_MODE_POWER_BIT_OFFSET) & 0x0F)
#define RT_SENSOR_MODE_GET_FETCH(mode)        (rt_uint8_t)((mode >> RT_SENSOR_MODE_FETCH_BIT_OFFSET) & 0x0F)

#define RT_SENSOR_MODE_CLEAR_ACCURACY(mode)   (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET)))
#define RT_SENSOR_MODE_CLEAR_POWER(mode)      (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_POWER_BIT_OFFSET)))
#define RT_SENSOR_MODE_CLEAR_FETCH(mode)      (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_FETCH_BIT_OFFSET)))

#define RT_SENSOR_MODE_SET_ACCURACY(mode, accuracy_mode) RT_SENSOR_MODE_CLEAR_ACCURACY(mode); (mode |= (accuracy_mode << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET))
#define RT_SENSOR_MODE_SET_POWER(mode, power_mode)       RT_SENSOR_MODE_CLEAR_POWER(mode); (mode |= (power_mode << RT_SENSOR_MODE_POWER_BIT_OFFSET))
#define RT_SENSOR_MODE_SET_FETCH(mode, fetch_mode)       RT_SENSOR_MODE_CLEAR_FETCH(mode); (mode |= (fetch_mode << RT_SENSOR_MODE_FETCH_BIT_OFFSET))

static char *const sensor_name_str[] =
{
    "None",
    "ac-",       /* Accelerometer     */
    "gy-",       /* Gyroscope         */
    "ma-",       /* Magnetometer      */
    "tm-",       /* Temperature       */
    "hm-",       /* Relative Humidity */
    "br-",       /* Barometer         */
    "li-",       /* Ambient light     */
    "pr-",       /* Proximity         */
    "hr-",       /* Heart Rate        */
    "tv-",       /* TVOC Level        */
    "ni-",       /* Noise Loudness    */
    "st-",       /* Step sensor       */
    "fr-",       /* Force sensor      */
    "du-",       /* Dust sensor       */
    "ec-",       /* eCO2 sensor       */
    "gn-",       /* GPS/GNSS sensor   */
    "tf-",       /* TOF sensor        */
    "sp-",       /* SpO2 sensor       */
    "ia-",       /* IAQ sensor        */
    "et-",       /* EtOH sensor       */
    "bp-",       /* Blood Pressure    */
    RT_NULL
};

/* sensor local ops */
static rt_ssize_t _local_fetch_data(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len)
{
    LOG_D("Undefined fetch_data");
    return -RT_EINVAL;
}
static rt_err_t _local_control(rt_sensor_t sensor, int cmd, void *arg)
{
    LOG_D("Undefined control");
    return -RT_EINVAL;
}

static struct rt_sensor_ops local_ops =
{
    .fetch_data = _local_fetch_data,
    .control = _local_control
};

int rt_hw_sensor_register(rt_sensor_t    sensor,
                          const char    *name,
                          rt_uint32_t    flag,
                          void          *data)
{
    rt_int8_t result;
    rt_device_t device;
    RT_ASSERT(sensor != RT_NULL);

    char *sensor_name = RT_NULL, *device_name = RT_NULL;

    if (sensor->ops == RT_NULL)
    {
        sensor->ops = &local_ops;
    }

    /* Add a type name for the sensor device */
    sensor_name = sensor_name_str[sensor->info.type];
    device_name = (char *)rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name));
    if (device_name == RT_NULL)
    {
        LOG_E("device_name calloc failed!");
        return -RT_ERROR;
    }

    rt_memcpy(device_name, sensor_name, rt_strlen(sensor_name) + 1);
    strcat(device_name, name);

    if (sensor->module != RT_NULL && sensor->module->lock == RT_NULL)
    {
        /* Create a mutex lock for the module */
        sensor->module->lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO);
        if (sensor->module->lock == RT_NULL)
        {
            rt_free(device_name);
            return -RT_ERROR;
        }
    }

    device = &sensor->parent;

#ifdef RT_USING_DEVICE_OPS
    device->ops         = &rt_sensor_ops;
#else
    device->init        = RT_NULL;
    device->open        = _sensor_open;
    device->close       = _sensor_close;
    device->read        = _sensor_read;
    device->write       = RT_NULL;
    device->control     = _sensor_control;
#endif
    device->type        = RT_Device_Class_Sensor;
    device->rx_indicate = RT_NULL;
    device->tx_complete = RT_NULL;
    device->user_data   = data;

    result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE);
    if (result != RT_EOK)
    {
        LOG_E("sensor[%s] register err code: %d", device_name, result);
        rt_free(device_name);
        return result;
    }

    LOG_I("sensor[%s] init success", device_name);
    rt_free(device_name);

    return RT_EOK;
}

    注册函数和v1版相比,除了名称外,几乎没有任何修改,因此可以沿用v1的分析。

打开入口

static void _sensor_cb(rt_sensor_t sen)
{
    if (sen->parent.rx_indicate == RT_NULL)
    {
        return;
    }

    if (sen->irq_handle != RT_NULL)
    {
        sen->irq_handle(sen);
    }

    /* The buffer is not empty. Read the data in the buffer first */
    if (sen->data_len > 0)
    {
        sen->parent.rx_indicate(&sen->parent, sen->data_len / sizeof(struct rt_sensor_data));
    }
    else if (RT_SENSOR_MODE_GET_FETCH(sen->info.mode) == RT_SENSOR_MODE_FETCH_INT)
    {
        /* The interrupt mode only produces one data at a time */
        sen->parent.rx_indicate(&sen->parent, 1);
    }
    else if (RT_SENSOR_MODE_GET_FETCH(sen->info.mode) == RT_SENSOR_MODE_FETCH_FIFO)
    {
        sen->parent.rx_indicate(&sen->parent, sen->info.fifo_max);
    }
}

static void _irq_callback(void *args)
{
    rt_sensor_t sensor = (rt_sensor_t)args;
    rt_uint8_t i;

    if (sensor->module)
    {
        /* Invoke a callback for all sensors in the module */
        for (i = 0; i < sensor->module->sen_num; i++)
        {
            _sensor_cb(sensor->module->sen[i]);
        }
    }
    else
    {
        _sensor_cb(sensor);
    }
}

static rt_err_t _sensor_irq_init(rt_sensor_t sensor)
{
    if (sensor->config.irq_pin.pin == PIN_IRQ_PIN_NONE)
    {
        return -RT_EINVAL;
    }

    rt_pin_mode(sensor->config.irq_pin.pin, sensor->config.irq_pin.mode);

    if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN)
    {
        rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING, _irq_callback, (void *)sensor);
    }
    else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP)
    {
        rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, _irq_callback, (void *)sensor);
    }
    else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT)
    {
        rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, _irq_callback, (void *)sensor);
    }

    rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_TRUE);

    LOG_I("interrupt init success");

    return 0;
}

static rt_err_t _sensor_open(rt_device_t dev, rt_uint16_t oflag)
{
    rt_sensor_t sensor = (rt_sensor_t)dev;
    RT_ASSERT(dev != RT_NULL);
    rt_err_t res = RT_EOK;
    rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) =  _local_control;

    if (sensor->module)
    {
        /* take the module mutex */
        rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
    }

    if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf == RT_NULL)
    {
        /* Allocate memory for the sensor buffer */
        sensor->data_buf = rt_malloc(sizeof(struct rt_sensor_data) * sensor->info.fifo_max);
        if (sensor->data_buf == RT_NULL)
        {
            res = -RT_ENOMEM;
            goto __exit;
        }
    }
    if (sensor->ops->control != RT_NULL)
    {
        local_ctrl = sensor->ops->control;
    }

    if (oflag & RT_DEVICE_FLAG_RDONLY && dev->flag & RT_DEVICE_FLAG_RDONLY)
    {
        /* If polling mode is supported, configure it to polling mode */
        if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_FETCH_MODE, (void *)RT_SENSOR_MODE_FETCH_POLLING) == RT_EOK)
        {
            RT_SENSOR_MODE_SET_FETCH(sensor->info.mode, RT_SENSOR_MODE_FETCH_POLLING);
        }
    }
    else if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX)
    {
        /* If interrupt mode is supported, configure it to interrupt mode */
        if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_FETCH_MODE, (void *)RT_SENSOR_MODE_FETCH_INT) == RT_EOK)
        {
            /* Initialization sensor interrupt */
            _sensor_irq_init(sensor);
            RT_SENSOR_MODE_SET_FETCH(sensor->info.mode, RT_SENSOR_MODE_FETCH_INT);
        }
    }
    else if (oflag & RT_DEVICE_FLAG_FIFO_RX && dev->flag & RT_DEVICE_FLAG_FIFO_RX)
    {
        /* If fifo mode is supported, configure it to fifo mode */
        if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_FETCH_MODE, (void *)RT_SENSOR_MODE_FETCH_FIFO) == RT_EOK)
        {
            /* Initialization sensor interrupt */
            _sensor_irq_init(sensor);
            RT_SENSOR_MODE_SET_FETCH(sensor->info.mode, RT_SENSOR_MODE_FETCH_FIFO);
        }
    }
    else
    {
        res = -RT_EINVAL;
        goto __exit;
    }

    /* Configure power mode to highest mode */
    if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER_MODE, (void *)RT_SENSOR_MODE_POWER_HIGHEST) == RT_EOK)
    {
        RT_SENSOR_MODE_SET_POWER(sensor->info.mode, RT_SENSOR_MODE_POWER_HIGHEST);
    }

    /* Configure accuracy mode to highest mode */
    if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_ACCURACY_MODE, (void *)RT_SENSOR_MODE_ACCURACY_HIGHEST) == RT_EOK)
    {
        RT_SENSOR_MODE_SET_ACCURACY(sensor->info.mode, RT_SENSOR_MODE_ACCURACY_HIGHEST);
    }

__exit:
    if (sensor->module)
    {
        /* release the module mutex */
        rt_mutex_release(sensor->module->lock);
    }

    return res;
}

      和V1版本相比,主要修改点有以下部分:

        a.sen->info.mode的作用范围变宽,原先8bit表示一个意思,现在时3bit表示3种功能,剩余5bit为保留位,对应的操作也改为宏的方式隐藏

        b.RT_PIN_NONE 变成了 PIN_IRQ_PIN_NONE,实际功能一致,个人怀疑是版本修改漏同步了v1

        c.对应驱动的RT_SENSOR_CTRL_SET_MODE入口变成了 RT_SENSOR_CTRL_SET_FETCH_MODE,对应的传递到驱动的参数也由 RT_SENSOR_MODE_xxxx 变成了 RT_SENSOR_MODE_FETCH_xxxx,实际功能未变化

        d.对应驱动的 RT_SENSOR_CTRL_SET_POWER入口变成了RT_SENSOR_CTRL_SET_POWER_MODE,参数 RT_SENSOR_POWER_NORMAL 变成了 RT_SENSOR_MODE_POWER_HIGHEST,具体功能未知,需从包管理器里面找到v2版驱动对应实现才清楚

        e.新增接口 RT_SENSOR_CTRL_SET_ACCURACY_MODE,具体功能未知

关闭入口

static rt_err_t _sensor_close(rt_device_t dev)
{
    rt_sensor_t sensor = (rt_sensor_t)dev;
    rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control;
    int i;

    RT_ASSERT(dev != RT_NULL);

    if (sensor->module)
    {
        rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
    }
    if (sensor->ops->control != RT_NULL)
    {
        local_ctrl = sensor->ops->control;
    }

    /* Configure power mode to power down mode */
    if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER_MODE, (void *)RT_SENSOR_MODE_POWER_DOWN) == RT_EOK)
    {
        RT_SENSOR_MODE_SET_POWER(sensor->info.mode, RT_SENSOR_MODE_POWER_DOWN);
    }

    if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL)
    {
        for (i = 0; i < sensor->module->sen_num; i ++)
        {
            if (sensor->module->sen[i]->parent.ref_count > 0)
                goto __exit;
        }

        /* Free memory for the sensor buffer */
        for (i = 0; i < sensor->module->sen_num; i ++)
        {
            if (sensor->module->sen[i]->data_buf)
            {
                rt_free(sensor->module->sen[i]->data_buf);
                sensor->module->sen[i]->data_buf = RT_NULL;
            }
        }
    }
    if (RT_SENSOR_MODE_GET_FETCH(sensor->info.mode) != RT_SENSOR_MODE_FETCH_POLLING)
    {
        /* Sensor disable interrupt */
        if (sensor->config.irq_pin.pin != PIN_IRQ_PIN_NONE)
        {
            rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
        }
    }

__exit:
    if (sensor->module)
    {
        rt_mutex_release(sensor->module->lock);
    }

    return RT_EOK;
}

      相比较于打开接口,关闭接口除了改变函数名称和参数名称,并未改任何功能,因此对照v1看就可以了。

读入口

static rt_ssize_t _sensor_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len)
{
    rt_sensor_t sensor = (rt_sensor_t)dev;
    rt_size_t result = 0;
    RT_ASSERT(dev != RT_NULL);

    if (buf == NULL || len == 0)
    {
        return 0;
    }

    if (sensor->module)
    {
        rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
    }

    /* The buffer is not empty. Read the data in the buffer first */
    if (sensor->data_len > 0)
    {
        if (len > sensor->data_len / sizeof(struct rt_sensor_data))
        {
            len = sensor->data_len / sizeof(struct rt_sensor_data);
        }

        rt_memcpy(buf, sensor->data_buf, len * sizeof(struct rt_sensor_data));

        /* Clear the buffer */
        sensor->data_len = 0;
        result = len;
    }
    else
    {
        /* If the buffer is empty, read the data */
        if (sensor->ops->fetch_data)
        {
            result = sensor->ops->fetch_data(sensor, buf, len);
        }
    }

    if (sensor->module)
    {
        rt_mutex_release(sensor->module->lock);
    }

    return result;
}

      与关闭接口一致,读入口也没有改变任何功能,仅仅是参数名和函数名的修改。

控制入口

static rt_err_t _sensor_control(rt_device_t dev, int cmd, void *args)
{
    rt_sensor_t sensor = (rt_sensor_t)dev;
    rt_err_t result = RT_EOK;
    RT_ASSERT(dev != RT_NULL);
    rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control;
    rt_uint8_t mode;

    if (sensor->module)
    {
        rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
    }
    if (sensor->ops->control != RT_NULL)
    {
        local_ctrl = sensor->ops->control;
    }

    switch (cmd)
    {
        case RT_SENSOR_CTRL_GET_ID:
            if (args)
            {
                result = local_ctrl(sensor, RT_SENSOR_CTRL_GET_ID, args);
            }
            break;
        case RT_SENSOR_CTRL_SET_ACCURACY_MODE:
            /* Configuration sensor power mode */
            mode = (rt_uint32_t)args & 0x000F;
            if (!(mode == RT_SENSOR_MODE_ACCURACY_HIGHEST || mode == RT_SENSOR_MODE_ACCURACY_HIGH ||\
                  mode == RT_SENSOR_MODE_ACCURACY_MEDIUM  || mode == RT_SENSOR_MODE_ACCURACY_LOW  ||\
                  mode == RT_SENSOR_MODE_ACCURACY_LOWEST  || mode == RT_SENSOR_MODE_ACCURACY_NOTRUST))
            {
                LOG_E("sensor accuracy mode illegal: %d", mode);
                return -RT_EINVAL;
            }
            result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_ACCURACY_MODE, args);
            if (result == RT_EOK)
            {
                RT_SENSOR_MODE_SET_ACCURACY(sensor->info.mode, mode);
                LOG_D("set accuracy mode code: %d", RT_SENSOR_MODE_GET_ACCURACY(sensor->info.mode));
            }
            break;
        case RT_SENSOR_CTRL_SET_POWER_MODE:
            /* Configuration sensor power mode */
            mode = (rt_uint32_t)args & 0x000F;
            if (!(mode == RT_SENSOR_MODE_POWER_HIGHEST || mode == RT_SENSOR_MODE_POWER_HIGH ||\
                  mode == RT_SENSOR_MODE_POWER_MEDIUM  || mode == RT_SENSOR_MODE_POWER_LOW  ||\
                  mode == RT_SENSOR_MODE_POWER_LOWEST  || mode == RT_SENSOR_MODE_POWER_DOWN))
            {
                LOG_E("sensor power mode illegal: %d", mode);
                return -RT_EINVAL;
            }
            result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER_MODE, args);
            if (result == RT_EOK)
            {
                RT_SENSOR_MODE_SET_POWER(sensor->info.mode, mode);
                LOG_D("set power mode code: %d", RT_SENSOR_MODE_GET_POWER(sensor->info.mode));
            }
            break;
        case RT_SENSOR_CTRL_SET_FETCH_MODE:
            /* Configuration sensor power mode */
            mode = (rt_uint32_t)args & 0x000F;
            if (!(mode == RT_SENSOR_MODE_FETCH_POLLING || mode == RT_SENSOR_MODE_FETCH_INT ||\
                  mode == RT_SENSOR_MODE_FETCH_FIFO))
            {
                LOG_E("sensor fetch data mode illegal: %d", mode);
                return -RT_EINVAL;
            }
            result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_FETCH_MODE, args);
            if (result == RT_EOK)
            {
                RT_SENSOR_MODE_SET_FETCH(sensor->info.mode, mode);
                LOG_D("set fetch mode code: %d", RT_SENSOR_MODE_GET_FETCH(sensor->info.mode));
            }
            break;
        case RT_SENSOR_CTRL_SELF_TEST:
            /* device self test */
            result = local_ctrl(sensor, RT_SENSOR_CTRL_SELF_TEST, args);
            break;
        case RT_SENSOR_CTRL_SOFT_RESET:
            /* device soft reset */
            result = local_ctrl(sensor, RT_SENSOR_CTRL_SOFT_RESET, args);
            break;
        default:
            if (cmd > RT_SENSOR_CTRL_USER_CMD_START)
            {
                /* Custom commands */
                result = local_ctrl(sensor, cmd, args);
            }
            else
            {
                result = -RT_EINVAL;
            }
            break;
    }

    if (sensor->module)
    {
        rt_mutex_release(sensor->module->lock);
    }

    return result;
}

      控制入口算是V2版框架改动最大的地方,主要修改如下:

            a.去掉了入口 RT_SENSOR_CTRL_GET_INFO,其实这个入口在V1上也没啥用,仅仅是系统自带的测试命令需要的入口,而v2版改为直接处理了,不再调用一层。

            b.去掉了 RT_SENSOR_CTRL_SET_RANGE 和 RT_SENSOR_CTRL_SET_ODR两个入口,这个有点无厘头,因为按我理解,其实大部分传感器都支持设置采样率和量程范围的功能,去掉这个接口,意味着只能靠驱动自己内部默认几个参数了

            c.RT_SENSOR_CTRL_SET_POWER 变成了 RT_SENSOR_CTRL_SET_POWER_MODE,功能个人猜测应该没变,但需要找已经适配的代码具体确认

            d.新增了 RT_SENSOR_CTRL_SET_ACCURACY_MODE入口,具体功能未知,需找已适配的代码去确认

            e.新增了入口 RT_SENSOR_CTRL_SET_FETCH_MODE,具体功能为切换传感器的工作模式(中断,轮询,FIFO)

            f.新增了入口 RT_SENSOR_CTRL_SOFT_RESET,从名称上感觉是软复位,是否是需看已适配的v2驱动

新增入口 -- 查找传感器设备

rt_sensor_t rt_sensor_device_find(const char *name)
{
    rt_uint8_t index;
    char device_name[RT_NAME_MAX];
    rt_device_t device;

    for (index = 0; sensor_name_str[index] != RT_NULL; index++)
    {
        rt_memset(device_name, 0, sizeof(device_name));
        rt_snprintf(device_name, sizeof(device_name), "%s%s", sensor_name_str[index], name);
        device = rt_device_find(device_name);
        if (device != RT_NULL)
        {
            return (rt_sensor_t)device;
        }
    }

    return RT_NULL;
}

     老实说,个人认为这个入口就是个坑,完全没考虑一颗芯片包含多种传感器的场景,如果不存在这种场景,可以考虑用一下这个接口,如果存在,那就不要用,很容易变成想要一个功能传感器,但拿到的是另一个功能的传感器。

总结

    至此,v2版驱动已经分析完毕,相比较于v1版的驱动框架,个人认为宣传的改进不算大,相反,v2框架还去掉了一些必要的选项(量程和采样率的设置),反而限制了v2版传感器框架的使用。如果使用的话,在v2版框架成熟前,个人倾向于优先使用v1版传感器框架。事实上,如果没记错的话,去年下半年,rtt官方也默认禁用了V2版框架,个人猜测也是因为类似的原因吧。




关键词: rtthread     sensor     框架     分析     v2    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]
心悸是什么原因引起的 人夫是什么意思 一个雨一个亏念什么 挂钟挂在客厅什么位置好 热络是什么意思
小孩小便红色是什么原因 7月22日是什么星座 落下帷幕什么意思 姑姑叫我什么 肝囊肿是什么
是什么符号 肺阴虚吃什么食物最好 晚上睡觉脚冰凉是什么原因 树叶为什么是绿色的 rh血型阳性什么意思
04年属猴的是什么命 埋单是什么意思 梦到前女友是什么意思 肚脐左侧疼是什么原因 为什么会有痔疮
做肠镜前一天可以吃什么hcv9jop2ns6r.cn 煲电话粥什么意思hcv9jop2ns3r.cn 脸色发黑发暗是什么原因hcv8jop7ns0r.cn 黄果树是什么树hcv9jop8ns0r.cn 中出是什么意识liaochangning.com
什么山没有石头hcv9jop2ns4r.cn 牙疼吃什么消炎药sscsqa.com alk是什么意思hcv8jop1ns1r.cn 朱元璋为什么杀徐达hcv8jop4ns9r.cn 草果在炖肉起什么作用hcv8jop6ns9r.cn
喝酒手发抖是什么原因hcv8jop1ns1r.cn 姜还是老的辣是什么意思hcv7jop5ns2r.cn 音序是什么意思hcv7jop4ns8r.cn 什么是重力hcv8jop8ns9r.cn mm是什么病hcv9jop0ns4r.cn
手关节疼痛是什么原因hcv7jop9ns0r.cn 人为什么会抑郁hcv9jop1ns5r.cn 王维是什么派诗人chuanglingweilai.com 内能与什么因素有关hcv7jop9ns7r.cn 环磷酰胺是什么药hcv9jop0ns8r.cn
百度