浅谈软件是如何控制硬件工作的

声明:以下知识仅限于本人对于软硬件的理解和整理并作为内部分享,因个人知识水平所限,可能存在一些遗漏和不足甚至错误的地方,如有发现可以留言指出。配合此视频看效果更佳哦~

概述

我们都知道软件是服务于硬件的,因为单纯的软件如果不跑到具体的硬件上面将是没有任何价值的。如果单纯的去谈软件是没有任何价值的,软件的开发往往依附于所运行的硬件环境。关于这个话题涉及的知识比较多,而且比较深奥,这个话题其实是《微机原理》这门课程所要解决的问题,这篇文章不打算以晦涩难懂比较深奥的知识揭开这个问题的本质,而是想基于作者(水寒)的知识积累和实践,通过一些简单的电路知识和计算机软硬件知识来了解软件和硬件是怎么交织在一起的。

数字电路

对于我们物联网而言,一般所讨论的硬件其实可以认为是数字电路相关的一套硬件电路。而数字电路和模拟电路有何区别呢?要搞清数字电路模拟电路,首先要搞清什么是数字信号什么是模拟信号。

模拟量转数字量采样过程

如上图所示,模拟信号是在时间上取值都是连续的,自然界的信号可以说都是模拟信号。但是模拟信号利于观察但是不利于数据交互传递和表示,所以通常我们在计算机中需要将大部分的模拟信号转换为数字信号,方便实现数字电路和软硬件数据交互。

数字电路或数字集成电路是由许多逻辑门组成的复杂电路,与模拟电路相比,它主要进行数字信号的处理(即信号以0与1两个状态表示),因此抗干扰能力较强

看到这里你也许还比较迷糊,似懂非懂的感觉,那就对啦!接下来我们以一个小实验来说明一下。

阅读更多

ECMAScript 6 入门学习笔记

本文是基于阮一峰《ECMAScript 6 入门》做的个人学习笔记,方便今后查阅,所以以下内容基本上绝大部分出自阮一峰的博客。

笔记1:数据类型和语法块

简单说,ECMAScript 是 JavaScript 语言的国际标准,JavaScript 是 ECMAScript 的实现。

let 命令

ES6 新增了 let 命令,用了声明变量,使用它声明的变量只在所在的代码块中有效

{
    let a = 10;
    var b = 11;
}

console.log(a);  //Error  is not defined
console.log(b);  // 11

for 循环的计数器就很合适使用 let 命令。

for(let i = 0; i < 10; i++){
    //...
}
console.log(i);  //Error

而且 let 不存在变量提升(变量可以在声明之前使用),也就是说我们一般需要先使用 let 来声明变量才能使用。

//var
console.log(foo);  //undefined
var foo = 2;

//let
console.log(bar);  //Error bar is not defined
let bar = 3;

阅读更多

JavaScript 高级程序设计(第3版)学习笔记

笔记2:面向对象部分

这是阅读《JavaScript 高级程序设计》书籍的学习笔记,整理和归纳,方便自己今后复习和查阅,这里总结的基本上都是一些比较特殊的知识点,和 Java 等其他高级语言重复的地方不在归纳范围内。建议先阅读第一部分 非面向对象部分。此部分主要是理解 JavaScript 中的面向对象的实现思路以及如何实现继承。

理解对象

ECMAScript 中有两种属性:数据属性和访问器属性。

数据属性

数据属性有 4 个描述其行为的特征。

[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为 true.

[[Enumerable]]:表示能否通过 for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为 true.

[[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为 true.

[[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为 undefined.

var person = {
    name : "XiaoMing"
}

阅读更多

JavaScript 高级程序设计(第3版)学习笔记

笔记1:非面向对象部分

这是阅读 《JavaScript 高级程序设计》 书籍的学习笔记,整理和归纳,方便自己今后复习和查阅,这里总结的基本上都是一些比较特殊的知识点,和 Java 等其他 高级语言 重复的地方不在归纳范围内。第一部分是基础部分(即非面向对象部分),基本上是围绕变量和函数展开的。

分号

ECMAScript 中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾,如下例所示:

var sum = a + b                 // 即使没有分号也是有效的语句——不推荐 
var diff = a - b;               // 有效的语句——推荐

推荐使用封号

变量

ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存值的占位符而已。定义变量时要使用 var 操作符(注意var是一个关键字),后跟变量名(即一个标识符),如下所示:

var message;

此时变量 message 会保存一个特殊的值 undefined, 定义变量的时候可以赋予初始值:

var message = "hi";
message = 100;   //有效,不推荐

虽然支持松散类型,但是不推荐给变量设置不同类型的值

阅读更多

webpack 安装和使用

webpack 是什么

webpack 是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含 less / sass)、图片等都作为模块来使用和处理。 webpack 的核心是 依赖分析,把依赖分析出来了,其他都是细枝末节了。

安装 webpack

前提,你的电脑需要安装 node 和 npm.

使用 npm install webpack 安装 webpack.

入门示例

我们创建两个 js 文件:

src/bar.js

export default function bar() {
  //
}

src/index.js

import bar from './bar';

bar();

阅读更多

致我过去的 2019 年

想了一下,这一年已经结束了,一如既往,也没做什么轰轰烈烈的大事,但是得写一下总结和计划,也算是给上一年一个交代了。

这一年

2019 年对我来说是非常平淡的一年,对我来说这一年是一个全新生活模式的开启,在这一年里也发生了一些大事。

这一年我们拥有了自己的新家,我感受到家庭的温馨,知道作为丈夫和父亲的责任是什么。

这一年我也深刻的感受到健康的重要性。我的生活作息更加规律,不再熬夜,不再玩游戏。撇弃了游戏,拾起了Kindle.

这一年我在工作上没有之前那么拼了,转而更加注重自己的生活品质和感受家庭的温馨。

这一年我成了准爸爸,我给他起了一个让我满意的名字(暂时保密)。

这一年我写了近百篇技术博客,录制了 50 多节技术视频,给自己划上了一个并不算完美的句号。

阅读更多

亚马逊中国 2019 年度 Kindle 电子书畅销排行榜单

亚马逊中国于 12 月 30 日发布了 2019 年度 Kindle 电子书畅销排行榜单,榜单依据 2019 年期间实际销售数量进行统计。《三体全集》《长安十二时辰》和《明朝那些事儿》分列“2019 亚马逊中国 Kindle 年度付费电子书畅销榜”前三甲。从城市维度来看,北京、上海、深圳不仅在 Kindle 电子书消费总量上排名前三,也是人均购买 Kindle 电子书数量最多的三座城市。

以下榜单共有 9 个主题,分别是付费电子书、热门影视剧、付费电子书新书、包月借阅服务、Prime 阅读借阅服务、新锐作家、高分好书、短书名、畅销分类。

榜单一:2019 Kindle 付费电子书畅销排行榜 TOP10

《三体全集》

《长安十二时辰》

《明朝那些事儿(套装全7册)》

《活着》

《流浪地球》

《无人生还》

《白夜行》

《富爸爸穷爸爸》

《围城》

《红楼梦》

阅读更多

将电子书发送到Kindle上的几种方法

本文转自:https://www.hangge.com

邮箱推送

邮箱推送是最原始的一种方式。

在亚马逊官网找到菜单【管理我的内容和设备】,选择最后一个【设置】选项卡,翻到下面找到【个人文档设置】,这里就可以看到自己的接受推送的邮箱(一般注册亚马逊账户后会默认有一个xxx@kindle.cn的邮箱,以实际为准),下面就可以进行添加认可的邮箱,类似于一个白名单,亚马逊只会认可该邮箱(们)推送过来的信息。添加好后就可以用你添加的邮箱,给xxx@kindle.cn发邮件了,主题自己随便写一个,正文也随便写或者不写,把你要推送的电子书添加到附件,点击发送就好嘞!等一会,你的kindle设备在联网状态下就会收到你的电子书然后开始下载。搞定! 原文出自:www.hangge.com 转载请保留原文链接:https://www.hangge.com/blog/cache/detail_1626.html

阅读更多

Android 中水平自动滚动列表实现

水平滚动的思路借鉴于 Android RecyclerView打造自动循环效果,但是这个不能实现循环左右移动,所以我进行了一个小修改,添加了方向这个概念,并在滚动到最顶端的时候自动改变了方向。

水平自动滚动广告效果演示

if(recyclerView.canScrollHorizontally(scrollDirection)){
    recyclerView.scrollBy(2 * scrollDirection, 2 * scrollDirection);
}else{  //改变方向
    scrollDirection = -scrollDirection;
}

首先我们考虑到水平列表可以使用 RecycleView 实现:

mRecycleView.setLayoutManager(new LinearLayoutManager(this.getContext(),
        LinearLayoutManager.HORIZONTAL, false));

然后我们重写一下 RecycleView 继承并使用 scrollBy() 方法来实现自动滚动。

阅读更多

读《82年生的金智英》后感

这是一部在韩国被定性为女权主义的小说,讲述了韩国当前的女性在社会中的地位和不公平待遇

可能你很难想象有很多韩国女性公众人物在推荐这本书时,都收到过男性的恶评。

虽然本书描写的是韩国的社会,但是本书中的大多数场景可能让你感到发生在我们身边,我作为一名即将当爸爸的丈夫的身份从本书中获得了很多难得的对妻子的理解和从另一个角度重新审视了平常生活中的我的一些不经意的行为和语言。

这本书总的来说对我很震撼,让我看到了一个平常不太留意的女性角度,让我更懂的怎样去换位思考,所以我建议身为丈夫的你或者即将成为丈夫的你读一读此书,希望你的另一半能感受更多的爱和温暖。

阅读更多

读《骆驼祥子》后感

说明:本文转载自 https://www.lz13.cn/duhougan/48670.html

这篇文章分析的很到位很透彻,基本上代表了我阅读此书后的感受,当然我个人可能无法写出如此全面的评价,所以转载了此文,希望对你有所帮助。

《骆驼祥子》真实地描绘了北京一个人力车夫的悲惨命运。祥子来自农村,在他拉上租来的洋车以后,立志买一辆车自己拉,做一个独立的劳动者。他所轻力壮,正当生命的黄金时代;又勤苦耐劳,不惜用全部力量去达到这一目的。在强烈的信心的鼓舞和支持下,经过三年的努力,他用自己的血汗换来了一辆洋车。但是没有多久,军阀的乱兵抢走了他的车;接着反动政府的侦探又诈去了他仅有的积蓄,主人躲避特务追踪还使他丢了比较安定的工作;虎妞对他的那种推脱不开的 “爱情” 又给他的身心都带来磨难。迎着这一个又一个的打击,他作过挣扎,仍然执拗地想用更大的努力来实现自己梦寐以求的生活愿望。但一切都是徒然:用虎妞的积蓄买了一辆车,很快又不得不卖掉以料理虎妞的丧事。他的这一愿望 “象个鬼影,永远抓不牢,而空受那些辛苦与委屈”;在经过多次挫折以后,终于完全破灭。他所喜爱的小福子的自杀,吹熄了心中最后一朵希望的火花,他丧失了对于生活任何企求和信心,从上进好强而沦为自甘堕落:原来那个正直善良的祥子,被生活的磨盘辗得粉碎。这个悲剧有力地揭露了旧社会把人变成鬼的罪行。

阅读更多

Android 虹软人脸识别 NV21 和 RGB24 转换问题

当我们使用活体检测检测完毕后,需要上传图片给后台进行人脸识别,在 Android 里面默认的 Camera 获取的图片格式是 NV21.

怎么知道这个默认格式呢?

Camera.Parameters parameters = camera.getParameters();
parameters.getPreviewFormat();

这个格式的图片本身虹软是支持的,但是有个条件限制:SDK 对图形尺寸做了限制,宽高需要大于 0,宽度为 4 的倍数, YUYV/I420/NV21/NV12 格式的图片高度为 2 的倍数, RGB24 格式的图片高度不限制。如果你的图片是 NV21 格式不符合这个条件就需要进行转换。

private static final int VALUE_FOR_4_ALIGN = 0b11;
private static final int VALUE_FOR_2_ALIGN = 0b01;

/**
    * 确保传给引擎的NV21数据宽度为4的倍数,高为2的倍数
    *
    * @param bitmap 传入的bitmap
    * @return 调整后的bitmap
    */
public static Bitmap alignBitmapForNv21(Bitmap bitmap) {
    if (bitmap == null || bitmap.getWidth() < 4 || bitmap.getHeight() < 2) {
        return null;
    }
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    boolean needAdjust = false;
    //保证宽度是4的倍数
    if ((width & VALUE_FOR_4_ALIGN) != 0) {
        width &= ~VALUE_FOR_4_ALIGN;
        needAdjust = true;
    }

    //保证高度是2的倍数
    if ((height & VALUE_FOR_2_ALIGN) != 0) {
        height--;
        needAdjust = true;
    }

    if (needAdjust) {
        bitmap = imageCrop(bitmap, new Rect(0, 0, width, height));
    }
    return bitmap;
}

阅读更多