无线开关大揭秘,原理就是这么简单!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无线开关大揭秘,原理就是这么简单!相关的知识,希望对你有一定的参考价值。

参考技术A

随着人们生活水准的提高,科学技术的不断进步,智慧家居早已不是什么新鲜事物,无线开关更是变成了一种家庭的必需标配,进入寻常百姓家,从电视,空调,乃至儿童玩具,无线开关已经成为我们生活必不可少的一部分,感谢人类的惰性,让我们的生活越来越便捷。


我们都在用遥控无线开关,却不一定都了解它是怎么运作的,所以,今天我要和大家介绍一下遥控无线开关的特点和原理,以方便大家更好的选购遥控无线开关。

遥控无线开关-特点

在了解遥控无线开关的原理之前,我们首先来简单介绍一下遥控无线开关,遥控无线开关其实就是利用射频识别技术,使用无线遥控器对各类器具进行控制的一种新型智慧开关,主要使用范围有各类灯饰、家电、门、窗帘等家居用品,无线开关和遥控器不必配套购买,用户可自由选配,误码率低,

抗干扰能力强,同时操作简单方便,性能稳定可靠,因此,受到广大消费者喜爱。

 

遥控无线开关—原理

遥控无线开关由发射器和接收器两者组合而成,发射器将控制者的控制按键经过编码,调制到射频信号上进行发射出无线信号,也可以说成是一个编码器。

而接收器是将接收到的无线信号进行编码信号再解码,得到与控制按键相对应的信号,然后去控制相应的电路工作了,也被称为解码器。


传输控制指令信号的载体有很多种,但是现在市场上主要用到的是这几种:无线电遥控、超声波遥控、红外线遥控,

家用电视机、空调的遥控大多通过红外线发射、接收控制信号,而儿童玩具遥控多用无线电。

遥控无线开关-优势
遥控无线开关安装异常简单方便,不需要接零线,也不需要对灯饰电器进行任何改动,可直接替换原有开关,电网停电后再来电,

开关会自动处于关闭状态,避免浪费不必要的电能,可以集中控制全家所有的智慧遥控开关。在款式设计上也是多种多样,可供选择面非常广泛,可以将遥控无线开关与传统机械开关进行结合使用,方便简单。

编辑总结:遥控无线开关无线开关

斯米克瓷砖杯第二届设计师大赛,瓜分10万元现金奖

亲,以上内容是否没有解决您的疑问,装修专家团为您提供一对一的咨询服务(装修预算报价审核,户型改造建议,疑难杂症方案,材料购买详解,装修猫腻提醒),请添加微信号:qijia520321

开关 开关插座

内存池原理大揭秘

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由amc发表于云+社区专栏

在 C 语言的动态申请内存技术中,相比起 alloc/free 系统调用,内存池(memory pool)是与现在系统中请求一大片连续的内存空间,然后在运行时根据实际需要分配出去的技术。使用内存池的优点有:

  1. 速度远比 malloc/free 快,因为减少了系统调用的次数,特别是频繁申请/释放内存块的情况
  2. 避免了频繁申请/释放内存之后,系统的大量内存碎片
  3. 节省空间

分类

根据分配出去的内存大小,内存池可以分为两类:

Fixed-size Allocation

每次分配出去的内存单元(称为 unit 或者 cell)的大小为程序预先定义的值。释放内存块时,则只需要简单地挂回内存池链表中即可。又称为 “固定尺寸缓冲池”。

常规的做法是:将不同 unit size 的内存池整合在一起,以满足不同内存块大小的使用需求

Variable-size allocation

不分配固定长度,内存的分配只是在一大块空闲的内存上滑动。优点是分配效率很高,缺点是成批地回收内存,因为释放的内存无法直接重复利用。

使用这种需要合理规划每块内存的管理区域,所以又叫做 “基于区域的” 内存管理。使用这种做法的分配器,举例有 Apache Portable Runtime 中的 apr_pool 工具。本文不讨论这种内存池。


原理和结构

概念和数据结构

定长内存池有一些基本和必要的概念,需要定义在内存池的结构数据中。以下命名方式使用变体的匈牙利命名法,比如 nNextn表示变量类型为×××。类似地,p表示指针。

Memory Unit

每次程序调用 MemPool_Alloc 获取一个内存区域后,会获得一块连续的内存区域。管理一个这样的内存区域的单元就成为内存单元 unit,有时也称作 chunk。每个 unit 需要包含以下数据:

  1. nNext:整型数据,表示下一个可供分配的 unit 的标识号。功能请参见后问
  2. pData[]:实际的内存区域,其大小在创建时由调用方指定

Memory Block

一个内存块,内存块中保存着一系列的内存单元。

这个数据结构需要包含以下基本信息:

  1. nSize:整型数据,表示该 block 在内存中的大小
  2. nFree:整型,表示剩下有几个 unit 未被分配
  3. nFirst:整型,表示下一个可供分配的 unit 的标识号
  4. pNext:指针,指向下一个 memory block

Memory Pool

一个内存池总的管理数据结构,换句话说,是一个内存池对象。

  1. pBlock:指针,指向第一个 memory block
  2. nUnitSize:整型,表示每个 unit 的尺寸
  3. nInitSize:整型,表示第一个 block 的 unit 个数
  4. nGrowSize:整型,表示在第一个 block 之外再继续增加的每个 block 的 unit 个数

函数接口

作为一个内存池,需要实现以下一些基本的函数接口,或者说可以是对象方法:

memPoolCreate()

创建一个 memory pool,必须的参数为 unit size,可选参数为上文 memory pool 的 nInitSizenGrowSize

memPoolDestroy()

销毁整个 memory pool 并交还给操作系统。

memPoolAlloc()

从 memory pool 中分配一个 unit,其尺寸是预先定义的 unit size。

memPoolFree()

释放一个指定的 unit。


工作过程

现在我们用一个 unit size 为 1024、init size 为 4(每一个 block 有 4 个 units)的 memory pool 为例,解释一下内存池的工作原理。下文假设整型的宽度为 4 个字节。

创建 memory pool

程序开始,调用并创建一个 memory pool。此时调用的函数为 memPoolCreate(),程序会创建一个数据结构,相应的结构体成员及其取值如下:

技术分享图片

memory pool alloc

当调用者第一次请求 memPoolAlloc() 时,内存池发现 block 链表为空,于是想系统申请内存,创建 memory block,并初始化如下(其中地址值为假设值):

技术分享图片

其中 nSize = 4112 = sizeof(memPool) + nInitSize * sizeof(memUnit)。每一个 nNext 依次加一,各指代着跟着自己的下一个 unit。最后一个 unit 的 nNext 值无意义,因此不说明其取值。

然后返回需要的 unit 中的内存。返回内存的逻辑如下:

  1. 内存池在 block 中查询 nFree 成员
  2. 由于 nFree > 0,表示有未分配的 unit,因此继续在该 block 中查看 nFirst 成员
  3. nFirst 等于 0,表示该 block 中位置为 0 的 unit 可用。因此内存池可以将这个 unit 中的 pData 地址返回给调用方。 pData 的地址值计算方式为:pBlock + sizeof(memBlock) + nFirst * (sizeof(memUnit)) + sizeof(nNext) = 0x10010
  4. nFree 减一
  5. 修改 nFirst 的值,标记下一个可用的 unit。注意这里的 nFirst 切切不能简单地加一,而是取返回给调用方的 unit 所对应的 nNext 的值,也就是下图(2)处原来的值 1
  6. pData 的地址值返回。为便于说明,这块区域我们标记为 CA

操作后各数据结构的状态如下:

技术分享图片

第二次调用 alloc 的情况类似。调用后各数据结构的状态如下:

技术分享图片

memory pool free

我们先看看结果:

技术分享图片

  1. 首先程序会检查 CA 的地址值,很快就会发现,地址 0x10010 位于上述第一个 block 的范围之内(0x10000 <= 0x10010 <= (0x10000 + 4112))。再计算偏移值可以很快得出其对应的 nNext 标号,也就是上图中的(2)位置。
  2. 回收 unit,此时需要标记相应的成员值以标示 unit 的回收状态。首先查看 nFirst 的值,参见上前幅图,nFirst 的值为 3,表示位置(3)处的 unit 是可用的。因此我们首先把 (2) 处的 nNext 值设置为 3,将其加回到可用 unit 的链表中
  3. nFirst 的值修改为 0,也就是代表刚刚回收回来的 unit 的标号,而(2)处的值赋值为 2,表示b(3)的 unit

其实可以看到,上面就是一个简单的链表操作。根据上面的过程,如果 CB 也释放了的话,那么 memory pool 的状态则会变成这样:

技术分享图片

到这个时候,由于整个 block 已经完全回收了(nFree == nInitSize),那么根据不同的策略,可以考虑将整个 block 从内存中释放掉。

block 满

我们回到 alloc 的逻辑中,可以看到内存池最开始会检查 block 的 nFree 成员。如果 nFree == 0 的时候,那么就会在该 block 的 pNext 中去找到下一个 block,再去检查 nFree。如果发现 block 链表已经结束了,那就意味着当前所有的 block 已满,必须创建新的 block。

在实际设计中,我们需要考虑选取合适的 init size 和 grow size 值。从上面的算法中可以看到,如果 alloc/free 调用非常频繁时,第一个 block 的使用效率是非常高的。


变体或改进

  1. 有些简化的版本中,可以不使用 pNext 来维护链表,也就是只有一个 block,并且内存的使用有一个明确且受控的上限值。这经常用在没有 malloc 系统调用的 RTOS 或者是一些对内存非常敏感的嵌入式系统中。
  2. 如果要用于多线程环境中,那么 memory pool 结构体需要加上锁

参考资料

相关阅读
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

以上是关于无线开关大揭秘,原理就是这么简单!的主要内容,如果未能解决你的问题,请参考以下文章

Protocol Buffer 序列化原理大揭秘 - 为什么Protocol Buffer性能这么好?

抖音头条为什么这么火?揭秘推荐系统原理之协同过滤算法

按钮开关的工作原理及如何区别作用

无线开关原理

冒泡排序算法原理和代码实现,就是这么简单。。。

按钮开关的工作原理及如何区别作用