数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

NoSQL最早起源于1998年,但从2009年开始,NoSQL真正开始逐渐兴起和发展。回望历史应该说NoSQL数据库的兴起,完全是十年来伴随互联网技术,大数据数据的兴起和发展,NoSQL在面临大数据场景下相对于关系型数据库运用,这一概念无疑是一种全新思维的注入。
接下来本文重点梳理下NoSQL领域最新发展趋势以及阿里云NoSQL最新现状,以飨读者。
云NoSQL数据库成为数据库领域重要增长引擎
云化趋势不可避免,根据Gartner的报告,2017年超过73%的DBMS增长来自云厂商,Gartner象限里面AWS在领导者象限上升趋势明确,老牌厂商下滑严重。在2018年Gartner报告中,阿里云数据库更是中国唯一首次入围远见者象限。而在众多云厂商里面增长最快的又是NoSQL数据库,云NoSQL成为数据库领域重要增长引擎。
阿里云覆盖了主流的NoSQL引擎
阿里云集团是国内最早提出数据战略,本身也拥有最大体量的数据,是最早投入NoSQL数据库技术研发,目前也拥有国内最大的专家团队。在持续十年技术加持下,阿里云NoSQL目前覆盖了所有主流的NoSQL数据库,如Redis/mongodb/HBase/图等等。下表是目前阿里云目前覆盖的主流的NoSQL数据库。
NoSQL数据库存储类型典型场景Redis/MemcacheKey/Value缓存,搭配所有数据库使用;直播、视频等各种在线场景。MongoDB文档非常适合游戏、地图、基于位置的数据查询等等场景。HBase Wide Column风控、画像、用户行为数据,用户详单,对象存储等等。ElasticSearch/Solr倒排索引文本模糊查询JanusGraph/GDB图关系分析和挖掘,金融、风控
阿里云NoSQL数据库多项独家关键技术领先竞争对手,是国内当之无愧的NoSQL数据库排头兵。
拥有业界最全的产品的形态
以Redis为例,全系覆盖全系列支持2.X, 3.X 4.X, 支持从适合开发者的单节点到多中心的各种产品形态,架构任意变换, 自动容灾, 全面监控。
通过各种产品形态,阿里云有能力服务从开发者、中小企业、大企业各种客户,满足不同客户对性价比,SLA,可靠性,管控的各种需求。
在最新版本跟进上,阿里云NoSQL也一直在走云厂商前列,18年6月6日全球首发HBase 2.0,同年10月份又全球第一家云厂商支持MongoDB 4.0版本。
另外预告一下,这个月我们会推出全新redis 5.0版本,满足众多企业对新版本的诉求,敬请期待!
把数据可靠性作为重中之重
对大多数公司来说数据的安全性以及可靠性是非常重要的,如何保障数据的安全以及数据的可靠是大多数数据库必须考虑的。2016 IDC的报告表示数据的备份(data-protection)和数据恢复(retention)是NoSQL的最基础的需求之一,阿里云NoSQL数据库也一直把怎么保障客户的数据安全放在首位。
以云HBase为例,传统数据库备份恢复的能力都是TB级别,在交易等场景下面是足够的,但面向大数据场景就捉襟见肘了。云HBase通过垂直整合高压缩、内核级优化等能力,将备份恢复的量级成功推高百倍以上,做到 百TB级别甚至更高 ,让客户在大数据量场景下也无后顾之忧。
云HBase支持全量(备份集)备份、全量(备份集)恢复、增量(实时)备份、增量(时间点)恢复完整备份恢复能力。
全球分布式能力助力企业解决业务出海、地域级灾备、全球同服/多活、跨域数据迁移等关键业务
云厂商之所以有这么强大的活力,除了在数据库内核本身长足的进步之外,结合云服务整体生态的创新是重要的一环。阿里云NoSQL数据库持续发力和覆盖了全球分布式能力,助力企业参与全球业务竞争。是否具备全球扩展和分布式的能力,是云NoSQL数据库重要的入门门槛。以Redis为例,我们再18年8月份全球云厂商首家推出Redis全球多活,解决多媒体、游戏、电商等多行业客户业务出海、地域级灾备、全球同服/多活、跨域数据迁移的诉求。多项关键能力独步领域内:
全球多活:内核级别支持,实现多节点全球容灾。 
高可用:同步通道支持断点续传,容忍天级别的隔断,子实例HA自动切换
 高性能:单通道10万TPS,高于Redis处理速度;延迟低、洲际内百毫秒延迟
 支持数据最终一致性:CRDT冲突解决方案+数据一致性检测,基于Redis内核改造,原生Redis内核无此功能。
融合多模和多负载能力,提供一站式低成本数据处理平台
2018年12月13日第8届中国云计算标准和应用大会隆重发布X-Pack,在云HBase基础上新增多模型和多负载支持。
 多模型支持:同时支持KV、时序、时空、图、文档等多种数据模型,内置丰富处理能力,让业务开发效率提升百倍。 多负载支持:ApsaraDB HBase在在线能力的基础上,融合流处理、批处理、OLAP,OLTP、高速对象存储,全文检索等能力,提供客户业务开箱即用的能力。
通过多模型和多负载的支持,基于Apache HBase及HBase生态构建的 低成本、一站式 数据处理平台,支持Spark、二级索引、全文查询、图、时序、时空、分析等能力,是物联网、风控推荐、对象存储、AI、Feeds等场景首选数据库。
多项独家企业级能力,领域内领先,不负重托
客户选择NoSQL数据库服务,一个非常看重的关键点是就是企业级能力,解决企业生产开发过程中,管理,维护各个方案的瓶颈。
NoSQL数据库服务深度结合企业应用场景,经过长期的发展,目前具备了多项独家企业级能力,以MongoDB为例: 跨域双活:数据双向同步,相比现有通道产品提升100%效率,业界领先。 首创物理+逻辑备份双能力:物理备份,相比开源版本备份效率提升100%,恢复效率提升300%。创新性提供逻辑snapshot能力,解决政企等定期大批量数据更新需求,同架构下性价比提升100%。 秒级监控及智能诊断能力:提供每秒粒度的监控数据采集,监控精度提升数十倍。结合监控、审计等数据提供智能诊断,分析系统运行瓶颈并自动化提供优化建议。
下面是云MongoDB和自建的社区版本的一个对比,云服务再搭建、安全、优化、运维、定制等各个方面全面胜出,全面降低客户的TCO。
即将重磅发布CloudNative图数据库
随着企业的数据越来越多,业务越来越复杂,客户提出了很多实时在线的高性能图数据存储和查询服务的诉求。我们也将再本月重磅发布阿里云首款Cloud Native专业的图数据库。
新的图数据库将会支持丰富的能力,并在易用性,高可用站上一个新的高度,非常适合拥有社交网络、金融欺诈检测、实时推荐引擎、知识图谱、网络/IT运营方面诉求的客户。
展望未来,阿里云NoSQL数据库也会持续围绕客户业务,成本,运维各个方面进行优化和创新,成就客户,争做最好的NoSQL数据库而持续努力!

一站式开发者服务,海量学习资源0元起!
阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中--》 【阿里云】开年Hi购季,开发者会场

原文链接
本文为云栖社区原创内容,未经允许不得转载。
硬件开发
2019-03-18 16:04:00
开发图表最关键的点在于选择准确的图表类型展示准确的数据,而准确的数据往往依赖于一个强大的取数模型,因此设计一个好的取数模型不仅可以解决数据安全的问题,更可以帮助每个访问者高效触达自己想要的数据,开发者可以通过使用Quick BI建立起多层次多粒度的取数模型。
在构建取数模型前,简单介绍一下数据集的概念。Quick BI 目前已经支持为20多种数据库建立连接,建立连接后我们会在系统内为每个连接生成一个逻辑实体称之为数据源。通过预览数据源可以查看对应数据库下面的物理表信息,并能够基于这些物理表创建数据集, 每个数据集都是基于物理表加工和建模后的标准OLAP模型。在Quick BI 中, 对用户表数据的读取和加工一般都是基于数据集模型的。
目前,Quick BI中的取数模型包括如图1所示的两层:
图1 Quick BI中的取数模型
第一层:
数据集过滤器,在Quick BI中数据集可以被多个仪表板的多个图表所引用,通过将过滤器设置在某个数据集上,空间内的数据开发人员可以确保所有引用该数据集的图表分析人员访问到的数据都受到范围限制。
根据过滤器的作用范围可以划分为全局过滤器和行级权限过滤器。
1、全局过滤器
顾名思义是会影响到所有引用该数据集的图表和用户,设置定后可以通过刷新预览功能来核对过滤后的数据,通过图2的方式可以设置全局过滤器。
图2 数据集全局过滤器
2、行级权限
可以让数据开发人员根据图表访问者的账号、标签或所属的用户组来定制其可以访问的数据范围,设置在用户级的过滤器会以“or”的方式继承其所属用户组的过滤器,通过图3的方式在数据集列表上可以设置行级权限过滤器。注意,使用这两种方式设置在度量上的过滤器都是明细级的过滤器,未做任何聚合。
图3 行集权限过滤器
第二层:
图表级过滤器,这类过滤器在设定时会指定作用的图表范围,只有选中的图表显示数据时才会受到影响。在此基础上,还可以根据作用的方式分为设定式和触发式。
1、设定式过滤器
由仪表板开发者在编辑模式下设置,预览模式下用户无法改变过滤器的设置,作用范围内的图表也会一直受到过滤器的限制,设定式过滤器包含了内部过滤器和全局参数。
1.1内部过滤器
只会作用于当前图表,当被设置成度量过滤器时还可以选择聚合方式,聚合方式支持sum、 cnt、max、min、avg、cntd, 它的设定方式是在仪表板编辑模式下通过拖拽数据集字段来设定如图4所示。
图4 内置过滤器
1.2全局参数
需要生成参数名并设置作用范围,其作用机制是通过拼接url参数来完成条件的注入的,拼接格式如下:
param=[{"paramKey":"moci","joinType":"and","conditionList":[{"operate":"=","value":"华北"}]}]
,用户可以直接修改url参数内容来达到数据控制,也可以在邮件订阅和图表跳转功能中快捷引用, 它的设定方式是在顶部菜单中选择全局参数来设定如图5所示。
图5 内置过滤器
2、触发式过滤器
能够在编辑模式设置初始值,在预览模式下也可以通过特定的操作来改变关联图表的显示数据,查询条件和联动参数属于触发式过滤器。
2.1查询条件功能非常强大,它支持让报表开发者自由的选择字段,选择聚合方式,设置作用图表,设置过滤初始值以及设置待选范围,而预览者可以在开发者限定的范围内自由切换过滤条件,其设定方式如图6所示。
图6 查询条件
2.2联动参数是建立在图表之间的一种作用关系,在可配置联动图表上配置了联动字段和作用图表后,预览者可以通过点击联动图表的某些区块来达到为被联动图表同步注入过滤条件的目的,其设定方式是先选择要联动的图表,然后在高级区域进行配置,如图7所示。
图7 联动参数
上述几种过滤器应用的场景各不相同,他们是通过AND的方式相互叠加的,仪表板编辑模式下图表菜单里有一个强大的查看SQL功能,可以看到当前取数模型生成的SQL语句,方便开发者对当前的取数模型进行调整。在真实的业务场景中的往往要组合他们中的一到多种才能建立起完成的取数模型,以一家销售公司为例,通过使用全局过滤器过滤掉无效数据,通过使用行级权限来控制每个销售团队只能看到自己辖区的销售结果汇总,通过使用全局参数来生成不同的链接给每个预览者看到关注产品的销售汇总,通过查询条件和过滤器来控制和切换不同客户的销售数据,通过联动参数来方便预览者直接关联其他图表查看某个客户的具体信息。
图8 查询条件

原文链接
本文为云栖社区原创内容,未经允许不得转载。
硬件开发
2019-03-13 16:03:00
一、设置tab为4个空格

二、设置注释的标准格式
1.设置类注解
/** * 作者: ${USER} * 创建时间:${DATE}. * 修改时间:${DATE}. * 类含义: */
2.设置方法注释


/**
* 方法含义:
* @param:
* @return:
* 作者: XXX
* 创建时间:$date$ $time$
* 修改时间:$date$ $time$
* 修改原因:
*/
输入cmt 按tab键就出来了

硬件开发
2018-01-12 11:44:00
做系统启动SD卡或系统盘,简直是神器! 尤其是搞ARM上面的系统,经常需要烧写SD卡。 在不同的操作系统使用工具不同,操作复杂,速度慢。
现在etcher来了: https://etcher.io/
简单、快速,支持 Windows/Linux/MacOS 操作系统!!!
感觉比DD快多了,12MB/s以上,基本接近常用MicroSD卡的标称速度。 默认情况下,unsafe模式是关闭的。 大容量的U盘将会被认为是系统盘而不会出现在Flash Target列表中,避免对重要的介质误操作(如启动盘、数据盘,你懂的!!!) 如果需要烧写大容量U盘作为启动盘,需要到设置中去打开,就可以了! 但是千万、千万不要选错了! 否则,所选的介质将会被物理级被覆盖,所有数据全部丢失!!!
还没有广告!!!
由resin.io爱心奉献,简直是天理良心!
硬件开发
2018-01-12 07:24:00
NCONFIG AT+NCONFIG? +NCONFIG:AUTOCONNECT,TRUE ===》是否开启自动注网模式 +NCONFIG:CR_0354_0338_SCRAMBLING,TRUE ===》是否开启扰码功能 +NCONFIG:CR_0859_SI_AVOID,TRUE ===》开启扰码功能 +NCONFIG:COMBINE_ATTACH,FALSE ===》是否使能联合附着 +NCONFIG:CELL_RESELECTION,FALSE ===》是否开启小区重选功能 +NCONFIG:ENABLE_BIP,FALSE ===》是否使能短信
硬件开发
2018-01-10 11:02:00
《如何像阿里巴巴一样高效跨企业项目协作》视频回顾链接分享: https://yq.aliyun.com/webinar/play/367

1.组织架构与业务架构

1.1组织架构是对业务架构的反映
在一个企业中,除行政、财务等维持企业本身正常运转的公共事务性、辅助性部门外,其他大部分基本是按照业务架构来设计的,一般称为“业务部门”。阿里巴巴的各个事业部就是一种典型的按照业务架构来设计的组织架构。在事业部之上,会根据更大的业务板块形成事业群,例如电商、云金融等。

另外,企业内会存在一些横向的按职能划分的部门或团队,如测试、前端等,但也经常为了更好的支持业务而进行垂直化,使得这些横向部门离业务更近,资源的响应更快。然而时间长久之后也会出现新的问题,例如在一些公共的系统、工具、流程的建设当中会出现很多低成本的重复建设。阿里巴巴在最近的几年里,除了上层的各个业务事业部以外,在后面逐渐形成了一个大中台,大中台是由各个技术团队和部门构成的一个大的横向团队,建设大中台的目的是为了消除低成本的重复建设,让技术做的更专业,把相关的技术问题解决的更彻底,通过技术上的抽象和复用,加速上层业务和产品的孵化与发展。在一些业务比较固定、比较单一的公司或企业里,也会采用按横向职能划分的方式来设计组织架构,例如研发部、系统部、采购部门、质监部门等。

横向部门或团队的存在本质上是为了支撑业务的快速发展,组织架构的调整和升级也是为了业务的发展。大中台对于阿里巴巴业务各个团队就像阿里云对它所服务的各个企业用户,本质上都是为了降低创新创业的成本,从而大幅度地提升效率。

1.2组织的变化滞后于业务的变化
组织架构本身是要保持稳定的,即使处于市场环境变化很快的互联网公司,公司的组织架构也不会发生频繁的变化,否则将会产生一些管理上的问题,例如人心不稳、团队动荡等情况。外部市场的变化对于大部分企业来说是不可控或不完全可控的,在今天的市场环境下,由于跨界竞争、弯道超车等情况存在,对于制定行业规范和游戏规则的少数头部企业来说,市场的变化仍然不是完全可以掌控的。

组织架构的设计是依附于已有发展的,组织架构要随着业务的变化做出相应的调整,但是组织的调整速度远远赶不上业务的变化速度,不能等到组织架构都调整到位、得到保障才去把业务做好,在部门或团队之间也会存在无人负责的灰色地带,所以在中间状态之下,跨组织边界的协作就显得非常重要。跨组织边界的协作对于企业内部表现为跨部门或团队的协作,对企业外部表现为跨企业的协作。在互联网生态环境下,业务边界是动态变化的,一个企业或多或少会与外部企业产生业务联系,企业之间协作的效率和质量在很大程度上影响着业务的成败。

2.跨企业协作面临的问题
下面以高德汽车事业部为案例进行讲解


高德是导航软件的供应商,在它的业务当中需要对接汽车整车场、硬件集成商以及众多的下级软件供应商如语音、输入法定制化APP供应商等。这是一个涉及到多家厂商及企业的合作的场景,在这样的合作场景下存在如下几个问题。

2.1沟通成本比较高


由于是跨企业、跨地域的多方合作,涉及到的参与人员比较多,不在同一个地方,相互之间的通讯方式比较多,极大地影响沟通效果,造成较高的成本。

2.2研发管理工具多种多样


不同公司使用的管理工具多种多样,例如Jira、Redmine等工具,阿里和高德使用的是Aone,由于产品之间不具有兼容性,各个系统之间没有办法直接进行对接,从而造成“人”不在一起和数据不在一起,无法将一个问题直接转给另一个企业的人员进行处理,没有一个地方能看到项目的全貌。PM很难把控项目的进展和风险。

针对以上问题出现两个直接的解决方法:
(1)把内部的系统,例如公司自己内部使用的Jira、Redmine开放给外网可以访问
(2)给外部合作人员开通VPN
但是以上两种方法的缺点是,都存在网络安全,数据泄漏,外部人员账号的管理(开通,访问权限控制,数据访问审批,回收)成本高的问题。对于安全性要求比较高的公司来说,方案一会直接被否决。另外,很多公司内部并没有完善的账号访问控制体系,外部人员通过VPN很容易发生信息泄露的问题。

2.3任务和问题的流转低效


上图左侧为高德同其他外部合作方之间的工作流程,整个过程中存在以下问题:
(1)人工干预的环节比较多、沟通多、效率低。
(2)以Excel作为任务和问题的载体,人手一份,最新版本的维护和同步成为大问题,各个工具导出的Excel格式并不完全兼容,从而增加了人工干预的调试工作,加大成本。
(3)Excel的传递和传输问题上,通过邮件、IM、网盘进行传输,容易造成数据泄漏,没有操作记录,无法进行追溯和安全审计。

3.阿里巴巴与合作伙伴的实践

3.1背景
跨组织边界的协作作为一种重要的常态,同时面临着很多类似于以上的问题和痛点,那么阿里巴巴在与生态合作伙伴之间进行跨企业协作的时候是如何应对这些问题的呢?


阿里巴巴与生态合作伙伴之间进行跨企业协作是广泛存在的,上图即为支付宝的各种服务以及生活号,其中涉及到支付宝同第三方ISV提供商之间广泛的合作。


上图为云OS同相关的汽车、智能家电、智能家居等厂商广泛的合作。由以上可以看出,在阿里巴巴内部的各个事业部都跟外部合作方有着广泛密切的合作。
由上文案例看出,跨企业协作面临的问题显然不是通过人工的方式可以来解决的,所以必须借助工具产品提供的解决方案。云效是孵化于阿里巴巴内部的研发系统平台,在解决跨企业协作相关问题上有成熟有效的解决方案。

3.2云效的跨企业协作解决方案机制


云效的跨企业协作解决方案本质上是解决账号和数据在一起的问题,并且以项目作为跨企业协作的基本单位。上图左侧简单地呈现了方案的工作机制,下侧的Aone是阿里巴巴研发协同平台,可以看作部署在阿里巴巴内部的云效站点,跨企业协作项目空间当中的数据在各个云效站点之间是实时同步的,包括人员的信息、项目的信息、任务和问题数据。假设上文案例中的高德与外部合作方的人员都在合作项目A空间当中,当高德团队的测试人员需要把问题转交给外部合作方的开放人员时,由于在内部Aone上可以直接看到外部合作方的人员,所以只需要在内部Aone上将问题的指派人直接修改为外部合作方的人员就可以了,外部人员就可以在外面的云效上同步地接受到这个问题,反过来开发人员同样可以将任务或问题转交给高德人员。这个方案不仅支持企业的两两合作,也可以支持多方的合作,例如上图的合作项目D。

借助于云效的跨企业协作解决方案,可以为上文中的高德汽车案例提供以下优化的解决方案。


由上图的解决方案可以看出消除了很多人工干预的环节,达到了账号和数据在一起的目的,PM可以比较清楚地看到整个项目的全貌。

3.2.1发起合作
创建跨企业协作项目空间的过程类似于建群和加群。可以由任意一个合作方发起创建项目空间。项目空间创建之前会有企业内部审批的流程,审批通过后系统会自动生成一个邀请码如下图,可将邀请码发送给相关的合作参与方。


3.2.2参与合作
其他的合作方可以用邀请码去申请参与到合作项目当中,参与的过程中也需要进行审批的流程,审批通过之后才会真正进入到合作的项目空间当中。由于跨企业协作涉及到企业之间数据的交换,为了防止未经审核的跨企业通道被打开,在发起与参与合作的环节都增加了相应的审批流程,用于备案和事后的审计。


3.2.3成功创建协作项目空间
跨企业协作项目空间成功创建后的效果如下图:


在这里,我们可以看到相关合作方的人员信息,合作过程中产生的任务也会存放在一起,这些数据和信息对于合作各方是透明共享的。

3.3云效的跨企业协作解决方案适用场景
云效的跨企业协作解决方案适用于很多场景:
(1)与外部企业合作做项目,不便派人实地驻场(异地办公,差旅成本),不便开通外网访问或VPN(安全问题,外部人员账号的管理成本)。例如上文的高德案例。
(2)企业有业务需求,但没有研发部门,需要与外包公司合作,自己或第三方负责项目管理,质量管控和产出物验收。
(3)自己做平台或生态,吸引外部开发者、第三方服务提供商的参与和共建,平台要对最终用户负责,管控服务或应用的质量。
阅读原文

http://click.aliyun.com/m/39269/
硬件开发
2018-01-08 14:57:00
Hypriot-支持ARM64的服务器操作系统
Hypriot目前支持下面的硬件系统,可以支持ARM64: HypriotOS for the Raspberry Pi HypriotOS for the NVIDIA ShieldTV HypriotOS for the ODROID C1+
推荐使用 https://github.com/hypriot/flash 进行安装。
1、OS镜像下载 全系列支持: https://github.com/hypriot/image-builder-rpi ARM64支持: https://github.com/DieterReuter/image-builder-rpi64
下面是支持的设备运用的示意图:
2、源码构建镜像
你可以本地构建SD card image,使用 Vagrant。
该 repo 代码仓库构建HypriotOS的SD card image,可以运行在Raspberry Pi 1、2、3以及Zero上。在GitHub releases页面可以找到预先构建好的SD card image。为了构建SD card image,我们需要: 获取文件,从root filesystem,来自 os-rootfs 。 获取空的 raw filesystem,来自 image-builder-raw ,带两个分区。 添加 Hypriot's Debian repos。 安装 Raspberry Pi kernel,来自 rpi-kernel 。 安装 Docker工具和引擎, Docker Compose 和 Docker Machine。
设置Build环境
首先确认 vagrant 已经安装。然后运行下面的命令创建Vagrant box,然后使用Vagrant Docker daemon。这个Vagrant box需要运行在guestfish inside。使用 export VAGRANT_DEFAULT_PROVIDER=virtualbox 去创建VirtualBox VM。
启动 vagrant box vagrant up
输出 docker host export DOCKER_HOST=tcp://127.0.0.1:2375
检查Docker是否在 vagrant 里运行。 docker info | grep 'Operating System' Operating System: Ubuntu 16.04.3 LTS
构建SD card image
构建 SD card image,输出被写入和压缩到 hypriotos-rpi-dirty.img.zip 。 make sd-image
运行 Serverspec tests
为了测试SD card image,通过 Serverspec 运行下面的命令。将扩展 SD card image在Docker container 中,然后运行 Serverspec tests ,对应于 builder/test/ 目录中。 make test
3、刷写SD卡和测试
现在烧写 SD card image到Raspberry Pi然后启动。运行 Serverspec 整体性测试,在树莓派中对应 builder/test-integration/ 目录。设置 BOARD 到运行的树莓派的IP address 或者 host name。 flash hypriotos-rpi-dirty.img.zip BOARD=black-pearl.local make test-integration
该测试可以在任何 Docker Machine工作, 因此你不需要创建 Vagrant box。
@使用初始化文件
使用 flash --userdata myinit.yml hypriot.img 的方式可以指定初始化文件,将使用cloud-init这个机制对系统进行初始化设置,详情参见 https://github.com/hypriot/flash 里的说明,使用非常方便。 注意,使用初始化文件或导致启动时耗费时间运行,出现登录错误的情况,要耐心等待初始化过程完成,会出现新设定的主机名,再登录,就可以了。
4、设置网络和容器服务
4.1 设置静态IP地址
Linux上,一般通过/etc/network/interfaces或者/etc/network/interface.d/*.*文件来指定。如果安装了dhcpcd,则通过/etc/dhcpcd.conf文件来指定。
目前,Hypriot没有使用dhcpcd,即时手动安装,也不起作用( 参考: https://github.com/hypriot/device-init/issues/6 ),因此只能使用指定interface文件的方法。如下所示,运行: sudo nano /etc/network/interfaces
输入下面的内容(IP地址等改为自己的): # interfaces(5) file used by ifup(8) and ifdown(8) # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d allow-hotplug wlan0 iface eth0 inet static address 192.168.1.97 network 192.168.1.0 netmask 255.255.255.0 broadcast 192.168.1.255 gateway 192.168.1.1 dns-nameservers 8.8.8.8 # Enable Wifi AP SSID wpa_conf /etc/wpa_supplicant/wpa_supplicant.conf
或者将其保存为文件 /etc/network/interface.d/wlan0,亦可。该文件启动时将被interface所包含进去。
4.2 配置WiFi无线接入点
运行命令( sudo nano /etc/wpa_supplicant/wpa_supplicant.conf ),输入下面内容(把MySSID和MyPassword改成自己的无线路由器设置): ctrl_interface=/var/run/wpa_supplicant network={ ssid="MySSID" psk="MyPassword" priority=1 }
保存后,重启network服务(sudo service network restart)即可。
4.3 安装Portainer容器管理 $ docker volume create portainer_data $ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
获取IP地址:ifconfig
远程ssh登录:ssh pirate@192.168.199.101,192.168.199.101为ifconfig获得的IP地址。
然后到浏览器,输入:http://192.168.199.101:9000或类似地址即可管理容器服务。
5、版本维护
对本项目维护者,你可以提交 SD card image 到GitHub releases 版本仓库,按照下面的方式建立版本: TAG=v0.0.1 make tag
打开 GitHub release,填写相应的变化描述和解决问题的链接。
贡献
你可以贡献给该 repo,通过 forking然后发送回 pull requests. 欢迎任何反馈!
硬件开发
2018-01-08 12:14:00
标签
分布式事务 , GTS , Global Transaction Service, 柔性事务, TCC , XA两阶段提交协议
全局事务服务(Global Transaction Service,简称 GTS)是阿里新推出的分布式事务处理方案,对其深入分析的资料相对匮乏。本文的目标是剖析GTS的技术路线,厘清其优势与约束。文章参考了GTS公开的专利、产品文档、相关网页,文章中肯定有不准确的地方,欢迎各位同学拍砖与指正。
一、GTS的目标
GTS是一个面向互联网交易场景的分布式事务解决方案。
制约分布式事务的三个因素
分布式事务是互联网交易场景面临的关键问题之一。不同于搜索、社交、联机分析应用,电子商务、支付是典型的交易场景,数据的错误会带来严重的后果,对数据的一致性与可用性有很高的要求。互联网环境带来了海量的数据容量、连接数与访问量,单一数据库节点无法应对,成为整个系统的瓶颈。为解决单一数据库成为瓶颈的问题,通过数据拆分实现数据库能力的线性扩展。数据拆分是使用分库分表的方式,将数据存储在多个数据库节点,利用分布式数据库平台解决数据库瓶颈的问题。分布式数据库环境中,一个事务会跨越多个数据库,面临分布式事务处理的问题。
分布式事务解决方案面临应用灵活性、数据一致性、性能三者的挑战。目前已有多种成熟方案,每种方案都是对这三个方面做出的取舍。
相互制约的三个因素为: 应用灵活性:应用访问数据的方式是否需要修改,以及修改的程度。 一致性:数据是强一致,还是最终一致的(允许中间不一致的状态)。 系统性能:分布式事务对整体性能的影响。
现有分布式处理方案
现有成熟的分布式解决方案包括XA两阶段提交、可靠消息与TCC模式等类型。XA两阶段提交属于强一致事务,可靠消息与TCC模式属于柔性事务。
XA两阶段提交
XA 是指由 X/Open 组织提出的分布式事务处理的规范。XA规范主要定义了Transaction Manager(TM)和Resource Manager(RM)之间的接口,结构如下图所示。

XA协议的流程可大致分为三个步骤: 步骤1:APP向TM创建全局事务,TM向APP返回全局事务号。 步骤2:APP使用全局事务号,访问RM的资源(当RM为数据库时,资源访问就是SQL操作)。当RM第一次收到访问时,使用该全局事务号向TM注册,TM返回事务分支事务号。 步骤3:APP向TM发出全局事务提交请求,TM与参与事务的RM通信,进行提交处理,全部完成后,向APP返回结果。
TM与RM之间的提交处理,采用两阶段提交协议。TM在第一阶段对所有的参与事务的RM请求“预备”操作,达成关于分布式事务一致性的共识。事务参与者必须完成所有的约束检查,并且确保后续提交或放弃时所需要的数据已持久化。在第二阶段,根据之前达到的提交或放弃的共识,请求所有参事务的RM完成相应的操作。
提交事务的过程中需要在多个资源节点之间进行协调,而各节点对锁资源的释放必须等到事务最终提交时,所以两阶段提交在执行同样的事务时会比一阶段提交消耗更多的时间。当事务并发量达到一定数量时,就会出现大量事务积压甚至出现死锁,系统性能和处理吞吐量就会严重下滑。
可靠消息
可靠消息的一种可能实现的结构如下图。

说明: 业务处理服务在业务事务提交前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不真正发送。 业务处理服务在业务事务提交后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才真正发送消息。 业务处理服务在业务事务回滚后,向实时消息服务取消发送。 消息状态确认系统定期找到未确认发送或回滚发送的消息,向业务处理服务询问消息状态,业务处理服务根据消息ID或消息内容确定该消息是否有效。
通过消息进行事务异步的方式,可以保证业务数据操作和消息的发送同时执行成功或失败,保持了事务的最终一致性。
采用可靠消息的方式,在两个事务间实现分布式事务时,可以很好地满足事务最终一致性以及事务的回滚,但如果一个事务上下文中超过两个事务操作后,需要开发人员实现整个事务流程的操作日志的记录、每个事务分支的回滚以及整个流程的准确调度。
TCC模式
TCC模式为全局事务执行提供了一个框架,开发人员只需要实现每个事务分支的回滚,不需要记录整个事务流程的操作日志。TCC模式结构如下图。

说明: 一个完整的业务活动由一个主业务服务与若干从业务服务组成。 主业务服务负责发起并完成整个业务活动。 从业务服务提供TCC型业务操作。 业务活动管理器控制业务活动的一致性,它登记业务活动中的操作,并在业务活动提交时确认所有的TCC型操作的confirm操作,在业务活动取消时调用所有TCC型操作的cancel操作。
TCC业务包括两个阶段完成: 第一阶段:主业务服务分别调用所有从业务的 try 操作,并在活动管理器中登记所有从业务服务。当所有从业务服务的 try 操作都调用成功或者某个从业务服务的 try 操作失败,进入第二阶段。 第二阶段:活动管理器根据第一阶段的执行结果来执行 confirm 或 cancel 操作。
如果第一阶段所有 try 操作都成功,则活动管理器调用所有从业务活动的 confirm操作。否则调用所有从业务服务的 cancel 操作。
小结
可靠消息与TCC模式通过避免XA两阶段提交对数据资源的长期锁定提升了性能,通过在数据库外部实现事务机制达到了最终一致性,但牺牲了应用灵活性,需要开发人员实现事务检查与回滚的细节,面临着花费大量精力保证应用正确性的问题。
GTS目标是在性能开销可接受的情况下,由GTS统一处理全局事务的故障恢复与并发控制,对应用开发屏蔽事务处理的细节,从而提升应用的灵活性与数据的一致性。
二、GTS的技术路线
GTS采用基于XA架构优化的技术路线,在保留XA架构灵活性的优点下,通过将XA提交中的第一阶段与第二阶段解耦,将提交过程转换为第一阶段本地事务提交+第二阶段异步清理的方式,从而提供提升系统性能,同时通过在GTS内部维护应用级别的日志与锁信息,实现了全局事务的回滚与并发控制。
GTS方案认为XA性能低效的根本原因是采用了阻塞协议。在分布式事务提交的第一阶段等待最慢的一个事务分支完成,即使在不存在锁冲突的情况下,各事务分支的数据库连接依然会被挂起所占用的资源都不能够释放,以防止全局事务提交前释放资源所造成的数据不一致。对于业务流量极高的大规模互联网企业,难以接受 XA 两阶段提交协议所带来的巨大性能开销。
GTS架构包含的组件与XA完全相同,示意架构如下图。

GTS全局事务处理流程与XA一致,也包括全局事务注册、数据访问与全局事务提交三个步骤,但在第二步与第三步的内部处理上与XA不同: 第二步数据访问中,各事务分支完成数据操作的同时,会将全局事务信息(锁与日志信息)存储在当前数据库的表中。 第三步全局事务提交中,采用一阶段本地事务提交+二阶段异步清理的方式。首先对各数据库做本地事务的提交,并释放数据库连接等系统资源,然后,向TM发出全局事务提交请求,TM收到请求后,立即返回成功,TM后续实际工作是对各个数据库使用全局事务标识符进行全局事务信息的清理。
GTS与XA在全局事务的故障恢复处理与并发控制采用了不同的实现机制: XA两阶段协议是基于数据库内核的日志与锁信息实现全局事务的回滚与并发控制。由于GTS一阶段本地事务提交中,会直接提交本地事务并释放连接,此时数据库内核的日志与锁表对全局事务不再有效。在第二步中,GTS会将日志和锁信息存储在表中,当事务本地提交后,日志和锁信息被持久化保存,用于实现全局事务的并发控制与故障恢复。 GTS的故障恢复只有UNDO操作没有REDO操作,日志表中存储了UNDO需要的信息,包括行记录标识、全局事务号、镜像查询语句、操作的前像与操作的后像。当发生故障时,对于已经本地提交的数据库,从UNDO表中找到修改的记录,记录的操作前像和操作后像,使用镜像查询语句从数据库中读取该记录的当前值。如果当前值与记录操作后像相同,则直接使用操作前像进行恢复,否则报警,进行人工处理。 GTS的全局锁表中存储了记录的加锁信息。封锁的粒度是行(记录),锁的类型包括共享锁和互斥锁,对于同一个记录,加锁的规则是共享锁与共享锁不冲突,共享锁与互斥锁冲突、互斥锁与互斥锁冲突。对插入(INSERT)、修改(UPDATE)、删除(DELETE)、更新模式的锁定查询(SELECT… FOR UPDATE) 操作加互斥锁。对于共享模式的锁定查询 (SELECT…LOCK IN SHARE MODE) 操作加共享锁。若没有锁冲突,在GTS锁表中,增加一行记录,表示加锁成功。 GTS的默认隔离级别为读未提交(脏数据),使用SELECT… FOR UPDATE和SELECT…LOCK IN SHARE MODE,可使查询隔离级别提升至读已提交。
三、GTS的架构与处理流程
架构
下图描述了GTS一种可能的实现架构。

与XA架构相同,GTS架构由应用、事务管理器、资源管理器三个部分组成。资源管理器由事务分支处理模块、镜像查询构造模块、并发控制模块、恢复控制模块,以及存储在数据库中的GTS事务信息(GTS锁表与GTS日志表)等组成。 事务分支处理模块:是资源管理器的外部接口,并完成内部各模块的调用。 镜像查询构造模块:从Insert、Update、Delete语句,生成该操作对应记录集的镜像查询语句。例如table_name表包含两个字段column1和column2,column1为主键,则镜像查询语句为select column1, column2 from table_name where column1=v1。 并发控制模块:基于GTS事务锁表,维护读写并发控制。锁表定义如下:
字段名 字段类型 字段描述 ID 整数 自增主键
TABLE_NAME 字符串 表名
KEY_VALUE 整数 数据行ID
XID 字符串 全局事务标识
XLOCK 整数 互斥锁标记
SLOCK
BRANCH_ID
整数
整数
共享锁标记
事务分支标识
恢复控制模块:基于GTS日志表,进行故障恢复。 日志表定义如下:
字段名 字段类型 字段描述
ID 整数 自增主键
GMT_CREATE 时间 创建时间
GMT_MODIFIED datetime 修改时间
XID 整数 全局事务ID
BRANCH_ID 整数 分支事务ID
ROLLBACK_INFO longblob 查询语句、前像与后像
STATUS
SERVER
整数
字符串
状态
分支所在DB IP
主要流程序列图
分别描述了insert/delete/update操作、读已提交操作、提交操作和回滚操作等四个操作的序列图(一种可能的实现方式)。
insert/delete/update操作流程序列图

读已提交操作流程序列图

提交操作流程序列图

回滚操作流程序列图

阿里官方案例
GTS产品网站给出了一个交易类事务中最典型的 转账案例 A和B两个用户的数据分别位于一个DRDS实例的两个不同分库中,用50个进程并发进行 A转账给3,每个进程转账10次,每次转账金额在1到10之间随机生成,转账过程中模拟了3%的网络异常,使用GTS事务保证了A和B钱的总数不变。 从代码上可看出,只需增加一条开启GTS的sql语句,就将单机事务应用提升至分布式事务,体现出很好的应用灵活性。测试中转账事务执行500次,成功490次,失败10次。转账结束10秒后,查询账户金额总数正确。
2017云栖大会 GTS产品介绍中,给出了使用GTS与不使用事务(1PC) 测试对比 。下图,GTS比1PC的性能损耗在10%,远远小于2PC方式,表现出优异的性能。
四、GTS的优势与约束
与基于消息队列与TCC补偿模式的分布式事务相比,在性能满足的情况下,GTS更好的应用灵活性与数据一致性: 灵活性:数据库应用基本实现零修改,同时,基于XA模型,可方便的支持消息队列数据库等多种RM。 数据一致性:GTS 的缺省事务隔离级别为读未提交,该模式下可以达到分布式事务的最大性能,但可能会读到脏数据。对于一致性要求高的应用,在性能允许的情况下,可以采用已提交读语句(for update、lock in share mode)将隔离级别提升至读已提交。
根据GTS实现机制的特点,其应用场景上有以下约束:加锁操作记录数量不能太大,操作冲突不能太多,加锁时间不能太长。违法以上约束时,GTS内部会占用过多资源、锁冲突和回滚增加,导致性能的下降。电商、物流、金融、零售行业中的核心交易场景有着高并发,高性能,单次操作数据集小,事务响应时间敏感的特点,GTS类方案在此类场景中有着广泛和良好的应用前景。
阅读原文
http://click.aliyun.com/m/38903/
硬件开发
2018-01-05 15:24:00
1. 取消寄存器写保护(也即是先IWDG_KR中写入0x5555)
目的:取消IWDG_PR和IWDG_RLR寄存器写保护,从而可以操作这两个寄存器
库函数:void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
2. 设置预分频系数
设置预分频寄存器(IWDG_PR)的预分频因子(IWDG_Prescaler),也就设置了计数器的时钟频率
例如:IWDG_Prescaler_256,就是设置计数器时钟频率为LSI_FREQ/256​
库函数:void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
3. 设置重装载值
向重装载寄存器(IWDG_RLR) 写入重装载值Reload​,最大0xFFF
超时时间TimeOut = Reload * 计数周期 = Reload / 计数频率
= ​Reload / IWDG_Prescaler
Reload = TimeOut * ​IWDG_Prescaler
例如:​IWDG_Prescaler = IWDG_Prescaler_256 = LSI_FREQ/256​
​Reload = LSI_FREQ/128
​​TimeOut = Reload / IWDG_Prescaler = (LSI_FREQ/256​)/(LSI_FREQ/128) = 0.5s = 500ms
库函数:void IWDG_SetReload(uint16_t Reload);
4. 重载计数值喂狗(向IWDG_KR写入0xAAAA)
向IWDG_KR寄存器写入0xAAAA时,重装载值会被传送到计数器中
库函数:void IWDG_ReloadCounter(void);
5. 启动看门狗(向IWDG_KR 写入0xCCCC)
写入0xCCCC,启动看门狗工作(若选择了硬件看门狗则不受此命令字限制)。
库函数:void IWDG_Enable(void);
6. 喂狗(向IWDG_KR写入0xAAAA)
喂狗,其实就是重载计数值喂狗(向IWDG_KR写入0xAAAA)
向IWDG_KR寄存器写入0xAAAA时,重装载值会被传送到计数器中
在看门够复位前,再次把数值写入;​
库函数:void IWDG_ReloadCounter(void);
#define LSI_FREQ 37000 // LSI频率约37KHz #define IWDG_RELOAD LSI_FREQ/32 //范围0-0xFFF() #define IWDG_CLOCK_PRECALER IWDG_Prescaler_256 //如果使用的是LSI,则时钟频率是LSI_FREQ/256 //IWDG_Prescaler_4 //IWDG_Prescaler_8 //IWDG_Prescaler_16 //IWDG_Prescaler_32 //IWDG_Prescaler_64 //IWDG_Prescaler_128 //IWDG_Prescaler_256 /** * @brief 初始化独立看门狗 * @param IWDG_CLOCK_PRECALER, IWDG_RELOAD * IWDG_CLOCK_PRECALER, IWDG_Prescaler: specifies the IWDG Prescaler value. * This parameter can be one of the following values: * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 * @retval None */ void IWDG_init(void) { /* IWDG timeout equal to 1s (the timeout may varies due to LSI frequency dispersion) */ /* Enable write access to IWDG_PR and IWDG_RLR registers */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* IWDG counter clock: LSI/256 */ IWDG_SetPrescaler(IWDG_CLOCK_PRECALER); /* Set counter reload value to obtain 1s IWDG TimeOut. TimeOut = 1s Counter Reload Value = TimeOut/IWDG counter clock period = TimeOut * IWDG counter clock Frequence = 1 * (LSI_FREQ/256) = LSI_FREQ/256 */ IWDG_SetReload(IWDG_RELOAD); /* Reload IWDG counter */ IWDG_ReloadCounter(); /* Enable IWDG (the LSI oscillator will be enabled by hardware) */ IWDG_Enable(); } /** * @brief 独立看门狗喂狗函数 * @param None * @retval None */ void IWDG_feed(void) { /* Reload IWDG counter */ IWDG_ReloadCounter(); }
硬件开发
2018-01-04 20:21:00
统计USB 1.0、USB 2.0、USB 3.0的部分参数,包括带宽,接线长度,电压电流等;
接口 USB 1.0 USB 2.0 USB 3.0
带宽 12 Mbit/s 480Mbit/s 5000Mbit/s
速度 1.5MB/s 60MB/s 625MB/s
最大接线长度 5米 5米 5米
输出电流与电压 5V/500mA 5V/500mA 5V/900mA
硬件开发
2018-01-04 18:42:00
1. 芯片容量的确定,往往容易疏忽。
小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx、 STM32F102xx和
STM32F103xx微控制器。
中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx、 STM32F102xx和
STM32F103xx微控制器。
大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控
制器。
互联型产品是指STM32F105xx和STM32F107xx微控制器。

2. 居动文件的选择,不同芯片选择不同的居动文件。
官方库中STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\a
rm 下面,根据芯片不同选择相应启动文件。 如 大容量芯片,则选 startup_stm32f10x_hd.s 文件复制到 CORE 下面。

3. 三处工程配置的修改
根据芯片不同选择
根据芯片不同选择

根据芯片不同选择
硬件开发
2018-01-04 18:08:00
非常简单的小制作,适合新手以及初学者 入门学习,也请各位大神多多指点。自己测了下稍微有些偏差,显示鞋码比我实际鞋码大了一号,各位大大有没有意见我改正下。下面是具体的制作过程和代码。
1.原理
鞋码匹配仪,利用超声波测距的原理。通过使用超声波遇到障碍返回的特性,计算超声波放出与返回的时间计算来测定障碍与超声波模块的距离。
鞋码匹配仪的固有大小已知,在脚放入时,大小会发生改变 使用已知距离对改变后的距离做差获得脚的尺寸,再通过尺寸与距离的转换得到正确的鞋码(此处使用标准鞋码)。
2. 所需元器件(某宝能买到 挺便宜的)
· 超声波模块 1个
· TPYBoard v102板子 1块
· 四位数码管 1个
· micro USB数据线 1条
· 杜邦线 若干
3. 超声波模块工作原理
(1)采用IO口TRIG触发测距,给最少10us的高电平信号。
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回。
(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。
如下图接线,VCC 供 5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。
4. 控制四位数码管显示数字


(1)1、2、3、4是“位选”针脚,用于控制具体哪一位显示。
(2)a、b、c、d、e、f、g、dp(h)是“段选”针脚,用法和1位数码管一致,用来显示具体的数值。
数码管(位选) TPYBoard v10x开发板
1 X3
2 X4
3
4
X5
GND(鞋码匹配用不到四位所以该脚拉低)
数码管(段选) TPYBoard v10x开发板
a X6
b X7
c X8
d Y9
e Y10
f Y11
g
dp(h)
Y12
留空(此脚为小数点的控制脚悬空即可)
5. 接线图
6. 源代码 import pyb
from pyb import Pin
from pyb import Timer
from machine import SPI,Pin
Trig = Pin('X2',Pin.OUT_PP)
Echo = Pin('X1',Pin.IN)
num=0
flag=0
run=1
def start(t):
global flag
global num
if(flag==0):
num=0
else:
num=num+1
def stop(t):
global run
if(run==0):
run=1
start1=Timer(1,freq=10000,callback=start)
stop1=Timer(4,freq=2,callback=stop)
sizecc = [35,36,37,38,39,40,41,42,43,44,45,46,47]#280-47 -5
while True:
if(run==1):
Trig.value(1)
pyb.udelay(100)
Trig.value(0)
while(Echo.value()==0):
Trig.value(1)
pyb.udelay(100)
Trig.value(0)
flag=0
if(Echo.value()==1):
flag=1
while(Echo.value()==1):
flag=1
if(num!=0):
#print('num:',num)
distance=num/1000*34000/2
print('Distance')
print(distance,'mm')
cc = (int)((distance-215)/5)
if cc<0:
cc=0
elif cc>12:
cc=12
print(sizecc[cc],'cc')
flag=0
run=0
硬件开发
2018-01-04 10:12:00
1.Linux版本 centOs 6.7
1.1 准备工作
(1)安装虚拟机 :
(2)Linux系统 :
(3)CRT(Linux客户端):
2. 常用命令
(1)pwd:查看现在所在位置
root账号默认在进入后的位置在 root文件夹下
其他账号默认 在 home目录下
(2)cd / 回到根目录下
(3) ll 查看目录下面的文件、目录及快捷方式
怎么区分三种文件呢?
d : 目录 - : 文件 l: 快捷键

(4)clear 清除
(5)cd 目录名 :进入到那个目录
(6) cd .. 与 cd -
(7) cd ~ 回家
(8) mkdir 目录 名称 :创建目录 (这里只是 目录 对于文件的创建不是这个命令)
方式一:单级创建目录
一般情况我们会将 自己的软件安装到 usr/local 下

方式二:级联创建目录 mkdir –p 目录1/目录2/目录3.......

(9)rmdir 删除 空目录

(10)Vim编辑器 创建文件或者编辑文件

(11)rm 目录(或文件) 删除目录 或文件
11.1 单步删除 文件 询问
11.2 单步删除 文件 不 询问
11.3 删除目录
询问删除
直接删除 (删除 目录中存在 文件或目录的)
(12) 查看文件内容
12.1 cat 文件名称 :查看文件中所有内容 不分页
12.2 more 文件名称:带了分页功能 空格显示下一页数据 回车 显示下一行的数据
12.3 less 文件名称: PgUp 和 PgDn 进行上下翻页.
12.4 tail 用于显示文件后几行的内容。

(13) cp 复制内容
13.1 复制内容
13.2 复制内容 并修改名称
(14) mv 移动或者重命名

(15) 【tar】命令:(***** 打包或解压)

常用参数:
-c:创建一个新tar文件
-v:显示运行过程的信息
-f:指定文件名
-z:调用gzip压缩命令进行压缩
-t:查看压缩文件的内容
-x:解开tar文件
打包
解压
压缩:
解压
(16) grep 查找符合条件的字符串

(17) 帮助 命令
(18) Linux进程命令

(19) 管道查询
管道是Linux命令中重要的一个概念, 其作用是将一个命令的输出用作另一个命令的输入。

ls --help | more 分页查询帮助信息
ps –ef | grep java 查询名称中包含java的进程
(20) 网络通讯命令
20.1 查看Linux 的IP
20.2 开启/关闭 网卡


20.3 ping 探测网络是否通畅
(21) 查看Linux进程 、杀死 进程
ps –ef 查看所有进程
ps -ef | grep 关键字 查看某一进程
kill 杀掉某一进程
kill 25642 杀掉25642编号的进程
kill -9 25642 强制杀死进程
(22) 关机重启
Linux centos重启命令: reboot

Linux centos关机命令: halt 立刻关机
(23) chmod 文件授权


(24) 防火墙
24.1 查看Linux防火墙 状态 /etc/init.d/iptables status

24.2 临时开启防火墙
24.3 临时关闭 防火墙
24.4 永久性关闭防火墙 (需要重启启动系统的)
chkconfig iptables off 永久性关闭防火墙

24.5 永久性开启防火墙(需要重启启动系统的)
chkconfig iptables on 永久性开启防火墙

(25) 开启端口
/sbin/iptables -I INPUT -p tcp --dport 8081 -j ACCEPT 添加到防火墙列表
/etc/rc.d/init.d/iptables save 保存一下
/etc/init.d/iptables status 查看防火墙列表












硬件开发
2018-01-01 19:26:00
96Boards( https://www.96boards.org/ )是一个基于ARM64的开发版,跟树莓派( http://www.raspberrypi.org )类似,但以64位ARM CPU为主,板式更为简洁。
96Boards-名片大小的64位ARM计算机主板+3D打印外壳。

操作系统有重大更新:
2017年ARM64有很多大的进展,96Boards当然也大大的受益了。
Docker for ARM64已经正式可用了,现在已经做到与主流版本同步了。
Docker项目在2017年拆分出了 Moby和Linuxkit,已经同步支持ARM64 ,堪称伟大的进步。ARM在向云计算和大规模集群以及物联网应用都迈出了更大的步伐,做低功耗的存储、下载、网络服务、区块链、传感器、机器人、自动车等智能设备都会更加得心应手。 96Boards可以担当更大的角色了。
新开了好多实用、好玩的项目: https://www.96boards.org/projects/ 3D打印的外壳,提供OpenSCAD的源文件: https://www.thingiverse.com/thing:1692217/#files Android TV, https://www.96boards.org/projects/AndroidTV/ Deep learning in Linux Debian, https://www.96boards.org/projects/deeplearning/ DLNA Media Server/Client, https://www.96boards.org/projects/DLNAMediaServer/ Gumstix Gadget Drone, https://www.96boards.org/projects/GadgetDrone/
还需要进一步努力完善的地方: 现在,也许是把gnome之类的GUI桌面移植到ARM64平台上的时候了。 如果有人把 https://www.armbian.com/download/ 加入96Boards,将会是非常好的东东。 鉴于 Alpine 已经成为Docker的核心,加入Alpine的直接支持也很有意义。 如果与Intel的 Movidius 深度学习芯片和 RealSense 三维视觉设备结合,再运行ROS,简直太酷了。 KaliLinux 在96Boards上运行,会不会过于强大?
硬件开发
2017-12-31 18:58:00
标签
PostgreSQL ,
背景
生物科学中相当重要的工作之一解开遗传密码?
欧式空间计算,是其中的一个需求,很有意思吧,PostgreSQL可以用来解开遗传密码。
https://en.wikipedia.org/wiki/Euclidean_distance
https://www.math.uci.edu/~gpatrick/source/205b06/chapviii.pdf
实际上PostgreSQL是一个扩展性非常强大的数据库,比如在文本相似计算方面,就有诸多扩展插件。
《17种相似算法与GIN索引 - pg_similarity》
https://github.com/eulerto/pg_similarity
https://baike.baidu.com/item/%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E5%BA%A6%E9%87%8F/1274107?fromtitle=%E6%AC%A7%E6%B0%8F%E8%B7%9D%E7%A6%BB&fromid=1798948
《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 3 rum, smlar应用场景分析》
《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 2 smlar插件详解》
《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 1 文本(关键词)分析理论基础 - TF(Term Frequency 词频)/IDF(Inverse Document Frequency 逆向文本频率)》
在基因科学方面,也有扩展插件应用:
《为了部落 - 如何通过PostgreSQL基因配对,产生优良下一代》
在化学分析方面,也有相似的插件:
http://www.rdkit.org/
某个生物科技公司,有这样的一种需求:
每张表有几十万行,几万列,全部浮点类型,任意列勾选,计算欧氏距离等需求。
设计
因为数据库设计限制,不能支持一张表几万列,不过PostgreSQL可以将多列存成数组。
1、DNA结构如下: create table dna ( id serial primary key, -- 主键 arr float8[] -- 浮点数组 );
比如每行代表一个物种的测序数据。
2、生成随机浮点数组的函数,可以方便的生成测试数据。 create or replace function gen_randarr(int) returns float8[] as $$ select array_agg(random()*1000) from generate_series(1, $1); $$ language sql strict; postgres=# select gen_randarr(10); gen_randarr ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {830.968368332833,283.642665948719,64.4483459182084,24.3995497003198,654.509209562093,762.801019474864,109.366949647665,849.462529178709,111.898560542613,650.523159187287} (1 row) Time: 0.758 ms
3、生成50万条测试数据,每组2万浮点数。 vi test.sql insert into dna (arr) values (gen_randarr(20000)); pgbench -M prepared -n -r -P 1 -f ./test.sql -c 50 -j 50 -t 10000
数据大概占用86GB空间。 postgres=# \dt+ dna List of relations Schema | Name | Type | Owner | Size | Description --------+------+-------+----------+-------+------------- public | dna | table | postgres | 86 GB | (1 row)
计算欧式距离的函数
可以使用plpgsql创建计算两个浮点数组的欧式距离的函数,长度可以不一样,因为可能不同物种的遗传数据不一样,有的多,有的少。
如果使用C函数,性能会更好。 CREATE OR REPLACE FUNCTION euc_distance(l float8[], r float8[]) RETURNS float8 AS $$ DECLARE s float8 := 0; -- 中间结果 x float8; -- LOOP中的数组元素值 i int := 1; -- 数组下标 r_len int := array_length(r,1); -- 右边数组的长度 l_len int := array_length(l,1); -- 左边数组的长度 BEGIN if l_len >= r_len then foreach x in array l LOOP s := s + ( (x - case when i<=r_len then r[i] else 0 end) ^ 2 ); i := i+1; END LOOP; else foreach x in array r LOOP s := s + ( (x - case when i<=l_len then l[i] else 0 end) ^ 2 ); i := i+1; END LOOP; end if; RETURN |/ s; END; $$ LANGUAGE plpgsql;
例子 postgres=# select euc_distance(array[1,2,3], array[1,2,3]); euc_distance -------------- 0 (1 row) Time: 0.386 ms postgres=# select euc_distance(array[1,2,3], array[1,2,3,4,5]); euc_distance ------------------ 6.40312423743285 (1 row) Time: 0.470 ms
通过这个函数,传入要计算的数组即可计算欧式距离。
计算部分指定位置的欧式距离
这个主要用于部分计算,例如人类和猴子,在某一段的相似性,那么需要从这两条记录中,分别取出要计算的部分,重新组成两个数组,然后计算它们两的欧氏距离。
例子: select t1.id, t2.id, euc_distance(t1.arr, t2.arr) from (select * from dna where id=1) t1, (select * from dna where id=2) t2; id | id | euc_distance ----+----+------------------ 1 | 2 | 57768.4024741692 (1 row) Time: 12.027 ms
或 select t1.id, t2.id, euc_distance( array[t1.arr[1], t1.arr[7], t1.arr[8], t1.arr[9], t1.arr[10]], -- 指定位置 array[t2.arr[1], t2.arr[7], t2.arr[8], t2.arr[9], t2.arr[10]] -- 指定位置 ) from (select * from dna where id=1) t1, (select * from dna where id=2) t2; id | id | euc_distance ----+----+------------------ 1 | 2 | 679.897967241517 (1 row) Time: 1.887 ms
计算被勾选物种的排列组合欧式距离
比如选中了100个物种,计算它们的任意组合的欧氏距离。
需要一些辅助函数:
1、组合去重函数,只去掉重复行。 CREATE or replace FUNCTION has_dupli_val(VARIADIC arr int[]) RETURNS boolean AS $$ select count(distinct val)<>count(*) dist_val from unnest($1) t(val) where val is not null; $$ language sql strict;
2、组合去重函数,去掉按列值排序后的重复行。 CREATE or replace FUNCTION arr_sort(arr int[]) RETURNS int[] AS $$ select array_agg(id order by id) from unnest(arr) t(id); $$ language sql strict;
3、比如选中了1,2,3,4这四种物种,如何得到他们的排列组合呢? select distinct on (arr_sort(array[t1.id, t2.id])) t1.id, t2.id from (select unnest(array[1,2,3,4]) id) t1, (select unnest(array[1,2,3,4]) id) t2 where not has_dupli_val(t1.id, t2.id); id | id ----+---- 1 | 2 3 | 1 1 | 4 2 | 3 4 | 2 4 | 3 (6 rows) Time: 1.066 ms
4、创建一个函数,用于计算输入组合物种的排列组合欧式距离。 create or replace function compute_eu_dist( arr_kind int[], -- 输入物种IDs out kind1 int, -- 物种1 out kind2 int, -- 物种2 out euc_dist float8 -- 物种1,2的欧氏距离 ) returns setof record as $$ declare l float8[]; -- 左数组 r float8[]; -- 右数组 begin for kind1,kind2 in select distinct on (arr_sort(array[t1.id, t2.id])) t1.id, t2.id from (select unnest(arr_kind) id) t1, (select unnest(arr_kind) id) t2 where not has_dupli_val(t1.id, t2.id) -- 排列组合 loop select arr into l from dna where id=kind1; -- 获取物种1的遗传信息 select arr into r from dna where id=kind2; -- 获取物种2的遗传信息 euc_dist := euc_distance(l,r); -- 计算物种1,2的欧式距离 return next; -- 返回 end loop; return; end; $$ language plpgsql strict;
计算例子:
输入5个物种的ID,返回这5个物种的排列组合欧式距离。 postgres=# select * from compute_eu_dist(array[1,2,3,4,5]); kind1 | kind2 | euc_dist -------+-------+------------------ 2 | 1 | 57768.4024741692 1 | 3 | 57866.2845528097 1 | 4 | 57632.9837382263 5 | 1 | 57779.36595061 3 | 2 | 58004.3926579964 4 | 2 | 57593.0783041254 5 | 2 | 57802.9690538283 3 | 4 | 57837.6707750057 3 | 5 | 57921.5524014271 4 | 5 | 57818.9181109456 (10 rows) Time: 100.582 ms
小结
PostgreSQL是一个扩展性很好的数据库,内置了丰富的数据类型。
本例,使用函数编程、数组类型两个特性,解决了生物科学中的遗传计算的场景的疑难问题(上万列,任意组合计算排列组合的欧式距离)。
同时PostgreSQL还能支持并行计算,在重计算的场景,可以提高计算响应速度。
硬件开发
2017-12-28 16:35:00
使用console线连接电脑和交换机。
使用超级终端登录com1,9600。
回车后再回车。
sys
查看当前状态
dis cu
查看组合复用端口的地址
进入端口设置
int g1/0/25
启用光口
combo enable fiber
保存设置
save
重启设备
ctr + z
reoot
硬件开发
2017-12-27 12:23:00
如何克隆SD卡的内容
树莓派安装好了软件,其它的需要重复安装。直接拷贝文件是不行的,因为安装过程中产生了新的分区。使用dd做克隆,就可以全部复制过去。
##step1. 定位你的SDCard
命令行输入: diskutil list
显示如: /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *251.0 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_HFS Macintosh HD 90.7 GB disk0s2 3: Apple_HFS d 34.9 GB disk0s3 4: Apple_HFS f 65.6 GB disk0s4 5: Apple_HFS g 59.1 GB disk0s5 /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: Apple_partition_scheme *14.2 MB disk1 1: Apple_partition_map 32.3 KB disk1s1 2: Apple_HFS Flash Player 14.2 MB disk1s2 /dev/disk2 #: TYPE NAME SIZE IDENTIFIER 0: Apple_partition_scheme *16.1 MB disk2 1: Apple_partition_map 32.3 KB disk2s1 2: Apple_HFS Flash Player 16.0 MB disk2s2 /dev/disk3 #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *31.9 GB disk3
那么你的sdcard就是盘符disk3
##step2. 用原卡制作镜像
命令行输入, 制作镜像文件: sudo dd if=/dev/rdisk3 of=/Users/liangwei/Downloads/yihud3.dmg bs=1m
##step3. 格式化新卡
把元卡拿出来, 把新卡放进去, 然后同step1, 找到新卡盘符, 然后命令行: diskutil unmountDisk /dev/disk3 sudo newfs_msdos -F 32 /dev/disk3
##step4. 烧写新卡 sudo dd if=/Users/liangwei/Downloads/yihud3.dmg of=/dev/rdisk3 bs=1m
树莓派的镜像卡也是这样烧写, 但是格式化的时候需要格式化为 FAT16: sudo newfs_msdos -F 16 /dev/disk3
硬件开发
2017-12-25 14:36:00
8237A有四种工作方式:单字节传送、数据块传送、请求传送和多片级联。  (1)单字节传送(single mode)   单字节传送方式是每次DMA传送时,仅传送一个字节。传送一个字节之后,当前字节计数器减1,地址寄存器加1或减1,HRQ变为无效,释放总线控制权,将控制权交还给CPU。如果传送使得字节计数器减为0或由外设产生信号时,则终止DMA传送。   单字节传送方式的特点是:一次传送一个字节,效率较低,但它会保证在两次DMA传送之间,CPU有机会获得总线控制权,执行一次 CPU总线 周期。  (2)数据块传送(block mode)   在这种数据传送方式下,8237A一旦获得总线控制权,就会连续地传送数据块,直到当前字节计数器减到0或由外设产生信号时,终止DMA传送,释放总线控制权。   数据块传送方式的特点是:一次请求传送一个数据块,效率高,但在整个DMA传送期间,CPU长时间无法控制总线(无法响应其他DMA请求,无法处理其他中断等)。  (3)请求传送(demand mode)   请求传送方式与数据块传送方式类似,也是一种连续传送数据的方式。   区别是:8237A在请求传送方式下,每传送一个字节就要检测一次DREQ信号是否有效,若有效,则继续传送下一个字节;若无效,则停止数据传送,结束DMA过程。但DMA的传送现场全部保持(当前地址寄存器和当前字节计数器的值),待请求信号DREQ再次有效时,8237A接着原来的计数值和地址继续进行数据传送,直到当前字节计数器减到0或由外设产生信号时,终止DMA传送,释放总线控制权。   请求传送方式的特点是:DMA操作可由外设利用DREQ信号控制数据传送的过程。  (4)多片级联(cascade mode)   当一片8237A通道不够用时,可通过多片级联的方式增加 DMA通道 ,由主、从两级构成,从片8237A的HRQ和HLDA引脚与主片8237A的DREQ和DACK引脚连接,一片主片最多可连接四片从片。在级联方式下,从片进行DMA传送,主片在从片与CPU之间传递联络信号,并对从片各通道的优先级进行管理。   级联方式的特点是:可扩展多个 DMA通道 。
硬件开发
2017-12-24 14:27:00
1、在 DiskGenius 记下出错分区的 总扇区数
2、使用 winhex 加载出错的硬盘 ——选择出错的分区 ——打开模板管理器
3、 因为文件系统为NTFS所以 选择 Boot S ector NTFS
4、 可以查看当中的Total sectors发现总扇区数不对, 改为DiskGenius里显示正确的数值
5、 然后关闭会提示是否保存选择保存,会提示很多次 , 关闭winhex时会出现点击确定,至此大功告成。
硬件开发
2017-12-24 00:40:00
TPYBoard v102 驱动28BYJ-48步进电机
实验目的
了解步进电机的工作原理
学习步进电机的驱动方法
实验器材
TPYBoard v102 1块
微型步进电机(28BYJ-48) 1个
步进电机驱动板(ULN2003APG) 1块
micro USB数据线 1条
杜邦线 若干
步进电机的介绍
本次实验采用的是28BYJ-48 四相八拍电机,电压DC5V~12V。
24BYJ48名称的含义:
24:电机外径24mm
B:步进电机中步字的拼音首字母
Y:永磁中永字的拼音首字母
J:减速的减字拼音首字母
48:四相8步
实物图
工作原理
步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,称为“步距角”,它的旋转是以固定的角度一步一步运行的。可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
28BYJ-48 步进电机参数表
上表中启动频率≥550 P.P.S(每秒脉冲数),意思是要想正常启动,需要单片机每秒至少给出550个步进脉冲。那么每一节拍需要持续的时间就是1S/550≈1.8ms,所以控制节拍刷新的速率应大约1.8ms。
驱动原理
当连续不断的给电机发送控制脉冲时,电机就会不断的转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,对应转子就会转过一定的角度(步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。
四相步进电机可以在不同的通电方式下运行,常见的通电方式:
四拍(单相绕组通电):A-B-C-D-A…
双四拍(双相绕组通电):AB-BC-CD-DA-AB-...
八拍: A-AB-B-BC-C-CD-D-DA-A…
模拟效果图
硬件连接
将步进电机白色接头插到驱动板对应的座子上即可。
TPYBoard v102驱动板与驱动板的接线图,如下:
TPYBoard v102 ULN2003APG驱动板
X1 IN1
X2 IN2
X3 IN3
X4 IN4
VIN
GND
5V正极
负极

程序源码如下: # main.py -- put your code here! import pyb from pyb import Pin Pin_All=[Pin(p,Pin.OUT_PP) for p in ['X1','X2','X3','X4']] #转速(ms) 数值越大转速越慢 最小值1.8ms speed=2 STEPER_ROUND=512 #转动一圈(360度)的周期 ANGLE_PER_ROUND=STEPER_ROUND/360 #转动1度的周期 print('ANGLE_PER_ROUND:',ANGLE_PER_ROUND) def SteperWriteData(data): count=0 for i in data: Pin_All[count].value(i) count+=1 def SteperFrontTurn(): global speed SteperWriteData([1,1,0,0]) pyb.delay(speed) SteperWriteData([0,1,1,0]) pyb.delay(speed) SteperWriteData([0,0,1,1]) pyb.delay(speed) SteperWriteData([1,0,0,1]) pyb.delay(speed) def SteperBackTurn(): global speed SteperWriteData([1,1,0,0]) pyb.delay(speed) SteperWriteData([1,0,0,1]) pyb.delay(speed) SteperWriteData([0,0,1,1]) pyb.delay(speed) SteperWriteData([0,1,1,0]) pyb.delay(speed) def SteperStop(): SteperWriteData([0,0,0,0]) def SteperRun(angle): global ANGLE_PER_ROUND val=ANGLE_PER_ROUND*abs(angle) if(angle>0): for i in range(0,val): SteperFrontTurn() else: for i in range(0,val): SteperBackTurn() angle = 0 SteperStop() if __name__=='__main__': SteperRun(180) SteperRun(-180)
硬件开发
2017-12-21 13:35:00
  对于喜欢登山的人来说,都会非常关心自己所处的高度跟温度,海拔高度的测量方法,海拔测量一般常用的有两种方式,一是通过GPS全球定位系统,二是通过测出大气压,根据气压值算出海拔高度。MicroPython技术交流群:157816561 技术网站: http://www.tpyboard.com
  BMP180是一直常见的气压传感器,BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,精度最低可以达到0.03hPa,并且耗电极低,只有3μA;BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。
  我们用TPYBoardv102跟BMP180气压传感器和OLED液晶屏制作一个简易的家庭气象站,检测屋内气压、温度跟当地海拔的高度。有兴趣的朋友可以接入其他的传感器,并显示在OLED上。
  BMP180实物图
  TPYBoardv102实物图
  上面是BMP180的实物图跟TPYBoardv102的实物图,OLED我就不介绍了,如果有需要的可以参考这个http://www.tpyboard.com/support/studyexample14/268.html,下面告诉大家硬件接线方法:
   效果展示图
  连接完毕后,将font.py,ssd1306.py与bmp180的库导入,就可以通过以下方法分别读取温度、气压、海拔高度。 from bmp180 import BMP bmp=BMP180(1) tem=bmp.getTemp() press=bmp.getPress() altitude=bmp.getAltitude()
  导入需要的类库,编辑好main.py,直接运行就ok了,下面是main.py的程序源码 import pyb from ssd1306 import SSD1306 from bmp180 import BMP180 bmp=BMP180(1) display = SSD1306(pinout={'dc': 'Y9', 'res': 'Y10'}, height=64, external_vcc=False) while 1: tem=bmp.getTemp() press=bmp.getPress() altitude=bmp.getAltitude() display.poweron() display.init_display() display.draw_text(1,1,str(tem),size=1,space=1) display.draw_text(60,1,'C',size=1,space=1) display.draw_text(1,10,str(press),size=1,space=1) display.draw_text(60,10,'pa',size=1,space=1) display.draw_text(1,20,str(altitude),size=1,space=1) display.draw_text(60,20,'m',size=1,space=1) # 显示出你想要显示的内容 display.display() pyb.delay(3000)
硬件开发
2017-08-22 16:21:04
  MicroPython以微控制器作为目标,从而使得Python可以用来控制硬件。说到MicroPython,也许有人会感到陌生。而说到和它密切相关的Python,是否会恍然大悟呢?Python属于解释型语言,经过数十年的磨砺,如今Python已经成为最具人气的开源编程语言之一。MicroPython顾名思义就是运行在MCU的Python,换句话说Python可以让单片机行动起来了。
   MicroPython开发板入门实战篇
  MicroPython脱胎于Python,基于ANSIC(C语言标准),然后在语法上又遵循了Python的规范,主要是为了能在嵌入式硬件上(这里特指微控制器级别)更易于的实现对底层的操作。截止到目前,已经有不少嵌入式硬件成功移植了Micropython,如STM32F4、esp8266、PYBoard等。而目前在MicroPython嵌入式领域最全、最专业的当属TPYBoard的MicroPython系列,是MicroPython从入门到实战的不二之选。
   MicroPython实战之教材篇
  《机器人Python极客编程入门与实践》是汇集Python极客团队和国内众多一线高手设计的MicroPython入门到实战的典型实战教材。包括数十个简单入门案例,如LED控制、wifi控制、智能小车、PM2.5检测仪等。其中书中教程实例所搭配的实验开发板即为TPYBoard开发板。所以有了先进的软件、硬件开发品台,剩下的只是创意!
   MicroPython实战之开发板篇
  1、 TPYBoardv10x基础篇
  TPYBoardv102是一款经典的MicroPython开发板,搭载STM32F405芯片,支持DFU和SWD两种调试方式,现分为三个版本,简约版、以及分别兼容MicroPython官方板的PYBoardv1.0、PYBoardv1.1,大小64mm*54mm。是MicroPython开发和入门的首选!
   2、 TPYBoardV20X局域网篇

  TPYBoard基于局域网通讯的V20X系列能稳定的应用于物联网开发环境,包括基于ESP8266的WIFI通信开发板TPYBoardv202、基于以太网通信的TPYBoardv201。TPYBoard通过搭载各种传感器加上zigbee、Lora、NB-iot、2G、4G等通信模块将组成物联网终端设备的典型产品形态,属于典型的MicroPython玩转物联网快速开发的利器。
   3、 TPYBoard70X北斗GPRS通讯系列
  TPYBoardv702支持通信定位功能的MicroPython开发板。支持北斗&GPS双模定位、GPRS通信、短信、蓝牙、电话等功能。板载重力传感、温湿度、加速度传感器、蜂鸣器、LCD5110显示屏灯。
  目前TPYBoard现已形成了完善的MicroPython开发体系,并形成了完善的技术文档以及技术支持服务。实践证明,加上稳定可靠的外围电路和抗干扰电源,以TPYBoard为核心的产品能成功应用于苛刻的工业环境,使开源硬件和开发平台得到更广泛的应用,产品多样性远远高于官方开发板,是MicroPython学习的首选。
  
硬件开发
2017-08-22 14:34:00
树莓派浇花系统
一、功能:
可用于浇花等
二、硬件要求:
树莓派3b,杜邦线(公对母)若干,面包板一个,1路继电器一个,带电源水泵一个,pvc水管,脸盆+塑料水桶
三、语言:
python 2.7+
四、原理:
树莓派控制继电器,继电器控制水泵工作。
(python程序给树莓派gpio发送高或低电平,控制继电器闭合、开启,间接控制水泵工作)
五、线路连接
1、树莓派和面包线连线
可以先按下面两张图,熟悉下树莓派3b引脚知识

树莓派接线:
1、红线接下排第2个引脚(引出5v电压),另一端接面包板正极
2、黑线接下排第3个引脚(引出0v地线),另一端接面包板正极
3、绿色线接下排第11个引脚(通用输入输出线),另一端接面包板abcde(不要接fghij,线路不通)任一一行、任意一列
2、一路继电器与面包版连接方式
先看下面两张图,了解下一路继电器接法(我们用的是第一种常开端接法)


继电器接线(红色接vcc,输入端5v电压;黑线接GND地线0v电压;绿线接IN,信号输入线)

继电器引出的,红线接面包板正极,黑线接负极,绿线和绿线在同一行中连接

继电器接小水泵
继电器的NO端接有水泵一侧的红线,COM口接水泵电源红线。 水泵的黑线相连
3、连线整体效果图
六、python代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
print "树莓派控制水泵"
try :
import RPi.GPIO as GPIO
except RuntimeError:
print ("引入错误")
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
out_chl = 22
v = 1
GPIO.setup(out_chl, GPIO.OUT)
while True:
print 'channel %d, output %d' % (out_chl, v)
GPIO.output(out_chl, v)
if v == 1:
v = 0
else :
v = 1
time.sleep(2)
七、效果视频
百度云盘: https://pan.baidu.com/s/1hs9YzOC
八、开源web控制板浇花系统(带语音提示,功能更新中……)
基于flask写的开源项目,功能比较少,持续开发中。本人python代码写的很烂,请多多指教。
github地址:https://github.com/chaodalong/waterflowers.git
硬件开发
2017-08-20 15:23:00
#!/bin/bash
# Bash script to install latest version of ffmpeg and its dependencies on Ubuntu 12.04 or 14.04
# Inspired from https://gist.github.com/faleev/3435377
# Remove any existing packages:
sudo apt-get -y remove ffmpeg x264 libav-tools libvpx-dev libx264-dev
# Get the dependencies (Ubuntu Server or headless users):
sudo apt-get update
sudo apt-get -y install build-essential checkinstall git libfaac-dev libgpac-dev \
libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev librtmp-dev libtheora-dev \
libvorbis-dev pkg-config texi2html yasm zlib1g-dev
# Install x264
sudo apt-get -y install libx264-dev
cd
git clone --depth 1 git://git.videolan.org/x264
cd x264
./configure --enable-static
make
sudo checkinstall --pkgname=x264 --pkgversion="3:$(./version.sh | \
awk -F'[" ]' '/POINT/{print $4"+git"$5}')" --backup=no --deldoc=yes \
--fstrans=no --default
# Install AAC audio decoder
cd
wget http://downloads.sourceforge.net/opencore-amr/fdk-aac-0.1.0.tar.gz
tar xzvf fdk-aac-0.1.0.tar.gz
cd fdk-aac-0.1.0
./configure
make
sudo checkinstall --pkgname=fdk-aac --pkgversion="0.1.0" --backup=no \
--deldoc=yes --fstrans=no --default
# Install VP8 video encoder and decoder.
cd
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx
cd libvpx
./configure
make
sudo checkinstall --pkgname=libvpx --pkgversion="1:$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default
# Add lavf support to x264
# This allows x264 to accept just about any input that FFmpeg can handle and is useful if you want to use x264 directly. See a more detailed explanation of what this means.
cd ~/x264
make distclean
./configure --enable-static
make
sudo checkinstall --pkgname=x264 --pkgversion="3:$(./version.sh | \
awk -F'[" ]' '/POINT/{print $4"+git"$5}')" --backup=no --deldoc=yes \
--fstrans=no --default
#downloaded rtmpdump
http://rtmpdump.mplayerhq.hu/
git clone git://git.ffmpeg.org/rtmpdump
cd rtmpdump
为了得到调试信息,这里简单修改一下文件夹rtmpdump和librtmp的Makefile文件,添加-g参数,注意去掉优化参数-O2那项
在rtmpdump的Makefile中的
OPT=-O2
CFLAGS=-Wall -g $(XCFLAGS) $(INC) $(DEF) $(OPT)
在librtmp的Makefile中的
CFLAGS=-Wall .... -g
2.安装相关依赖类
需要用到的依赖库是zlib, openssl库,使用如下命令安装
sudo apt-get install openssl
sudo apt-get install libssl-dev
sudo apt-get install zlib1g-dev
可以先查看可用的安装包
sudo apt-cache search openssl
通过阅读Makefile文件,我发现rtmpdump需要引用的动态库如下
-lz -lssl -lcrypto -lrtmp -lpthread
make后会生成4个可执行文件, 分别是rtmpdump,rtmpsvr, rtmpsuck, rtmpgw, 其中pthread直会在rtmpsvr, rtmpsuck, rtmpgw这3个程序中用到.
3.编译安装
make
sudo make install
首先要保证相关库已经成功安装到/usr/local/lib下面
再要保证/usr/local/lib在/etc/ld.so.conf配置文件中,然后
sudo ldconfig
来更新动态库缓存
检查rtmpdump所有依赖库是否都引用成功
ldd rtmpdump
#downloaded libogg
wget https://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.xz
Installation of libogg
Install libogg by running the following commands:
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/libogg-1.3.2 &&
make
To test the results, issue: make check.
Now, as the root user:
make install
#downloaded libvorbis-1.3.5
wget https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.xz
Installation of libvorbis
Optionally fix installation of the package when --enable-docs is added to the configure switches:
sed -i '/components.png \\/{n;d}' doc/Makefile.in
Install libvorbis by running the following commands:
./configure --prefix=/usr --disable-static &&
make
To test the results, issue: make LIBS=-lm check.
Now, as the root user:
make install &&
install -v -m644 doc/Vorbis* /usr/share/doc/libvorbis-1.3.5
#downloaded libtheora
wget https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.xz
Installation of libtheora
Install libtheora by running the following commands:
sed -i 's/png_\(sizeof\)/\1/g' examples/png2theora.c &&
./configure --prefix=/usr --disable-static &&
make
If you wish to run the tests, issue: make check.
Now, as the root user:
make install
# Installing FFmpeg
cd
git clone --depth 1 git://source.ffmpeg.org/ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-libfdk-aac --enable-libmp3lame
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp
--enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264
--enable-nonfree --enable-version3
make
sudo checkinstall --pkgname=ffmpeg --pkgversion="5:$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default
hash x264 ffmpeg ffplay ffprobe
# Optional: install qt-faststart
# This is a useful tool if you're showing your H.264 in MP4 videos on the web. It relocates some data in the video to allow playback to begin before the file is completely downloaded. Usage: qt-faststart input.mp4 output.mp4.
cd ~/ffmpeg
make tools/qt-faststart
sudo checkinstall --pkgname=qt-faststart --pkgversion="$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default install -Dm755 tools/qt-faststart \
/usr/local/bin/qt-faststart

我用一段转码测试了一下
#ffmpeg -i file.avi output.flv
发现报了一个库找不到的错
去搜索了一下相关问题
于是乎我就
软链接了一下,再次测试就通过了
硬件开发
2017-08-19 23:04:00
连接LilyPad之Windows平台的驱动
LilyPad和其他的Arduino控制板的不同之处是它是为电子织物和可穿戴设计的。那么,它的大小就必须要紧凑。所以,它并没有板载其他大多数板子都具有的USB通讯芯片。要为LilyPad上传程序就需要通过一个FTDI兼容的设备来完成,即LilyPad官方提供的LilyPad Programmer,如图2.34所示。
图2.64 LilyPad编程器
Windows平台的驱动
如果你使用的是Windows7及以上版本的系统并且已经接入和互联网,那么当你将LilyPad编程器通过USB连接到电脑的时候,系统会自动为其安装驱动。如果你的系统没有为你自动安装或者你的电脑没有接入互联网,那么就需要手动安装驱动。FTDI官方提供了非常方便的驱动包,用户只需要下载并直接执行安装即可。
FTDI的官网是http://www.ftdichip.com。LilyPad使用的是FT232RL芯片,所以需要下载D2XX系列的驱动,其链接为http://www.ftdichip.com/Drivers/D2XX.htm,对应版本的下载链接。
Window操作系统下载的驱动包名为CDM v2.12.00 WHQL Certified.exe。用户只需要直接执行并安装它即可,由于它并没有可定制项,所以安装过程不再赘述。当为芯片安装正确的驱动之后,在设备管理器的“端口”中就可以看到一个名为USB Serial Port的端口。
此时,我们就可以进行下一步的连接了。
硬件开发
2017-08-18 10:13:00
最好用的嵌入式网络C库、Lua库
Evmongoose是一个异步的、基于事件框架(libev)的集成多种协议的嵌入式网络库,包括:TCP、HTTP、WebSocket、MQTT等等。 它基于mongoose和libev实现,并且支持Lua API。
Evmongoose支持高度的可定制化来扩展你的应用程序。在开始这个项目之前,我一直都没有找到一个令我满意的基于事件框架的HTTP服务器库。那些HTTP 服务器库只能loop它自己的对象,不能添加我自己的对象。比如我想基于事件框架监视某个信号(比如SIGINT)或者某个文件。
特性
新特性
使用libev编程
高度的可定制化
Lua API(依赖lua-ev)
继承自mongoose
TCP服务器/TCP客户端、UDP服务器/UDP客户端, SSL/TLS
SSL库可选择OpenSSL或者mbedtls,对于存储苛刻的系统可选择mbedtls
HTTP客户端,HTTP服务器
HTTP文件上传
HTTP代理
WebSocket客户端,WebSocket服务器
MQTT客户端,MQTT代理
CoAP客户端,CoAP服务器
DNS客户端,DNS服务器,异步DNS解析
Url重写
项目主页: https://github.com/zhaojh329/evmongoose
请看中文说明: https://github.com/zhaojh329/evmongoose/blob/master/README_ZH.md
具有丰富的使用例程,欢迎大家一起参与改进,提bug
硬件开发
2017-08-14 16:12:00
sudo apt-get samba samba
sudo apt-get samba samba-common-bin
接下来编辑最重要的smb.conf配置文件,在此之前先找一个用来暴露的文件夹并赋予读写权限
pi @raspberrypi :/home/share $ sudo vim /etc/samba/smb.conf
下面贴出我的配置文件
#
# Sample configuration file for the Samba suite for Debian GNU/Linux.
#
#
# This is the main Samba configuration file. You should read the
# smb.conf(5) manual page in order to understand the options listed
# here. Samba has a huge number of configurable options most of which
# are not shown in this example
#
# Some options that are often worth tuning have been included as
# commented-out examples in this file.
# - When such options are commented with ";", the proposed setting
# differs from the default Samba behaviour
# - When commented with "#", the proposed setting is the default
# behaviour of Samba but the option is considered important
# enough to be mentioned here
#
# NOTE: Whenever you modify this file you should run the command
# "testparm" to check that you have not made any basic syntactic
# errors.
# A well-established practice is to name the original file
# "smb.conf.master" and create the "real" config file with
# testparm -s smb.conf.master >smb.conf
# This minimizes the size of the really used smb.conf file
# which, according to the Samba Team, impacts performance
# However, use this with caution if your smb.conf file contains nested
# "include" statements. See Debian bug #483187 for a case
# where using a master file is not a good idea.
#
#======================= Global Settings =======================
[global]
## Browsing/Identification ###
# Change this to the workgroup/NT-domain name your Samba server will part of
workgroup = WORKGROUP
# server string is the equivalent of the NT Description field
server string = %h server
# Windows Internet Name Serving Support Section:
# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
# wins support = no
# WINS Server - Tells the NMBD components of Samba to be a WINS Client
# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
; wins server = w.x.y.z
# This will prevent nmbd to search for NetBIOS names through DNS.
dns proxy = no
# What naming service and in what order should we use to resolve host names
# to IP addresses
; name resolve order = lmhosts host wins bcast
#### Networking ####
# The specific set of interfaces / networks to bind to
# This can be either the interface name or an IP address/netmask;
# interface names are normally preferred
; interfaces = 127.0.0.0/8 eth0
# Only bind to the named interfaces and/or networks; you must use the
# 'interfaces' option above to use this.
# It is recommended that you enable this feature if your Samba machine is
# not protected by a firewall or is a firewall itself. However, this
# option cannot handle dynamic or non-broadcast interfaces correctly.
; bind interfaces only = yes
#### Debugging/Accounting ####
# This tells Samba to use a separate log file for each machine
# that connects
log file = /var/log/samba/log.%m
# Cap the size of the individual log files (in KiB).
max log size = 1000
# If you want Samba to only log through syslog then set the following
# parameter to 'yes'.
# syslog only = no
# We want Samba to log a minimum amount of information to syslog. Everything
# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
# through syslog you should set the following parameter to something higher.
syslog = 0
# Do something sensible when Samba crashes: mail the admin a backtrace
panic action = /usr/share/samba/panic-action %d
####### Authentication #######
# "security = user" is always a good idea. This will require a Unix account
# in this server for every user accessing the server. See
# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
# in the samba-doc package for details.
security = share
# You may wish to use password encryption. See the section on
# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
encrypt passwords = true
# If you are using encrypted passwords, Samba will need to know what
# password database type you are using.
passdb backend = tdbsam
obey pam restrictions = yes
# This boolean parameter controls whether Samba attempts to sync the Unix
# password with the SMB password when the encrypted SMB password in the
# passdb is changed.
unix password sync = yes
# For Unix password sync to work on a Debian GNU/Linux system, the following
# parameters must be set (thanks to Ian Kahan < for
# sending the correct chat script for the passwd program in Debian Sarge).
passwd program = /usr/bin/passwd %u
passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
# This boolean controls whether PAM will be used for password changes
# when requested by an SMB client instead of the program listed in
# 'passwd program'. The default is 'no'.
pam password change = yes
# This option controls how unsuccessful authentication attempts are mapped
# to anonymous connections
map to guest = bad user
########## Domains ###########
# Is this machine able to authenticate users. Both PDC and BDC
# must have this setting enabled. If you are the BDC you must
# change the 'domain master' setting to no
#
; domain logons = yes
#
# The following setting only takes effect if 'domain logons' is set
# It specifies the location of the user's profile directory
# from the client point of view)
# The following required a [profiles] share to be setup on the
# samba server (see below)
; logon path = \\%N\profiles\%U
# Another common choice is storing the profile in the user's home directory
# (this is Samba's default)
# logon path = \\%N\%U\profile
# The following setting only takes effect if 'domain logons' is set
# It specifies the location of a user's home directory (from the client
# point of view)
; logon drive = H:
# logon home = \\%N\%U
# The following setting only takes effect if 'domain logons' is set
# It specifies the script to run during logon. The script must be stored
# in the [netlogon] share
# NOTE: Must be store in 'DOS' file format convention
; logon script = logon.cmd
# This allows Unix users to be created on the domain controller via the SAMR
# RPC pipe. The example command creates a user account with a disabled Unix
# password; please adapt to your needs
; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u
# This allows machine accounts to be created on the domain controller via the
# SAMR RPC pipe.
# The following assumes a "machines" group exists on the system
; add machine script = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u
# This allows Unix groups to be created on the domain controller via the SAMR
# RPC pipe.
; add group script = /usr/sbin/addgroup --force-badname %g
########## Printing ##########
# If you want to automatically load your printer list rather
# than setting them up individually then you'll need this
# load printers = yes
# lpr(ng) printing. You may wish to override the location of the
# printcap file
; printing = bsd
; printcap name = /etc/printcap
# CUPS printing. See also the cupsaddsmb(8) manpage in the
# cupsys-client package.
; printing = cups
; printcap name = cups
############ Misc ############
# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting
; include = /home/samba/etc/smb.conf.%m
# Most people will find that this option gives better performance.
# See smb.conf(5) and /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/speed.html
# for details
# You may want to add the following on a Linux system:
# SO_RCVBUF=8192 SO_SNDBUF=8192
# socket options = TCP_NODELAY
# The following parameter is useful only if you have the linpopup package
# installed. The samba maintainer and the linpopup maintainer are
# working to ease installation and configuration of linpopup and samba.
; message command = /bin/sh -c '/usr/bin/linpopup "%f" "%m" %s; rm %s' &
# Domain Master specifies Samba to be the Domain Master Browser. If this
# machine will be configured as a BDC (a secondary logon server), you
# must set this to 'no'; otherwise, the default behavior is recommended.
# domain master = auto
# Some defaults for winbind (make sure you're not using the ranges
# for something else.)
; idmap uid = 10000-20000
; idmap gid = 10000-20000
; template shell = /bin/bash
# The following was the default behaviour in sarge,
# but samba upstream reverted the default because it might induce
# performance issues in large organizations.
# See Debian bug #368251 for some of the consequences of *not*
# having this setting and smb.conf(5) for details.
; winbind enum groups = yes
; winbind enum users = yes
# Setup usershare options to enable non-root users to share folders
# with the net usershare command.
# Maximum number of usershare. 0 (default) means that usershare is disabled.
; usershare max shares = 100
# Allow users who've been granted usershare privileges to create
# public shares, not just authenticated ones
usershare allow guests = yes
#======================= Share Definitions =======================
[homes]
comment = Home Directories
browseable = no
# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
read only = yes
# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
create mask = 0700
# Directory creation mask is set to 0700 for security reasons. If you want to
# create dirs. with group=rw permissions, set next parameter to 0775.
directory mask = 0700
# By default, \\server
硬件开发
2017-08-13 17:40:00
USB设备分类
And you can get the USB spec from http://www.usb.org/developers/docs

USB从设备的分类可以从USB设备接口描述符(Standard Interface Descriptor)对应的的bInterfaceClass这一个byte得到。
bInterfaceClass的典型代码为1,2,3,6,7,8,9,10,11,255。分别代表意思为
1-audio:表示一个音频设 备。
2-communication device:通讯设备,如电话,moden等等。
3-HID:人机交互设备,如键盘,鼠标等。
6-image图象设备,如扫描仪,摄像头等,有时数码相 机也可归到这一类。
7-打印机类。如单向,双向打印机等。
8-mass storage海量存储类。所有带有一定存储功能的都可以归到这一类。如数码相机大多数都归这一类。
9-hub类。
11-chip card/smart card。
255-vendor specific.厂家的自定义类,主要用于一些特殊的设备。如接口转接卡等。
#define USB_DEVICE_CLASS_RESERVED 0x00
#define USB_DEVICE_CLASS_AUDIO 0x01
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
#define USB_DEVICE_CLASS_MONITOR 0x04
#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
#define USB_DEVICE_CLASS_POWER 0x06
#define USB_DEVICE_CLASS_PRINTER 0x07
#define USB_DEVICE_CLASS_STORAGE 0x08
#define USB_DEVICE_CLASS_HUB 0x09
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF

http://www.usb.org/developers/defined_class 官方更全的分类
Base Class Descriptor Usage Description
00h Device Use class information in the Interface Descriptors
01h Interface Audio
02h Both Communications and CDC Control
03h Interface HID (Human Interface Device)
05h Interface Physical
06h Interface Image
07h Interface Printer
08h Interface Mass Storage
09h Device Hub
0Ah Interface CDC-Data
0Bh Interface Smart Card
0Dh Interface Content Security
0Eh Interface Video
0Fh Interface Personal Healthcare
10h Interface Audio/Video Devices
11h Device Billboard Device Class
12h Interface USB Type-C Bridge Class
DCh Both Diagnostic Device
E0h Interface Wireless Controller
EFh Both Miscellaneous
FEh
FFh
Interface
Both
Application Specific
Vendor Specific
硬件开发
2017-08-10 00:54:00
sudo apt-get install motion
sudo nano /etc/default/motion
将里面的no修改成yes,让motion可以一直在后台运行: start_motion_daemon=yes
sudo nano /etc/motion/motion.conf

# 在守护程序(后台)模式下启动,打2开终端(默认:off) daemon on # 检测到运动后,输出“正常”图片(默认:on) [...] output_normal off # 存储进程编号的文件,又叫pid文件。(默认:未定义)。 process_id_file /var/run/motion/motion.pid # 图像宽度(像素)。有效范围:取决于摄像头,默认:352个像素 width 640 # 图像高度(像素)。有效范围:取决于摄像头,默认:288个像素 height 480 # 每秒拍摄的最大帧数量。 # 有效范围:2-100。默认:100(几乎没有限制)。 framerate 7 # 如果你使用网络摄像头要使用的URL,尺寸将自动检测(包括http://、ftp://或file:///) # 必须是返回单JPEG图片或原始MJPEG流的URL。默认:未定义 netcam_url value http://http://192.168.10.250:8080/videostream.cgi # 网络摄像头的用户名和密码(只要在需要时)。默认:未定义 # 语法是用户:密码 netcam_userpass admin:mypassword # 存储图片和短片的目标基本目录 # 推荐使用的绝对路径。(默认值:当前工作目录) target_dir /home/carla/motion-images # ffmpeg用于视频压缩的编解码器。 [...] ffmpeg_video_codec mpeg4 创建用来存储PID文件的目录,因为它在motion.conf中表明: $ sudo mkdir /var/run/motion

启动motion sudo motion
退出motion
killall -TERM motion 或者 service motion stop
硬件开发
2017-08-08 00:59:00
09-18版本以后的官方镜像都集成了rpi-update工具,直接执行“sudo rpi-update”就行了
插上usb摄像头,输入ls /dev, 查看dev中是否存在一个video0这个设备,如果有了说明系统识别了,如果不认,重复第一步确保firmware最新,还不行就换摄像头吧
硬件开发
2017-08-06 22:18:00
据了解,BuzzBox搭载了许多感应器,可以测量温度、湿度等,同时它还能够与智能手机连接,通过WiFi或其他网络将资料传送至专属App。使用者可以随时在App中确认蜜蜂与蜂巢的情况,此外BuzzBox也具有基本的防盗功能,当蜂巢被入侵或遭小偷光顾时,手机会马上响起警报。

Aaron Makaruk介绍称,BuzzBox的耗电量相当小,因此它可以使用太阳能电池板来提供电力,满足日常工作所需,此外,由于BuzzBox需要安装在室外,所以BuzzBox也加入了防水设计,基本上一经安装,就无需再进行特别的保养和维护了。
至于如何分析蜜蜂和蜂巢情况,根据官方的说法,其搭载了一个专门为分析蜜蜂而设计的蜂巢声音辨识系统(Beehive Audio Classification System),能够分析蜜蜂发出的声音,判断蜂群是否遭受疾病、寄生虫侵袭,或是蜂群是否飞离原巢等。
为了让广大养蜂人和爱好者能够更好地养蜂,这套系统特别采用了开源式开发,提供了开放式的资料库,BuzzBox也会随时上传使用过程中收集的资料,开发团队会整理来自世界各地的数据,与认可的研究实验室合作,然后通过大数据来不断提升其功能的精确度,有兴趣加入的人可以在这些开源专案中找到相关设计图,甚至还可以自行制作一个BuzzBox,从而提升养蜂的质量。
硬件开发
2017-08-06 22:05:00
gedit /usr/share/applications/phpstorm.desktop
写入如下东西 [Desktop Entry]
Categories=Development;
Comment[zh_CN]=
Comment=
注意:这里的目录是你自己文件程序位置
Exec=/opt/phpstorm/PhpStorm-172.3544.41/bin/phpstorm.sh
GenericName[zh_CN]=IDE
GenericName=IDE
注意:这里的目录是你自己文件程序位置
Icon=/opt/phpstorm/PhpStorm-172.3544.41/bin/phpstorm.png
MimeType=
注意:这里的名字自己定义
Name[zh_CN]=phpstorm
Name=phpstorm
Path=
StartupNotify=true
Terminal=false
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=owen
chmod +x phpstorm.desktop
进入/usr/share/applications目录,找到这个文件
复制,粘贴到桌面
ok
硬件开发
2017-08-05 03:38:00
黄 晓军, 张 静, 和 张 凯
2012 年 1 月 16 日发布
前言:
目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等。其中所用到的数据传输方式包括 XML,JSON 等,然而 XML 相对体积太大,传输效率低,JSON 体积较小,新颖,但还不够完善。本文将介绍由 Facebook 开发的远程服务调用框架 Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。本文将详细介绍 Thrift 的使用,并且提供丰富的实例代码加以解释说明,帮助使用者快速构建服务。
一个简单的 Thrift 实例
本文首先介绍一个简单的 Thrift 实现实例,使读者能够快速直观地了解什么是 Thrift 以及如何使用 Thrift 构建服务。
创建一个简单的服务 Hello。首先根据 Thrift 的语法规范编写脚本文件 Hello.thrift,代码如下:
清单 1. Hello.thrift
1
2
3
4
5
6
7
8
namespace java service.demo
service Hello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
其中定义了服务 Hello 的五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。 Thrift 是对 IDL(Interface Definition Language) 描述性语言的一种具体实现。因此,以上的服务描述文件使用 IDL 语法编写。使用 Thrift 工具编译 Hello.thrift,就会生成相应的 Hello.java 文件。该文件包含了在 Hello.thrift 文件中描述的服务 Hello 的接口定义,即 Hello.Iface 接口,以及服务调用的底层通信细节,包括客户端的调用逻辑 Hello.Client 以及服务器端的处理逻辑 Hello.Processor,用于构建客户端和服务器端的功能。
创建 HelloServiceImpl.java 文件并实现 Hello.java 文件中的 Hello.Iface 接口,代码如下:
清单 2. HelloServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package service.demo;
import org.apache.thrift.TException;
public class HelloServiceImpl implements Hello.Iface {
@Override
public boolean helloBoolean(boolean para) throws TException {
return para;
}
@Override
public int helloInt(int para) throws TException {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return para;
}
@Override
public String helloNull() throws TException {
return null;
}
@Override
public String helloString(String para) throws TException {
return para;
}
@Override
public void helloVoid() throws TException {
System.out.println("Hello World");
}
}
创建服务器端实现代码,将 HelloServiceImpl 作为具体的处理器传递给 Thrift 服务器,代码如下:
清单 3. HelloServiceServer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package service.server;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;
import service.demo.HelloServiceImpl;

public class HelloServiceServer {
/**
* 启动 Thrift 服务器
* @param args
*/
public static void main(String[] args) {
try {
// 设置服务端口为 7911
TServerSocket serverTransport = new TServerSocket(7911);
// 设置协议工厂为 TBinaryProtocol.Factory
Factory proFactory = new TBinaryProtocol.Factory();
// 关联处理器与 Hello 服务的实现
TProcessor processor = new Hello.Processor(new HelloServiceImpl());
TServer server = new TThreadPoolServer(processor, serverTransport,
proFactory);
System.out.println("Start server on port 7911...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
}
创建客户端实现代码,调用 Hello.client 访问服务端的逻辑实现,代码如下:
清单 4. HelloServiceClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package service.client;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;

public class HelloServiceClient {
/**
* 调用 Hello 服务
* @param args
*/
public static void main(String[] args) {
try {
// 设置调用的服务地址为本地,端口为 7911
TTransport transport = new TSocket("localhost", 7911);
transport.open();
// 设置传输协议为 TBinaryProtocol
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
// 调用服务的 helloVoid 方法
client.helloVoid();
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
}
}
}
代码编写完后运行服务器,再启动客户端调用服务 Hello 的方法 helloVoid,在服务器端的控制台窗口输出“Hello World”(helloVoid 方法实现在控制台打印字符串,没有返回值,所以客户端调用方法后没有返回值输出,读者可以自己尝试其他有返回值方法的调用,其结果可以打印在客户端的控制台窗口 )。
Thrift 架构
Thrift 包含一个完整的堆栈结构用于构建客户端和服务器端。下图描绘了 Thrift 的整体架构。
图 1. 架构图
如图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据 Thrift 定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据 Thrift 文件生成代码实现数据的读写操作。红色部分以下是 Thrift 的传输体系、协议以及底层 I/O 通信,使用 Thrift 可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。
Thrift 服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器 / 容器一起运行,可以和现有的 J2EE 服务器 /Web 容器无缝的结合。
服务端和客户端具体的调用流程如下:
图 2. Server 端启动、服务时序图( 查看大图 )
该图所示是 HelloServiceServer 启动的过程以及服务被客户端调用时,服务器的响应过程。从图中我们可以看到,程序调用了 TThreadPoolServer 的 serve 方法后,server 进入阻塞监听状态,其阻塞在 TServerSocket 的 accept 方法上。当接收到来自客户端的消息后,服务器发起一个新线程处理这个消息请求,原线程再次进入阻塞状态。在新线程中,服务器通过 TBinaryProtocol 协议读取消息内容,调用 HelloServiceImpl 的 helloVoid 方法,并将结果写入 helloVoid_result 中传回客户端。
图 3. Client 端调用服务时序图( 查看大图 )
该图所示是 HelloServiceClient 调用服务的过程以及接收到服务器端的返回值后处理结果的过程。从图中我们可以看到,程序调用了 Hello.Client 的 helloVoid 方法,在 helloVoid 方法中,通过 send_helloVoid 方法发送对服务的调用请求,通过 recv_helloVoid 方法接收服务处理请求后返回的结果。
数据类型
Thrift 脚本可定义的数据类型包括以下几种类型: 基本类型: bool:布尔值,true 或 false,对应 Java 的 boolean byte:8 位有符号整数,对应 Java 的 byte i16:16 位有符号整数,对应 Java 的 short i32:32 位有符号整数,对应 Java 的 int i64:64 位有符号整数,对应 Java 的 long double:64 位浮点数,对应 Java 的 double string:未知编码文本或二进制字符串,对应 Java 的 String 结构体类型: struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean 容器类型: list:对应 Java 的 ArrayList set:对应 Java 的 HashSet map:对应 Java 的 HashMap 异常类型: exception:对应 Java 的 Exception 服务类型: service:对应服务的类
协议
Thrift 可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本 (text) 和二进制 (binary) 传输协议,为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目 / 产品中的实际需求。常用协议有以下几种: TBinaryProtocol —— 二进制编码格式进行数据传输
使用方法如清单 3 和清单 4 所示。 TCompactProtocol —— 高效率的、密集的二进制编码格式进行数据传输
构建 TCompactProtocol 协议的服务器和客户端只需替换清单 3 和清单 4 中 TBinaryProtocol 协议部分即可,替换成如下代码:
清单 5. 使用 TCompactProtocol 协议构建的 HelloServiceServer.java
1
TCompactProtocol.Factory proFactory = new TCompactProtocol.Factory();
清单 6. 使用 TCompactProtocol 协议的 HelloServiceClient.java
1
TCompactProtocol protocol = new TCompactProtocol(transport);
TJSONProtocol —— 使用 JSON 的数据编码协议进行数据传输
构建 TJSONProtocol 协议的服务器和客户端只需替换清单 3 和清单 4 中 TBinaryProtocol 协议部分即可,替换成如下代码:
清单 7. 使用 TJSONProtocol 协议构建的 HelloServiceServer.java
1
TJSONProtocol.Factory proFactory = new TJSONProtocol.Factory();
清单 8. 使用 TJSONProtocol 协议的 HelloServiceClient.java
1
TJSONProtocol protocol = new TJSONProtocol(transport);
TSimpleJSONProtocol —— 只提供 JSON 只写的协议,适用于通过脚本语言解析
传输层
常用的传输层有以下几种: TSocket —— 使用阻塞式 I/O 进行传输,是最常见的模式
使用方法如清单 4 所示。 TFramedTransport —— 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO
若使用 TFramedTransport 传输层,其服务器必须修改为非阻塞的服务类型,客户端只需替换清单 4 中 TTransport 部分,代码如下,清单 9 中 TNonblockingServerTransport 类是构建非阻塞 socket 的抽象类,TNonblockingServerSocket 类继承 TNonblockingServerTransport
清单 9. 使用 TFramedTransport 传输层构建的 HelloServiceServer.java
1
2
3
4
5
6
TNonblockingServerTransport serverTransport;
serverTransport = new TNonblockingServerSocket(10005);
Hello.Processor processor = new Hello.Processor(new HelloServiceImpl());
TServer server = new TNonblockingServer(processor, serverTransport);
System.out.println("Start server on port 10005 ...");
server.serve();
清单 10. 使用 TFramedTransport 传输层的 HelloServiceClient.java
1
TTransport transport = new TFramedTransport(new TSocket("localhost", 10005));
TNonblockingTransport —— 使用非阻塞方式,用于构建异步客户端
使用方法请参考 Thrift 异步客户端构建
服务端类型
常见的服务端类型有以下几种: TSimpleServer —— 单线程服务器端使用标准的阻塞式 I/O
代码如下:
清单 11. 使用 TSimpleServer 服务端构建的 HelloServiceServer.java
1
2
3
4
5
TServerSocket serverTransport = new TServerSocket(7911);
TProcessor processor = new Hello.Processor(new HelloServiceImpl());
TServer server = new TSimpleServer(processor, serverTransport);
System.out.println("Start server on port 7911...");
server.serve();
客户端的构建方式可参考清单 4。 TThreadPoolServer —— 多线程服务器端使用标准的阻塞式 I/O
使用方法如清单 3 所示。 TNonblockingServer —— 多线程服务器端使用非阻塞式 I/O
使用方法请参考 Thrift 异步客户端构建
Thrift 异步客户端构建
Thrift 提供非阻塞的调用方式,可构建异步客户端。在这种方式中,Thrift 提供了新的类 TAsyncClientManager 用于管理客户端的请求,在一个线程上追踪请求和响应,同时通过接口 AsyncClient 传递标准的参数和 callback 对象,服务调用完成后,callback 提供了处理调用结果和异常的方法。
首先我们看 callback 的实现:
清单 12.CallBack 的实现:MethodCallback.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package service.callback;
import org.apache.thrift.async.AsyncMethodCallback;

public class MethodCallback implements AsyncMethodCallback {
Object response = null;

public Object getResult() {
// 返回结果值
return this.response;
}

// 处理服务返回的结果值
@Override
public void onComplete(Object response) {
this.response = response;
}
// 处理调用服务过程中出现的异常
@Override
public void onError(Throwable throwable) {

}
}
如代码所示,onComplete 方法接收服务处理后的结果,此处我们将结果 response 直接赋值给 callback 的私有属性 response。onError 方法接收服务处理过程中抛出的异常,此处未对异常进行处理。
创建非阻塞服务器端实现代码,将 HelloServiceImpl 作为具体的处理器传递给异步 Thrift 服务器,代码如下:
清单 13.HelloServiceAsyncServer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package service.server;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;
import service.demo.HelloServiceImpl;

public class HelloServiceAsyncServer {
/**
* 启动 Thrift 异步服务器
* @param args
*/
public static void main(String[] args) {
TNonblockingServerTransport serverTransport;
try {
serverTransport = new TNonblockingServerSocket(10005);
Hello.Processor processor = new Hello.Processor(
new HelloServiceImpl());
TServer server = new TNonblockingServer(processor, serverTransport);
System.out.println("Start server on port 10005 ...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
}
HelloServiceAsyncServer 通过 java.nio.channels.ServerSocketChannel 创建非阻塞的服务器端等待客户端的连接。
创建异步客户端实现代码,调用 Hello.AsyncClient 访问服务端的逻辑实现,将 MethodCallback 对象作为参数传入调用方法中,代码如下:
清单 14.HelloServiceAsyncClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package service.client;
import java.io.IOException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;
import service.callback.MethodCallback;
import service.demo.Hello;

public class HelloServiceAsyncClient {
/**
* 调用 Hello 服务
* @param args
*/
public static void main(String[] args) throws Exception {
try {
TAsyncClientManager clientManager = new TAsyncClientManager();
TNonblockingTransport transport = new TNonblockingSocket(
"localhost", 10005);
TProtocolFactory protocol = new TBinaryProtocol.Factory();
Hello.AsyncClient asyncClient = new Hello.AsyncClient(protocol,
clientManager, transport);
System.out.println("Client calls .....");
MethodCallback callBack = new MethodCallback();
asyncClient.helloString("Hello World", callBack);
Object res = callBack.getResult();
while (res == null) {
res = callBack.getResult();
}
System.out.println(((Hello.AsyncClient.helloString_call) res)
.getResult());
} catch (IOException e) {
e.printStackTrace();
}
}
}
HelloServiceAsyncClient 通过 java.nio.channels.Socketchannel 创建异步客户端与服务器建立连接。在本文中异步客户端通过以下的循环代码实现了同步效果,读者可去除这部分代码后再运行对比。
清单 15. 异步客户端实现同步效果代码段
1
2
3
4
5
Object res = callBack.getResult();
// 等待服务调用后的返回结果
while (res == null) {
res = callBack.getResult();
}
通过与清单 9 和清单 10 的代码比较,我们可以构建一个 TNonblockingServer 服务类型的服务端,在客户端构建一个 TFramedTransport 传输层的同步客户端和一个 TNonblockingTransport 传输层的异步客户端,那么一个服务就可以通过一个 socket 端口提供两种不同的调用方式。有兴趣的读者可以尝试一下。
常见问题
NULL 问题
我们在对服务的某个方法调用时,有时会出现该方法返回 null 值的情况,在 Thrift 中,直接调用一个返回 null 值的方法会抛出 TApplicationException 异常。在清单 2 中,HelloServiceImpl 里实现了 helloNull 方法,返回 null 值,我们在 HelloServiceClient.java 中加入调用该方法的代码,出现如下图所示的异常:
图 4. TApplicationException 异常
为了处理返回 null 值情况,我们要捕获该异常,并进行相应的处理,具体客户端代码实现如下:
清单 16. 处理服务返回值为 null 的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package service.client;
import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;

public class HelloServiceClient {
/**
* 调用 Hello 服务,并处理 null 值问题
* @param args
*/
public static void main(String[] args) {
try {
TTransport transport = new TSocket("localhost", 7911);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
System.out.println(client.helloNull());
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
if (e instanceof TApplicationException
&& ((TApplicationException) e).getType() ==
TApplicationException.MISSING_RESULT) {
System.out.println("The result of helloNull function is NULL");
}
}
}
}
调用 helloNull 方法后,会抛出 TApplicationException 异常,并且异常种类为 MISSING_RESULT,本段代码显示,捕获该异常后,直接在控制台打印“The result of helloNull function is NULL”信息。
安装部署
Apache Thrift 的官方网站为: http://thrift.apache.org/tutorial/ ,具体安装步骤如下: 下载 thrift 源文件( http://svn.apache.org/repos/asf/thrift/tags/thrift-0.6.1/ ) 将 thrift 源文件导入 eclipse,进入 /lib/java 目录,使用 ant 编译 build.xml 获得 libthrift-0.6.1-snapshot.jar 将 libthrift-0.6.1-snapshot.jar、slf4j-api-1.5.8.jar、slf4j-log4j12-1.5.8.jar 和 log4j-1.2.14.jar 导入 eclipse 开发环境 下载 thrift 编译工具,该工具可将 thrift 脚本文件编译成 java 文件,下载地址: http://apache.etoak.com//thrift/0.6.0/thrift-0.6.1.exe 创建 Hello.thrift 脚本文件,具体代码如上一章节所述,进入 thrift-0.6.1.exe 所在目录,执行命令"thrift-0.6.1.exe -gen java x:\Hello.thrift",在当前运行盘符下,可看见 gen-java 目录,进入目录可看到生成的 Java 代码。更多 thrift 的命令内容,请参考 thrift 自带的 help 命令 编写服务端和客户端代码,完成 thrift 的安装和部署
基于 Apache Thrift 框架生成的服务包括客户端和服务器端,具体的部署模式如下所示:
图 5. 部署图
从图中我们可以看到,客户端和服务器端部署时,需要用到公共的 jar 包和 java 文件,如图“Common file”区域,其中 Hello.java 由 Hello.thrift 编译而来。在服务器端,服务必须实现 Hello.Iface 接口,同时要包括服务器的启动代码 HelloServiceServer.java。在客户端,包括客户端调用服务的代码 HelloServiceClient.java。客户端和服务器通过 Hello.java 提供的 API 实现远程服务调用。
总结
本文介绍了 Apache Thrift 的安装部署和架构,并通过大量实例介绍了在不同情况下如何使用 Apache Thrift 来构建服务,同时着重介绍了 Thrift 异步客户端的构建,希望能给读者带来一些帮助。
硬件开发
2017-08-04 18:29:00
#Idea20172-2.x中文输入法问题 将idea安装目录下的jre64换成jdk的jre,并且将jdk/lib的tools.jar拷贝到jre64/lib下,问题解决
参考: https://www.zhihu.com/question/37582743
硬件开发
2017-08-03 15:30:05
前一段时间在微信订阅号中介绍了国外的BitBot小车,今天尝试了小车的控制,用另外一个microbit作为遥控器,通过无线方式进行控制,通过遥控器(microbit)上的加速度传感器,可以灵活的实现前进、后退、转弯等动作,十分有趣。
小车控制 from microbit import * import radio def _dat(l1,l2,r1,r2): pin0.write_analog(l1) pin8.write_analog(l2) pin1.write_analog(r1) pin12.write_analog(r2) def _bd(t): if(t>1000): a=1000;b=0 elif(t>200): a=t;b=0 elif(t>-200): a=0;b=0 elif(t>-1000): a=0;b=-t else: a=0;b=1000 return [a,b] def bitbot(l,r): t=_bd(l) a=t[0];b=t[1] t=_bd(r) c=t[0];d=t[1] _dat(a,b,c,d) print(a,b,c,d) print('BitBot start:') radio.on() while 1: sdat=radio.receive() if sdat!=None: li=sdat.split(',') if li[0]=='BB': bitbot(int(li[1]),int(li[2])) sleep(50)

遥控 from microbit import * import radio radio.on() cnt = 0 a=b=0 start=0 while 1: if button_a.was_pressed(): start=1 print('start') if button_b.was_pressed(): start=0 radio.send('BB,0,0') display.show('E') print('stop') sleep(100) if start==1: cnt = cnt +1 if cnt>99: cnt=0 display.show(str(cnt//10)) a=(a+accelerometer.get_y())//2 b=(b+accelerometer.get_x())//2 l=a-b r=a+b radio.send('BB,'+str(r)+','+str(l)) print(a,b)
硬件开发
2017-07-20 15:08:00
对于智能手机而言,任何一个部件都有可能影响到手机的整体性能和体验,处理器、内存、闪存、屏幕等等。不过对于以下刚入门的新手用户而言,当和其他网友们热烈讨论UFS2.0、eMMC 5.1、LPDDR4这些名词时,或许会一头雾水:这些究竟是什么?
想要了解UFS2.0、eMMC 5.1、LPDDR4这些词的意义和区别,首先需要了解的是手机内存和闪存这两个容易混淆的概念。
内存
手机内存(RAM,随机存取存储器)又称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。这种存储器在断电时将丢失其存储内容,故主要用于存储短时间使用的程序。说人话,就是我们常说的手机运行内存。
在PC平台,内存经历了SIMM内存、EDO DRAM内存、SDRAM内存、Rambus DRAM内存、DDR内存的发展,到如今普及到DDR4内存,而手机上采用的LPDDR RAM是“低功耗双倍数据速率内存”的缩写, 与桌面平台的DDR4内存相比,面向移动平台的LPDDR4,其能够在带来等效的性能(速度)的同时,兼顾更少的能源消耗。
闪存
闪存(Flash Memory)是一种长寿命的非易失性(在断电情况下仍能保持所存储的数据信息)的存储器,即使断电也不会丢失数据,数据删除不是以单个的字节为单位而是以固定的区块为单位(NOR Flash为字节存储。),区块大小一般为256KB到20MB。通俗地说,它就相当于电脑中的硬盘,运行内存在断电后不会保留存储的数据,而要长期保持数据不丢失还是需要将数据从内存写入到硬盘当中。对于电脑这样的桌面设备,我们可以塞进去一块硬盘,而对于手机这样的移动设备,显然就不现实了。
于是,1984年,东芝公司的发明人舛冈富士雄首先提出了快速闪存存储器(此处简称闪存)的概念。特点是非易失性,其记录速度也非常快,同时体积小,因此后来被广泛运用于数码相机,掌上电脑,MP3、手机等小型数码产品中。Intel是世界上第一个生产闪存并将其投放市场的公司, 当时为NOR闪存,后来日立公司于1989年研制了NAND闪存,逐渐替代了NOR闪存。值得一提的是,如今广泛用于PC上的SSD和手机的ROM,本质上是一家人,都是NAND闪存。
UFS和eMMC
通过上面的简单介绍,大家已经能够理解内存和闪存的区别。那么我们不妨先来看看闪存规格eMMC和UFS。其中,eMMC的全称为“embedded Multi Media Card”,即嵌入式的多媒体存储卡。是由MMC协会所订立的、主要是针对手机或平板电脑等产品的内嵌式存储器标准规格。简单说,就是在原有内置存储器的基础上,加了一个控制芯片,再以统一的方式封装,并预留一个标准接口,以便手机客户拿来直接使用。 2015年前所有主流的智能手机和平板电脑都采用这种存储介质。
2011年电子设备工程联合委员会(Joint Electron Device En gineering Council,简称JEDEC)发布了第一代通用闪存存储(Universal Flash Storage,简称UFS)标准,即UFS 2.0的前身。不过第一代的UFS并不受欢迎,也没有对eMMC标准产生明显的影响。
到了2013年,JEDEC在当年9月发布了UFS 2.0的新一代闪存存储标准,UFS 2.0闪存读写速度理论上可以达到1400MB/s,不仅比eMMC有更巨大的优势,而且它甚至能够让电脑上使用的SSD也相形见绌。于是后来逐渐在高端设备市场上取代eMMC,成为移动设备的主流标配。而实际上, UFS 2.0共有两个版本,其中一个是HS-G2,也就是目前的UFS 2.0。然而,另个一个版本则为HS-G3,可以称为UFS 2.1,其数据读取速度将飙至1.5G/s,也就是UFS 2.0的两倍。
那么UFS和eMMC有什么区别呢?区别在于,UFS 2.0的闪存规格则采用了新的标准,它使用的是串行接口,很像PATA、SATA的转换。并且它支持全双工运行,可同时读写操作,还支持指令队列。相比之下,eMMC是半双工,读写必须分开执行,指令也是打包的,在速度上就已经是略逊一筹了。而且UFS芯片不仅传输速度快,功耗也要比eMMC 5.0低一半,可以说是当下以及日后旗舰手机闪存的理想搭配。
DDR和LPDDR
DDR=Dual Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器。而DDR SDRAM是Double Data Rate SDRAM的缩写,是双倍速率同步动态随机存储器的意思。SDRAM在一个时钟周期内只传输一次数据,它是在时钟的上升期进行数据传输;而DDR内存则是一个时钟周期内传输两次次数据,它能够在时钟的上升期和下降期各传输一次数据, 因此称为双倍速率同步动态随机存储器。 DDR内存可以在与SDRAM相同的总线频率下达到更高的数据传输率。
▲DDR结构框架图
而LPDDR是什么呢?它的全称是Low Power Double Data Rate SDRAM,是DDR的一种,又称为mDDR(Mobile DDR SDRAM),是美国JEDEC固态技术协会(JEDEC Solid State Technology Association)面向低功耗内存而制定的通信标准,以低功耗和小体积著称,专门用于移动式电子产品。
DDR内存经历了从DDR到DDR2、DDR3以及DDR4时代,而DDR5的时代目前还没有到来。从DDR、DDR2发展到DDR3,频率更高、电压更低的同时延迟也在不断变大,慢慢改变着内存子系统,而DDR4最重要的使命是提高频率和带宽,每个针脚都可以提供2Gbps(256MB/s)的带宽,拥有高达4266MHz的频率,内存容量最大可达到128GB,运行电压正常可降低到1.2V、1.1V。
▲点击查看大图
LPDDR的运行电压(工作电压)相比DDR的标准电压要低,从第一代LPDDR到如今的LPDDR4,每一代LPDDR都使内部读取大小和外部传输速度加倍。其中LPDDR4可提供32Gbps的带宽,输入/输出接口数据传输速度最高可达3200Mbps,电压降到了1.1V。 至于最新的LPDDR4X,与LPDDR4相同,只是通过将I / O电压降低到0.6 V而不是1.1 V来节省额外的功耗,也就是更省电。
硬件开发
2017-07-18 10:23:00
这是一篇针对计算机系入门同学学习用途的购机指导,既然关键词是计算机IT、学习用途,本文就仅考虑你的机器往往用于编程、写作业、成果展示以及一般性测试和游戏等一般用途。有特殊需求(比如什么要选修Human computer interaction的人、对于图形渲染很有要求的非普通码农们)则不适用本指南。
本文若干名词解释: 硬指标:购机时建议必须满足的指标 软指标:建议最好能够满足的指标 FAQ:购机过程中Frequently Aske Questions
硬指标: 内存8G以及以上:大内存意味着任务多时不卡顿,具体机理上计算机架构的时候自己学去 机械硬盘1T或以上:你会问云时代要这么大内存何用?答:你是编程的人,放lib和库有用。而且最好分一半给你的C盘,不然调整系统路径玩死你(这点后面还会提) 核第三代i7或以上:两年以前可能i5够用。但是近些年来随着科学计算、数值计算、移动计算开发等等的兴起,i5的核在跑计算的时候可能就已经略显吃力了。因此推荐新入的同学确保你的计算机核的水平在第三代i7以及以上。 操作系统:Win7 / Win10均可:重要的事情说三遍,别用win8,别用win8,别用win8!至于用不用Mac看个人。对了。据用Mac的人说码农最好用Pro,Air跑代码略吃力。用不用Linux么……呵呵,这就看造化了 接口:VGA、HDMI、网线以及读卡器都至少要有的哦,不为啥,为了你课堂展示的时候能够有点效率罢了。否则想想在全班面前找线的样子也尴尬是吧
软指标: 接口(USB 3 + USB2 * 2)以及以上配置:接口这个数量比较方便(可以一个插入无线鼠标,另一个常插接口转换器) 价格低于5000元:反正折腾两年,日夜用,再好的电脑也搞不好要坏,还不如……唉,你懂的 高清屏:眼睛是心灵的窗户,屏幕这东西马虎不得,别买来然后不定期频闪的就坑了
FAQ: 固态硬盘(SSD)几何?? 答:对于高级编程的来说是个然并卵的东西。固态硬盘一般不超过256吧(而且这已经是当前很土豪的配置了,一般就60G左右),然后一般是作为启动盘吧。OK,20几个G的系统文件就去了。剩下的40几个G……放编程用的库么?好,那么东西不放C盘,那么往往会导致你配置路径配置到要哭。这些都是楼主的痛苦经历吧,可能水平有限所致。然而仅供参考 光驱到底要不要?? 答:建议是不要。No.1.光驱可以通过接口转换器 + 外置光驱替代,淘宝价格好的不到40。No.2,但凡机子本身带光驱,光驱都作为主板架构的一部分在考虑,万一坏了可能想拆换就麻烦了;一个坏了直接不到40块再换一个,哈儿都知道怎么搞方便吧。这也是现在市场上笔记本大多不带光驱的原因。
硬件开发
2017-07-03 19:40:00
ubuntu常见错误--Could not get lock /var/lib/dpkg/lock解决
通过终端安装程序sudo apt-get install xxx时出错: E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it
出现这个问题可能是有另外一个程序正在运行,导致资源被锁不可用。而导致资源被锁的原因可能是上次运行安装或更新时没有正常完成,进而出现此状况,解决的办法其实很简单,在终端中敲入以下两句: sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/loc
硬件开发
2016-12-07 13:20:00
crontab -e 3 0 * * * nohup python -u /home/pi/work/baidu/check_in.py > /home/pi/work/logs/baidu/check_in.log 2>&1 & 3 0 * * * python /home/pi/work/jd/check_in.py # coding: utf-8 import sys reload(sys) sys.setdefaultencoding( "utf-8" ) import requests import re num = 0 num_error = 0 ok_num = 0 error_num = 0 Cookie = 'Your cookie' headers = { 'Accept':'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6', 'Connection': 'keep-alive', 'Content-Length': '61', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': Cookie, 'DNT': '1', 'Host': 'tieba.baidu.com', 'Origin': 'http://tieba.baidu.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', } headers1 = { "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding":"gzip, deflate, sdch", "Accept-Language":"zh-CN,zh;q=0.8", "Cache-Control":"max-age=0", "Connection":"keep-alive", "Cookie": Cookie, "Host":"tieba.baidu.com", "Upgrade-Insecure-Requests":"1", "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" } url_forum = 'http://tieba.baidu.com/f/like/mylike' r2 = requests.get(url_forum, headers=headers1) search = re.findall(ur'a href=.*?title="(.+?)">', r2.text) num_forum = len(search) print 'num_forum', num_forum num = 0 num_error = 0 ok_num = 0 error_num = 0 pid = True while num != num_forum and pid: for i in search: payload = {'ie': 'utf-8', 'kw': i, 'tbs': 'fb6ecec1996df5d41435580832'} r = requests.post('http://tieba.baidu.com/sign/add', data=payload, headers=headers, timeout=3) html = r.text.decode('raw_unicode_escape') print "%s %s ..." % ("Execute task:", i) if html == u'{"no":1101,"error":"亲,你之前已经签过了","data":""}': ok_num += 1 print "%s is repeat task." % i else: ok_num += 1 print "%s finished." % i if ok_num == num_forum: pid = False else: error_num += 1 if error_num == 5: pid = False print 'over' # coding: utf-8 import requests import re # Please replace your cookie here. Cookie = "" headers = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch, br", "Accept-Language": "zh-CN,zh;q=0.8", "Cache-Control": "max-age=0", "Connection": ":keep-alive", "Cookie": Cookie, "Host": "vip.jd.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" } url_forum = 'http://vip.jd.com' print 'curl', url_forum r = requests.get(url_forum, headers=headers) isLogin = re.findall(ur'pageConfig.isLogin="(.+?)"', r.text) token = re.findall(ur'pageConfig.token="(.+?)"', r.text) print 'token :', token[0], ', isLogin:', isLogin[0] url_forum = 'https://vip.jd.com/common/signin.html?token='+token[0] print 'curl', url_forum r2 = requests.get(url_forum, headers=headers) print r2.text headers = { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.8", "Connection": ":keep-alive", "Cookie": Cookie, "Host": "vip.jr.jd.com", "Origin": "https://vip.jr.jd.com", "Referer": "https://vip.jr.jd.com/", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" } url_forum = 'https://vip.jr.jd.com/newSign/doSign' print 'curl', url_forum r = requests.post(url_forum, headers=headers) print r.text # Glod lottery, once everyday. url_forum = 'http://vip.jr.jd.com/award/drawAward' #url_forum = ' http://vip.jr.jd.com/newSign/doSign' print 'curl', url_forum r = requests.post(url_forum, headers=headers) print r.text url_forum = 'http://ld.m.jd.com/SignAndGetBeans/signStart.action?sid=210aafce2985f69c0ebfeae0f5459fbw' r = requests.get(url_forum) print 'curl', url_forum print r.text
over
硬件开发
2016-12-07 13:11:00
Ubuntu下查看linux版本,内核版本,系统位数,gcc版本
1. 查看linux版本 leblancs@leblancs-virtual-machine:~$ cat /etc/issue Ubuntu 16.10 \n \l leblancs@leblancs-virtual-machine:~$

2. 查看内核版本
1) leblancs@leblancs-virtual-machine:~$ cat /proc/version Linux version 4.8.0-28-generic (buildd@lgw01-16) (gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12) ) #30-Ubuntu SMP Fri Nov 11 14:03:52 UTC 2016 leblancs@leblancs-virtual-machine:~$
2) uname命令 leblancs@leblancs-virtual-machine:~$ uname -a Linux leblancs-virtual-machine 4.8.0-28-generic #30-Ubuntu SMP Fri Nov 11 14:03:52 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux leblancs@leblancs-virtual-machine:~$
3) leblancs@leblancs-virtual-machine:~$ uname --help Usage: uname [OPTION]... Print certain system information. With no OPTION, same as -s. -a, --all print all information, in the following order, except omit -p and -i if unknown: -s, --kernel-name print the kernel name -n, --nodename print the network node hostname -r, --kernel-release print the kernel release -v, --kernel-version print the kernel version -m, --machine print the machine hardware name -p, --processor print the processor type (non-portable) -i, --hardware-platform print the hardware platform (non-portable) -o, --operating-system print the operating system --help display this help and exit --version output version information and exit GNU coreutils online help: Full documentation at: or available locally via: info '(coreutils) uname invocation' leblancs@leblancs-virtual-machine:~$

3.查看系统位数
1) leblancs@leblancs-virtual-machine:~$ getconf WORD_BIT 32 leblancs@leblancs-virtual-machine:~$ getconf LONG_BIT 64 leblancs@leblancs-virtual-machine:~$
2) leblancs@leblancs-virtual-machine:~$ file /bin/bash /bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=6587b60b0a57e1a0f83f7523a658e0bf329fdb5f, stripped leblancs@leblancs-virtual-machine:~$

4. 查看gcc版本 leblancs@leblancs-virtual-machine:~$ gcc --version gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. leblancs@leblancs-virtual-machine:~$
硬件开发
2016-12-07 10:54:00