CSS扩频技术传输性能优异 实现更远距离的无线通信
CSS技术并非是一种新的技术。在自然界里,Chirp脉冲就为海豚和蝙蝠等生物所用。20世纪40年代Hüttmann教授发明了雷达应用专利,后由Sidney Darlington进一步将CSS技术引入雷达系统创造性地开发了脉冲压缩(Chirp)雷达。自1997年以来人们开始研究将CSS技术应用于商业的无线数据传输。后来,IEEE 802.15.4标准将CSS指定为了一种用于低速率无线个人局域网(LR-WPAN)的技术,实现了数据速率可扩展性、远距离、更低功耗和成本,其与差分相移键控调制(DPSK)等技术相结合,可以实现更好的通信性能。CSS技术使用了其全部分配带宽来广播信号,从而使其对信道噪声具有一定的鲁棒性。CSS技术在非常低的功率下也能够抵抗多径衰落,非常适用于要求低功耗和较低数据速率的应用场景。CSS技术的低成本、低功耗、远距离以及数据速率的可扩展性等特性为产品商业化应用提供了现实的可能。
从CSS技术应用情况来看,德国Nanotron公司使用CSS技术在2.4GHz频段上实现了570米的距离通信。美国Semtech公司的LoRa产品使用CSS技术在Sub-1GHz频段上实现了几公里,甚至几十公里的距离通信。
CSS技术通信距离远可以在一定范围内实现更大规模的无线连接,大大降低无线接入和组网的成本,组建经济高效的无线广域网络,有助于物联网络规模化部署应用。CSS技术的普及应用将为新兴的非蜂窝广域网络市场的发展注入了新的活力,将会有力地推动行业应用的发展。
非蜂窝广域网络方兴未艾 物联网发展步入规模化应用阶段
低功耗广域网络(Low-Power Wide Area Network, LPWAN)大致可以分为蜂窝和非蜂窝广域网络。蜂窝广域网络是指由运营商建设的基于蜂窝技术的网络,一般是指3GPP主导的物联网标准,代表技术有NB-IoT、LTE-M(eMTC)和EC-GSM-IoT等;非蜂窝广域网络主要是指由企业自主建设使用免许可频段组建的网络,代表技术有SIGFOX、LoRaWAN、ZETA等。也有的提出0G网络,是相对于1G/2G/3G/4G而言,在通信领域一般是指蜂窝移动电话之前的移动电话技术,如无线电话。在物联网领域,0G指的是一个低带宽的无线网络,没有SIM卡、没有流量、低成本接入、远距离通信、传输少量数据的网络,也就是非蜂窝广域网络。非蜂窝广域网络的发展是源于对数据大规模采集和大量设备管理等的需求,并借助互联网技术和平台提升了基于数据的智能化管理水平。物联网市场发展步入规模化应用阶段。目前,非蜂窝广域网络主要应用于市政、园区、水务、消防、物流、家居、电力、社区、工厂、农业、环境等领域。
不同网络技术示意图
实际上,非蜂窝广域网络和蜂窝广域网络相互之间是一种相互依存互为补充的关系。一般地,非蜂窝广域网络都是通过网关(或称为集中器,或称为基站)连接到互联网,而网关连接到互联网的方式一般是有线或蜂窝网络等公网,最终还是要走公网的管道,毕竟有线和蜂窝网络是广泛存在的基础性网络。另一方面,传感器或设备多是基于微控制器(MCU)的,受其资源限制,仅可运行轻量的简单通信协议或定制化通信协议,通过网关转换成互联网协议(IP),网关起到了非蜂窝广域网络和互联网连接器的作用。非蜂窝广域网络更是蜂窝网络的拓展延伸。非蜂窝广域网络不同的无线接入技术可以满足物联网实际部署中各种各样无线连接的应用需求,为传感器网络或设备联网提供了灵活的无线接入方式和便捷的网络部署。
非蜂窝和蜂窝技术也可以相互融合。最近有报道称,在手机上集成了无线通信技术,可以在没有蜂窝网络的情况下,实现两机或多机的无线远距离相互通信,并可以实现自组网、定位等功能,这也为非蜂窝广域网络的应用提供了新的应用场景。
同时,非蜂窝网络也在国家电网方面具有非常强劲的发展势头。据最近流传的国家电网《电力设备无线传感器网络节点组网协议》显示,针对电力设备无线传感器网络的组网和传感器接入应用,在物理层协议规范中有对CSS物理层进行了定义,”CSS物理层:工作在470-510MHz或者2400-2483.5MHz频段,采用线性调频扩频(CSS)调制。线性调频扩频(CSS)调制应符合LoRaWAN™ 1.1 Specification 和IEEE Std 802.15.4TM-2015物理层的规定”。随着泛在电力物联网的建设发展,非蜂窝广域网络在泛在电力物联网中将会有着更为广阔的应用场景。除电力市场之外,其他抄表类市场应用,如:水表、气表、燃气表等,也是非蜂窝广域网络重要的典型应用市场。
另外,在一些重要的应用领域里,考虑到数据和安全等方面的因素,需要非蜂窝网络技术将设备接入到专网上,以保障私域网络的数据隐私和安全性。非蜂窝无线技术以其独特的优势在物联网络应用中发挥着重要的作用。
非蜂窝广域网络可以组建无线传感网络,连接和管理一定范围内大量传感器或设备等,也可以成为一种网络基础设施,由专门公司来提供网络服务,或者说是一种物联网络运营服务。在国外物联网运营模式已开始发展,如Sigfox等。而国内情况还处于探索发展阶段,目前主要还是以提供解决方案为主。
低功耗广域网络市场发展前景看好 非蜂窝广域网络预期规模增速明显
根据IHS Markit预测,2017年全球LPWAN连接数量为8753.7万个,预计到2023年可达171698.4万个,2017-2023年复合增长率(CAGR)为64%。其中,除NB-IoT和LTE-M等蜂窝连接之外,非蜂窝广域网络连接数量2017年为8124.8万个,2023年预计可达84443.6万个,2017-2023年复合增长率(CAGR)为48%。到2023年非蜂窝广域网络连接规模占比约为50%,非蜂窝广域网络市场未来具有很大的发展潜力。
射频收发器受市场关注 Sub-1GHz频段更受青睐
一个完整的应用非蜂窝技术的应用图包括感知层、网络层和应用层。其中感知层中的射频收发器主要用于传感器和网关之间的信息交互。
非蜂窝技术系统应用框图
射频收发器是非蜂窝技术组网应用的关键器件,随着非蜂窝广域网络的发展,射频收发器产品越来越受到市场关注。从业界目前非蜂窝广域网络技术应用情况来看, 采用的都是国外半导体公司的射频收发器产品,这些厂商有Semtech、ST、Silicon Labs、TI、NXP、ON等,鲜有国内半导体公司的产品。Semtech公司的LoRa产品在中国市场上得到了很多公司的支持,国内少数公司通过IP授权的方式获得了LoRa IP,提供本地化产品,这些厂商有翱捷(ASR)、国民技术、华普等公司。随着射频收发器市场需求的发展,国内的一些芯片设计公司也开始研究和开发射频收发器产品。最近有报道称,国内上海磐启微电子有限公司推出了基于CSS技术的Chirp-IOT芯片PAN3028,融合了多维信号调制技术解决了频率不连续对射频的影响,提高了接收灵敏度,在射频收发器领域实现了新的技术突破。Chirp-IOT产品的国产化也填补了中国非蜂窝广域网络市场的空白。
由于射频收发器在Sub-1GHz频段上具有良好的无线传输特性,传输距离远、障碍物穿透能力强等,非蜂窝广域网络基本都是采用Sub-1GHz射频收发器组建网络。下面是关于Sub-1GHz射频收发器主要的厂商:
Sub-1GHz射频收发器厂商
万物智联市场快速发展需求大 集成电路设计国产化迎新机遇
中国市场规模大,对集成电路的需求也大,而目前还较多地依赖于集成电路的进口。根据海关统计,2018年中国进口集成电路有4170亿块,进口金额达3107亿美元。据国家统计局的统计显示,我国2018年集成电路产量1739.47亿个,国产集成电路产量不足进口量一半。近些年,国家不断加大对集成电路产业的政策扶持力度,出现了一大批新的集成电路设计公司,集成电路技术水平也在逐步提升。加之近两年中美贸易环境的变化,加速了集成电路国产化的速度。在涉及到国家核心重要应用领域,仍然是强调国产自主可控。这是中国集成电路设计公司一个重要的发展契机,也是非蜂窝广域网络行业一个发展机会。随着万物智联市场的快速发展,中国集成电路设计也将会迎来一波新的发展机遇。
根据半导体行业协会的统计,2018年中国集成电路设计产值为2519.3亿人民币,同比增长21.5%,2009到2018年中国集成电路设计产值年复合增长率(CAGR)为28.7%,集成电路设计产业保持了较高的发展速度。
结语
CSS技术在无线通信方面具有显著的优势,有助于非蜂窝广域网络实现大范围的组网应用。随着物联网市场无线连接需求的不断增长,射频收发器产品越来越受到芯片公司的关注。而国内射频收发器产品厂商少,行业发展还比较薄弱,需要更多的国内射频收发器厂商共同的参与,助力非蜂窝广域网络行业的发展,赋能非蜂窝广域网无线超连接,创新更多的物联网应用。
未来,随着集成电路技术的不断发展,或许会出现更多的新技术、新产品,这也将会大大丰富非蜂窝广域网络生态。“独木不成林”。需要各行各业共同的参与,建立共建共享共荣的良性发展生态。
那是因为你的代码并没有兼容FF浏览器。出现这个问题的原因是:
在FF下,UL,OL,DT,DL,都是会有默认的向右缩进40PX的距离。
所以,在你的CSS样式定义中,就必须要做兼容,代码如下:
#newsid ul
{
margin:0px 0px 0px -40px这个是FF
*margin:0px这个是ie7
_margin:0px这个是IE6
}
除了在td中的UL,OL,DL,DT外,其他情况出现的都要加上上面的代码,才可以兼容。
探究 CSS 解析原理吃早饭的时候,同事随意问了一句:你知道 CSS 是怎么解析的吗?我一头雾水。对哦,作为前端,每天都在与 CSS 打交道,我竟然忽视了最基本的原理。
一、浏览器渲染
开篇,我们还是不厌其烦的回顾一下浏览器的渲染过程,先上图:
正如上图所展示的,我们浏览器渲染过程分为了两条主线:
其一,HTML Parser 生成的 DOM 树;
其二,CSS Parser 生成的 Style Rules ;
在这之后,DOM 树与 Style Rules 会生成一个新的对象,也就是我们常说的 Render Tree 渲染树,结合 Layout 绘制在屏幕上,从而展现出来。
本文的重点也就集中在第二条分支上,我们来探究一下 CSS 解析原理。
二、Webkit CSS 解析器
浏览器 CSS 模块负责 CSS 脚本解析,并为每个 Element 计算出样式。CSS 模块虽小,但是计算量大,设计不好往往成为浏览器性能的瓶颈。
CSS 模块在实现上有几个特点:CSS 对象众多(颗粒小而多),计算频繁(为每个 Element 计算样式)。这些特性决定了 webkit 在实现 CSS 引擎上采取的设计,算法。如何高效的计算样式是浏览器内核的重点也是难点。
先来看一张图:
Webkit 使用 Flex 和 Bison 解析生成器从 CSS 语法文件中自动生成解析器。
它们都是将每个 CSS 文件解析为样式表对象,每个对象包含 CSS 规则,CSS 规则对象包含选择器和声明对象,以及其他一些符合 CSS 语法的对象,下图可能会比较明了:
Webkit 使用了自动代码生成工具生成了相应的代码,也就是说词法分析和语法分析这部分代码是自动生成的,而 Webkit 中实现的 CallBack 函数就是在 CSSParser 中。
CSS 的一些解析功能的入口也在此处,它们会调用 lex , parse 等生成代码。相对的,生成代码中需要的 CallBack 也需要在这里实现。
举例来说,现在我们来看其中一个回调函数的实现,createStyleRule(),该函数将在一般性的规则需要被建立的时候调用,代码如下:
CSSRule* CSSParser::createStyleRule(CSSSelector* selector) { CSSStyleRule* rule = 0 if (selector) { rule = new CSSStyleRule(styleElement) m_parsedStyleObjects.append(rule) rule->setSelector(sinkFloatingSelector(selector)) rule->setDeclaration(new CSSMutableStyleDeclaration(rule, parsedProperties, numParsedProperties)) } clearProperties() return rule }
从该函数的实现可以很清楚的看到,解析器达到某条件需要创建一个 CSSStyleRule 的时候将调用该函数,该函数的功能是创建一个 CSSStyleRule ,并将其添加已解析的样式对象列表 m_parsedStyleObjects 中去,这里的对象就是指的 Rule 。
那么如此一来,经过这样一番解析后,作为输入的样式表中的所有 Style Rule 将被转化为 Webkit 的内部模型对象 CSSStyleRule 对象,存储在 m_parsedStyleObjects 中,它是一个 Vector。
但是我们解析所要的结果是什么?
通过调用 CSSStyleSheet 的 parseString 函数,将上述 CSS 解析过程启动,解析完一遍后,把 Rule 都存储在对应的 CSSStyleSheet 对象中;
由于目前规则依然是不易于处理的,还需要将之转换成 CSSRuleSet。也就是将所有的纯样式规则存储在对应的集合当中,这种集合的抽象就是 CSSRuleSet;
CSSRuleSet 提供了一个 addRulesFromSheet 方法,能将 CSSStyleSheet 中的 rule 转换为 CSSRuleSet 中的 rule ;
基于这些个 CSSRuleSet 来决定每个页面中的元素的样式;
这里描述了大致过程,深入阅读可以查看如下链接:
Webkit CSS 引擎分析CSS 样式表解析过程Webkit CSS实现
三、CSS 选择器解析顺序
可能很多同学都知道排版引擎解析 CSS 选择器时是 从右往左 解析,这是为什么呢?
1.HTML 经过解析生成 DOM Tree(这个我们比较熟悉);而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,最终用来进行绘图。Render Tree 中的元素(WebKit 中称为「renderers」,Firefox 下为「frames」)与 DOM 元素相对应,但非一一对应:一个 DOM 元素可能会对应多个 renderer,如文本折行后,不同的「行」会成为 render tree 种不同的 renderer。也有的 DOM 元素被 Render Tree 完全无视,比如 display:none 的元素。
2.在建立 Render Tree 时(WebKit 中的「Attachment」过程),浏览器就要为每个 DOM Tree 中的元素根据 CSS 的解析结果(Style Rules)来确定生成怎样的 renderer。对于每个 DOM 元素,必须在所有 Style Rules 中找到符合的 selector 并将对应的规则进行合并。选择器的「解析」实际是在这里执行的,在遍历 DOM Tree 时,从 Style Rules 中去寻找对应的 selector。
3.因为所有样式规则可能数量很大,而且绝大多数不会匹配到当前的 DOM 元素(因为数量很大所以一般会建立规则索引树),所以有一个快速的方法来判断「这个 selector 不匹配当前元素」就是极其重要的。
4.如果正向解析,例如「div div p em」,我们首先就要检查当前元素到 html 的整条路径,找到最上层的 div,再往下找,如果遇到不匹配就必须回到最上层那个 div,往下再去匹配选择器中的第一个 div,回溯若干次才能确定匹配与否,效率很低。
对于上述描述,我们先有个大概的认知。接下来我们来看这样一个例子,参考地址:
<div> <div class="jartto"> <p><span>111 </span></p> <p><span>222 </span></p> <p><span>333 </span></p> <p><span class='yellow'>444 </span></p> </div></div>
CSS 选择器:
div >div.jartto p span.yellow{ color:yellow}
对于上述例子,如果按从左到右的方式进行查找:
1.先找到所有 div 节点;
2.在 div 节点内找到所有的子 div ,并且是 class = “jartto”;
3.然后再依次匹配 p span.yellow 等情况;
4.遇到不匹配的情况,就必须回溯到一开始搜索的 div 或者 p 节点,然后去搜索下个节点,重复这样的过程。
这样的搜索过程对于一个只是匹配很少节点的选择器来说,效率是极低的,因为我们花费了大量的时间在回溯匹配不符合规则的节点。
如果换个思路,我们一开始过滤出跟目标节点最符合的集合出来,再在这个集合进行搜索,大大降低了搜索空间。来看看从右到左来解析选择器:
1.首先就查找到 的元素;
2.紧接着我们判断这些节点中的前兄弟节点是否符合 P 这个规则,这样就又减少了集合的元素,只有符合当前的子规则才会匹配再上一条子规则。
结果显而易见了,众所周知,在 DOM 树中一个元素可能有若干子元素,如果每一个都去判断一下显然性能太差。而一个子元素只有一个父元素,所以找起来非常方便。
试想一下,如果采用从左至右的方式读取 CSS 规则,那么大多数规则读到最后(最右)才会发现是不匹配的,这样会做费时耗能,最后有很多都是无用的;而如果采取从右向左的方式,那么只要发现最右边选择器不匹配,就可以直接舍弃了,避免了许多无效匹配。
浏览器 CSS 匹配核心算法的规则是以从右向左方式匹配节点的。这样做是为了减少无效匹配次数,从而匹配快、性能更优。
深入阅读,请移步:
jQuery 源码解析CSS 选择器从右向左的匹配规则CSS 选择器
四、CSS 语法解析过程
CSS 样式表解析过程中讲解的很细致,这里我们只看 CSS 语法解释器,大致过程如下:
1.先创建 CSSStyleSheet 对象。将 CSSStyleSheet 对象的指针存储到 CSSParser 对象中。
2.CSSParser 识别出一个 simple-selector ,形如 “div” 或者 “.class”。创建一个 CSSParserSelector 对象。
3.CSSParser 识别出一个关系符和另一个 simple-selecotr ,那么修改之前创建的 simple-selecotr, 创建组合关系符。
4.循环第3步直至碰到逗号或者左大括号。
5.如果碰到逗号,那么取出 CSSParser 的 reuse vector,然后将堆栈尾部的 CSSParserSelector 对象弹出存入 Vecotr 中,最后跳转至第2步。如果碰到左大括号,那么跳转至第6步。
6.识别属性名称,将属性名称的 hash 值压入解释器堆栈。
7.识别属性值,创建 CSSParserValue 对象,并将 CSSParserValue 对象存入解释器堆栈。
8.将属性名称和属性值弹出栈,创建 CSSProperty 对象。并将 CSSProperty 对象存入 CSSParser 成员变量m_parsedProperties 中。
9.如果识别处属性名称,那么转至第6步。如果识别右大括号,那么转至第10步。
10.将 reuse vector 从堆栈中弹出,并创建 CSSStyleRule 对象。CSSStyleRule 对象的选择符就是 reuse vector, 样式值就是 CSSParser 的成员变量 m_parsedProperties 。
11.把 CSSStyleRule 添加到 CSSStyleSheet 中。
12.清空 CSSParser 内部缓存结果。
13.如果没有内容了,那么结束。否则跳转值第2步。
五、内联样式如何解析?
通过上文的了解,我们知道,当 CSS Parser 解析完 CSS 脚本后,会生成 CSSStyleSheetList ,他保存在Document 对象上。为了更快的计算样式,必须对这些 CSSStyleSheetList 进行重新组织。
计算样式就是从 CSSStyleSheetList 中找出所有匹配相应元素的 property-value 对。匹配会通过CSSSelector 来验证,同时需要满足层叠规则。将所有的 declaration 中的 property 组织成一个大的数组。数组中的每一项纪录了这个 property 的selector,property 的值,权重(层叠规则)。
可能类似如下的表现:
p >a { color : red background-color:black} a { color : yellow} div { margin : 1px}
重新组织之后的数组数据为(weight我只是表示了他们之间的相对大小,并非实际值。)
selector property weight 1, a color:yellow 1 2, p >a color:red 2 3, p >a background-color:black 2 4, div margin:1px 3
好了,到这里,我们来解决上述问题:
首先,要明确,内敛样式只是 CSS 三种加载方式之一;
其次,浏览器解析分为两个分支,HTML Parser 和 CSS Parser,两个 Parser 各司其职,各尽其责;
最后,不同的 CSS 加载方式产生的 Style rule ,通过权重来确定谁覆盖谁;
到这里就不难理解了,对浏览器来说,内联样式与其他的加载样式方式唯一的区别就是权重不同。
深入了解,请阅读Webkit CSS 引擎分析
六、何谓 computedStyle ?
到这里,你以为完了?Too young too simple, sometimes naive!
浏览器还有一个非常棒的策略,在特定情况下,浏览器会共享 computedStyle,网页中能共享的标签非常多,所以能极大的提升执行效率!如果能共享,那就不需要执行匹配算法了,执行效率自然非常高。
也就是说:如果两个或多个 element 的 computedStyle 不通过计算可以确认他们相等,那么这些 computedStyle 相等的 elements 只会计算一次样式,其余的仅仅共享该 computedStyle 。
那么有哪些规则会共享 computedStyle 呢?
该共享的 element 不能有 id 属性且 CSS 中还有该 id 的 StyleRule,哪怕该 StyleRule 与 Element 不匹配。
tagName 和 class 属性必须一样
mappedAttribute 必须相等
不能使用 sibling selector,譬如:first-child, :last-selector, + selector
不能有 style 属性。哪怕 style 属性相等,他们也不共享
当然,知道了共享 computedStyle 的规则,那么反面我们也就了解了:不会共享 computedStyle 的规则,这里就不展开讨论了。
深入了解,请参考:Webkit CSS 引擎分析 - 高效执行的 CSS 脚本
七、眼见为实
如上图,我们可以看到不同的 CSS 选择器的组合,解析速度也会受到不同的影响,你还会轻视 CSS 解析原理吗?
感兴趣的同学可以参考这里:speed/validity selectors test for frameworks
八、有何收获?
1.使用 id selector 非常的高效。在使用 id selector 的时候需要注意一点:因为 id 是唯一的,所以不需要既指定 id 又指定 tagName:
Badp#id1 {color:red} Good #id1 {color:red}
当然,你非要这么写也没有什么问题,但这会增加 CSS 编译与解析时间,实在是不值当。
2.避免深层次的 node ,譬如:
Bad div >div >div >p {color:red} Good p-class{color:red}
3.慎用 ChildSelector ;
4.不到万不得已,不要使用 attribute selector,如:p[att1=”val1”]。这样的匹配非常慢。更不要这样写:p[id=”id1”]。这样将 id selector 退化成 attribute selector。
Bad p[id="id1"]{color:red} p[class="class1"]{color:red} Good #id1{color:red} .class1{color:red}
5.理解依赖继承,如果某些属性可以继承,那么自然没有必要在写一遍;
6.规范真的很重要,不仅仅是可读性,也许会影响你的页面性能。这里推荐一个CSS 规范,可以参考一下。
更多资源
CSS 解析顺序优先级详细探索简单剖析 CSS 的解析规则
赞
24个金币已到账
金币可兑换现金
立即提现
子宫肌瘤怎么办?告诉你一个调理方法!直达病灶!