Coder Social home page Coder Social logo

blog's People

Contributors

meishaoming avatar

Stargazers

 avatar

Watchers

 avatar

blog's Issues

B-L072Z-LRWAN1

新入一块板子,ST 官方出的 LoRa 开发板 B-L072Z-LRWAN1,可进行快速原型验证。





其中把 stm32 和 Lora 封装成了一个模块 CMWX1ZZABZ-091 LoRa®/Sigfox™ module (Murata)

板子上共有七个 LED 灯:

LED 序号 功能
LED1、LED2、LED3、LED4 通用功能、受GPIO 控制
LED5 ST-LINK烧录指示
LED6 电源错误指示
LED7 5V 电源指示

CMWX1ZZABZ-091 模块

image

STM32L072CZ    
PC0 RESET SX1276
PA7 MOSI
PA6 MISO
PB3 SCK
PB4 DIO0
PB1 DIO1
PB0 DIO2
PC13 DIO3
PA5 DIO4 (not fitted)
PA4 DIO5 (not fitted)
PA15 spi_css
PA12 TXCO
PA1 ANT_SWITCH_RX
PC1 ANT_SWITCH_TX_BOOST
PC2 ANT_SWITCH_TX_RFO
PB5 LED1 LED
PA5 LED2
PB6 LED3
PB7 LED4
PB2 BUTTON BUTTON

raspberry pi cm3 flashing under macos

CM3 自带 4GB eMMC。要把 Raspbian 系统 烧写进去还需要一个底板,通过 USB Device 的方式来烧录。

本文记录在 MacOS 上烧写系统到 CM3 的过程,并分析讨论涉及到的硬件原理。

准备工作

底板

我买的是一个国产底板 Compute Module IO Board Plus

image

系统文件

下载 RASPBIAN STRETCH LITE 刷机文件。LITE 版本解压后约 1.8GB,没有桌面系统。而 RASPBIAN STRETCH WITH DESKTOP 解压后 4.95GB,CM3 的 eMMC 只有 4GB,用不了。

usbboot

git clone --depth=1 https://github.com/raspberrypi/usbboot.git

cd usbboot
make

生成 rpiboot 工具。

刷机过程

  • 拔掉 USB SLAVE 1/2/3/4 SELECT 跳线帽(注意这要拔掉的是两个跳线帽)
  • 将 BOOT ENABLE USB SLAVE 跳线帽接到 EN 端
  • 用 USB 线将底板的 USB SLAVE 接口连接到电脑(板子只通过 USB Slave 供电,不要再用 power 供电)

打 MacOS 的「关于」-> 「系统报告」-> 「硬件」-> 「USB」

可以看到 BCM2710 Boot 这个设备:

image

执行 sudo ./rpiboot 命令:

image

看到 rpiboot 通过 USB 发送了 bootcode.bin 和 start.elf 到 CM3 上执行。

此时电脑弹出磁盘,说明发送过去的 start.elf 将 CM3 上的 eMMC 模拟成一个 USB mass storage ,挂载到电脑上。

image

用 diskutil 可以看到:

image

USB 总线上也出现了 Compute Module 设备:

image

把映像文件 dd 进 CM3 磁盘:

sudo dd if=./img/2018-06-27-raspbian-stretch-lite.img of=/dev/disk2 bs=32m

整个命令执行耗时 15min+ 。刷完后在电脑上可以看到 boot 分区:

image

硬件分析

image image

  • 拔掉 USB SLAVE 1/2/3/4 SELECT 跳线帽,作用是断开 USB DP/DM 到 HUB 的连接
  • 将 BOOT ENABLE USB SLAVE 跳线帽接到 EN 端。Q1 导通(Q2是默认导通的),EMMC_DISABLE_N 导通接到地,禁止 eMMC

EMMC_DISABLE_N 如何控制 SoC 的启动?

image

  • EMMC_DISABLE_N 拉低时,SD_CLK 接地,SD/eMMC 读失败
  • EMMC_DISABLE_N 拉高时或浮空,SD_CLK 正常连接,板子从 eMMC 启动

SoC 启动时尝试各种启动方式,当所有方式失败后,最后尝试 USB Device 方式启动。详见 raspberry pi boot process

参考链接

办理《港澳通行证》和《**通行证》

背景

  1. 坐标深圳,深户与非深户可能有略微差别
  2. 已有一纸本《港澳通行证》还有一年到期,现重新办理
  3. 同时申请《**通行证》,都归「出入境」这个单位管
  4. 预约时可选择证件办好后邮寄配送,到付

办理流程

image

相关链接

隔几天查询一下,可以看到进度:

image

拿证

预约的时候选择取证方式,可以自取或邮寄。我选择了邮寄,走 EMS,两个证是分开寄的,每笔 18 元快递费。

  • 7.10 预约
  • 7.11 现场办理
  • 7.19 拿到港澳通行证
  • 7.20 拿到**能行证

从开始办理到拿证,约 7~8 个工作日。

📱Android UI 适配

用 Sketch 画了一套图,需要给开发切图和标注尺寸。但我们的屏幕 dpi 为 220,没有严格符合 Android 定义的任一通用屏幕密度。按照 hdpi 规格切图的话,最终的 dp 尺寸会有偏差,导致开发无法还精确还原设计稿。

第一次做这种工作,梳理了下这里面的几个概念和问题。

什么是 dpi

屏幕有不同的规格,同一分辨率的屏幕其物理尺寸可以不同。比如同样是 1920x1200 分辨率的屏幕,可以是 10.1 英寸,也可以是 7 英寸。对于这两块屏幕来说,它们每英寸区域中的像素数量不同,我们也称为「屏幕密度」不同。

Android 里面把对每英寸的点数有个单位:dpi (dots per inch)。在这里它与 PPI 是一个意思。

不同 dpi 会造成什么问题

以前还在使用 windows xp 的时候我有过这样的经验:新买的一台电脑屏幕分辨率很高,装上 winxp 之后,如果把屏幕分辨率设置为显示器的分辨率,图标看起来都非常小。导致在桌面找个图标很费劲,操作非常麻烦。

为了让所有图标看起来大一些,不得不在 winxp 系统里把屏幕分辨率调低(那时最流行的是 1024x768)。而调低之后整个桌面和所有图标看着又都变形了。

如果我们以像素 px 为单位,一个在低 dpi 的屏幕上大小正常的图标,到了高 dpi 的屏幕上,相对的物理尺寸就会变小。图标物理尺寸变小,操作起来就很麻烦。在触摸屏上这个问题犹甚。

如何解决 dpi 差异问题

对于 ui:

Android 定义了六种通用的密度:

  1. ldpi(低)~120dpi
  2. mdpi(中)~160dpi
  3. hdpi(高)~240dpi
  4. xhdpi(超高)~320dpi
  5. xxhdpi(超超高)~480dpi
  6. xxxhdpi(超超超高)~640dpi

ui 在针对不同 dpi 的屏幕会切出不同尺寸(以px为单位)的图以获得最佳效果。这些图片资源放在 Android 源码工程的 res 目录下。Android 在需要图片资源渲染 ui 时,会根据当前系统的屏幕密度(lcd_density) 配置,选择最接近的目录,然后使用该目录中的图片资源。

对于开发:

在布局时不以 px 为单位,而使用 dp。px 与 dp 的换作关系为:

px = dp * (dpi / 160)

对于 160dpi(每英寸有 160 个像素点) 的屏幕来说,1dp = 1px 。

在代码布局时,开发写在 xml 配置文件中的尺寸单位是 dp。而 Android 在渲染 ui 时,会根据当前系统的屏幕密度(lcd_density) 配置,计算出对应的 px。

正好我手里有一个 Android 平板,10.1 英寸,分辨率 1920x1200。adb 进去查看到 ro.sf.lcd_density = 220 。

10.1 inch 是对角线长度,查询屏幕长宽尺寸,Display size: 8.56" × 5.35" = 45.85in² 。

计算 PPI (pixels per inch) :

1920/8.56 = 224.3
1200/5.35 = 224.3

所以系统里把 dpi 设置为 220 应该是差不多的。

用 Sketch 作图时,使用的单位都是 px。而切图和标注尺寸给开发需要把单位转换成 dp。但是发现自动转换工具只能转换成 Android 定义的那几种通用规格。

在这种情况下,切图和尺寸标注还是按那几种通用规格来。Android 渲染时会选择最接近的 hdpi 来计算 px 值。这种情况下会有一点偏差,此时需要做出选择,有些地方需要严格按照尺寸来贴,有些地方可以自动计算 px 以适应当前屏幕。

参考

「草稿」LoRa - SX1278 芯片

image

image

  SX1272 SX1276 SX1277 SX1278 SX1279
Frequency bands of operation 850MHz to 1GHz 137 to 1020MHz 137 to 1020MHz 137 to 525MHz 137 to 960MHz
Programmable Bandwidth 125 KHz250 KHz500 KHz 7.8 KHz10.4 KHz15.6 KHz20.8 KHz31.2 KHz41.7 KHz62.5 KHz125 KHz250 KHz500 KHz 7.8 KHz10.4 KHz15.6 KHz20.8 KHz31.2 KHz41.7 KHz62.5 KHz125 KHz250 KHz500 KHz 7.8 KHz10.4 KHz15.6 KHz20.8 KHz31.2 KHz41.7 KHz62.5 KHz125 KHz250 KHz500 KHz 7.8 KHz10.4 KHz15.6 KHz20.8 KHz31.2 KHz41.7 KHz62.5 KHz125 KHz250 KHz500 KHz
Receiver Sensitivity -137 dBm -148 dBm -139 dBm -148 dBm -148 dBm
Max. Link Budget 157 dB 168 dB 168 dB 168 dB 168 dB
IIP3 -12.5 dBm -11 dBm -11 dBm -11 dBm -11 dBm
Rx Current 10 mA100nA register retention 9.9 mA200nA register retention 9.9 mA200nA register retention 9.9 mA200nA register retention 9.9 mA200nA register retention
Modulation types supported GFSKFSKMSKGMSKLoRaOOK GFSKFSKMSKGMSKLoRaOOK GFSKFSKMSKGMSKLoRaOOK GFSKFSKMSKGMSKLoRaOOK GFSKFSKMSKGMSKLoRaOOK
Dynamic Range (RSSI) 127 dB 127 dB 127 dB 127 dB 127 dB
Temperature sensor and low battery indication YES YES YES YES YES
Packet engine size 256 bytes 256 bytes 256 bytes 256 bytes 256 bytes
Block Immunity 89 dB Excellent Excellent Excellent Excellent
Bit Synchronizer YES YES YES YES YES
Preamble detection YES YES YES YES YES
Spreading factors   6, 7, 8, 9, 10, 11, 12 6, 7, 8, 9 6, 7, 8, 9, 10, 11, 12 6, 7, 8, 9, 10, 11, 12

1

当我们想传送信息时,需要依靠特定的介质。

比如与人面对面交谈,信息首先转化成了声音(振动),带动空气振动,对方接收到振动(声音),然后转换成信息,最后理解信息。

这里信息是靠振动传递的,而依赖的介质是空气。

在电子领域,信息的传送介质多种多样:电线(电话线)、光纤、电磁波。

2

电磁波 electromagnetic wave

载波 carrier wave

把待发送的电磁波叠加到一个很高频率的载波上,这个过程称为调制。

为什么需要调制?

频谱的资源是有限的。可以将信息的频谱搬移到其它频段上,充份利用频谱资源。

在很高的频段上,收发的天线可以做的更小。

同一个物理发射设备可以通过不同的载波频率发送信息

3

调试方法有许多:

模拟调制:

  • AM: Amplitude Modulation 调幅
    • DSB(Double-sideband modulation) 双边带调制
    • SSB(Single-sideband modulation) 单边带调制
    • VSB(Vestigial-sideband modulation) 残余边带调制
  • FM: Frequency Modulation 调频
  • PM: Phase Modulation 调相

数字调制:

ASK: Amplitude-shift keying 幅度偏移调制,常见的有 OOK、QAM
PSK: Phase-shift keying 相位偏移调制
FSK: Frequency-shift keying 频率偏移调制,常见的有 MSK、GFSK

image

SX1276/77/78/79

什么是调制?

幅度调制 (AM: Amplitude Modulation)

常见的调制技术有

ASK

FSK

GFSK

什么是扩频?

扩频调制技术

spread spectrum modulation technique

优点:

更宽的晶振频率的精度和稳定性要求
更强的抗干扰性

扩频因子:6/7/8/9/10/11/12。对传输速率的影响:6 最快,12最慢。
循环纠错编码:码率 1,2,3,4 - 4/5,4/6,4/7,4/8
带宽:增加带宽可提高传输速率,但牺牲接收灵敏度

LoRa Packet 格式:

image

preamble 前导码,用于数据流同步。可设置前导码长度
Header 报头,可设置报头类型:显示报头、隐式报头

LoRa 跳频:FHSS

从频率表中选一个跳频信道,在预定跳频周期结束后,发送端和接收端跳到预定义列表中的下一个信道,继续发送和接收数据包的下一部分内容。任一信道内的驻留时间由 FreqHoppingPeriod 决定。

ESP8266 AT 指令使用示例

设置 WiFi 模式

三个模式:

  • 1 Station
  • 2 SoftAP
  • 3 SoftAP+Station

设置默认的 WiFi 模式为 Station:

AT+CWMODE_DEF=1

OK

设置当前的 WiFi 模式为 Station:

AT+CWMODE_CUR=1

OK

连接 AP

AT+CWJAP_CUR="SSID","PASSWORD"
WIFI CONNECTED
WIFI GOT IP

OK

查看状态

状态码:

  • 2 Station 已经连接 AP,获得 IP 地址
  • 3 Station 已建立 TCP 或 UDP 传输
  • 4 Station 断开网络连接
  • 5 未连接 AP

连接前

AT+CIPSTATUS
STATUS:5

OK

连接 AP 后

AT+CIPSTATUS
STATUS:2

OK

查 IP 和 MAC 地址

AT+CIFSR
+CIFSR:STAIP,"192.168.31.58"
+CIFSR:STAMAC,"68:c6:3a:84:28:a7"

OK

断开 AP 连接

AT+CWQAP

OK
WIFI DISCONNECT

断开后再查 IP:

AT+CIFSR
+CIFSR:STAIP,"0.0.0.0"
+CIFSR:STAMAC,"68:c6:3a:84:28:a7"

OK

连接 TCP

如果服务端没开启,连接立即被拒绝,失败:

AT+CIPSTART="TCP","59.110.215.205",9900

ERROR
CLOSED

服务端开启,连接成功:

AT+CIPSTART="TCP","59.110.215.204",8800
CONNECT

OK

再查询状态:

AT+CIPSTATUS
STATUS:3
+CIPSTATUS:0,"TCP","59.110.215.205",9900,14909,0

OK

断开 TCP 连接

AT+CIPCLOSE
CLOSED

OK

断开连接后再查看状态:

AT+CIPSTATUS
STATUS:4

OK

设置传输模式

  • 0 普通传输模式
  • 1 透传模式

使用透传模式:

AT+CIPMODE=1

OK

开始传输

AT+CIPSEND

OK

>

收到 > 之后即可开始传输。

退出透传

+++

发送 +++ 之后等 1 秒。保证模块能够把 +++ 作为单独一包来处理。

raspberry pi cm3 with wifi bt

raspberry pi cm3 with wifi bt

在使用 CM3 来做一个项目,要用到 WiFi&BT。Pi 3B 上使用的 WiFi&BT 芯片是 BCM43438,在 CM3 上参照 Pi 3B 也用了这颗芯片。本文记录调试过程中查到的一些知识点。

UART 的 RTS 和 CTS

RTS (Require To Send) 是输出信号,当它输出低电平时,表示告诉对端设备:我可以接收数据,你可以发送了。

CTS (Clear To Send) 是输入信号,当检查到它为低电平时,表示对方可以接收设备,我可以发送了。

所以跟 TX/RX 信号一样,RTS 和 CTS 信号线也是与对端交叉连接。

主控端 设备端
TX RX
RX TX
RTS CTS
CTS RTS

raspberry pi 3b 的 uart

树莓派硬件上有两个 UART,分别是

  • UART0: PL011,设备节点为 ttyAMA0
  • UART1: mini UART,设备节点为 ttyS0

硬件上一般会使用 PL011 UART 来连接 BT,mini UART 作为 linux console output。

mini UART 的时钟源来自 VPU ,所以 VPU 的频率变化会引起 mini UART 的波特率变化。当在 config.txt 里加上了 enable_uart=1,VPU 的固件(start.elf)会把 VPU 的频率固定在 250MHz,使得 mini UART 的波特率保持一致。

UART 的输出 pin 脚可以配置。Pi 3B 的配置情况是:

  • UART0 (ttyAMA0) - pin 32(tx), 33(rx)
  • UART1 (ttyS0) - pin 14(tx), 15(rx)

UART 还可以配置 flow control 引脚 RTS/CTS。在 Pi 3B 中 GPIOs 28-31 作为 PCM 功能,BT 没有接 RTS 和 CTS。而在 Zero W 中,GPIO 30 和 31 用作 RTS 和 CTS 。

参考上一小节 RTS/CTS 的作用,当不使用 flow control 功能时,设备端(BCM43438)的 RTS 引脚悬空,CTS 引脚接地。

参考 THE RASPBERRY PI UARTS

raspberry pi WiFi & BT

raspberry pi 3b 使用了 BCM43438 这个 WiFi + BT 的芯片。

WiFi 功能使用了 sdio1:pin 34-39 (clk,cmd,d0~d3) 。

BT 使用了 ttyAMA0: pin 32(tx), 33(rx)。gpio43 作为 GPCLK2 功能输出 32.768KHz 时钟给 BT。

gpio43 作为 bt_pins (/proc/device-tree/soc/gpio@7e200000/bt_pins) ,这样 hciuart 服务才能运行:

pi-bluetooth.hciuart.service

[Unit]
Description=Configure Bluetooth Modems connected by UART
ConditionPathIsDirectory=/proc/device-tree/soc/gpio@7e200000/bt_pins
Requires=dev-serial1.device
After=dev-serial1.device

[Service]
Type=forking
ExecStart=/usr/bin/btuart

[Install]
WantedBy=multi-user.target

btuart 使用 hciattach 工具,在串口 /dev/ttyAMA0 上发送 HCI 命令。对端(BCM43438)会回应,根据回应的内容触发加载相应的驱动,并加载 firmware 到 BCM43438 中的蓝牙模块中:

...
9月 24 03:42:28 raspberrypi btuart[297]: bcm43xx_init
9月 24 03:42:28 raspberrypi btuart[297]: Flash firmware /lib/firmware/brcm/BCM4345C0.hcd
9月 24 03:42:28 raspberrypi btuart[297]: Set BDADDR UART: b8:27:eb:eb:f5:3d
9月 24 03:42:28 raspberrypi btuart[297]: Set Controller UART speed to 3000000 bit/s
...

要了解这里的详细过程,得读一读 hciattach 的源代码。

「翻译」:LoRa/LoRaWAN 入门

原文:Your Primer for LoRa/LoRaWAN


由 Cisco、Actility、IBM、Kerlink、Orange 和 SK Telecom 公司支持的 LPWAN 技术有什么特别之处?

LoRa+LoRaWAN=LPWAN

LPWAN 技术的通讯系统有几部分组成。物理层,在硬件层面定义了数据传输的电气规范。数据链路层负责检测物理层的变化,并通过协议发送数据。

LoRa 常误用于指代 LPWAN 通讯系统。严格来说,LoRa 是 Semtech 公司的专利。 SX1272 和 SX1276 芯片的物理层使用了一种称之为扩频调制的技术。

LoRaWAN 是一个定义 LPWAN 通讯协议(基于 LoRa 芯片)的开放标准。LoRaWAN 定义数据链路层的媒体访问控制(MAC),由 LoRa 联盟维护。LoRa 和 LoRaWAN 的这种区别很重要,有其它的公司如 Link Labs 在 LoRa 芯片上使用了私有的 MAC 层实现,Link Lab 称之为 Symphony Link。

总之:

  • LoRa = PHY Layer
  • LoRaWAN 或 Symphony Link = MAC Layer
  • LoRa + Symphony Link = LPWAN 技术栈

image

星形网络

许多网页把 LoRaWAN 规类为星型或星型对星型拓扑结构,并表示它比网状结构更适合于低功耗和远距离传输。

image

星型网络意味着:消息由网关中继到中心服务器。每个节点把数据发给多个网关,然后网关把数据转发给网络服务器,由服务器执行冗余检查、安全校验、消息调度等工作。

这种设计意味着:

  • 跟踪。末端节点把数据发给多个网关,网关和网关之间不需要通讯。这使得移动的末端节点更容易跟踪。
  • 公共网络。中心服务器可以减少冲突,意味着对于公共网络 LoRaWAN 可能不如私有部署的网络。

image

三种设备类型

LoRaWAN 有三种类型的设备适用于不同距离的应用场景。

image

商业模式

SigFox 和 LoRa/LoRaWAN 有着完全不同的商业模式。SigFox 不是开放协议,但允许厂商(STMicroelectronic, Texas Instruments, Atmel)生产兼容 SigFox 的无线产品。SigFox 的重点是部署自己的网络,提供廉价硬件,并将网络作为服务销售。

而 LoRa/LoRaWAN 是一个开放协议,但用户必须使用 Semtech 的 LoRa 芯片。开放标准使得它很灵活,可定制(如 Symphony Link),但开发速度较慢。

两者都宣称它们的网络覆盖超过 100 个美国城市。随着蜂窝物联网在 2017 年的商业化,哪种商业模式最终会获胜,拭目以待。

☠️stm32 - 串口打印

调试单片机,最习惯的方式还是预留一个串口做打印。这也是每次项目最开始要做的事情。

串口直接输出

STM32CubeMX 配置好 UART 的参数:

image

然后直接使用 UART 发送函数即可在串口上看到输出了:

HAL_UART_Transmit(&huart1, (uint8_t *)"hello\r\n", 7, 1);

printf 输出

有时候需要打印一些变量的值,希望有最基本的格式化输出。

可以使用工具链中的 libc 里自带的 printf,但编译结果的尺寸会变大很多。

这里使用 @mpalandprintf 项目,对于代码尺寸的影响是:

* 使用其中最基础的打印功能,代码尺寸增加 1.9KB
* 增加 `%f` 支持,代码尺寸再增加 3.1KB
* 增加 `%llu or %p` 支持,代码尺寸再增加 1.2KB

另外,使用时发现一件奇怪的事情:

printf("hello, world\r\n");  // 无法打印出来

printf("%s", "hello world\r\n"); // 可以打印出来。

于是我加了连续两行打印看看:

    printf("hello, world\r\n");
    printf("%s", "sam");

发现只能打印出 sam

arm-none-eabi-objdump -d main.o 反汇编一看:

原来第一条打印被优化成了 puts,怪不得打印不出来。参见 About GCC printf optimization

解决这个问题,增加一个编译参数:

CFLAGS += -ffreestanding

参见:Guide to Bare Metal Programming with GCC

查看编译结果中每个函数的尺寸,从小到大排列:

arm-none-eabi-nm -a --demangle --print-size --size-sort -t d build/light2.elf

第二列显示的是每个函数的尺寸(十进制),计算总大小:

arm-none-eabi-nm -a --demangle --print-size --size-sort -t d build/light2.elf | awk '{ sum+=$2} END {print sum}'

中断打印

HAL_UART_Transmit(&huart1, (uint8_t *)"hello\r\n", 7, 1);

这一句是阻塞的,直到 UART 把数据发送完才会返回。以 115200 8n1 的配置来计算,每发送一个 bit 需要 1/115200 s,每发送一个字符要加一个停止位,所以每发送一个字符约耗时 9/115200 = 78us 。

以上面一句 "hello\r\n" 发送完耗时 546us。一旦打印频繁,这个消耗还是非常大。

ring buffer

UART RECEIVE BUFFERING

esp8266 - 固件烧写 for nodemcu

安装烧录工具:

pip install esptool

查看 Flash size :

    $ esptool.py -p /dev/cu.SLAB_USBtoUART flash_id

    // 下面是我的 nodemcu 上得到的结果
    esptool.py v2.3.1
    Connecting........_
    Detecting chip type... ESP8266
    Chip is ESP8266EX
    Features: WiFi
    Uploading stub...
    Running stub...
    Stub running...
    Manufacturer: 20
    Device: 4016
    Detected flash size: 4MB
    Hard resetting via RTS pin...

FLASH 完整擦除:

esptool.py --port /dev/cu.SLAB_USBtoUART --baud 921600 erase_flash

烧录地址:


烧录 FOTA :

esptool.py --port /dev/cu.SLAB_USBtoUART --baud 921600 write_flash \
    0x00000 bin/boot_v1.6.bin \
    0x01000 bin/at/512+512/user1.1024.new.2.bin \
    0x3fb000 bin/blank.bin \
    0x3fc000 bin/esp_init_data_default_v08.bin

下面是烧录时的打印信息

esptool.py v2.3.1
Connecting........_
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0040
Compressed 3856 bytes to 2763...
Wrote 3856 bytes (2763 compressed) at 0x00000000 in 0.0 seconds (effective 670.7 kbit/s)...
Hash of data verified.
Compressed 407796 bytes to 293037...
Wrote 407796 bytes (293037 compressed) at 0x00001000 in 4.1 seconds (effective 789.4 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x003fb000 in 0.0 seconds (effective 2145.2 kbit/s)...
Hash of data verified.
Compressed 128 bytes to 75...
Wrote 128 bytes (75 compressed) at 0x003fc000 in 0.0 seconds (effective 64.1 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

烧完之后,就可以通过串口用 AT 指令交互了:

AT+CWMODE=3

AT+CWJAP="SSID","PASSWORD"

AT+CIFSR

AT+CIPSTART="TCP","URL",PORT

AT+CIPSEND=4

A3080+STM32 模块

同事买的一个 光流传感器模块

image

image

调试和数据输出的引脚都接出来了。只是没有电路图。

引脚,从上到下:

- GND
- 5V
- 3.3V
- TX
- RX
- DIO
- CLK
- NRST
- LED
- GND

模块说明:

CJMCU-3080 光流传感器 XY轴 移动传感器 水平移动

ADNS-3080+高速STM32单片机 镜头采用200万像素

通信方式:串口 TTL转USB接口输出电脑。移动传感器, 可直接读取数据,也可接任意单片机读取数据。

模块电源:3-5V

连接好以后,打开串口助手,设置波特率为115200,可
以得到X 和Y 移动距离的数据。
一帧的数据格式如下:
Byte1 X 的高8 位
Byte2 X 的低8 位
Byte3 Y 的高8 位
Byte4 Y 的低8 位
Byte5 结束位 0x53
Byte6 结束位 0x53
 

其中X 和Y 为有符号16 位数。
注意: 收到货,打开镜头座,去掉保护膜,测试环境光线要充足,测试面带纹理为佳。无程序和原理图提供

STM8 各系列简介

整理电脑里的资料,发现以前做 STM8 时画的一个 mindnode 导图,用于简单了解 STM8 各系列的市场定位和用途。删了可惜,归档又不知道如何分类。先记在这里。

stm8

WS2812B 灯带

WS2812B 是一种 LED 型号,控制电路与发光部件集成于一体,5050 封装(5mm*5mm*1.6mm)。

数据手册

它是 WorldSemi (华彩威) 公司 的产品。这是一家总部位于东莞的公司,2007年成立。该公司最重要的产品就是 WS28xx 系列,基于使用带有串行数据传输的RGB控制器,这允许独立控制内部 RGB 二级管的亮度和颜色,并且可以灵活的级联。

先来看一个视频介绍:

Programmable LED WS2812 tape

WS2812B 控制时序

官方数据手册中的描述:

image

网上找到另一份 数据手册 中的描述:

image

典型时间为 0.4/0.85 us,一个周期为 1.25us,频率 800KHz。

一条 WS2812B 级联组成的灯带,控制只需要一根数据线。每颗 WS2812B 用 24bit 控制 GRB(注意顺序)。

image

  • 输入的第 1 个 bit,控制的是第一颗灯的 G7
  • 当第一颗灯收到 24bit 数据就将数据锁存起来,后续收到的数据通过 DOUT 输出(给下一颗 LED)
  • 第二颗灯收到第二个 24bit 然后锁存,如果有更多数据到来,则继续通过 DOUT 输出
  • 如此往复

WS2812B 与 WS2812 的区别

WS2812 VS WS2812B

  1. 做了电源保护,电源接反也不会烧坏
  2. 单颗引脚由 6pin 减少为 4pin
  3. 更亮、一致性更好
  4. 结构优化,控制电路与发光件分离,散热更好

WS2812B 灯带连接

image

image

image

image

stm8s 控制 WS2812B 灯带

使用 STM8S 的 SPI 来输出波型。

  • HSE = 8MHz
  • SPI 采用 2 分频,spi clk = 8M/2 = 4MHz
  • SPI 发送一个 bit 的时间是 1/4M=250ns

根据 WS2812B 时序要求,用 SPI 的 4 个bit 去表示 WS2812B 的一个bit,TH 和 TL 的时间分别为 250ns 和 750ns,符合 WS2812B 的要求。

对 RGB 数据按 bit 做转换:0 - 1110(0xE), 1 - 1000(0x8)。

转换函数为:

void ws2812_set_pixel_color(int nr, uint8_t r, uint8_t g, uint8_t b)
{
    if (nr < LED_NR) {
        rgb_buffer[nr*12+0]  = ((g & 0x80) ? 0xE0 : 0x80) | ((g & 0x40) ? 0x0E : 0x08);
        rgb_buffer[nr*12+1]  = ((g & 0x20) ? 0xE0 : 0x80) | ((g & 0x10) ? 0x0E : 0x08);
        rgb_buffer[nr*12+2]  = ((g & 0x08) ? 0xE0 : 0x80) | ((g & 0x04) ? 0x0E : 0x08);
        rgb_buffer[nr*12+3]  = ((g & 0x02) ? 0xE0 : 0x80) | ((g & 0x01) ? 0x0E : 0x08);
        rgb_buffer[nr*12+4]  = ((r & 0x80) ? 0xE0 : 0x80) | ((r & 0x40) ? 0x0E : 0x08);
        rgb_buffer[nr*12+5]  = ((r & 0x20) ? 0xE0 : 0x80) | ((r & 0x10) ? 0x0E : 0x08);
        rgb_buffer[nr*12+6]  = ((r & 0x08) ? 0xE0 : 0x80) | ((r & 0x04) ? 0x0E : 0x08);
        rgb_buffer[nr*12+7]  = ((r & 0x02) ? 0xE0 : 0x80) | ((r & 0x01) ? 0x0E : 0x08);
        rgb_buffer[nr*12+8]  = ((b & 0x80) ? 0xE0 : 0x80) | ((b & 0x40) ? 0x0E : 0x08);
        rgb_buffer[nr*12+9]  = ((b & 0x20) ? 0xE0 : 0x80) | ((b & 0x10) ? 0x0E : 0x08);
        rgb_buffer[nr*12+10] = ((b & 0x08) ? 0xE0 : 0x80) | ((b & 0x04) ? 0x0E : 0x08);
        rgb_buffer[nr*12+11] = ((b & 0x02) ? 0xE0 : 0x80) | ((b & 0x01) ? 0x0E : 0x08);
    }
}

另外需要注意的是 SPI 的 CPHA 必须配置为 CPHA=1(SPI_CLOCKPHASE_2EDGE)。用示波器抓到 CPHA=0 时的波型不符合要求。

image

从示波器可以看出发送 2 个字节之间约有 1.8us 的空闲。猜测应该是循环之间的指令执行时间。1.8us 大概 14 条指令,C 实现:

void ws2812_show(void)
{
    /* nr led needs nr*3 bytes == nr*3*8 bits
     * 1 ws2812 bit use 4 spi bit.
     * total bits = nr*3*8*4 bits == nr*3*4 bytes
     */
    int i;
    for (i = 0; i < sizeof(rgb_buffer); i++) {
        SPI_SendData(rgb_buffer[i]);
    }
    // reset 250*8=2us (> 280us)
    SPI_SendData(0x00);
    delay_ms(1);
}

跑在 8MHz 的 MCU,单条指令执行时间 1/8MHz=0.125us,14 条执令花在了上面实现中有循环、取数、函数调用(此为猜测)。

stm32 控制 WS2812B 灯带

django a blog

按照 Django Girls Tutorial 教程走了一遍。整个教程从零开始一步一步搭建出一个简单的博客系统。

这个博客系统主要功能有:

  • 首页,显示所有文章列表,按照发布日期从最近开始排序
  • 文章页面,在首页点击一个文章标题就跳到这个文章的页面,只显示这篇文章的标题和内容等信息
  • 新增页面,博客导航栏有一个新增按钮,点击它进入添加文章页面
  • 文章编辑,在文章页面有编辑按钮,可以点击进入该文章的编辑状态
  • 管理页面,使用 django 的 admin 功能,可以添加、删除文章

最后博客的样子:

这里记录整个系统成长起来的过程。

目录

📌 云主机:nginx https 配置

云主机:nginx https 配置

接上一篇 云主机:用户登陆配置

配置目标:

  • https 证书,证书自动更新
  • nginx 作反向代理,连接 nodejs 后端程序

安装 nginx

使用 yum info nginx 查看到仓库源里的 nginx 版本是 1.12.2,最新稳定版。就安装这一个。

$ sudo yum install -y nginx

去阿里云的控制台,将这个主机实例的 80 端口和 433 端口打开。

使能 nginx 服务,启动:

$ sudo systemctl enable nginx
$ sudo systemctl start nginx

此时,在我们本机的浏览器就可以访问主机的公网 ip 地址了。得到的结果是 nginx 的欢迎页:

证明 nginx 安装成功。

为域名生成证书

我们希望全站走 HTTPS。使用 Let’s Encrypt 。有一套工具放在 [github][https://github.com/certbot/certbot] 上。

我们先在云主机上安装 git:

$ sudo yum install -y git

下载 letencrypt 工具:

$ sudo git clone --depth=1 https://github.com/certbot/certbot.git /opt/letsencrypt

先停止 nginx 服务,再生成证书:

$ sudo systemctl stop nginx
$ cd /opt/letsencrypt/
$ ./certbot-auto certonly --standalone

它会安装 python 环境和一些信赖包。有三个交互操作:

  1. Is this ok [y/d/N]: y 输入 y 确认安装
  2. Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): 输入自己的邮箱地址
  3. (A)gree/(C)ancel: 输入 A,同意
  4. (Y)es/(N)o: 输入 Y 确认
  5. Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): 输入要部署 HTTPS 的域名

最后得到结果:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/dev.fmtech.me/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/dev.fmtech.me/privkey.pem
   Your cert will expire on 2018-06-21. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

生成的证书存放在 /etc/letsencrypt/live/dev.fmtech.me/ 目录下。

SSL 配置文件

先生成一个 dhparam.pem 文件,用于 HTTPS 中的密钥交换。

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

这一步比较耗时。

创建 SSL 配置文件,其中会指定 dhparam.pem 的位置。

$ sudo mkdir -p /etc/nginx/snippets
$ sudo vim /etc/nginx/snippets/ssl-params.conf

在 /etc/nginx/snippets/ssl-params.conf 文件中添加如下内容:

# See https://cipherli.st/ for details on this configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 119.29.29.29 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

# Add our strong Diffie-Hellman group
ssl_dhparam /etc/ssl/certs/dhparam.pem;

nginx 配置 HTTPS

注释掉 /etc/nginx/nginx.conf 中的 80 端口默认配置。

/etc/nginx/conf.d/ 创建我们的配置:

$ sudo vim /etc/nginx/conf.d/default.conf

内容如下:

# HTTP — redirect all traffic to HTTPS
server {
    listen 80;
    listen [::]:80 default_server ipv6only=on;
    return 301 https://$host$request_uri;
}

# HTTPS — proxy all requests to the Node app
server {
    # Enable HTTP/2
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name dev.fmtech.me;
    root /usr/share/nginx/html;

    # Use the Let’s Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/dev.fmtech.me/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dev.fmtech.me/privkey.pem;

    # Include the SSL configuration from cipherli.st
    include snippets/ssl-params.conf;

    location / {
    }
    error_page 404 /404.html;
    location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }
}

这个配置的第一段,是把所有 HTTP 请求都转发给同一域名的 HTTPS。

第二段处理 HTTPS 请求。测试一下配置文件是否正确:

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful  

重启 nginx 服务:

sudo systemctl reload nginx

在本地机器浏览器里访问:dev.fmtech.me,会自动跳转到 https://dev.fmtech.me/,说明配置成功。

ssllabs 里对本域名作个 SSL 安全测试。得到 A+ 则说明配置成功了。

证书自动更新

Let’s Encrypt 好在免费,但每个证书的有效其只有 90 天,快过期时执行下面的命令即可更新:

$ /opt/letsencrypt/certbot-auto renew

该命令会检查是否有必要更新证书。只有在快过期时才会真正执行更新。

使用 cron 工具来让这个检查工作定期自动执行,这里每周一凌晨一点执行一次,并于 5 分钟后重启 nginx:

$ sudo crontab -e

添加两行:

0 1 * * 1 /opt/letsencrypt/certbot-auto --no-self-upgrade renew --pre-hook "nginx -s quit" --post-hook "systemctl start nginx"

cron 的配置保存于 /var/spool/cron/root。

重启 crond 服务:

$ sudo systemctl reload crond

参考

jetson tx2 刷机

NVIDIA 为这套 jetson 开发板制定了一套系统,系统中配置好了机器学习的环境。通过刷机来把开发板上的软件升级到最新版本。

JetPack,也就是 NVIDIA JetPack SDK 的简称。这是 Jetson 硬件平台的系统开发环境,其中的内容参见 What's Included in JetPack?

  • Host 是我们的开发主机,是一台装了 Ubuntu 系统的 PC 机,在上面配置我们的开发环境
  • JetPack installer 是刷机工具,用于给 Jetson 硬件刷系统。也可用来升级 Host 上的 SDK

准备一台电脑,装好 Ubuntu。我有一个 vmware 里装了 Ubuntu 18.04,就拿这个系统来搭环境,熟悉开发步骤。

JetPack 页面 下载最新的 JetPack。

我的电脑里已经有一个 ubuntu 18.04 虚拟机,准备先用它来试着搭一下。在安装时出现下面的提示,点 Yes 之后安装界面出不来。只能使用 ubuntu 的 14.04 或 16.04 两个版本。

image

重新好安装 ubuntu 16.06,继续安装。这里我又踩了一个坑,系统安装时只分配了 10G 磁盘,步骤进行到一半就把磁盘用光了。无奈再重来一次,系统安装时分了 50G 磁盘。

image

image

image

image

image

到这一步要准备刷机了。

  1. 开发板 USB 接到我们的 Host,网口按上面的拓扑图接到跟电脑同一个路由器下。
  2. 接通电源,按住 REC 按键
  3. 短按 POWER 键开机
  4. 2s 后松开 REC 键

在 Host 里 lsusb 可以看到开发板:

image

image

安装到这里,刷机的第一步就完成了。这一步就是在开发板上安装了一个 ubuntu 操作系统。

这时开发板就开始重启,并最终进入 ubuntu 系统。此后不会再用到 Host 和开发板的 USB 连接了,后续完全靠网络来通讯。

此时 Host 在等待开发板重启完成,并能找到开发板的 IP,以便后续传数据到开发板的系统中。

这一步我遇到的坑是,开发板系统启动完成后,从有线网络 eth0 始终无法获取到 IP。导致 Host 端会等待超时。解决此问题的办法是,开发板 ubuntu 启动完成后,手动连接 wifi。只要网络连通,Host 就立即找到了开发板,后续安装过程也就一气呵成。

image

image

参考资料

📌 云主机:nodejs 环境配置

云主机:nodejs 环境配置

接上一篇 云主机:用户登陆配置

配置目标:

  • nodejs 环境
  • pm2 监控
  • 系统重启后服务能自动启动

安装 nodejs

使用 nvm 安装。nvm 可以管理 nodejs 的版本。

安装 nvm

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash

nvm 刚刚安装,需要重新导入环境变量才可以使用:

$ source ~/.bashrc

安装 nodejs 最新 lts 版本:

$ nvm install --lts

查看安装的 node 版本:

$ node --version
v8.10.0

配置淘宝的 npm 源:

$ npm config set registry https://registry.npm.taobao.org

查看当前的源:

$ npm config get registry
https://registry.npm.taobao.org/

全局安装 pm2:

$ npm i -g pm2

后续在本地使用 pm2 deploy 来部署服务。

全局安装 nodemon:

$ npm i -g nodemon

安装 mongodb

参考 Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux

创建 repo:

sudo vim /etc/yum.repos.d/mongodb-org-3.6.repo

添加内容:

[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

安装:

$ sudo yum install -y mongodb-org

使能并启动 mongod 服务:

$ sudo systemctl enable mongod
$ sudo systemctl start mongod

部署

使用 pm2 deploy

首先,需要云主机生成密钥对,把公钥放到 github 仓库中的 Settings -> Deploy keys 里面。这样云主机就有权限从 github 仓库拉取代码。

$ ssh-keygen

$ cat ~/.ssh/id_rsa.pub

在本机使用 pm2 deploy:

 pm2 deploy production update
 
 pm2 deploy production setup

开机自动启动

$ pm2 startup
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/sam/.nvm/versions/node/v8.10.0/bin /home/sam/.nvm/versions/node/v8.10.0/lib/node_modules/pm2/bin/pm2 startup systemd -u sam --hp /home/sam

在终端执行提示中的命令:

$ sudo env PATH=$PATH:/home/sam/.nvm/versions/node/v8.10.0/bin /home/sam/.nvm/versions/node/v8.10.0/lib/node_modules/pm2/bin/pm2 startup systemd -u sam --hp /home/sam

最终会生成 pm2-sam 服务:/etc/systemd/system/pm2-sam.service

最后,执行:

$ pm2 save

pm2 会把当前环境中 pm2 管理的程序记录到 ~/.pm2/dump.pm2 文件中。

开机时,pm2-sam 服务会检查 dump.pm2 文件内容,并启动其中描述的程序。

📌 云主机:用户登陆配置

云主机:用户登陆配置

刚买了一台阿里云主机,操作系统: CentOS 7.4 64位。

配置目标:

  • 以普通用户登陆和操作,禁止 root 登陆
  • 登陆使用密钥校验,不需要每次都输入密码

普通用户

下文中用户名都以 sam 为例。

创建用户 sam,并设置密码:

adduser sam
passwd sam

查看用户信息:

# id sam
uid=1000(sam) gid=1000(sam) 组=1000(sam)

将其添加到 sudo 组里,但是 CentOS 没有 sudo 组。加到 wheel 组里:

usermod -aG wheel sam

再次查看 sam 用户信息:

# id sam
uid=1000(sam) gid=1000(sam) 组=1000(sam),10(wheel)

切换到 sam 用户,测试 sudo 权限:

su - sam
sudo ls /

登陆配置

在 sam 用户下,创建文件 ~/.ssh/authorized_keys,放置我们自己电脑上的公钥,以后登陆就不需要输入密码了:

$ mkdir -p ~/.ssh
$ vim ~/.ssh/authorized_keys

填入公钥之后,变更文件和文件夹的权限:

$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys

ssh 禁止密码登陆和 root 用户登陆:

sudo vim /etc/ssh/sshd_config

找到 `PasswordAuthentication`,把它的值设置成 no
找到 `PermitRootLogin`,把它的值设置成 no

PermitRootLogin yes
PasswordAuthentication no

重启 sshd 服务:

$ sudo systemctl reload sshd

退出到本机上,尝试以 root 登陆会得到报错:

Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

在其它机器上尝试以 sam 用户和密码登陆,也会得到上面这句报错。证明配置成功。

SPI Flash 操作

在 driver 上把访问 SPI Flash 的行为抽象成初始化+三个操作:

int spi_flash_init(struct spi_flash *flash);

int spi_flash_read(struct spi_flash *flash, off_t from, void *buf, size_t len);

int spi_flash_write(struct spi_flash *flash, off_t to, const void *buf, size_t len);

int spi_flash_erase(struct spi_flash *flash, off_t addr, size_t len);

擦除

单位 名称 大小 擦除指令
page 1page = 256 Bytes ~~
sector 扇区 1 sector = 16 pages = 4KB 0x20
32KB block 32KB 块 1 block = 128 pages = 32KB 0x52
64KB block 64KB 块 1 block = 256 pages = 64KB 0xD8
Chip ~~ ~~ 0xC7

擦除有四个粒度:

  • sector, 4KB
  • 32KB block
  • 64KB block
  • chip

驱动中只使用 sector 擦除就够了。

执行一个 sector 擦除操作:

  1. 写使能
  2. 拉低 CS
  3. 发送擦除指令 0x20
  4. 发送擦除地址(3 个字节,高位先发送)
  5. 拉高 CS
  6. 等待 chip 的 BUSY 清零
  7. 检查待擦除的长度是否到了,如果没到,地址增加 4K,跳到第2步继续

如果传入的地址没有 sector 对齐,没关系,还是会擦除目标地址所在的那个 sector。

SPI Flash 的写操作也称为编程。Page Program 指令每次可以写 1~256 字节。写操作流程:

  1. 写使能
  2. 拉低 CS
  3. 发送写指令 0x02
  4. 发送地址(3 个字节,高位先发送)
  5. 发送要写的数据,直到发送完成
  6. 拉高 CS

写完成时,把 CS 拉高,Flash 就知道要写多少个字节了。

如果要写一个完整的页,则传入的地址必须页对齐(地址最后 8 位为 0)。

一次写操作,Flash 端会从接收的地址开始执行写操作,写完一个字节则地址加 1。如果地址增加超过页末尾,地址会回滚到页起始位置然后继续执行写操作。

读是最简单的:

  1. 拉低 CS
  2. 发送读指令:0x03
  3. 发送读地址(3 个字节,高位先发送)
  4. 发送 dummy 数据,从 MISO 读入数据,直到读到指定数量字节数
  5. 拉高 CS

Flash 在收到读指令、确定好起始地址之后,会从 MISO 发出数据。发完一个字节,地址加 1。读操作的地址会一直自增,不会回滚。所以一个读指令就可以把整个 chip 的数据读出来。

另外需要注意的是,读操作之前,需要保证芯片不在 BUSY 状态才行。在驱动中,我在写操作结束前来保证这一点。每次写操作的最后都必須等待 BUSY 为 0 来确保写操作执行完全。这样下次读操作就不需要先检查 BUSY 状态了。

UART 波形分析

UART 波形分析

配置 115200 8n1

  • 每个 bit 持续时间为 1s/115200=8.68us
  • 起始位:1位,值为 0
  • 数据位:8位
  • 奇偶校验位:无
  • 停止位:1位,值为 1
  • 空闲状态:高电平 1

image

开机的一句打印通过串口输出:

printf("hello\r\n");
  • 输出每个字节需要 10 个字节:1 + 8 + 0 + 1
  • 每个停止位后面是空闲状态(高电平)
  • 按每帧来数,找启始位 0

波形分析

先看整体波型

image

放大看:

image

图中一格是 40us,一格里有 5 个标线,大约能有 5 个 bit

image

如图,数出图中的帧。先找 START 位,数 10 个,用蓝色标出 STOP 位。

数出数据:

  • 0000101101 -> 0001,0110 -> 0x68 -> 'h'
  • 0101001101 -> 1010,0110 -> 0x65 -> 'e'
  • 0001101101 -> 0011,0110 -> 0x6c -> 'l'
  • 0001101101 -> 0011,0110 -> 0x6c -> 'l'
  • 0111101101 -> 1111,0110 -> 0x6f -> 'o'

jetson tx2 打包刷机 image

前面用过 Jetpack 官方说明进行 jetson tx2 刷机。但这个步骤太长了,中间也要联网下载机器学习相关的组件。我刷好一块板子后,在上面部署了一个服务。

但还有十几块板子要做同样的工作。最好的方式是能把部署好的板子里的系统打包成一个 img,然后直接刷到其它板子里。

jetpack 里已经提供了相关的工具。网上找到教程:

板子按住 REC 键开机,进入 Recovery 模式。用 USB 连接到电脑,执行下面命令打包出 img,这一步很耗时。

sudo ./flash.sh -r -k APP -G backup.img jetson-tx2 mmcblk0p1

中途又经历了一次失败,因为打包出来的 image 很大,还没等打包完成磁盘就占满了。第一次刷机的时候就因为磁盘不够 jetpack 用的,重装了一次分了 50G。结果到这一步还不够。又划了 50 G 给 ubuntu,用 gparted 格好。再把 backup.img 打包到该路径下。

sudo ./flash.sh -r -k APP -G /media/sam/201b1104-6d81-4252-ae4a-960cf80b70e5/backup.img jetson-tx2 mmcblk0p1

image

最后tg生成 29G 的 backup.img.raw,相当于把板子上 32G 的 eMMC 内容全部复制上来了。再转成 Sparse image,结果也有 9G 。

把 backup.img 复制到 bootloader/system.img

cp /media/sam/201b1104-6d81-4252-ae4a-960cf80b70e5/backup.img bootloader/system.img

烧写新板子

sudo ./flash.sh -r -k APP jetson-tx2 mmcblk0p1

烧完之后启动,HDMI 不正常,显示器无法正常显示图形界面。

网上查了一大通资料后,发现 -k APP 其实只刷了 APP 这个分区。在 bootloader/flash.xml 里可以找到所有分区的信息。它里面远不止一个分区。

再刷一遍,刷机时不指定分区:

sudo ./flash.sh -r jetson-tx2 mmcblk0p1

记录了这两次刷机的 log:

烧写一台花费的时间:

real	17m28.794s
user	0m14.368s
sys	0m25.751s

WiFi 探针

这里记录了在 jetson tx2 开发套件上实现 WiFi 探针功能踩过的一些坑。

最开始想使用 tx2 板载网卡,但发现它不支持 monitor 模式。

然后在淘宝选了一款 esp8266 方案的 WiFi 探针,但受限于整套方案上网条件的限制(只能有一台主机作为出口),这个探针的扫描结果无法上传。

最后还是选了一款支持 802.11ac 的 USB WiFi 网卡,编译驱动,使用 airodump-ng 来抓包,再解析、上传数据。

整个过程记录为几篇:

  1. Ubuntu 下用 wireshark 分析 802.11 帧结构
  2. WiFi 探针原理
  3. 一个 esp8266 方案的 WiFi 探针
  4. 用 USB 网卡做 WiFi 探针
  5. 另一个 ESP8266 方案的 WiFi 探针

整个过程用到了两个 USB 无线网卡:水星 MW150US 和 TP-LINK TL-WDN6200 。

为什么会选这两款?因为办公室里就有这两款 USB 网卡,直接拿来用,算是看见什么吃什么。

ESP8266 模块 ESP-01

之前买的 ESP-01

购买地址

image

image

~ ~ ~ ~
8 GND 6 GPIO2 4 GPIO0 2 RX
7 TX 5 CH_PD 3 RST 1 VCC

8 个 pin 引出来:

  1. VCC, Voltage (+ 3.3 V (upto 3.6 V it can handle))
  2. RX, Receive data bit X
  3. RST, REST (reset, must be pulled to 3.3v)
  4. GPIO 0, General Purpose Input-Output No. 0
  5. CH_PD, Chip Power Down (enable/power down, must be pulled to 3.3v directly or via resistor)
  6. GPIO 2, General Purpose Input-Output No. 2
  7. TX, Transmit data bit X
  8. GND, Ground (0 V)

工作时,将 RST、CH_PD 都拉高。

音叉式DC接头

DC 接头在日常生活中很常见,笔记本电脑的电源接口、有的路由器或电视机顶盒的电源接头。

DC 是直流 (Direct Current) 的意思,对应交流 AC (Alternating Current)。

DC 公头:

DC 母座:

DC 接头的规格有:

DC 接头的规格

公头有两种:直插DC公头、音叉DC公头。

直插DC头,内壁为一个光滑的金属圆柱体。

音叉DC公头的意思是其内部带有类似音叉形状的弹片,插入后弹片会卡紧母头,保证接触稳固。

家庭网络设备升级 2018

前段时间家里的一个路由器坏了(通电后一直重启),于是借此契机升级了一下家庭的网络设备。

家里之前的网络方案:

                                   有线连接
光纤 ~~ 光猫 ~~ (WAN) 路由器1 (LAN) ~~~~~~~~~~ (LAN) 路由器2
                       \                             \
                        ~~ 2.4G + 5G WiFi             ~~ 5G WiFi (低功率)
  • 光纤的入口在客厅的电视墙,所以光猫和路由器1 都在这个位置
  • 路由器1 有 2.4G 和 5G WiFi,作为家庭主要 WiFi 覆盖
  • 书房离客厅距离较远,中间隔了许多堵墙。还好开发商在书房和客厅预留了网线(测试可以跑千兆),于是在书房增加路由器2,有线连接到路由器1的 LAN 口
  • 路由器1 过来的网线接在路由器2的 LAN 口上,路由器2 关闭 DHCP 服务,作为桥接 AP。关闭 2.4G WiFi,打开 5G WiFi,信号调到较弱(只管书房的这十来平米就够了)

顺便说一下:

  • 路由器1 是 极路由2,MT7620A + MT7610 方案
  • 路由器2 是小米路由 mini,自己编译了一个 padavan(网上俗称老毛子)的固件放在里面跑
  • 宽带用的移动 100M。月租 58 元,还送 IPTV (当时主要是想要 IPTV,网络电视太卡)

此次升级的重点是:

  1. 全千兆(上面用的极路由2和小米路由mini都是百兆)
  2. 存储高清电影,局域网播放(电视是小米电视4,视频解码可放在电视端)

路由器选型

主要还是按主芯片方案来选。因为主芯片和其配套的 WiFi 模块、固件,都由芯片原厂提供参考方案。路由器厂家的变动不会很大,顶多会在LNA、PA 等功率放大器上用点料。

  • MT7621A 方案

应该是千兆入门方案吧。CPU: MIPS 1004Kc @880MHz,双核四线程。市面上的机型也比较多:小米路由 pro、newifi3、极路由4、斐讯k2p 等。售价基本都在 500 以内。

  • 博通方案

印象中博通方案的路由器,里面都有一块巨大的散热片。网上也普遍反映博通的路由器发热量大。所以我就直接 pass 掉了。

目前比较高端的应该是 BCM4709 的方案了,ARM Cortex-A9 双核 1.4G。比较流行的机型有 Asus 的 AC88U。

  • 高通方案

IPQ8064:ARMv7-A 1.4GHz Quad Core,28nm 工艺(跟 iPhone5s 的CPU一个制程)。常见的机型有:小米路由器 HD、Google OnHub、Netgear R7500。

IPQ8065:ARMv7-A 1.7GHz Quad Core。是 IPQ8064 的超频版本。常见机型有:Netgear R7800。

最后选择了 Netgear R7800。上到千元级别的路由器,配置和功能都是顶级的,相差不大。选择它的主要原因还是出于对高通方案的好感,对 Netgear 大厂的信赖。

还有就是高通方案的开源支持比较好,openwrt 已经有 R7800 固件下载。。

贴一下 R7800 我关心的参数:

- Memory: 128MB flash (NAND) and 512MB RAM (DDR3)
- USB 3.0 x 2 
- eSATA x 1
- 1xWAN, 4xLAN, Speed: 10/100/1000

实物到手拆封后也是被惊到,体积大、用料足、做工好,一眼看上去很贵的感觉。

懒的拍了,找了一张网上的图(出处):

image

R7800 无线功率设置为 100%,地区切换到美区(实测美区信号比**要强)。在主卧能收到稳定的 2.4G 信号(两堵墙,5G 还是不行),信号基本稳定在 -55dB 左右,足够上网、看视频了。

电影存储、播放

一直希望家里有这么个东西,可以下载一些高清电影或电视剧放着。若某晚有心情了,就躺在沙发上,把客厅主灯调成观影模式,享受一下视觉体验。

之前也仔细看了一下 NAS 解决方案。但除了看高清电影,其它功能我是真的真的不需要啊。查了一圈,NAS 除了存储之外,其它功能也基本就是鸡肋。为了存储而单独上一台 NAS 我觉得有点多了。使用路由器+硬盘的方式,是比较轻量的解决方案。

R7800 上面有一个 ESATA 接口,可以直接接硬盘。但考虑到硬盘还是要外部供电,得上个硬盘盒。而市面上的硬盘盒又基本都是 USB 接口的。最后选择了机械硬盘+硬盘盒+USB3.0。

硬盘盒单独 12V 供电,USB 3.0 连接到 RS7800 上,速度足够。硬盘盒带自动休眠功能,如果 30 分钟没有读写硬盘,硬盘会进入休眠。再次读写时会自动唤醒。

R7800 有 samba 和 DLNA 服务,可以把硬盘作为共享盘共享给局域网的其它机器,把硬盘上的媒体文件通过 DLNA 让其它支持的设备发现和访问。其实还有 http 和 ftp 功能,不过我没用到。

拓扑图:

12V供电 ~~~
           \      USB3.0
机械硬盘 ~~ 硬盘盒 ~~~~~~~~~ RS7800 ~~ Samba 共享盘 ~~ 家庭局域网(电视、手机、电脑)

实现完这一套之后,在家里可以完成如下操作:

  1. 随时在电视上播放硬盘里的高清视频,这是我之前最大的诉求了
  2. 用手机也可以直接看硬盘里的视频。这意味着家庭多人都可以随时使用自己的手机看硬盘里的电影或照片,互不影响
  3. 手机上直接把视频和照片备份到共享盘里(用文件管理器之类的软件)

整套搭好之后,下载了一个 10G+ 的电影《出租车司机》。高清带来的通透感,让这一切折腾都值了。

费用

  • Netgear R7800:1000.00
  • 机械硬盘,希捷(SEAGATE)酷鱼系列 4TB:659.00
  • 硬盘盒,优越者 USB3.0 通用2.5/3.5寸硬盘盒:65.00

总计:1724 元。

这里日一下京东。当时 R7800 价格是 1399,搞秒杀 999 又抢不到。逼得我上淘宝买。结果今天(6.6)上去京东一看 999,货管够。买的那款硬盘已经降到 629.00 ,价格波动基本就是耍猴呢。

这次升级完之后,总结下来还是有一些坑没有彻底填完。

1

书房的 WIFI 是桥接的 AP,意味着从客厅走到书房里需要 WIFI 切换。这一切如果自动完成倒还好,但偶尔客厅的 2.4G 弱信号会一直连着不断。这时候非得手动切换WiFi 才行。

如果路由器可以设置客户端的信号低于某个值则主动踢掉它,还算是比较好的解决办法。但在 R7800 里没有找到。

彻底解决这个问题还得用上 AC + 瘦AP 的 Mesh 方案。Mesh 网络支持无线漫游 (roaming)。瘦AP 只作用于物理层的无线射频收发,数据协议的交换完全由 AC 来完成。最终效果是:如果正在微信视频,从客厅走到书房,这次通讯不会断开(在 TCP/IP 层的连接信息不会断开或改变)。

而我现在使用的桥接AP 方案,即使手机上的 WiFi 热点能自动切换到书房的 SSID,底层的通讯还是会断开、重置一次(至于微信视频是否会断开,取决于微信内的音视频通讯是否会在断开后重新建立,如果有的话,那么对于用户来说这一切是透明的,通讯断开了一次也感受不到)。

相比于网件的 R7800 ,华硕的 AC88U 里带 AiMESH 功能。可以再搭配一个华硕的路由器组成 Mesh 网络。同是千元级别的路由器,这局华硕赢一分。

另外,网上查到 openwrt 也支持了 802.11r roaming。802.11r 是快速漫游协议。但我不想刷机了,毕竟刚买了一台 保时捷911 就拿去改装,不合适不合适。

2

另外一个没能填好的坑是电影下载。

R7800 里自带 BT 下载工具。但以现在的网络下载环境,不使用费付网盘的话,那下载速度还是感人。现在下载电影的方式是,连接共享盘作为电脑上的一个盘,然后使用网盘工具直接下载到共享盘里。

我一直在用百度网盘超级会员和腾讯微云的普通会员。在家里测试了一下(电脑连接到 5G WiFi):

  • 下载速度:微云可以达到 10M+,最高可到 16M。而百度网盘只有 2~3M 左右。有可能因为我在深圳的缘故
  • 离线下载:微云和百度网盘都有离线下载,提交一个磁力链接或种子,立刻下载好。实际使用下来,百度网盘的兼容性比较好。有的链接或种子微云找不到资源,但百度网盘能找到。微云的离线下载单次有文件个数限制,一次不能下载太多。同时使用百度网盘没有遇到这种限制
  • 价格:微云普通会员,每个月 10 块钱。百度只有超级会员才有一些比较实际的功能,一年 200+。比较之下,还是微云比较值

理想的下载方式是,找到一个磁力链接或种子,直接提交给路由器,它就能自动去下载。速度也不能太慢,现在的电影电视动则 几G+,如果是 几百K 的下载速度,真叫人捉急。真希望百度网盘或微云能去跟路由器厂家合作。或者开放接口,由社区开发这些功能跑在路由器上,也不是难事。

3

还有一个大坑是,调试网络的时候,发现小米电视4 的网口竟然是百兆的。我天!都 8102 年了。

image

参数页面里不直接写明,是怕被喷吧。就连最近刚发布的 小米电视4 75英寸 也一样。

git 源码安装

本来是 yum install -y git 就可以了。但是 CentOS 7 的 yum 源里 git 的版本还是太低了。

这导致在使用 pm2 deploy 时服务器的代码不能 update 到最新,参见 #2935。必须把 git 版本升到 1.9 以后。


源码安装 git

Installing from Source

$ sudo yum install -y autoconf perl-devel
$ sudo yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel

$ wget -c https://github.com/git/git/archive/v2.16.3.tar.gz
$ tar xf v2.16.3.tar.gz
$ cd git-2.16.3/
$ make configure
$ ./configure --prefix=/usr
$  make
$ sudo make install

浏览器自动刷新

写 HTML 时,每次都要手动点击浏览器刷新,非常麻烦。

vscode 里也有一个 html live preview 的插件,但插件里的显示效果与真实浏览器里的还是不一样。

应该是有相关工具解决这一问题。这里用 nodemon + osascript 也手动实现了一个。

原理是:nodemon 监控,一旦有文件修改则执行一个脚本。这个脚本让 safari 执行刷新操作。

效果是,编辑目录下的 html, css, js 文件,保存时则触发浏览器刷新。


nodemon 命令:

nodemon --exec "./reload-safari.scpt" -e ".html,.css,.js"

reload-safari.scpt

#!/usr/bin/osascript

tell application "Safari"
     repeat with i from 1 to the count of windows
          set this_win to (window i)
          repeat with j from 1 to the count of every tab in this_win    
               do JavaScript "window.location.reload()" in (tab j of window i)
          end repeat
     end repeat
end tell

需要打开 Safari 浏览器里的 「开发」-> 「允许 Apple 事件中的 Javascript」。

😈 Linux usb-serial 增加 idVendor:idProduct

同事手里有一个 USB 转串口小板。芯片上的 logo 是 cp210x,但实际插到电脑上看到的 idVender:idProduct 不在厂商的 id 列表里。

插入电脑后,lsub 查看到的 id 是:0b00 3070

想把这个 id 号加入到 cp210x 的 id 列表中,使用 cp210x 的驱动。

手动操作:

sudo modprobe cp210x # 手动加载驱动,否则没有 `/sys/bus/usb-serial/` 目录
sudo -sH # 切换到 root 
echo 0b00 3070 > /sys/bus/usb-serial/drivers/cp210x/new_id

再插到电脑,就可以看到 /dev/ttyUSB0 设备了。

以上整套操作写到 udev 规则中自动执行:

# /etc/udev/rules.d/99-usb-tty.rules
ACTION=="add", ATTRS{idVendor}=="0b00", ATTRS{idProduct}=="3070", RUN+="/sbin/modprobe cp210x" RUN+="/bin/sh -c 'echo 0b00 3070 > /sys/bus/usb-serial/drivers/cp210x/new_id'"

如果有一个导购机器人会是怎样

如果有一个导购机器人会是怎样

昨天听到「导购机器人」这个东西。未看到实物之前,先畅想一下它可能会有的功能。

快速路径规划

在大型超市购物,不知道要买的东西在哪。先寻问工作人员,了解大概方位之后,再去到该处小范围寻找。

导购机器人可预置超市地图和所有货品的位置信息。只需要导购机器人上搜索指定货物,即可规划好路线前往。

当用户要一次购买多个不同品类的货器时,可以规划出消费者在超市空间内的动线。

用户购买完毕后,引导用户至商场出口或停车场。

导购清单

有一个习惯是去超市前先写好购物清单,防止漏买。这个清单也可能是平时逐渐积累,周一到周五想起来的东西就记到购物清单上,到周末统一去一趟超市集中采购。

把这个购物清单提交给导购机器人,由导购机器人做路径规划,帮助用户更高效的采购。

购物车

购购机器人可以承载最大 40kg 的物品,可以取代购物车。

付款结算

现在有的超市收银处有用户自助收银的机器。导购机器人在完成导购工作之后,也可做自助收银的工作。

volatile 关键字使用一例

应该是第二次遇到这类问题了。上次没有看汇编代码,这次记录一下。

背景:

STM32 使用 SYSTICK,中断处理函数中增加计数器 jiffies。而在 delay_ms() 做一个循环延时。

static uint32_t jiffies = 0;

void isr_systick(void)
{
    jiffies++;
}

void delay_ms(uint32_t n)
{
    uint32_t start = jiffies;

    while (jiffies - start < n)
    {
    }
}

在主循环中对 LED 做 blinky 操作:

    while (1)
    {
        LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_11);
        delay_ms(300);
    }

但是发现会卡在 delay_ms() 中。最开始还以为中断没有触发,但把 Toggle 操作放到中断处理函数中,把 systick 时间拉长,LED 会闪烁。证明,中断处理函数被正确调用,问题就在 delay_ms() 中了。

反汇编一看:

08000374 <delay_ms>:
 8000374:	2800      	cmp	r0, #0
 8000376:	d1fd      	bne.n	8000374 <delay_ms>
 8000378:	4770      	bx	lr

汇编代码实际执行的是用参数 n 与 0 作比较,如果不相等则继续循环。这肯定不对。
编译器认为在函数中 jiffiesstart 相等,于是 delay_ms() 被优化成了:

void delay_ms(uint32_t n)
{
    while (0 < n)
    {
    }
}

这使得 delay_ms() 变成了一个死循环。

而加了 volatile 参数之后的反汇编代码:

08000374 <delay_ms>:
 8000374:	4b03      	ldr	r3, [pc, #12]	; (8000384 <delay_ms+0x10>)
 8000376:	681a      	ldr	r2, [r3, #0]
 8000378:	4b02      	ldr	r3, [pc, #8]	; (8000384 <delay_ms+0x10>)
 800037a:	681b      	ldr	r3, [r3, #0]
 800037c:	1a9b      	subs	r3, r3, r2
 800037e:	4283      	cmp	r3, r0
 8000380:	d3fa      	bcc.n	8000378 <delay_ms+0x4>
 8000382:	4770      	bx	lr
 8000384:	20000200 	.word	0x20000200

这就对了。

raspberry pi 3b+

image

硬件配置

  • Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-bit SoC @ 1.4GHz
  • 1GB LPDDR2 SDRAM
  • 2.4GHz and 5GHz IEEE 802.11.b/g/n/ac wireless LAN, Bluetooth 4.2, BLE
  • Gigabit Ethernet over USB 2.0 (maximum throughput 300 Mbps)
  • Extended 40-pin GPIO header
  • Full-size HDMI
  • 4 USB 2.0 ports
  • CSI camera port for connecting a Raspberry Pi camera
  • DSI display port for connecting a Raspberry Pi touchscreen display
  • 4-pole stereo output and composite video port
  • Micro SD port for loading your operating system and storing data
  • 5V/2.5A DC power input
  • Power-over-Ethernet (PoE) support (requires separate PoE HAT)

系统

  • NOOBS 一个系统安装工具,其中包括了 Raspbian 和 LibreELEC
  • NOOBS LITE 安装工具,系统要网络在线下载安装
  • RASPBIAN STRETCH WITH DESKTOP 完整系统,包括桌面环境
  • RASPBIAN STRETCH LITE 只有基础系统和命令行操作

我下载了 2018-04-18-raspbian-stretch.zip ,1.8G 。

解压后 2018-04-18-raspbian-stretch.img 4.95G 。

SD 卡系统安装教程

sudo dd bs=1m if=2018-04-18-raspbian-stretch.img of=/dev/rdisk2 conv=sync

注意 /dev/rdisk2 要看 SD 卡在系统里的节点,要看仔细了。

默认用户名、密码:pi/raspberry

引脚

http://pinout.xyz


连接串口,查看 boot console log。修改 /boot/config.txt,增加下面两句以启用串口:

uart_enable=yes
enable_uart=1

mqtt - mosquitto 和 paho.mqtt.embedded-c 初体验

mosquitto

下载代码:

git clone https://github.com/eclipse/mosquitto.git

macos 环境编译,在 CMakeLists.txt 文件的头部加上一句:

set(CMAKE_MACOSX_RPATH 1)

使用 cmake 编译(在 macos 上找不到 openssl 库的位置,手动指定):

mkdir build
cd build
cmake -DOPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2n -DOPENSSL_LIBRARIES=/usr/local/Cellar/openssl/1.0.2n/lib ..
make -j8

编译完成之后,在 build/client/ 目录下有两个文件:mosquitto_pub, mosquitto_sub,可以用来做快速体验:

sub:

./mosquitto_sub -h test.mosquitto.org -t "test/sam/hi"

pub:

./mosquitto_pub -h test.mosquitto.org -t "test/sam/hi" -m 'hello world'

paho.mqtt.embedded-c

下载代码:

git clone https://github.com/eclipse/paho.mqtt.embedded-c.git

同样在 CMakeLists.txt 文件的头部加上一句:set(CMAKE_MACOSX_RPATH 1)

cd paho.mqtt.embedded-c

mkdir build.paho

cd build.paho

cmake ..

make -j8

测试例子:

cd MQTTClient-C/samples/linux/

./stdoutsubc "test/sam/hi" --host "test.mosquitto.org"

同样用上面的 mosquitto_pub 来执行 pub 操作。

stm32 deadlock 排查一例

以前排查 bug 时记的一个笔记,备份在这里。

背景

单片机里串口的操作处理,发送和接收各有一个缓冲区,在中断里处理发送和接收。

调试时发现了串口工作一会 就卡住了。

调试过程

串口发送:

int serial_write(serial_t *serial, const void *buffer, int length)
{
    uart_t *uart = &serial->uart;
    fifo_t *txbuf = serial->txbuf;

    int data_written = 0;
    const char *ptr = buffer;

    while (data_written < length) {
        if (fifo_is_full(txbuf)) {
            break;
        }
        fifo_push(txbuf, *ptr++);
        data_written++;
    }

    if (!serial->tx_irq_enabled && !fifo_is_empty(txbuf)) {
        uart_tx_irq_enable(uart);
        serial->tx_irq_enabled = true;
    }

    return data_written;
}

中断处理:

static void uart_isr(uart_t *uart)
{
    serial_t *serial = CONTAINER_OF(uart, serial_t, uart);
    fifo_t *txbuf = serial->txbuf;
    fifo_t *rxbuf = serial->rxbuf;

    if (uart_writeable(uart)) {
        if (fifo_is_empty(txbuf)) {
            if (serial->tx_irq_enabled) {
                uart_tx_irq_disable(uart);
                serial->tx_irq_enabled = false;
            }
        } else {
            char ch;
            fifo_pop(txbuf, &ch);
            uart_putc(uart, ch);
        }
    }
}

死锁时的状态:

(gdb) p 'console.c'::serial
$2 = {uart = {huart = 0x2000026c <huart1>, irq_isr = 0x8001911 <uart_isr>}, 
  txbuf = 0x2000001c <tx_buf>, rxbuf = 0x2000000c <rx_buf>, tx_irq_enabled = false, 
  rx_irq_enabled = false}
(gdb) x/16xw 0x40013800
0x40013800:	0x000000c0	0x00000000	0x0000022c	0x0000208c
0x40013810:	0x00000000	0x00000000	0x00000000	0x00000000
0x40013820:	0x00000000	0x00000000	0x00000000	0x00000000
0x40013830:	0x00000000	0x00000000	0x00000000	0x00000000

image

SR 为 0x000000c0,即 TXE 和 TC 为 1。

image

CR1 为 0x0000208c,即 UE, TXEIE, TE, RE 这几位为 1 。意思分别为:

  • UE - usart enable

  • TXEIE - TXE interrupt enable

  • TE - transmitter enable

  • RE - Receiver enable

    serial->tx_irq_enabled 为 false,而 tx_irq 并没有禁止。

    因为没有数据在发送,SR.TXE 一直为 1。
    而 CR1.TXEIE 为 1,则会触发中断。

    tx 中断一直触发,CPU 挂在一直处理 uart tx 中断函数,无法处理其它代码。

什么时候会造成这种情况?

从 c 代码上看,好像不可能出现这种情况。看下汇编:

image

如图。如果在 movs r3, #1 这一行执行完毕之后,触发中断,进入中断处理。

中断中则会执行:

image

一开始进入中断时,fifo 中有数据。

不管这里怎么处理,中断处理返回,回到 上图 strb r3, [r4, #16] 时,r3 的值就不一定是 1 了。如果 r3 为 0,则结果就是:tx irq enable,且 serial->tx_irq_enabled = false。

image

参考

STM32F030 扎记

参考手册

Memory mapping

对于 STM32F030C8 :

  • FLASH - 64KB
  • SRAM - 8KB

启动方式

以上三个存储区在英文文档里分别称为:

- User Flash
- System Memory
- embedded SRAM
  • BOOT0 的值可由 Option Bytes 里的 nBOOT0(BOOT_SEL=0) 或硬件引脚(BOOT_SEL=1) 决定
  • BOOT1 是 Option bytes 中的 nBOOT1 bit

Option bytes 的默认配置:

  • BOOT_SEL=1,所以 BOOT0 的值由 BOOT0 引脚决定
  • nBOOT1=1

对照上面启动模式选择表,在 Option bytes 默认的情况下,我们通过硬件上变化 BOOT0 引脚的电平即可决定 MCU 是正常从 User Flash 启动还是进入 USART 烧写模式。

MCU 内置的 bootloader 就放在 System Memory 里。用于通过 USART 烧写 Flash。

关于内置 bootloader 的行为,可参见 STM32 microcontroller system memory boot mode

STM32 的 SYSCLK 和 Flash latency 调整

记录一下这次 Debug 过程。用到了 openocd + gdb,一行一行的看代码,反复几遍。大胆猜测,小心求证,才解决了这个问题。

背景

STM32F103, reset 启动之后,默认使用内部晶振 HSI,8MHz。

一般我们使用更精准的外部晶振 HSE,再开启 PLL 以便 SYSCLK 能够跑到 72MHz。

Reference Manual 3.3.3 Embedded Flash memory 里有讲到 Flash latency

看到手册里这样的描述感觉上还是比较干涩的,因为一直以来使用 stm32cube 生成工程时,完全不用关心这些细节的东西。知道这里讲的是调整 Flash read 的速度,但不知道如果不调整的话会有什么问题。

计算机有时候就是一个试错科学,只要真正看到出了问题才会认识得深刻。不然心里总是不踏实。

分析

static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
{
  ErrorStatus status = SUCCESS;
  uint32_t sysclk_frequency_current = 0U;

  /* Calculate current SYSCLK frequency */
  sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);

  /* Increasing the number of wait states because of higher CPU frequency */
  if (sysclk_frequency_current < SYSCLK_Frequency)
  {
    /* Set FLASH latency to highest latency */
    status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  }

  /* Update system clock configuration */
  if (status == SUCCESS)
  {
    /* Enable PLL */
    LL_RCC_PLL_Enable();
    while (LL_RCC_PLL_IsReady() != 1U)
    {
      /* Wait for PLL ready */
    }

    /* Sysclk activation on the main PLL */
    LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
    {
      /* Wait for system clock switch to PLL */
    }

    /* Set APB1 & APB2 prescaler*/
    LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
    LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  }

  /* Decreasing the number of wait states because of lower CPU frequency */
  if (sysclk_frequency_current > SYSCLK_Frequency)
  {
    /* Set FLASH latency to lowest latency */
    status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  }

  /* Update SystemCoreClock variable */
  if (status == SUCCESS)
  {
    LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
  }

  return status;
}

上面这个函数是切换时钟的过程:

  1. 打开 PLL 并等待其稳定
  2. 设置 AHB 分频系数
  3. SYSCLK 的时钟源选择 PLL, 并等待 PLL 被真正使用
  4. 设置 APB1, APB2 分频系数

使用 openocd + gdb 调试时,LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); 这句代码切换 SYSCLK 时钟源为 PLL 时就会跑飞,PC 变为 0xfffffffe

切换 HCLK 时钟,Flash Latency 要根据 HCLK 频率来高速:

  • 如果 HCLK 设置后更快,则要提前把 Flash Latency 调整到更大
  • 如果 HCLK 设置的更小,则为了之后的 Flash read 性能,会在最后后把 Flash Latency 调小一些

这里的过程:HCLK 由 8MHz 调整为 72MHz。所以应该提前把 Flash Latency 设置成 two wait states

而代码中 SystemCoreClock 记录原来 HCLK 的值,但这个值默认是 72MHz。代码理解为「没有必要提前调整Flash Latency 」。

修正

reset 开机后,尽早把 SystemCoreClock 设置为 HSI_VALUE 就好了。

LL_SetSystemCoreClock(HSI_VALUE);

stm32 deadlock 排查一例

串口发送:

int serial_write(serial_t *serial, const void *buffer, int length)
{
    uart_t *uart = &serial->uart;
    fifo_t *txbuf = serial->txbuf;

    int data_written = 0;
    const char *ptr = buffer;

    while (data_written < length) {
        if (fifo_is_full(txbuf)) {
            break;
        }
        fifo_push(txbuf, *ptr++);
        data_written++;
    }

    if (!serial->tx_irq_enabled && !fifo_is_empty(txbuf)) {
        uart_tx_irq_enable(uart);
        serial->tx_irq_enabled = true;
    }

    return data_written;
}

中断处理:

static void uart_isr(uart_t *uart)
{
    serial_t *serial = CONTAINER_OF(uart, serial_t, uart);
    fifo_t *txbuf = serial->txbuf;
    fifo_t *rxbuf = serial->rxbuf;

    if (uart_writeable(uart)) {
        if (fifo_is_empty(txbuf)) {
            if (serial->tx_irq_enabled) {
                uart_tx_irq_disable(uart);
                serial->tx_irq_enabled = false;
            }
        } else {
            char ch;
            fifo_pop(txbuf, &ch);
            uart_putc(uart, ch);
        }
    }
}

死锁时的状态:

(gdb) p 'console.c'::serial
$2 = {uart = {huart = 0x2000026c <huart1>, irq_isr = 0x8001911 <uart_isr>}, 
  txbuf = 0x2000001c <tx_buf>, rxbuf = 0x2000000c <rx_buf>, tx_irq_enabled = false, 
  rx_irq_enabled = false}
(gdb) x/16xw 0x40013800
0x40013800:	0x000000c0	0x00000000	0x0000022c	0x0000208c
0x40013810:	0x00000000	0x00000000	0x00000000	0x00000000
0x40013820:	0x00000000	0x00000000	0x00000000	0x00000000
0x40013830:	0x00000000	0x00000000	0x00000000	0x00000000

image

SR 为 0x000000c0,即 TXE 和 TC 为 1。

image

CR1 为 0x0000208c,即 UE, TXEIE, TE, RE 这几位为 1 。意思分别为:

  • UE - usart enable

  • TXEIE - TXE interrupt enable

  • TE - transmitter enable

  • RE - Receiver enable

    serial->tx_irq_enabled 为 false,而 tx_irq 并没有禁止。

    因为没有数据在发送,SR.TXE 一直为 1。
    而 CR1.TXEIE 为 1,则会触发中断。

    tx 中断一直触发,CPU 挂在一直处理 uart tx 中断函数,无法处理其它代码。

原因:

什么时候会造成这种情况?

从 c 代码上看,好像不可能出现这种情况。看下汇编:

image

如图。如果在 movs r3, #1 这一行执行完毕之后,触发中断,进入中断处理。

中断中则会执行:

image

一开始进入中断时,fifo 中有数据。

不管这里怎么处理,中断处理返回,回到 上图 strb r3, [r4, #16] 时,r3 的值就不一定是 1 了。如果 r3 为 0,则结果就是:tx irq enable,且 serial->tx_irq_enabled = false。

image

参考

100个gdb小技巧

信用卡使用流水账

许多年前办理过一张信用卡。招行的,YOUNG卡。

image

当时也不知道各种信用卡具体有什么区别。办这张卡可能是当时觉得自己还挺年轻的。这张卡一直用到现在,额度由最初的不到 2w 一路涨到现在 5w,偶有不够的话可以临时调整额度。

后来申请了一张 MasterCard全币卡。当时是希望能有一张卡即能在国内用,也能在网上的其它国家消费。

当时申请这张卡是因为免年费,而且外观好看。但卡下来之后才了解到这是一张单币卡。于是一直放着没有激活。

image

后来公司发工资的银行换成了**银行。要求大家办理**银行的卡。后来没过几个月,自然的接到了**银行的推荐办卡电话,上门办卡。

那一阵子开销比较大,信用卡也几乎刷爆。于是就同意了办理。**银行的卡下来,丑爆,而且毫无特色,还一口气给我办了三张:一张银联卡、一张 MASTER 卡,一张银联+VISA双币卡。后来也用不上,就一直放着没开。

  • 双币卡

双币卡的结算货币通常是人民币-美元。

  1. 当使用美元消费时,以美元计帐。
  2. 当使用非美元货币消费时,将当地货币转换为美元计账。这个转换不是按交易日汇率,而是以 VISA 或 MASTER 系统清算处理日的汇率来计算。这个转换一般会收取转换手续费,大约为 1%~2% 。
  3. 最终的帐单以美元计账,还款时使用人民币按当前汇率购汇,兑换成美元,然后汇入美元账户还款。
  • 全币卡

全币卡主要区别在于第 3 步。以美元结算之后,会按当天汇率,转换计入人民币账单。最终的还款以人民币还款。

综上,还是使用全币卡比较方便一点。现在招行和中行的全币卡,实际上也是以美元计账(并不是人民币直接兑换当地货币,毕竟美元流通性最好),只不过会免除上面步骤 2 里的「当地货币-美元」的转换手续费。

另外,手上还有一张建设银行的信用卡。为什么会办理这张呢?因为买车时车厂跟建行搞了这么一个套路,必须办理指定建行信用卡用来还款。这张卡打算还清了就销卡。

信用卡也是一套完整的产品,综合使用下来,还是招行客户端、微信端体验更好一点。也没打算薅哪家的信用卡的羊毛,没那个精力和运气。无非是谁好用一点,用的习惯一点,就用谁家的。至于产品的本质功能,在这个层面上已经拉不开差距。

最近想海淘点东西,paypal 不能支付,于是就想起来以前办的卡了。那张 MasterCard全币卡 弄丢了。而**银行的卡因为是双币卡。最终,还是打算再申请一张「招商银行Visa全币卡」。

image

jetson tx2 boot log

nvidia@tegra-ubuntu:/opt/apollo/bin$ dmesg 
[    0.000000] Booting Linux on physical CPU 0x100
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 4.4.38-tegra (buildbrain@mobile-u64-773) (gcc version 4.8.5 (GCC) ) #1 SMP PREEMPT Thu May 17 00:15:19 PDT 2018
[    0.000000] Boot CPU: AArch64 Processor [411fd073]
[    0.000000] earlycon: Early serial console at MMIO32 0x3100000 (options '')
[    0.000000] bootconsole [uart0] enabled
[    0.000000] Reserved memory: initialized node ramoops_carveout, compatible id nvidia,ramoops
[    0.000000] cma: Reserved 64 MiB at 0x00000000fc000000
[    0.000000] On node 0 totalpages: 2052096
[    0.000000]   DMA zone: 8192 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 519680 pages, LIFO batch:31
[    0.000000]   Normal zone: 23968 pages used for memmap
[    0.000000]   Normal zone: 1532416 pages, LIFO batch:31
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.0 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] PERCPU: Embedded 17 pages/cpu @ffffffc1f5f9a000 s31360 r8192 d30080 u69632
[    0.000000] pcpu-alloc: s31360 r8192 d30080 u69632 alloc=17*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 2019936
[    0.000000] Kernel command line: root=/dev/mmcblk0p1 rw rootwait console=ttyS0,115200n8 console=tty0 OS=l4t fbcon=map:0 net.ifnames=0 memtype=0 video=tegrafb no_console_suspend=1 earlycon=uart8250,mmio32,0x03100000 nvdumper_reserved=0x2772e0000 gpt tegraid=18.1.2.0.0 tegra_keep_boot_clocks maxcpus=6 boot.slot_suffix= boot.ratchetvalues=0.2.1 androidboot.serialno=0324217137410 bl_prof_dataptr=0x10000@0x277040000 sdhci_tegra.en_boot_part_access=1 root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
[    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
[    0.000000] Memory: 7975976K/8208384K available (11296K kernel code, 1841K rwdata, 5796K rodata, 1168K init, 691K bss, 166872K reserved, 65536K cma-reserved)
[    0.000000] Virtual kernel memory layout:
                   vmalloc : 0xffffff8000000000 - 0xffffffbdbfff0000   (   246 GB)
                   vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
                             0xffffffbdc2000000 - 0xffffffbdc9da0000   (   125 MB actual)
                   fixed   : 0xffffffbffa7fd000 - 0xffffffbffac00000   (  4108 KB)
                   PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000   (    16 MB)
                   modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
                   memory  : 0xffffffc000000000 - 0xffffffc1f6800000   (  8040 MB)
                     .init : 0xffffffc001132000 - 0xffffffc001256000   (  1168 KB)
                     .text : 0xffffffc000080000 - 0xffffffc001132000   ( 17096 KB)
                     .data : 0xffffffc001278000 - 0xffffffc001444730   (  1842 KB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=6, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Build-time adjustment of leaf fanout to 64.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=6.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=6
[    0.000000] NR_IRQS:64 nr_irqs:64 0
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] Architected cp15 timer(s) running at 31.25MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xe6a171046, max_idle_ns: 881590405314 ns
[    0.000002] sched_clock: 56 bits at 31MHz, resolution 32ns, wraps every 4398046511088ns
[    0.009871] Console: colour dummy device 80x25
[    0.014530] console [tty0] enabled
[    0.018087] bootconsole [uart0] disabled
[    0.022190] kmemleak: Kernel memory leak detector disabled
[    0.022202] Calibrating delay loop (skipped), value calculated using timer frequency.. 62.50 BogoMIPS (lpj=125000)
[    0.022214] pid_max: default: 32768 minimum: 301
[    0.022262] Security Framework initialized
[    0.022299] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes)
[    0.022310] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes)
[    0.022692] Initializing cgroup subsys io
[    0.022705] Initializing cgroup subsys memory
[    0.022722] Initializing cgroup subsys devices
[    0.022732] Initializing cgroup subsys freezer
[    0.022741] Initializing cgroup subsys net_cls
[    0.022751] Initializing cgroup subsys perf_event
[    0.022760] Initializing cgroup subsys net_prio
[    0.022770] Initializing cgroup subsys pids
[    0.022778] Initializing cgroup subsys debug
[    0.022917] CPU0 ipc=752
[    0.022927] CPU1 ipc=1024
[    0.022934] CPU2 ipc=1024
[    0.022943] CPU3 ipc=752
[    0.022953] CPU4 ipc=752
[    0.022962] CPU5 ipc=752
[    0.023000] ASID allocator initialised with 65536 entries
[    0.046253] tegra-id: chipid=21817.
[    0.046270] tegra-id: opt_subrevision=1.
[    0.046283] Tegra Revision: A02p SKU: 0xdc CPU Process: 0 SoC Process: 0
[    0.046982] DTS File Name: /dvs/git/dirty/git-master_linux/kernel/kernel-4.4/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dts
[    0.047007] DTB Build time: May 17 2018 00:17:47
[    0.062585] CPU1: Booted secondary processor [4e0f0030]
[    0.074114] CPU2: Booted secondary processor [4e0f0030]
[    0.085845] CPU3: Booted secondary processor [411fd073]
[    0.097826] CPU4: Booted secondary processor [411fd073]
[    0.109828] CPU5: Booted secondary processor [411fd073]
[    0.109892] Brought up 6 CPUs
[    0.109950] SMP: Total of 6 processors activated.
[    0.109963] CPU: All CPU(s) started at EL2
[    0.110384] devtmpfs: initialized
[    0.137130] Initilizing CustomIPI irq domain
[    0.137380] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.138136] pinctrl core: initialized pinctrl subsystem
[    0.138311] OS set in device tree is not L4T.
[    0.138502] regulator-dummy: no parameters
[    0.138606] Initializing plugin-manager
[    0.138657] Plugin module not found
[    0.139060] node /plugin-manager/soc-prod-a02-fragment match with chip-id A02P
[    0.139393] node /plugin-manager/fragement@0 match with odm-data enable-denver-wdt
[    0.139995] node /plugin-manager/fragement@4 match with odm-data enable-denver-wdt
[    0.141135] node /plugin-manager/fragment-sdwake-p3310-1000-300 match with board >=3310-1000-300
[    0.141507] node /plugin-manager/fragement-pmon-p3310-1000-300 match with board >=3310-1000-300
[    0.141761] node /plugin-manager/fragement-pmon-p3310-1000-800 match with board >=3310-1000-800
[    0.141978] node /plugin-manager/fragment-devslp@0 match with board >=3310-1000-200
[    0.142395] node /plugin-manager/fragment-500-pcie-config match with board >=3310-1000-500
[    0.142834] node /plugin-manager/fragment-500-xusb-config match with board >=3310-1000-500
[    0.143109] node /plugin-manager/fragment-500-e3325-pcie match with board >=3310-1000-500
[    0.143483] node /plugin-manager/fragment-p3310-c00-comm match with board >=3310-1000-800
[    0.143727] node /plugin-manager/fragment-p3310-c00-pmic match with board >=3310-1000-800
[    0.143945] node /plugin-manager/fragment-p3310-c01 match with board >=3310-1000-900
[    0.144201] node /plugin-manager/fragment-p3310-c03 match with board >=3310-1000-B00
[    0.145744] node /plugin-manager/fragment-e3326@0 match with board 3326-*
[    0.146816] node /plugin-manager/fragment-p3310-c00-camera match with board >=3310-1000-800
[    0.148583] Adding domain adsp-pd to PM domain ape-pd
[    0.150947] NET: Registered protocol family 16
[    0.153500] console [pstore-1] enabled
[    0.153513] pstore: Registered ramoops as persistent store backend
[    0.153526] ramoops: attached 0x200000@0x277080000, ecc: 0/0
[    0.165361] cpuidle: using governor ladder
[    0.169847] cpuidle: using governor menu
[    0.170992] bpmp: waiting for handshake
[    0.171006] bpmp: handshake completed
[    0.171048] bpmp: synchronizing channels
[    0.171074] bpmp: channels synchronized
[    0.171085] bpmp: mail init ok
[    0.171422] vdso: 2 pages (1 code @ ffffffc00127d000, 1 data @ ffffffc00127c000)
[    0.171455] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.172387] atomic_pool_init():526: DMA: preallocated 1024 KiB pool for atomic allocations
[    0.173794] tegra_powergate_init: DONE
[    0.173815] DTS File Name: /dvs/git/dirty/git-master_linux/kernel/kernel-4.4/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dts
[    0.173850] DTB Build time: May 17 2018 00:17:47
[    0.174764] Tegra reboot handler registered.
[    0.175813] Registering Tegra186 clocks (this may take a while)...done
[    0.177944] arm-smmu 12000000.iommu: probing hardware configuration...
[    0.177962] arm-smmu 12000000.iommu: SMMUv2 with:
[    0.177976] arm-smmu 12000000.iommu: 	stage 1 translation
[    0.177988] arm-smmu 12000000.iommu: 	stage 2 translation
[    0.178000] arm-smmu 12000000.iommu: 	nested translation
[    0.178015] arm-smmu 12000000.iommu: 	stream matching with 128 register groups, mask 0x7f80
[    0.178034] arm-smmu 12000000.iommu: SMMU address space size (0x800000) differs from mapped region size (0x1000000)!
[    0.178052] arm-smmu 12000000.iommu: 	64 context banks (0 stage-2 only)
[    0.178067] arm-smmu 12000000.iommu: 	Stage-1: 39-bit VA -> 48-bit IPA
[    0.178081] arm-smmu 12000000.iommu: 	Stage-2: 39-bit IPA -> 48-bit PA
[    0.226710] arm-smmu 12000000.iommu: registered 67 master devices
[    0.232546] iommu: Adding device 3460000.sdhci to group 0
[    0.233403] iommu: Adding device 3400000.sdhci to group 1
[    0.236883] iommu: Adding device 3507000.ahci-sata to group 2
[    0.237340] iommu: Adding device 3160000.i2c to group 3
[    0.237786] iommu: Adding device c240000.i2c to group 4
[    0.238119] iommu: Adding device 3180000.i2c to group 5
[    0.238480] iommu: Adding device 3190000.i2c to group 6
[    0.238997] iommu: Adding device 31b0000.i2c to group 7
[    0.239342] iommu: Adding device 31c0000.i2c to group 8
[    0.239696] iommu: Adding device c250000.i2c to group 9
[    0.240033] iommu: Adding device 31e0000.i2c to group 10
[    0.242066] iommu: Adding device 3210000.spi to group 11
[    0.242379] iommu: Adding device c260000.spi to group 12
[    0.242745] iommu: Adding device 3240000.spi to group 13
[    0.243577] iommu: Adding device 3100000.serial to group 14
[    0.243896] iommu: Adding device 3110000.serial to group 15
[    0.244220] iommu: Adding device c280000.serial to group 16
[    0.244518] iommu: Adding device 3130000.serial to group 17
[    0.245767] iommu: Adding device 2490000.ether_qos to group 18
[    0.246414] iommu: Adding device b000000.rtcpu to group 19
[    0.246896] iommu: Adding device c1a0000.aon to group 20
[    0.247780] Wake73 for irq=42
[    0.248131] iommu: Adding device smmu_test to group 21
[    0.248681] mc: mapped MMIO address: 0xffffff8000560000 -> 0x2c10000
[    0.248722] mc: mapped MMIO address: 0xffffff8000640000 -> 0x2c20000
[    0.248759] mc: mapped MMIO address: 0xffffff8000660000 -> 0x2c30000
[    0.248798] mc: mapped MMIO address: 0xffffff8000fa0000 -> 0x2c40000
[    0.248854] mc: mapped MMIO address: 0xffffff8000fc0000 -> 0x2c50000
[    0.248888] mc-err: Set intmask: 0xf3140
[    0.249164] ecc-err: dram ecc disabled-MC_ECC_CONTROL:0x0000000c
[    0.250018] Wake76 for irq=199
[    0.250043] Wake77 for irq=199
[    0.250064] Wake78 for irq=199
[    0.250088] Wake79 for irq=199
[    0.250134] Wake80 for irq=199
[    0.250154] Wake81 for irq=199
[    0.250174] Wake82 for irq=199
[    0.250289] iommu: Adding device 3530000.xhci to group 22
[    0.250678] iommu: Adding device 3550000.xudc to group 23
[    0.251499] tegra-pmc c360000.pmc: scratch reg offset dts data not present
[    0.251537] tegra-pmc: ### PMC reset source: Software reset
[    0.251562] tegra-pmc: ### PMC reset level: L1
[    0.251585] tegra-pmc: ### PMC reset status reg: 0x2d
[    0.251862] padctrl padctrl.0: Pad control driver tegra-pmc-padctrl registered
[    0.251901] tegra-pmc c360000.pmc: IO padctrl driver initialized
[    0.252069] tegra186-aowake c370000.pmc: WAKE_AOWAKE_CTRL_0 = 3
[    0.252099] tegra186-aowake c370000.pmc: WAKE_AOWAKE_CNTRL_24(PMU_INT) = 320
[    0.252605] iommu: Adding device 13e10000.host1x to group 24
[    0.252932] iommu: Adding device 13e10000.host1x:ctx0 to group 25
[    0.253187] iommu: Adding device 13e10000.host1x:ctx1 to group 26
[    0.253416] iommu: Adding device 13e10000.host1x:ctx2 to group 27
[    0.253685] iommu: Adding device 13e10000.host1x:ctx3 to group 28
[    0.253936] iommu: Adding device 13e10000.host1x:ctx4 to group 29
[    0.254160] iommu: Adding device 13e10000.host1x:ctx5 to group 30
[    0.254378] iommu: Adding device 13e10000.host1x:ctx6 to group 31
[    0.254665] iommu: Adding device 13e10000.host1x:ctx7 to group 32
[    0.255129] iommu: Adding device 150c0000.nvcsi to group 33
[    0.255641] iommu: Adding device 15700000.vi to group 34
[    0.256016] iommu: Adding device 15600000.isp to group 35
[    0.256361] iommu: Adding device 15210000.nvdisplay to group 36
[    0.256564] iommu: Adding device 15340000.vic to group 37
[    0.256781] iommu: Adding device 154c0000.nvenc to group 38
[    0.256974] iommu: Adding device 15480000.nvdec to group 39
[    0.257305] iommu: Adding device 15380000.nvjpg to group 40
[    0.257502] iommu: Adding device 15500000.tsec to group 41
[    0.257721] iommu: Adding device 15100000.tsecb to group 42
[    0.258421] iommu: Adding device 15810000.se to group 43
[    0.258646] iommu: Adding device 15820000.se to group 44
[    0.258874] iommu: Adding device 15830000.se to group 45
[    0.259062] iommu: Adding device 15840000.se to group 46
[    0.259580] iommu: Adding device 17000000.gp10b to group 47
[    0.260988] tegra-reset 5000000.clock: registered 193 resets.
[    0.263758] iommu: Adding device d000000.bpmp to group 48
[    0.263998] bpmp: ping status is 0
[    0.264185] bpmp d000000.bpmp: firmware tag is 83385b61e34297b2f37e76e0cd1ff81e
[    0.264550] bpmp d000000.bpmp: probe ok
[    0.267398] iommu: Adding device 2600000.dma to group 49
[    0.268335] GPIO line 461 (cam0-rst) hogged as output/low
[    0.268414] GPIO line 456 (cam0-pwdn) hogged as output/low
[    0.268470] GPIO line 457 (cam1-rst) hogged as output/low
[    0.268521] GPIO line 426 (cam1-pwdn) hogged as output/low
[    0.268576] GPIO line 424 (wifi-enable) hogged as output/high
[    0.268628] GPIO line 445 (sdmmc-wake-input) hogged as input
[    0.268703] GPIO line 446 (sdmmc-wake-output) hogged as output/low
[    0.268848] gpiochip_add_data: registered GPIOs 320 to 511 on device: tegra-gpio
[    0.270792] GPIO line 315 (wifi-wake-ap) hogged as input
[    0.270932] gpiochip_add_data: registered GPIOs 256 to 319 on device: tegra-gpio-aon
[    0.271925] iommu: Adding device 10003000.pcie-controller to group 50
[    0.272272] iommu: Adding device sound to group 51
[    0.274100] iommu: Adding device 3510000.hda to group 52
[    0.275317] iommu: Adding device adsp_audio to group 53
[    0.276773] iommu: Adding device 2993000.adsp to group 54
[    0.286625] vdd-ac-bat: 5000 mV 
[    0.288879] vdd-1v8-ap: 1800 mV 
[    0.308598] SCSI subsystem initialized
[    0.308777] libata version 3.00 loaded.
[    0.308955] usbcore: registered new interface driver usbfs
[    0.309016] usbcore: registered new interface driver hub
[    0.309134] usbcore: registered new device driver usb
[    0.313001] GPIO line 241 (touch-rail-1) hogged as output/high
[    0.313459] GPIO line 242 (touch-rail-2) hogged as output/high
[    0.313563] gpiochip_add_data: registered GPIOs 240 to 255 on device: tca9539
[    0.314960] GPIO line 228 (lcd-bias-en-rail) hogged as output/high
[    0.315058] gpiochip_add_data: registered GPIOs 224 to 239 on device: tca9539
[    0.326043] media: Linux media interface: v0.10
[    0.326115] Linux video capture interface: v2.00
[    0.330281] pps_core: LinuxPPS API ver. 1 registered
[    0.330329] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <[email protected]>
[    0.330383] PTP clock support registered
[    0.331407] tegra_wdt_t18x 30c0000.watchdog: Tegra WDT init timeout = 120 sec
[    0.331484] tegra_wdt_t18x 30c0000.watchdog: Registered successfully
[    0.333006] max77620 4-003c: PMIC Version OTP:0x45 and ES:0x8
[    0.335152] GPIO line 221 (spmic_gpio_input_5) hogged as input
[    0.335343] GPIO line 222 (spmic_gpio_input_6) hogged as input
[    0.335452] gpiochip_add_data: registered GPIOs 216 to 223 on device: max77620-gpio
[    0.342756] vddio-ddr: at 1125 mV 
[    0.346595] avdd_dsi_csi: 1200 mV 
[    0.350594] vdd-1v8: 1800 mV 
[    0.354595] vdd-3v3-sys: 3300 mV 
[    0.355358] spmic-ldo0: at 1800 mV 
[    0.356113] spmic-ldo1: at 800 mV 
[    0.358597] vddio-3v3: 3300 mV 
[    0.359265] vddio-sdmmc1: 1800 <--> 3300 mV at 3300 mV 
[    0.362599] vdd-rtc: at 800 mV 
[    0.363231] avdd-ts-hv: 1800 <--> 3300 mV at 1800 mV 
[    0.365359] spmic-ldo6: at 1500 mV 
[    0.369359] vdd-pex-1v05: 1000 mV 
[    0.369903] dvdd-pex: 1000 mV 
[    0.370170] max77620 4-003c: max77620 probe successful
[    0.370421] Advanced Linux Sound Architecture Driver Initialized.
[    0.371398] en-vdd-sd: 3300 mV 
[    0.372016] en-vdd-cam: 1800 mV 
[    0.373849] vdd-hdmi: 5000 mV 
[    0.374031] vdd-usb0-5v: 5000 mV 
[    0.374204] vdd-usb1-5v: 5000 mV 
[    0.377849] en-vdd-ts-1v8: 1800 mV 
[    0.381848] en-vdd-ts-hv-3v3: 3300 mV 
[    0.382367] en-vdd-disp-3v3: 3300 mV 
[    0.382870] en-mdm-pwr-3v7: 3700 mV 
[    0.383378] en-vdd-disp-1v8: 1800 mV 
[    0.383890] en-vdd-cam-hv-2v8: 2800 mV 
[    0.384406] en-vdd-cam-1v2: 1200 mV 
[    0.384920] vdd-fan: 5000 mV 
[    0.385041] vdd-3v3: 3300 mV 
[    0.385761] dis-vdd-1v2: 1200 mV 
[    0.385883] en-vdd-vcm-2v8: 2800 mV 
[    0.386397] vdd-usb2-5v: 5000 mV 
[    0.386503] vdd-sys-bl: 3300 mV 
[    0.387033] en-vdd-sys: 1200 mV 
[    0.390392] extcon-gpio-states external-connection:extcon@1: Cable state 0
[    0.390779] clocksource: Switched to clocksource arch_sys_counter
[    0.409332] nvmap_heap_init: nvmap_heap_init: created heap block cache
[    0.409617] nvmap: nvmap_override_cache_ops() set roc flush ops to replace cache ops by set/ways
[    0.410088] nvmap_page_pool_init: Total RAM pages: 2010378
[    0.410106] nvmap_page_pool_init: nvmap page pool size: 251297 pages (981 MB)
[    0.410298] nvmap_background_zero_thread: PP zeroing thread starting.
[    0.414793] Wake76 for irq=199
[    0.414806] Wake77 for irq=199
[    0.414817] Wake78 for irq=199
[    0.414827] Wake79 for irq=199
[    0.414837] Wake80 for irq=199
[    0.414846] Wake81 for irq=199
[    0.414856] Wake82 for irq=199
[    0.415591] thermal thermal_zone0: Registering thermal zone thermal_zone0 for type BCPU-therm
[    0.415789] thermal thermal_zone1: Registering thermal zone thermal_zone1 for type MCPU-therm
[    0.416171] thermal thermal_zone2: Registering thermal zone thermal_zone2 for type GPU-therm
[    0.416250] thermal thermal_zone3: Registering thermal zone thermal_zone3 for type PLL-therm
[    0.416393] thermal thermal_zone4: Registering thermal zone thermal_zone4 for type Tboard_tegra
[    0.416530] thermal thermal_zone5: Registering thermal zone thermal_zone5 for type Tdiode_tegra
[    0.416677] thermal thermal_zone6: Registering thermal zone thermal_zone6 for type PMIC-Die
[    0.416969] isomgr_init(): iso emc max clk=1866000KHz
[    0.416981] isomgr_init(): max_iso_bw=26870400KB
[    0.417064] NET: Registered protocol family 2
[    0.417368] TCP established hash table entries: 65536 (order: 7, 524288 bytes)
[    0.417591] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
[    0.417883] TCP: Hash tables configured (established 65536 bind 65536)
[    0.417943] UDP hash table entries: 4096 (order: 5, 131072 bytes)
[    0.417996] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
[    0.418158] NET: Registered protocol family 1
[    0.418369] RPC: Registered named UNIX socket transport module.
[    0.418384] RPC: Registered udp transport module.
[    0.418396] RPC: Registered tcp transport module.
[    0.418408] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.418429] PCI: CLS 0 bytes, default 128
[    0.418522] Trying to unpack rootfs image as initramfs...
[    0.432142] host1x 13e10000.host1x: initialized
[    0.432982] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    0.434613] futex hash table entries: 2048 (order: 6, 262144 bytes)
[    0.434707] audit: initializing netlink subsys (disabled)
[    0.434740] audit: type=2000 audit(0.420:1): initialized
[    0.441623] io scheduler noop registered
[    0.441727] io scheduler cfq registered (default)
[    0.444279] tegra-pwm 3280000.pwm: PWM clk can sleep in ops
[    0.445462] tegra-pwm 3290000.pwm: PWM clk can sleep in ops
[    0.446526] tegra-pwm 32a0000.pwm: PWM clk can sleep in ops
[    0.447560] tegra-pwm c340000.pwm: PWM clk can sleep in ops
[    0.450919] tsec 15500000.tsec: initialized
[    0.452028] tsec 15100000.tsecb: initialized
[    0.454325] nvdec 15480000.nvdec: initialized
[    0.457964] falcon 15340000.vic: initialized
[    0.458963] falcon 154c0000.nvenc: initialized
[    0.460016] falcon 15380000.nvjpg: initialized
[    0.460796] iommu_context_dev 13e10000.host1x:ctx0: initialized (streamid=56)
[    0.461290] iommu_context_dev 13e10000.host1x:ctx1: initialized (streamid=57)
[    0.461786] iommu_context_dev 13e10000.host1x:ctx2: initialized (streamid=58)
[    0.462282] iommu_context_dev 13e10000.host1x:ctx3: initialized (streamid=59)
[    0.462787] iommu_context_dev 13e10000.host1x:ctx4: initialized (streamid=60)
[    0.463284] iommu_context_dev 13e10000.host1x:ctx5: initialized (streamid=61)
[    0.463775] iommu_context_dev 13e10000.host1x:ctx6: initialized (streamid=62)
[    0.464270] iommu_context_dev 13e10000.host1x:ctx7: initialized (streamid=63)
[    0.466905] DC OR NODE connected to /host1x/sor1
[    0.467031] generic_infoframe_type: 0x87
[    0.467036] tegra_camera_platform tegra-camera-platform: tegra_camera_probe:camera_platform_driver probe
[    0.467134] misc tegra_camera_ctrl: tegra_camera_isomgr_register tpg_max_iso = 3916800KBs
[    0.467149] tegradc 15210000.nvdisplay: DT parsed successfully
[    0.467165] misc tegra_camera_ctrl: tegra_camera_isomgr_register isp_iso_bw=4687500, vi_iso_bw=1500000, max_bw=4687500
[    0.467181] tegradc 15210000.nvdisplay: Display dc.ffffff8002320000 registered with id=0
[    0.474815] tegra_nvdisp_bandwidth_register_max_config: max config iso bw = 16727000 KB/s
[    0.474835] tegra_nvdisp_bandwidth_register_max_config: max config EMC floor = 665600000 Hz
[    0.474852] tegra_nvdisp_bandwidth_register_max_config: max config hubclk = 357620000 Hz
[    0.474899] tegradc 15210000.nvdisplay: vblank syncpt # 7 for dc 1
[    0.474914] tegradc 15210000.nvdisplay: vpulse3 syncpt # 8 for dc 1
[    0.475104] tegra-adma 2930000.adma: Tegra ADMA driver register 10 channels
[    0.477277] tegra-fuse-burn 3820000.efuse:efuse-burn: Fuse burn driver initialized
[    0.477529] tegradc 15210000.nvdisplay: hdmi: no prod_list_hdmi_board, use default range
[    0.477624] kfuse 3830000.kfuse: initialized
[    0.478811] tegra-pmc-iopower pmc-iopower: NO_IOPOWER setting 0x0
[    0.479208] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.481104] console [ttyS0] disabled
[    0.481150] 3100000.serial: ttyS0 at MMIO 0x3100000 (irq = 37, base_baud = 25500000) is a Tegra
[    0.481741] tegra-i2c 3190000.i2c: no acknowledge from address 0x50
[    0.483845] tegradc 15210000.nvdisplay: probed
[    2.574667] console [ttyS0] enabled
[    2.576642] 3110000.serial: ttyTHS1 at MMIO 0x3110000 (irq = 38, base_baud = 0) is a TEGRA_UART
[    2.576843] Console: switching to colour frame buffer device 80x30
[    2.577718] c280000.serial: ttyTHS2 at MMIO 0xc280000 (irq = 39, base_baud = 0) is a TEGRA_UART
[    2.577926] serial-tegra 3130000.serial: RX in PIO mode
[    2.578832] 3130000.serial: ttyTHS3 at MMIO 0x3130000 (irq = 40, base_baud = 0) is a TEGRA_UART
[    2.604822] brd: module loaded
[    2.609381] loop: module loaded
[    2.609638] nct1008_nct72 7-004c: find device tree node, parsing dt
[    2.609642] nct1008_nct72 7-004c: starting parse dt
[    2.609730] nct1008_nct72 7-004c: success parsing dt
[    2.609847] nct1008_nct72 7-004c: success in enabling tmp451 VDD rail
[    2.670127] tegradc 15210000.nvdisplay: fb registered
[    2.684228] gk20a 17000000.gp10b: failed to allocate secure buffer -12
[    2.710851] tmp451: Enabled overheat logging at 104.00C
[    2.717345] nct1008_nct72 7-004c: nct1008_probe: initialized
[    2.726184] THERMAL EST: found 3 subdevs
[    2.731274] THERMAL EST num_resources: 0
[    2.736321] [THERMAL EST subdev 0]
[    2.740822] [THERMAL EST subdev 1]
[    2.745274] [THERMAL EST subdev 2]
[    2.749880] thermal thermal_zone7: Registering thermal zone thermal_zone7 for type thermal-fan-est
[    2.760897] THERMAL EST: thz register success.
[    2.766455] THERMAL EST: end of probe, return err: 0
[    2.772450] tegra_profiler: Branch: Dev
[    2.777250] tegra_profiler: Version: 1.117
[    2.782280] tegra_profiler: Samples version: 41
[    2.787739] tegra_profiler: IO version: 22
[    2.794191] armv8_pmu: imp: 0x41, idcode: 0x1
[    2.799402] armv8_pmu: [0] arch: AA64 PmuV3 ARM CORTEX-A57, type: 5, ver: 0, pmu ver: 0x1
[    2.808886] armv8_pmu: imp: 0x4e, idcode: 0x1
[    2.813907] armv8_pmu: [1] arch: AA64 PmuV3 NVIDIA (Denver), type: 6, ver: 2, pmu ver: 0x1
[    2.823542] armv8_pmu: imp: 0x4e, idcode: 0x1
[    2.828629] armv8_pmu: [2] arch: AA64 PmuV3 NVIDIA (Denver), type: 6, ver: 2, pmu ver: 0x1
[    2.838356] armv8_pmu: imp: 0x41, idcode: 0x1
[    2.843454] armv8_pmu: [3] arch: AA64 PmuV3 ARM CORTEX-A57, type: 5, ver: 0, pmu ver: 0x1
[    2.853075] armv8_pmu: imp: 0x41, idcode: 0x1
[    2.858200] armv8_pmu: [4] arch: AA64 PmuV3 ARM CORTEX-A57, type: 5, ver: 0, pmu ver: 0x1
[    2.867894] armv8_pmu: imp: 0x41, idcode: 0x1
[    2.873072] armv8_pmu: [5] arch: AA64 PmuV3 ARM CORTEX-A57, type: 5, ver: 0, pmu ver: 0x1
[    2.883129] tegra_profiler: auth: init
[    2.891331] tegra-ahci 3507000.ahci-sata: AHCI 0001.0301 32 slots 2 ports 3 Gbps 0x1 impl platform mode
[    2.902335] tegra-ahci 3507000.ahci-sata: flags: 64bit ncq sntf pm led pmp pio slum part deso sadm apst 
[    2.914615] scsi host0: tegra_ahci
[    2.919321] scsi host1: tegra_ahci
[    2.923827] ata1: SATA max UDMA/133 mmio [mem 0x03507000-0x03508fff] port 0x100 irq 25
[    2.933339] ata2: DUMMY
[    2.937740] spi-tegra114 3210000.spi: Static pin configuration used
[    2.945328] spi-tegra114 c260000.spi: Static pin configuration used
[    2.952878] spi-tegra114 3240000.spi: Static pin configuration used
[    2.960810] tun: Universal TUN/TAP device driver, 1.6
[    2.966621] tun: (C) 1999-2004 Max Krasnyansky <[email protected]>
[    2.973735] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    2.980307] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    2.987036] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.3.0-k
[    2.994732] igb: Copyright (c) 2007-2014 Intel Corporation.
[    3.002110] PPP generic driver version 2.4.2
[    3.005090] eqos 2490000.ether_qos: Setting local MAC: 0 4 4b 8d 84 77
[    3.005511] libphy: dwc_phy: probed
[    3.018729] PPP BSD Compression module registered
[    3.024163] PPP Deflate Compression module registered
[    3.029951] PPP MPPE Compression module registered
[    3.035457] NET: Registered protocol family 24
[    3.040696] usbcore: registered new interface driver r8152
[    3.047032] usbcore: registered new interface driver asix
[    3.053147] usbcore: registered new interface driver ax88179_178a
[    3.059887] usbcore: registered new interface driver cdc_ether
[    3.066412] usbcore: registered new interface driver smsc75xx
[    3.067956] bcm54xx_low_power_mode(): put phy in iddq-lp mode
[    3.079149] usbcore: registered new interface driver net1080
[    3.085449] usbcore: registered new interface driver cdc_subset
[    3.092012] usbcore: registered new interface driver zaurus
[    3.098242] usbcore: registered new interface driver cdc_ncm
[    3.104880] Wake76 for irq=199
[    3.108489] Wake77 for irq=199
[    3.112064] Wake78 for irq=199
[    3.115620] Wake79 for irq=199
[    3.119147] Wake80 for irq=199
[    3.122685] Wake81 for irq=199
[    3.126164] Wake82 for irq=199
[    3.129704] tegra-xotg xotg: usb2 phy is not available yet
[    3.136208] usbcore: registered new interface driver cdc_acm
[    3.142302] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[    3.151211] usbcore: registered new interface driver usb-storage
[    3.157749] usbcore: registered new interface driver usbserial
[    3.164070] usbcore: registered new interface driver cp210x
[    3.170122] usbserial: USB Serial support registered for cp210x
[    3.176509] usbcore: registered new interface driver ftdi_sio
[    3.182750] usbserial: USB Serial support registered for FTDI USB Serial Device
[    3.191054] usbcore: registered new interface driver option
[    3.197173] usbserial: USB Serial support registered for GSM modem (1-port)
[    3.204731] usbcore: registered new interface driver pl2303
[    3.210862] usbserial: USB Serial support registered for pl2303
[    3.217611] tegra-usb-cd usb_cd: otg phy is not available yet
[    3.226028] tegra-xudc-new 3550000.xudc: usb2 phy is not available yet
[    3.254819] ata1: SATA link down (SStatus 0 SControl 300)
[    3.365909] max77686-rtc max77620-rtc: rtc core: registered max77620-rtc as rtc0
[    3.377517] tegra_rtc c2a0000.rtc: rtc core: registered c2a0000.rtc as rtc1
[    3.385611] tegra_rtc c2a0000.rtc: Tegra internal Real Time Clock
[    3.392990] i2c /dev entries driver
[    3.398421] [OV5693]: probing v4l2 sensor.
[    4.273676] gspca_main: v2.14.0 registered
[    4.278992] usbcore: registered new interface driver gspca_zc3xx
[    4.286466] max77620-power max77620-power: Event recorder REG_NVERC : 0x0
[    4.296332] FAN dev name: pwm-fan
[    4.300843] FAN:gpio request success.
[    4.305629] FAN: can't find tach_gpio
[    4.310439] pwm_fan_driver pwm-fan: cap state:7, cap pwm:255
[    4.317435] pwm_fan_driver pwm-fan: got pwm for fan
[    4.323463] pwm_fan_driver pwm-fan: tach period: 1000
[    4.329922] pwm_fan_driver pwm-fan: index 0: pwm=0, rpm=0, rru=40, rrd=40, state:2
[    4.339688] pwm_fan_driver pwm-fan: index 1: pwm=80, rpm=1000, rru=2, rrd=2, state:2
[    4.349667] pwm_fan_driver pwm-fan: index 2: pwm=120, rpm=2000, rru=1, rrd=1, state:2
[    4.359782] pwm_fan_driver pwm-fan: index 3: pwm=160, rpm=3000, rru=1, rrd=1, state:2
[    4.370072] pwm_fan_driver pwm-fan: index 4: pwm=255, rpm=4000, rru=1, rrd=1, state:3
[    4.379561] pwm_fan_driver pwm-fan: index 5: pwm=255, rpm=5000, rru=1, rrd=1, state:3
[    4.388950] pwm_fan_driver pwm-fan: index 6: pwm=255, rpm=6000, rru=1, rrd=1, state:3
[    4.398387] pwm_fan_driver pwm-fan: index 7: pwm=255, rpm=7000, rru=1, rrd=1, state:4
[    4.407871] pwm_fan_driver pwm-fan: index 8: pwm=255, rpm=10000, rru=1, rrd=1, state:4
[    4.417510] pwm_fan_driver pwm-fan: index 9: pwm=255, rpm=11000, rru=1, rrd=1, state:4
[    4.428380] device-mapper: uevent: version 1.0.3
[    4.434196] device-mapper: ioctl: 4.34.0-ioctl (2015-10-28) initialised: [email protected]
[    4.445016] sdhci: Secure Digital Host Controller Interface driver
[    4.452183] sdhci: Copyright(c) Pierre Ossman
[    4.457523] sdhci-pltfm: SDHCI platform and OF driver helper
[    4.464424] sdhci-tegra 3460000.sdhci: Parent select= pll_p rate=408000000
[    4.473187] sdhci-tegra 3460000.sdhci: Parent select= pll_c4_out0 rate=196249804
[    4.483448] tegra-se-elp 3ad0000.se_elp: tegra_se_elp_probe: complete
[    4.483658] sdhci-tegra 3460000.sdhci: Client registration for eMC Successful
[    4.499278] hidraw: raw HID events driver (C) Jiri Kosina
[    4.508146] usbcore: registered new interface driver usbhid
[    4.514662] usbhid: USB HID core driver
[    4.518802] mmc0: SDHCI controller on 3460000.sdhci [3460000.sdhci] using ADMA 64-bit with 64 bit addr
[    4.519084] sdhci-tegra 3440000.sdhci: Parent select= pll_p rate=408000000
[    4.519378] sdhci-tegra 3440000.sdhci: Client registration for eMC Successful
[    4.556632] nvadsp 2993000.adsp: in probe()...
[    4.562795] mmc1: SDHCI controller on 3440000.sdhci [3440000.sdhci] using ADMA 64-bit with 64 bit addr
[    4.576020] sdhci-tegra 3400000.sdhci: Got CD GPIO
[    4.582721] sdhci-tegra 3400000.sdhci: Got WP GPIO
[    4.591442] sdhci-tegra 3400000.sdhci: Parent select= pll_p rate=408000000
[    4.592225] nvadsp 2993000.adsp: Registering AMC Error Interrupt
[    4.592281] nvadsp 2993000.adsp: AMC/ARAM initialized.
[    4.592602] nvadsp 2993000.adsp: nvadsp_app_module_probe
[    4.593685] Denver: backdoor interface is NOT available.
[    4.596543] coresight-tmc 8030000.etf: TMC initialized
[    4.598942] coresight-tmc 8050000.etr: TMC initialized
[    4.599554] coresight-tpiu 8060000.tpiu: TPIU initialized
[    4.600363] coresight-funnel 9010000.funnel_bccplex: FUNNEL initialized
[    4.601037] coresight-funnel 8010000.funnel_major: FUNNEL initialized
[    4.601694] coresight-funnel 8820000.funnel_minor: FUNNEL initialized
[    4.602099] mmc0: MAN_BKOPS_EN bit is not set
[    4.602232] coresight-replicator 8040000.replicator: REPLICATOR initialized
[    4.603183] coresight-etm4x 9840000.ptm: ETM 4.0 initialized
[    4.610351] mmc0: Skipping tuning since strobe enabled
[    4.616513] coresight-etm4x 9940000.ptm: ETM 4.0 initialized
[    4.617281] coresight-etm4x 9a40000.ptm: ETM 4.0 initialized
[    4.618129] coresight-etm4x 9b40000.ptm: ETM 4.0 initialized
[    4.618174] Module initialized successfully 
[    4.619132] mmc0: periodic cache flush enabled
[    4.619143] mmc0: new HS400 MMC card at address 0001
[    4.619672] mmcblk0: mmc0:0001 032G34 29.1 GiB 
[    4.619878] mmcblk0boot0: mmc0:0001 032G34 partition 1 4.00 MiB
[    4.620078] mmcblk0boot1: mmc0:0001 032G34 partition 2 4.00 MiB
[    4.620280] mmcblk0rpmb: mmc0:0001 032G34 partition 3 4.00 MiB
[    4.621872]  mmcblk0: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29
[    4.622385] tegra186-cam-rtcpu b000000.rtcpu: Trace buffer configured at IOVA=0xa0000000
[    4.624875] tegra186-cam-rtcpu b000000.rtcpu: already unhalted
[    4.625307] tegra-ivc ivc-b000000.rtcpu: region 0: iova=0xa0110000-0xa011957f size=38272
[    4.625913] tegra-ivc ivc-b000000.rtcpu:echo@0: echo: ver=0 grp=1 RX[16x64]=0x1000-0x1480 TX[16x64]=0x1480-0x1900
[    4.626025] tegra-ivc ivc-b000000.rtcpu:vinotify@12c0: vinotify: ver=0 grp=1 RX[64x128]=0x1900-0x3980 TX[64x128]=0x3980-0x5a00
[    4.626075] tegra-ivc ivc-b000000.rtcpu:mods@32c0: mods: ver=0 grp=1 RX[1x64]=0x5a00-0x5ac0 TX[1x64]=0x5ac0-0x5b80
[    4.626123] tegra-ivc ivc-b000000.rtcpu:ivccontrol@52c0: ivccontrol: ver=0 grp=1 RX[16x320]=0x5b80-0x7000 TX[16x320]=0x7000-0x8480
[    4.626173] tegra-ivc ivc-b000000.rtcpu:ivccapture@72c0: ivccapture: ver=0 grp=1 RX[16x64]=0x8480-0x8900 TX[16x64]=0x8900-0x8d80
[    4.626221] tegra-ivc ivc-b000000.rtcpu:dbg@7c00: dbg: ver=0 grp=1 RX[1x384]=0x8d80-0x8f80 TX[1x384]=0x8f80-0x9180
[    4.626264] tegra-ivc ivc-b000000.rtcpu:dbg@7e00: dbg: ver=0 grp=1 RX[1x384]=0x9180-0x9380 TX[1x384]=0x9380-0x9580
[    4.626519] tegra186-cam-rtcpu b000000.rtcpu: using cam RTCPU IRQ (52)
[    4.626556] tegra186-cam-rtcpu b000000.rtcpu: tegra_camrtc_mon_create is successful
[    4.628353] tegra-ivc ivc-b000000.rtcpu:echo@0: ivc channel driver missing
[    4.628358] tegra-ivc ivc-b000000.rtcpu:vinotify@12c0: ivc channel driver missing
[    4.628362] tegra-ivc ivc-b000000.rtcpu:mods@32c0: ivc channel driver missing
[    4.628394] tegra-ivc ivc-b000000.rtcpu:ivccontrol@52c0: ivc channel driver missing
[    4.628397] tegra-ivc ivc-b000000.rtcpu:ivccapture@72c0: ivc channel driver missing
[    4.628401] tegra-ivc ivc-b000000.rtcpu:dbg@7c00: ivc channel driver missing
[    4.628405] tegra-ivc ivc-b000000.rtcpu:dbg@7e00: ivc channel driver missing
[    4.628476] tegra186-cam-rtcpu b000000.rtcpu: firmware version cpu=sce cmd=4 sha1=a8b1ecdd9615cd817a56df035be363fce3b0b88f
[    4.634424] tegra-ivc-cdev ivc-b000000.rtcpu:echo@0: probing /dev/camchar-echo
[    4.635528] tegra-ivc-cdev ivc-b000000.rtcpu:dbg@7c00: probing /dev/camchar-dbg
[    4.635726] camchar: rtcpu character device driver loaded
[    4.640756] tegra186-aondbg aondbg: aondbg driver probe() OK
[    4.641236] register_ari_mca_banks: Registered MCA ROC:IOB
[    4.641481] register_ari_mca_banks: Registered MCA ROC:CCE
[    4.642188] tegra18-bridge 2390000.axi2apb: bridge probed OK
[    4.642239] tegra18-bridge 23a0000.axi2apb: bridge probed OK
[    4.642279] tegra18-bridge 23b0000.axi2apb: bridge probed OK
[    4.642315] tegra18-bridge 23c0000.axi2apb: bridge probed OK
[    4.642352] tegra18-bridge 23d0000.axi2apb: bridge probed OK
[    4.642393] tegra18-bridge 2100000.axip2p: bridge probed OK
[    4.642427] tegra18-bridge 2110000.axip2p: bridge probed OK
[    4.642461] tegra18-bridge 2120000.axip2p: bridge probed OK
[    4.642494] tegra18-bridge 2130000.axip2p: bridge probed OK
[    4.642534] tegra18-bridge 2140000.axip2p: bridge probed OK
[    4.642571] tegra18-bridge 2150000.axip2p: bridge probed OK
[    4.642612] tegra18-bridge 2160000.axip2p: bridge probed OK
[    4.642650] tegra18-bridge 2170000.axip2p: bridge probed OK
[    4.642724] tegra18-bridge 2180000.axip2p: bridge probed OK
[    4.642758] tegra18-bridge 2190000.axip2p: bridge probed OK
[    4.642850] tegra18_a57_serr_init: on CPU 1 a Denver Core
[    4.643004] parse_throttle_dt_data: Num cap clks = 4
[    4.643009] parse_throttle_dt_data: clk=mcpu type=1
[    4.643012] parse_throttle_dt_data: clk=bcpu type=2
[    4.643023] parse_throttle_dt_data: clk=gpu type=4
[    4.643026] parse_throttle_dt_data: clk=emc type=3
[    4.643771] tegra_throttle_probe: probe successful. #cdevs=4
[    4.643876] tegra18x_actmon d230000.actmon: in actmon_register()...
[    4.647563] tegra18x_actmon d230000.actmon: initialization Completed for the device mc_all
[    4.647960] hw perfevents: enabled with denver15_uncore_pmu PMU driver, 3 counters available
[    4.650648] tegra-se-nvhost 15810000.se: initialized
[    4.651331] tegra-se-nvhost 15810000.se: tegra_se_probe: complete
[    4.651775] tegra-se-nvhost 15820000.se: initialized
[    4.652462] tegra-se-nvhost 15820000.se: tegra_se_probe: complete
[    4.652817] tegra-se-nvhost 15830000.se: initialized
[    4.652967] tegra-se-nvhost 15830000.se: tegra_se_probe: complete
[    4.653306] tegra-se-nvhost 15840000.se: initialized
[    4.653935] tegra-se-nvhost 15840000.se: tegra_se_probe: complete
[    4.659146] tegra-gpcdma 2600000.dma: GPC DMA driver register 32 channels
[    4.663136] cpufreq: platform driver Initialization: pass
[    4.663261] tegra_cluster_clk e090000.cluster_clk_priv: in probe()...
[    4.663332] mmc1: queuing unknown CIS tuple 0x80 (5 bytes)
[    4.663340] tegra_cluster_clk e090000.cluster_clk_priv: passed
[    4.663519] tegra186-padctl 3520000.pinctrl: padctl mmio start 0x0000000003520000 end 0x0000000003520fff
[    4.663525] tegra186-padctl 3520000.pinctrl: ao mmio start 0x0000000003540000 end 0x0000000003540fff
[    4.663561] tegra186-padctl 3520000.pinctrl: FUSE_SKU_USB_CALIB_0 0x28b915
[    4.663565] tegra186-padctl 3520000.pinctrl: FUSE_USB_CALIB_EXT_0 0x8
[    4.664992] tegra186-padctl 3520000.pinctrl: using UTMI port 0 for otg
[    4.665631] tegra186-padctl 3520000.pinctrl: VBUS over-current detection enabled
[    4.666244] tegra-bpmp-thermal d000000.bpmp:bpmpthermal: zone 0 not supported
[    4.666688] tegra-bpmp-thermal d000000.bpmp:bpmpthermal: zone 3 not supported
[    4.673688] cpuidle: Initializing cpuidle driver init for Denver cluster
[    4.673825] cpuidle: Initializing cpuidle driver init for A57 cluster
[    4.675034] tachometer tegra-tachometer: Tachometer driver tegra-tachometer registered
[    4.675038] Tachometer driver initialized with pulse_per_rev: 2 and win_len: 2
[    4.679186] tegra210_adsp_audio_platform_probe: platform probe started
[    4.680253] tegra210-adsp adsp_audio: Default param-type to BYTE for mp3-dec1
[    4.683021] tegra210-adsp adsp_audio: Default param-type to BYTE for spkprot
[    4.684079] tegra210-adsp adsp_audio: Default param-type to BYTE for src
[    4.684810] tegra210-adsp adsp_audio: Default param-type to BYTE for aac-dec1
[    4.685265] input: tegra-hda HDMI/DP,pcm=3 as /devices/3510000.hda/sound/card0/input0
[    4.685447] input: tegra-hda HDMI/DP,pcm=7 as /devices/3510000.hda/sound/card0/input1
[    4.685792] tegra210-adsp adsp_audio: Default param-type to BYTE for aec
[    4.685799] tegra210-adsp adsp_audio: adma channel page address dt entry not found
[    4.685801] tegra210-adsp adsp_audio: using adma channel page 0
[    4.698328] tegra210_adsp_audio_platform_probe probe successfull.
[    4.698329] OPE platform probe
[    4.698424] OPE platform probe successful
[    4.781989] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF1 <-> ADMAIF1 mapping ok
[    4.782083] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF2 <-> ADMAIF2 mapping ok
[    4.782178] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF3 <-> ADMAIF3 mapping ok
[    4.782272] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF4 <-> ADMAIF4 mapping ok
[    4.782365] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF5 <-> ADMAIF5 mapping ok
[    4.782482] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF6 <-> ADMAIF6 mapping ok
[    4.782575] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF7 <-> ADMAIF7 mapping ok
[    4.782684] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF8 <-> ADMAIF8 mapping ok
[    4.782801] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF9 <-> ADMAIF9 mapping ok
[    4.782894] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF10 <-> ADMAIF10 mapping ok
[    4.782992] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF11 <-> ADMAIF11 mapping ok
[    4.783084] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF12 <-> ADMAIF12 mapping ok
[    4.783196] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF13 <-> ADMAIF13 mapping ok
[    4.783288] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF14 <-> ADMAIF14 mapping ok
[    4.783378] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF15 <-> ADMAIF15 mapping ok
[    4.783486] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF16 <-> ADMAIF16 mapping ok
[    4.783584] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF17 <-> ADMAIF17 mapping ok
[    4.783673] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF18 <-> ADMAIF18 mapping ok
[    4.783769] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF19 <-> ADMAIF19 mapping ok
[    4.783863] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF20 <-> ADMAIF20 mapping ok
[    4.787346] tegra-snd-t186ref-mobile-rt565x sound: ADSP-FE1 <-> ADSP PCM1 mapping ok
[    4.787442] tegra-snd-t186ref-mobile-rt565x sound: ADSP-FE2 <-> ADSP PCM2 mapping ok
[    4.787469] compress asoc: ADSP-FE3 <-> ADSP COMPR1 mapping ok
[    4.787491] compress asoc: ADSP-FE4 <-> ADSP COMPR2 mapping ok
[    4.818833] input: tegra-snd-t186ref-mobile-rt565x Headphone Jack as /devices/sound/sound/card1/input2
[    4.819380] tegra-snd-t186ref-mobile-rt565x sound: codec-dai "dit-hifi" registered
[    4.819383] tegra-snd-t186ref-mobile-rt565x sound: This is a dummy codec
[    4.819852] GACT probability NOT on
[    4.819862] Mirror/redirect action on
[    4.819872] u32 classifier
[    4.819873]     Actions configured
[    4.819896] nf_conntrack version 0.5.0 (65536 buckets, 262144 max)
[    4.820453] IPVS: Registered protocols ()
[    4.820477] IPVS: Connection hash table configured (size=4096, memory=64Kbytes)
[    4.820559] IPVS: Creating netns size=1424 id=0
[    4.820585] IPVS: ipvs loaded.
[    4.820591] IPVS: [rr] scheduler registered.
[    4.820681] ipip: IPv4 over IPv4 tunneling driver
[    4.820980] Initializing XFRM netlink socket
[    4.821239] NET: Registered protocol family 10
[    4.826523] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    4.826588] NET: Registered protocol family 17
[    4.826604] NET: Registered protocol family 15
[    4.826646] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    4.826651] 8021q: 802.1Q VLAN Support v1.8
[    4.831816] Registered cp15_barrier emulation handler
[    4.845143] Registered setend emulation handler
[    4.846929] registered taskstats version 1
[    4.850444] isp 15600000.isp: initialized
[    4.854325] nvcsi 150c0000.nvcsi: initialized
[    4.859244] Wake76 for irq=199
[    4.859245] Wake77 for irq=199
[    4.859246] Wake78 for irq=199
[    4.859247] Wake79 for irq=199
[    4.859247] Wake80 for irq=199
[    4.859248] Wake81 for irq=199
[    4.859249] Wake82 for irq=199
[    4.859551] xhci-tegra 3530000.xhci: UTMI port 0 has OTG_CAP
[    4.859553] xhci-tegra 3530000.xhci: No USB3 port has OTG_CAP
[    4.860639] mmc1 tuning done saved tap delay=22
[    4.860640] mmc1: hw tuning done ...
[    4.860646] mmc1: tuning_window[0]: 0xfffffffe
[    4.860651] mmc1: tuning_window[1]: 0xffff8fff
[    4.860655] mmc1: tuning_window[2]: 0xe3ffffff
[    4.860659] mmc1: tuning_window[3]: 0x7fffffff
[    4.860663] mmc1: tuning_window[4]: 0x0
[    4.860667] mmc1: tuning_window[5]: 0x0
[    4.860694] mmc1: tuning_window[6]: 0x0
[    4.860698] mmc1: tuning_window[7]: 0x0
[    4.860700] sdhci: Tap value: 22 | Trim value: 5
[    4.860703] sdhci: SDMMC_VENDOR_INTR_STATUS[0x108]: 0x40000
[    4.865259] mmc1: queuing unknown CIS tuple 0x91 (3 bytes)
[    4.865293] mmc1: new ultra high speed SDR104 SDIO card at address 0001
[    4.882852] xhci-tegra 3530000.xhci: Direct firmware load for tegra18x_xusb_firmware failed with error -2
[    4.882854] xhci-tegra 3530000.xhci: Falling back to user helper
[    4.883152] spi-tegra114 3210000.spi: Static pin configuration used
[    4.883819] spi-tegra114 c260000.spi: Static pin configuration used
[    4.884552] spi-tegra114 3240000.spi: Static pin configuration used
[    4.885218] tegra-xotg xotg: OTG rev:0200, ADP:0, SRP:1, HNP:1, RSP:0
[    4.885252] tegra-xotg xotg: update_id_state: ID floating
[    4.885256] tegra-xotg xotg: update_vbus_state: VBUS not detected
[    4.885269] tegra-xotg xotg: Nvidia XUSB OTG Controller
[    4.886961] tegra-xotg xotg: otg: gadget gadget registered
[    4.886963] tegra-xotg xotg: set gadget otg_caps from OTG controller
[    4.886964] tegra-xotg xotg: otg: host not registered yet
[    4.886966] tegra-xotg xotg: otg: start OTG finite state machine
[    4.887007] tegra-xudc-new 3550000.xudc: entering ELPG
[    4.887499] tegra-xudc-new 3550000.xudc: entering ELPG done
[    4.888103] input: gpio-keys as /devices/gpio-keys/input/input3
[    4.925578] tegra_rtc c2a0000.rtc: setting system clock to 2018-08-17 10:31:17 UTC (1534501877)
[    4.955611] bpmp: mounted debugfs mirror
[    4.956142] [dram-timers] DRAM derating cdev registered.
[    4.960576] spmic-ldo0: disabling
[    4.960768] spmic-ldo1: disabling
[    4.960914] vddio-sdmmc1: disabling
[    4.961089] en-vdd-sd: disabling
[    4.961090] en-vdd-cam: disabling
[    4.961092] vdd-usb0-5v: disabling
[    4.961094] vdd-usb1-5v: disabling
[    4.961097] en-vdd-disp-3v3: disabling
[    4.961099] en-mdm-pwr-3v7: disabling
[    4.961100] en-vdd-disp-1v8: disabling
[    4.961102] en-vdd-cam-hv-2v8: disabling
[    4.961103] en-vdd-cam-1v2: disabling
[    4.961105] vdd-fan: disabling
[    4.961106] vdd-3v3: disabling
[    4.961108] en-vdd-vcm-2v8: disabling
[    4.961109] vdd-usb2-5v: disabling
[    4.961111] vdd-sys-bl: disabling
[    4.961112] en-vdd-sys: disabling
[    4.968391] ALSA device list:
[    4.968392]   #0: tegra-hda at 0x3518000 irq 400
[    4.968393]   #1: tegra-snd-t186ref-mobile-rt565x
[    4.969367] tegra-vi4 15700000.vi: initialized
[    4.970561] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi-2 bound
[    4.970564] tegra-vi4 15700000.vi: subdev ov5693 2-0036 bound
[    6.168179] sdhci-tegra 3400000.sdhci: wakeup init done, cd_irq: 256
[    6.175417] sdhci-tegra 3400000.sdhci: Client registration for eMC Successful
[    6.222905] mmc2: SDHCI controller on 3400000.sdhci [3400000.sdhci] using ADMA 64-bit with 64 bit addr
[    6.238039] EXT4-fs (mmcblk0p1): mounted filesystem with ordered data mode. Opts: (null)
[    6.247159] VFS: Mounted root (ext4 filesystem) on device 179:1.
[    6.255935] devtmpfs: mounted
[    6.259790] Freeing unused kernel memory: 1168K (ffffffc001132000 - ffffffc001256000)
[    6.268890] Freeing alternatives memory: 96K (ffffffc001256000 - ffffffc00126e000)
[    6.285072] btb inv war enabled
[    6.344007] random: systemd: uninitialized urandom read (16 bytes read, 89 bits of entropy available)
[    6.356864] random: systemd: uninitialized urandom read (16 bytes read, 90 bits of entropy available)
[    6.367701] random: systemd: uninitialized urandom read (16 bytes read, 90 bits of entropy available)
[    6.379576] systemd[1]: systemd 229 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN)
[    6.400693] systemd[1]: Detected architecture arm64.
[    6.413216] systemd[1]: Set hostname to <tegra-ubuntu>.
[    6.429177] random: systemd: uninitialized urandom read (16 bytes read, 91 bits of entropy available)
[    6.444968] random: systemd-sysv-ge: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.445203] random: systemd-cryptse: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.457340] random: systemd-gpt-aut: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.457403] random: systemd-gpt-aut: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.457418] random: systemd-gpt-aut: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.457519] random: systemd-gpt-aut: uninitialized urandom read (16 bytes read, 92 bits of entropy available)
[    6.596084] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
[    6.606945] systemd[1]: Listening on Journal Audit Socket.
[    6.614478] systemd[1]: Reached target Encrypted Volumes.
[    6.622437] systemd[1]: Created slice User and Session Slice.
[    6.630273] systemd[1]: Reached target User and Group Name Lookups.
[    6.638674] systemd[1]: Listening on Journal Socket (/dev/log).
[    6.647139] systemd[1]: Created slice System Slice.
[    6.654519] systemd[1]: Created slice system-getty.slice.
[    6.662359] systemd[1]: Created slice system-serial\x2dgetty.slice.
[    6.670610] systemd[1]: Reached target Slices.
[    6.677016] systemd[1]: Listening on udev Control Socket.
[    6.684290] systemd[1]: Reached target Swap.
[    6.690356] systemd[1]: Reached target Remote File Systems (Pre).
[    6.698230] systemd[1]: Reached target Remote File Systems.
[    6.705922] systemd[1]: Listening on Syslog Socket.
[    6.712254] systemd[1]: Listening on Journal Socket.
[    6.720636] systemd[1]: Started Braille Device Support.
[    6.729714] systemd[1]: Starting Journal Service...
[    6.738253] systemd[1]: Starting Create list of required static device nodes for the current kernel...
[    6.751477] systemd[1]: Starting Remount Root and Kernel File Systems...
[    6.757179] EXT4-fs (mmcblk0p1): re-mounted. Opts: (null)
[    6.768114] systemd[1]: Mounting Debug File System...
[    6.776951] systemd[1]: Mounting POSIX Message Queue File System...
[    6.792538] systemd[1]: Starting Load Kernel Modules...
[    6.799381] systemd[1]: Listening on udev Kernel Socket.
[    6.806153] systemd[1]: Listening on /dev/initctl Compatibility Named Pipe.
[    6.819037] systemd[1]: Mounted Debug File System.
[    6.825291] systemd[1]: Mounted POSIX Message Queue File System.
[    6.833169] systemd[1]: Started Journal Service.
[    7.006692] systemd-journald[266]: Received request to flush runtime journal from PID 1
[    7.157694] random: nonblocking pool is initialized
[    7.220812] tegra-pcie 10003000.pcie-controller: 4x1, 1x1 configuration
[    7.233523] tegra-pcie 10003000.pcie-controller: PCIE: Enable power rails
[    7.233989] tegra-pcie 10003000.pcie-controller: probing port 0, using 4 lanes
[    7.236178] tegra-pcie 10003000.pcie-controller: probing port 2, using 1 lanes
[    7.270751] xhci-tegra 3530000.xhci: cannot find firmware....retry after 1 second
[    7.674827] tegra-pcie 10003000.pcie-controller: link 0 down, retrying
[    7.908968] using random self ethernet address
[    7.914074] using random host ethernet address
[    7.983794] Mass Storage Function, version: 2009/09/11
[    7.989621] LUN: removable file: (no medium)
[    7.998509] using random self ethernet address
[    8.003682] using random host ethernet address
[    8.013831] usb0: HOST MAC b2:70:9e:57:56:95
[    8.018901] usb0: MAC e2:77:7e:3f:85:d9
[    8.023765] usb1: HOST MAC ba:df:d6:74:b0:bf
[    8.028781] usb1: MAC 86:ae:77:cc:0c:76
[    8.033323] tegra-xudc-new 3550000.xudc: exiting ELPG
[    8.040131] tegra-xudc-new 3550000.xudc: exiting ELPG done
[    8.046340] tegra-xudc-new 3550000.xudc: ep 0 (type: 0, dir: out) enabled
[    8.053848] tegra-xudc-new 3550000.xudc: entering ELPG
[    8.060497] tegra-xudc-new 3550000.xudc: entering ELPG done
[    8.067119] tegra-xudc-new 3550000.xudc: exiting ELPG
[    8.074434] tegra-xudc-new 3550000.xudc: exiting ELPG done
[    8.080673] tegra-xudc-new 3550000.xudc: entering ELPG
[    8.080946] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081014] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081048] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081080] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081112] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081144] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081176] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081207] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081240] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081271] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081303] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081335] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081367] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081399] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081430] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081463] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081495] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081528] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081560] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081591] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081623] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081656] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081688] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081719] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081752] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081785] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081816] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081848] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081880] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081913] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081942] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081970] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.081998] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082026] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082055] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082084] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082111] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082139] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082167] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082195] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082223] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082251] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082281] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082310] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082339] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082368] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082398] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082428] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082456] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082484] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082514] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082543] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082572] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.082603] tegra210-adsp adsp_audio: ADSP is not booted yet
[    8.130083] tegra-pcie 10003000.pcie-controller: link 0 down, retrying
[    8.221953] device usb0 entered promiscuous mode
[    8.226259] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[    8.230506] device usb1 entered promiscuous mode
[    8.236230] IPv6: ADDRCONF(NETDEV_UP): usb1: link is not ready
[    8.236236] l4tbr0: port 2(usb1) entered forwarding state
[    8.236252] l4tbr0: port 2(usb1) entered forwarding state
[    8.283110] xhci-tegra 3530000.xhci: Firmware timestamp: 2017-12-07 10:50:08 UTC, Version: 55.09 release
[    8.284579] xhci-tegra 3530000.xhci: xHCI Host Controller
[    8.284593] xhci-tegra 3530000.xhci: new USB bus registered, assigned bus number 1
[    8.285411] xhci-tegra 3530000.xhci: hcc params 0x0184fd25 hci version 0x100 quirks 0x00010810
[    8.285432] xhci-tegra 3530000.xhci: irq 59, io mem 0x03530000
[    8.285536] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    8.285538] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    8.285540] usb usb1: Product: xHCI Host Controller
[    8.285542] usb usb1: Manufacturer: Linux 4.4.38-tegra xhci-hcd
[    8.285543] usb usb1: SerialNumber: 3530000.xhci
[    8.285789] hub 1-0:1.0: USB hub found
[    8.285809] hub 1-0:1.0: 4 ports detected
[    8.314984] xhci-tegra 3530000.xhci: xHCI Host Controller
[    8.314991] xhci-tegra 3530000.xhci: new USB bus registered, assigned bus number 2
[    8.315208] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003
[    8.315211] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    8.315213] usb usb2: Product: xHCI Host Controller
[    8.315215] usb usb2: Manufacturer: Linux 4.4.38-tegra xhci-hcd
[    8.315217] usb usb2: SerialNumber: 3530000.xhci
[    8.315500] hub 2-0:1.0: USB hub found
[    8.315523] hub 2-0:1.0: 3 ports detected
[    8.315919] tegra-xotg xotg: otg: host 3530000.xhci registered
[    8.400876] dhd_module_init in
[    8.400904] tegra_net_perf_init: cannot get wifi sclk
[    8.400969] found wifi platform device bcmdhd_wlan
[    8.402047] wifi_platform_get_country_code_map: could not get country_code_map
[    8.402049] wifi_plat_dev_drv_probe:platform country code map is not available
[    8.402060] Power-up adapter 'DHD generic adapter'
[    8.402065] wifi_platform_set_power = 1
[    8.532445] tegra-pcie 10003000.pcie-controller: link 0 down, retrying
[    8.534468] tegra-pcie 10003000.pcie-controller: link 0 down, ignoring
[    8.594823] usb 1-2: new high-speed USB device number 2 using xhci-tegra
[    8.605432] wifi_platform_bus_enumerate device present 1
[    8.623392] wifi_platform_bus_enumerate device present 0
[    8.623865] F1 signature read @0x18000000=0x17214354
[    8.627321] F1 signature OK, socitype:0x1 chip:0x4354 rev:0x1 pkg:0x2
[    8.627797] DHD: dongle ram size is set to 786432(orig 786432) at 0x180000
[    8.627849] wifi_platform_prealloc: failed to alloc static mem section 7
[    8.627854] wifi_platform_get_mac_addr
[    8.629466] CFG80211-ERROR) wl_setup_wiphy : Registering Vendor80211
[    8.629956] wl_create_event_handler(): thread:wl_event_handler:28c started
[    8.629961] CFG80211-ERROR) wl_event_handler : tsk Enter, tsk = 0xffffffc1e1721a70
[    8.630195] dhd_attach(): thread:dhd_watchdog_thread:28d started
[    8.630238] dhd_attach(): thread:dhd_dpc:28e started
[    8.630287] dhd_attach(): thread:dhd_rxf:28f started
[    8.630291] dhd_deferred_work_init: work queue initialized 
[    8.630447] Dongle Host Driver, version 1.201.82 (r)
               Compiled in drivers/net/wireless/bcmdhd on May 17 2018 at 00:12:47
[    8.630723] tegra_sysfs_register
[    8.630747] Register interface [wlan0]  MAC: 00:04:4b:8d:84:75

[    8.630749] dhd_prot_ioctl : bus is down. we have nothing to do
[    8.630860] sdhci-tegra 3440000.sdhci: Tuning already done, restoring the best tap value : 22
[    8.631899] wifi_platform_set_power = 0
[    8.639335] usb 2-1: new SuperSpeed USB device number 2 using xhci-tegra
[    8.664911] usb 2-1: New USB device found, idVendor=0bda, idProduct=0411
[    8.664914] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    8.664917] usb 2-1: Product: 4-Port USB 3.0 Hub
[    8.664918] usb 2-1: Manufacturer: Generic
[    8.665491] xhci-tegra 3530000.xhci: tegra_xhci_mbox_work mailbox command 6
[    8.670107] hub 2-1:1.0: USB hub found
[    8.670871] hub 2-1:1.0: 4 ports detected
[    8.740902] usb 1-2: New USB device found, idVendor=0bda, idProduct=5411
[    8.740905] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    8.740907] usb 1-2: Product: 4-Port USB 2.0 Hub
[    8.740908] usb 1-2: Manufacturer: Generic
[    8.741688] hub 1-2:1.0: USB hub found
[    8.742232] hub 1-2:1.0: 4 ports detected
[    8.885239] tegra-xudc-new 3550000.xudc: entering ELPG done
[    8.940816] tegra-pcie 10003000.pcie-controller: link 2 down, retrying
[    9.018844] l4tbr0: port 2(usb1) entered disabled state
[    9.025354] usb 1-2.4: new full-speed USB device number 3 using xhci-tegra
[    9.140841] usb 1-2.4: New USB device found, idVendor=0d8c, idProduct=0014
[    9.148789] usb 1-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    9.158126] usb 1-2.4: Product: USB Audio Device
[    9.163750] usb 1-2.4: Manufacturer: C-Media Electronics Inc.
[    9.172822] input: C-Media Electronics Inc. USB Audio Device as /devices/3530000.xhci/usb1/1-2/1-2.4/1-2.4:1.3/0003:0D8C:0014.0001/input/input4
[    9.236780] IPVS: Creating netns size=1424 id=1
[    9.243072] hid-generic 0003:0D8C:0014.0001: input,hidraw0: USB HID v1.00 Device [C-Media Electronics Inc. USB Audio Device] on usb-3530000.xhci-2.4/input3
[    9.348558] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[    9.396291] usbcore: registered new interface driver snd-usb-audio
[    9.400625] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[    9.400745] 
               Dongle Host Driver, version 1.201.82 (r)
               Compiled in drivers/net/wireless/bcmdhd on May 17 2018 at 00:12:47
[    9.400747] wl_android_wifi_on in
[    9.400749] wifi_platform_set_power = 1
[    9.412844] tegra-pcie 10003000.pcie-controller: link 2 down, retrying
[    9.644599] gk20a 17000000.gp10b: railgate is disabled.
[    9.671527] mmc1: queuing unknown CIS tuple 0x80 (5 bytes)
[    9.689123] tegradc 15210000.nvdisplay: blank - powerdown
[    9.743308] sdhci-tegra 3440000.sdhci: Tuning already done, restoring the best tap value : 22
[    9.752700] F1 signature read @0x18000000=0x17214354
[    9.762644] F1 signature OK, socitype:0x1 chip:0x4354 rev:0x1 pkg:0x2
[    9.769894] DHD: dongle ram size is set to 786432(orig 786432) at 0x180000
[    9.814832] tegra-pcie 10003000.pcie-controller: link 2 down, retrying
[    9.822843] tegra-pcie 10003000.pcie-controller: link 2 down, ignoring
[    9.829467] tegra-pcie 10003000.pcie-controller: PCIE: no end points detected
[    9.837152] tegra-pcie 10003000.pcie-controller: PCIE: Disable power rails
[    9.924018] dhdsdio_write_vars: Download, Upload and compare of NVRAM succeeded.
[    9.973582] dhd_bus_init: enable 0x06, ready 0x06 (waited 0us)
[    9.979753] Enabling wake69
[    9.983325] wifi_platform_get_mac_addr
[    9.988733] Firmware up: op_mode=0x0005, MAC=00:04:4b:8d:84:75
[   10.001113] dhd_preinit_ioctls pspretend_threshold for HostAPD failed  -23
[   10.012951] Firmware version = wl0: Dec 12 2017 15:09:35 version 7.35.221.34 (r679642) FWID 01-e35dbe99
[   10.024916] dhd_interworking_enable: failed to set WNM info, ret=-23
[   10.031545] tegra_sysfs_on
[   10.146437] cfg80211: World regulatory domain updated:
[   10.151708] cfg80211:  DFS Master region: unset
[   10.156191] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[   10.166077] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   10.166089] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   10.166092] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[   10.166097] cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (N/A)
[   10.166101] cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (0 s)
[   10.166104] cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   10.166107] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[   10.166110] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[   10.376664] CFGP2P-ERROR) wl_cfgp2p_add_p2p_disc_if : P2P interface registered
[   10.409667] WLC_E_IF: NO_IF set, event Ignored
[   10.424316] xhci-tegra 3530000.xhci: tegra_xhci_mbox_work mailbox command 5
[   10.431400] xhci-tegra 3530000.xhci: tegra_xhci_mbox_work ignore firmware MBOX_CMD_DEC_SSPI_CLOCK request
[   11.018830] CPU1: shutdown
[   11.021578] psci: CPU1 killed.
[   11.049448] CPU2: shutdown
[   11.052444] psci: CPU2 killed.
[   11.109077] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   11.118525] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   11.915494] eqos 2490000.ether_qos eth0: Link is Down
[   12.221027] CFG80211-ERROR) wl_cfg80211_connect : Connectting with78:11:dc:00:e5:e2 channel (3) ssid "FMTech", len (6)

[   12.263932] Bridge firewalling registered
[   12.315800] ip_tables: (C) 2000-2006 Netfilter Core Team
[   12.355127] CFG80211-ERROR) wl_notify_connect_status : wl_bss_connect_done succeeded with 78:11:dc:00:e5:e2
[   12.385344] CFG80211-ERROR) wl_bss_connect_done : Report connect result - connection succeeded
[   12.397434] cfg80211: Regulatory domain changed to country: CN
[   12.403712] cfg80211:  DFS Master region: FCC
[   12.408029] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[   12.418021] cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   12.423609] CFG80211-ERROR) wl_notify_connect_status : wl_bss_connect_done succeeded with 78:11:dc:00:e5:e2
[   12.435815] cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (N/A)
[   12.445329] cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (0 s)
[   12.454857] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 3000 mBm), (N/A)
[   12.462912] cfg80211:   (57240000 KHz - 59400000 KHz @ 2160000 KHz), (N/A, 2800 mBm), (N/A)
[   12.471322] cfg80211:   (59400000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4400 mBm), (N/A)
[   12.479758] cfg80211:   (63720000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 2800 mBm), (N/A)
[   12.581356] fuse init (API version 7.23)
[   12.609951] dhd_ndo_add_ip: ndo ip addr add failed, retcode = -23
[   12.616115] dhd_inet6_work_handler: Adding host ip for NDO failed -23
[   12.929034] IPv6: ADDRCONF(NETDEV_UP): docker0: link is not ready
[   13.580853] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   14.431970] eqos 2490000.ether_qos eth0: Link is Down
[   15.204507] IPVS: Creating netns size=1424 id=2
[   16.097453] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   16.845438] IPVS: Creating netns size=1424 id=3
[   16.948499] eqos 2490000.ether_qos eth0: Link is Down
[   18.613924] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   19.465011] eqos 2490000.ether_qos eth0: Link is Down
[   21.091775] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   21.981528] eqos 2490000.ether_qos eth0: Link is Down
[   23.607684] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   24.498163] eqos 2490000.ether_qos eth0: Link is Down
[   26.124451] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   27.014666] eqos 2490000.ether_qos eth0: Link is Down
[   28.640948] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   29.531209] eqos 2490000.ether_qos eth0: Link is Down
[   31.157430] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   32.047714] eqos 2490000.ether_qos eth0: Link is Down
[   33.674073] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   34.564221] eqos 2490000.ether_qos eth0: Link is Down
[   36.190987] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   37.080735] eqos 2490000.ether_qos eth0: Link is Down
[   38.707205] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   39.330757] bcm54xx_low_power_mode(): put phy in iddq-lp mode
[   46.629260] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   47.398461] eqos 2490000.ether_qos eth0: Link is Down
[   49.199560] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   49.998920] eqos 2490000.ether_qos eth0: Link is Down
[   51.662213] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   52.431504] eqos 2490000.ether_qos eth0: Link is Down
[   54.114664] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   54.864137] eqos 2490000.ether_qos eth0: Link is Down
[   56.586614] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   57.380646] eqos 2490000.ether_qos eth0: Link is Down
[   59.044208] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   59.813283] eqos 2490000.ether_qos eth0: Link is Down
[   61.476859] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   62.245916] eqos 2490000.ether_qos eth0: Link is Down
[   63.909560] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   64.678542] eqos 2490000.ether_qos eth0: Link is Down
[   66.342145] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   67.111191] eqos 2490000.ether_qos eth0: Link is Down
[   68.774903] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   69.543819] eqos 2490000.ether_qos eth0: Link is Down
[   71.207523] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   71.976453] eqos 2490000.ether_qos eth0: Link is Down
[   73.640178] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   74.409091] eqos 2490000.ether_qos eth0: Link is Down
[   76.072816] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   76.841725] eqos 2490000.ether_qos eth0: Link is Down
[   78.525082] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   79.274258] eqos 2490000.ether_qos eth0: Link is Down
[   80.937880] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   81.706891] eqos 2490000.ether_qos eth0: Link is Down
[   83.508401] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   84.307280] eqos 2490000.ether_qos eth0: Link is Down
[   85.971381] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   86.740018] eqos 2490000.ether_qos eth0: Link is Down
[   88.403741] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   89.172670] eqos 2490000.ether_qos eth0: Link is Down
[   90.836519] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   91.605289] eqos 2490000.ether_qos eth0: Link is Down
[   93.269181] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   94.037923] eqos 2490000.ether_qos eth0: Link is Down
[   95.701830] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   96.470558] eqos 2490000.ether_qos eth0: Link is Down
[   98.134487] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   98.903221] eqos 2490000.ether_qos eth0: Link is Down
[  100.567197] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  101.335830] eqos 2490000.ether_qos eth0: Link is Down
[  103.098065] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  103.936224] eqos 2490000.ether_qos eth0: Link is Down
[  105.600227] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  106.368864] eqos 2490000.ether_qos eth0: Link is Down
[  108.032927] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  108.801496] eqos 2490000.ether_qos eth0: Link is Down
[  110.465502] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  111.234132] eqos 2490000.ether_qos eth0: Link is Down
[  113.547007] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  114.337834] eqos 2490000.ether_qos eth0: Link is Down
[  116.002018] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  116.770463] eqos 2490000.ether_qos eth0: Link is Down
[  118.434552] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  119.203126] eqos 2490000.ether_qos eth0: Link is Down
[  120.867322] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  121.635893] eqos 2490000.ether_qos eth0: Link is Down
[  123.299963] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  124.068375] eqos 2490000.ether_qos eth0: Link is Down
[  125.732566] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  126.500998] eqos 2490000.ether_qos eth0: Link is Down
[  128.165277] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  128.933631] eqos 2490000.ether_qos eth0: Link is Down
[  130.617502] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  131.366238] eqos 2490000.ether_qos eth0: Link is Down
[  133.050159] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  133.798958] eqos 2490000.ether_qos eth0: Link is Down
[  135.502511] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  136.315421] eqos 2490000.ether_qos eth0: Link is Down
[  137.979729] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  138.748062] eqos 2490000.ether_qos eth0: Link is Down
[  140.412391] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  141.180705] eqos 2490000.ether_qos eth0: Link is Down
[  142.845010] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  143.613287] eqos 2490000.ether_qos eth0: Link is Down
[  145.277705] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  146.045972] eqos 2490000.ether_qos eth0: Link is Down
[  147.710322] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  148.478591] eqos 2490000.ether_qos eth0: Link is Down
[  150.143057] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  150.911255] eqos 2490000.ether_qos eth0: Link is Down
[  152.575756] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  153.343856] eqos 2490000.ether_qos eth0: Link is Down
[  155.008258] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  155.776494] eqos 2490000.ether_qos eth0: Link is Down
[  157.440994] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  158.209135] eqos 2490000.ether_qos eth0: Link is Down
[  159.873610] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[  160.641747] eqos 2490000.ether_qos eth0: Link is Down
[  162.502927] eqos 2490000.ether_qos eth0: Link is Up - 100Mbps/Full - flow control rx/tx

jetson tx2 开机

拿到一套 jetson tx2 开发套件。

image

核心板和扩展板:

image


这套机器刚买回来,还是出厂状态。HDMI 连接到显示器,接上电源,短按 POWER 键。电源键旁边的两个黄色 LED 灯亮,开机。显示器上会有 Linux 启动信息。最后进入终端。

cd NVDIA-INSTALLER/
sudo ./installer.sh (密码为 nvidia)
reboot (安装完成之后重启)

重启之后就可以进入图形界面了。是个标准的 ubuntu。

image

装上 WIFI 天线,无线的信号强了不少。然后连接我们的 SSID,WIFI 连接成功之后,查询到分配的 IP 地址。即可从我们的电脑上 ssh 远程登陆到开发板。

然后在终端下查看开发板上的系统信息:

nvidia@tegra-ubuntu:~$ uname  -a
Linux tegra-ubuntu 4.4.38-tegra #1 SMP PREEMPT Fri Jul 28 09:55:22 PDT 2017 aarch64 aarch64 aarch64 GNU/Linux


nvidia@tegra-ubuntu:~$ uname -a
Linux tegra-ubuntu 4.4.38-tegra #1 SMP PREEMPT Fri Jul 28 09:55:22 PDT 2017 aarch64 aarch64 aarch64 GNU/Linux


nvidia@tegra-ubuntu:~$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7850        1090        6005          30         753        6648
Swap:             0           0           0


nvidia@tegra-ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        28G  5.8G   21G  23% /
devtmpfs        7.7G     0  7.7G   0% /dev
tmpfs           7.7G  172K  7.7G   1% /dev/shm
tmpfs           7.7G   30M  7.7G   1% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           7.7G     0  7.7G   0% /sys/fs/cgroup
tmpfs           786M   92K  785M   1% /run/user/1001


nvidia@tegra-ubuntu:~$ cat /etc/debian_version 
stretch/sid

看到 jetson_clocks.sh 里有 do_fan 的字样。试着执行:sudo ./jetson_clocks.sh 果然 CPU 风扇开始转了。

image

STM32F103ZET6 普中科技 开发板

最开始学习 STM32 时买的一块开发板。选择它的原因是外设比较丰富,接口基本上都引出来了。板载有现成的扩展模块可以把基础的环境弄好。

外设:

  • USART1 ~ CH340
  • USART2 ~ 485/ESP8266
  • USART3 ~ R232 (与 I2C2 复用引脚)
  • I2C1 ~ FW 编码器输入
  • I2C2 ~ ADX345 (与 USART3 复用引脚)+ EEPROM (24c02)
  • SPI1 ~ LCD
  • SPI2 ~ SPI Flash (W25Q64) + Ethernet + NRF24L01
  • ADC0, ADC1 ~ ADC IN
  • GPIO ~ LEDx8
  • GPIO ~ KeyPad
  • BUZZER
  • PWM0, PWM1
  • FSMC ~ SRAM + TFT LCD
  • IR
  • DS18B20
  • CAN
  • USB
  • SD
  • JTAG

这外设可以说是应有尽有了。

STM32-PZ6806L开发板原理图.pdf

image

LoRa - M-KL9 模块使用

拿到一块 M-KL9 模块,出自 南京芮捷

这是一个 LoRa 透传模块,邮票孔封装。模块内部由 MCU + Lora 芯片 组成:

  • MCU - NXP MKL16Z128VFM4 (丝印上的信息是 M16M7V)

    • Cortex-M0+ , 48 MHz
    • SRAM 16kB
    • Flash 128kB
  • Lora 芯片 - Semtech 公司的 SX1278

模块引脚定义:

与网关通信

另有该公司的一款 LoRa 网关,两者匹配起来使用。

网关的默认配置项:

  • 发射功率 - 20dBm
  • 接收频点 - 8 个频点分别是: 475.5/475.7/475.9/476.1/476.3/476.5 /476.7/476.9 MHz
  • 发送频点 - 507.5MHz, 对应 LoRa 中正交因子 SF12
  • 频宽 - 125KHz,固定不可修改

节点的发送、接收频点与网关相反,查询到模块的默认配置:

AT+CFG?
NET:    Node to Gateway
TFREQ:  475.5MHz
RFREQ:  507.5MHz
POW:    20dBm
BW:     125kHz
SF:     12
CR:     4/5
MODE:   LORA
SYNC:   0x12
PREM:   8
CRC:    ON
TIQ:    OFF
RIQ:    OFF
SEQ:    OFF
IP:     OFF
AES:    OFF

看看 LoRaWAN 约定的频段:

image

串口交互:

注意:串口的配置为 9600 8n1 (不是常用的 115200 波特率)。

上电后,串口会收到一条打印:

LoRa M-KL9, HAL V11, Firmware V2006, www.rejeee.com

上电后默认是透传模式,输入+++(不带\r\n) 会切换成 AT 交互模式,返回OK表示成功:

+++
OK

AT+ID? 查询模块 ID:

AT+ID?

CACBB8000000270A

AT+CFG? 查询配置参数:

AT+CFG?
NET:    Node to Gateway
TFREQ:  475.5MHz
RFREQ:  507.5MHz
POW:    20dBm
BW:     125kHz
SF:     12
CR:     4/5
MODE:   LORA
SYNC:   0x12
PREM:   8
CRC:    ON
TIQ:    OFF
RIQ:    OFF
SEQ:    OFF
IP:     OFF
AES:    OFF

AT+ADDR?查询模块单播地址:

AT+ADDR?

0000270A

AT+MADDR?查询模块组播地址:

AT+MADDR?

CACBB800

设置指令:

  • 设置功率:AT+POW=<XX>
  • 扩频因子:AT+SF=<XX>
  • CRC 校验:AT+CRC=<XX>
  • 发送频率:AT+TFREQ=<XXXXXXXX> //十六进制
  • 接收频率:AT+RFREQ=<XXXXXXXX> //十六进制
  • 设置带宽:AT+BW=<x> // 07,08,09 - 125k, 250k, 500k
  • 编码速率:AT+CR=<XX>
  • 发送载波反转:AT+TIQ=<XX>
  • 接收载波反转:AT+RIQ=<XX>
  • 发包序号和模块地址:AT+SIP=<XX>
  • AES 加密秘钥:AT+AK=<XX>
  • 单播地址:AT+ADDR=<XX>
  • 组播地址:AT+MADDR=<XX>
  • 配置同步字:AT+SYNC=<XX>
  • 调制方式选择:AT+MODE=<XX>
  • 配置前导码:AT+PREM=<XX>
  • 网络模式:AT+NET=<XX>
  • 休眠时间设置:AT+EL=<XXXX>
  • 发送数据:AT+TX=< X..X >
  • 开启接收:AT+RX=< XX>

Data Whitening

Data Whitening

在数字通信系统中,如果传输的数据是「白噪声」,会有许多好处。在某些通讯系统中是从 0 和 1 的交变点提取定位信息,如果连续过长的 0 或 1 将会影响同步的建立和保持。白噪声具有随机性,保证不会有过长连续 0 或 1 的数据。另外,白噪声的功率密度比较平均,在宽带内的各频点上分布均匀(这也是其称为「白」噪声的原因,平坦的功率谱组成白色)。

这就产生了加扰(scrambling)技术。在发送端用加扰器(scrambler)来改变信源产生的数字信号的统计特性,使其近似于白噪声。然后在接收端使用解扰器(descrambler)恢复出原始数字信号。整个过程如下图:

输入数字信号 -> 加扰器 -> 调制器 -> 信道 -> 解调器 -> 解扰器 -> 输出数字信号

加扰的过程也称为 Data Whiteing,译为「数据白化」,其实叫为数据加扰更明确。在 sx127x 芯片手册里,也把这个过程也称为 DC free(去直流)。

加扰有许多方法:

  1. 曼彻斯特编码(Manchester encoding)。这个编码会保证没有两个连续的 1 或 0 。但编码后的数据长度会比之前长一倍,最后的结果会使得传输速率降低一半。
  2. 伪随机序列 ,如常用的 PN9

这里只描述伪随机序列。处理后的序列即是一个伪随机序列,或伪噪声(PN: Pseudo Noise)序列。

伪噪声序列有几个性质(摘自《通信原理》第七版 12.2):

  1. 均衡性 balance。序列的一个周期中 1 和 0 的个数基本相等(准确的说 1 比 0 的个数多 1 个)
  2. 游程(连续 1 或 0 的长度)分布:长度为 1 的游程占游程总数的 1/2,长度为 2 的游程占游程总数的 1/4,长度为 k 的游程数目占游程总数的 1/2k-1
  3. 功率谱密度趋于白噪声
  4. 伪噪声特性

伪随机序列算法常见的有 CCITT data whitening 和 IBM data whitening 两种算法。它们都使用相同的多项式:x9+x5+1 ,区别只是「按 bit 异或」和「按 byte 异或」。

在介绍这两种算法之前,必须先了解 线性反馈移位寄存器,LFSR: Linear feedback shift register 。数学原理我也没看懂,得看《通信原理》。

CCITT data whitening

image

如图。LSFR 的 初始值为 0x1FF,它的 LSB bit 输出与待处理数据的 MSB bit 异或,得到被加噪后的数据的 MSB bit。

下面是代码实现:

/*
 *       8   7                   0
 *    +-----+---------------------+
 *    | MSB |         LSB         |
 *    +-----+---------------------+
 *
 *    bit 0-7 : WhiteningKEYLSB
 *    bit 8   : WhiteningKEYMSB
 *
 *    Init value: 0x1FF
 *
 */

int ccit_whitening(uint8_t *buffer, size_t len)
{
    uint8_t WhiteningKeyMSBPrevious = 0;
    uint8_t revertedWhiteningKeyLSB = 0;

    uint8_t WhiteningKEYMSB = 0x01;     // 0x01 at init
    uint8_t WhiteningKEYLSB = 0xFF;     // 0xFF at init

    revertedWhiteningKeyLSB = WhiteningKEYLSB;

    for (uint16_t j = 0; j < len - 1; j++) {
        buffer[j] ^= revertedWhiteningKeyLSB;

        for (uint8_t i = 0; i < 8; i++) {
            WhiteningKeyMSBPrevious = WhiteningKEYMSB;
            WhiteningKEYMSB = (WhiteningKEYLSB & 0x01) ^ ((WhiteningKEYLSB >> 5) & 0x01);
            WhiteningKEYLSB = ((WhiteningKeyMSBPrevious << 7) & 0x80 | (WhiteningKEYLSB >> 1) & 0xff);
        }

        revertedWhiteningKeyLSB = (WhiteningKEYLSB & 0xF0) >> 4 | (WhiteningKEYLSB & 0x0F) << 4;
        revertedWhiteningKeyLSB = (revertedWhiteningKeyLSB & 0xCC) >> 2 | (revertedWhiteningKeyLSB & 0x33) << 2;
        revertedWhiteningKeyLSB = (revertedWhiteningKeyLSB & 0xAA) >> 1 | (revertedWhiteningKeyLSB & 0x55) << 1;
    }
}

代码一眼还是很难看懂,解释一下:

  1. 移位寄存器 LSFR 输出 8 次,得到一个 byte,再与输入的 buffer[j] 进行异或运算,并存入 buffer[j] 里
  2. 当前 LSFR 里的低 8 位 WhiteningKEYLSB 值就是接下来 8 次移位得到的值,首个 8 次移位得到的 byte 值为 0xFF
  3. 然后进行 8 次移位,得到 8 次移位后的 WhiteningKEYLSB
  4. 要将 WhiteningKEYLSB 的 LSB 与输入数据的 MSB 进行异或,所以先要将 WhiteningKEYLSB 的值反转一下

最下面的三次运算是将 WhiteningKEYLSB 的 8 bit 进行 revert 运算,如下图:

image

IBM data whitening

image

。算法步骤:

  1. pn9 = 0x1FF
  2. 输入字节与pn9异或,得到输出字节
  3. pn9 按多项式,得到下一个值
  4. 输入下一个字节,跳到第 2 步

与同一个值异或两次,数值会还原。所以接收端按同样的步骤再 pn9_encode 一次,就可以恢复原始数据。

pn9 = 0x1ff

for i in range(512):
    feedback = (pn9 & 0x1) ^ ((pn9 >> 4) & 0x1)
    pn9 = (1 << 8) | (pn9 >> 1)
    print(hex(pn9))

参考

raspberry pi boot process

raspberry pi boot process

树莓派有许多硬件版本 RPi HardwareHistory。不同的硬件共用同一套软件,一个 image 安装文件 可在不同板子上启动。本文讨论和分析它是如何做到这一点的。

树莓派的 SoC

各版本的树莓派硬件上共使用了 三款 SoC:

SoC 型号 树莓派版本 ARM core 版本
BCM2835 RPI Model A, B, B+, CM, RPI Zero 700 MHz ARM11 ARM1176JZF-S core
BCM2836 RPI 2 Model B 900MHz quad-core ARMv7 Cortex-A7
BCM2837 RPI 3, CM3, CM3L, later models of the RPI 2 Quad-core 1.2GHz 64-bit ARMv8 Cortex-A53
BCM2837B0 RPI 3B+ Quad-core 1.4GHz, Cortex-A53, 40nm
BCM2711B0 RPI 4B Quad-core 1.5GHz, Cortex-A72, 28nm

BCM2835 是 SoC 的型号。Soc 中包含了 VideoCore 和 ARM core。VideoCore 就是我们常说的 GPU,ARM core 就是 CPU。

BCM2808/9/10 是指 SoC 中的 VideoCore 型号。增加 ARM core 之后,对应的型号为 BCM2835/6/7 。

所以在 /boot/ 目录中有下面这些文件:

/boot/bcm2708-rpi-0-w.dtb
/boot/bcm2708-rpi-b.dtb
/boot/bcm2708-rpi-b-plus.dtb
/boot/bcm2708-rpi-cm.dtb
/boot/bcm2709-rpi-2-b.dtb
/boot/bcm2710-rpi-3-b.dtb
/boot/bcm2710-rpi-3-b-plus.dtb
/boot/bcm2710-rpi-cm3.dtb

上电后, VideoCore 最先工作,而 ARM core 没有立即开始工作,SDRAM 也未初始化不能使用。

VideoCore 内部的 boot ROM 开始执行,它选择并依次尝试从几个介质启动。

可以从哪个介质启动

树莓派可以从 SD1、SD2、NAND、SPI、USB 等外设启动。常用的启动方式有:

  1. 从 SD 卡启动,这是默认的也是最常用的方式
  2. 从 eMMC 启动,在 CM3 上使用
  3. 从 U盘启动,也是就是 MSD (mass storage device) ,属于 USB Host 启动方式
  4. 从网络启动(LAN951x 是个 USB 网卡),属于 USB Host 启动方式
  5. 通过 USB 连接到一台 PC 启动(以 USB Device 挂载到 PC 上作为一个 USB 设备),这种方式用于 CM3 通过 USB 烧写 eMMC

这些启动方式并不是全部使能。boot ROM 通过 OTP 寄存器的一些 bit 和 GPIO 状态(如果使能的话)来选择尝试按顺序从哪几个外设启动。

OTP

SoC 内部有 OTP (One-Time Programmable) 存储块。共 66 个寄存器,每个寄存器 32-bit。OTP 的寄存器只能编程一次,只能由 0 变为 1,无法由 1 变为 0 (once set, OTP bits can never be unset)。

寄存器的意义参见 OTP register and bit definitions 。其中寄存器 17 用于启动模式的设置。

17 – bootmode register
- Bit 1: sets the oscillator frequency to 19.2MHz
- Bit 3: enables pull ups on the SDIO pins
- Bit 19: enables GPIO bootmode
- Bit 20: sets the bank to check for GPIO bootmode
- Bit 21: enables booting from SD card
- Bit 22: sets the bank to boot from
- Bit 28: enables USB device booting
- Bit 29: enables USB host booting (ethernet and mass storage)

使用命令 sudo vcgencmd otp_dump 可以打印所有寄存器的值。我在 3b+ 上的打印寄存器 17 的值为:

17:3020000a

这个值的启动设置是:

  • 使能从 SD 卡启动
  • 使能从 USB device 启动。连接到主机后,接收由主机发送启动文件(可用于 CM3 的烧写)
  • 使能从 USB host 启动。网络启动或U盘启动

GPIO bootmode

使能 GPIO bootmode 的话,启动时会再根据相应 GPIO 的状态来决定是否使能该启动方式。GPIO 引脚状态为 0 时,该启动方式禁止。GPIO 为 1 时,再看 OTP 寄存器是否使能该启动方式。此时 OTP 相应的 bit 与 GPIO 引脚是「与」的关系。

Uses program_gpio_bootmode to disable some modes by reading GPIOs 22-26 or 39-43 to see if the default values do not equal the default pull to '0'. If it is low, it will disable that boot mode for each of SD1, SD2, NAND, SPI, USB. If the value read is a '1', then that boot mode is enabled (note this cannot enable boot modes that have not already been enabled in the OTP).

如何开启 GPIO bootmode ?

在 config.txt 里设置 program_gpio_bootmode 可以触发 OTP 编程。增加设置之后,要重新上电,OTP 编程完成后就可以去掉 config.txt 中的相应配置了。

boot mode program_gpio_bootmode=1 program_gpio_bootmode=2
SD1 GPIO22 GPIO39
SD2 GPIO23 GPIO40
NAND GPIO24 GPIO41
SPI GPIO25 GPIO42
USB GPIO26 GPIO43

需要注意的是,一旦开启 GPIO bootmode,相应的 GPIO 就不能再做为普通 GPIO 使用了。

boot ROM 选择启动外设全过程是:

  1. 上电,VideoCore 里的 boot ROM 开始执行
  2. 读 OTP 寄存器中的外设使能 bit
  3. 如果 GPIO bootmode 使能,则再读相应 GPIO 管脚的状态来使能或禁止相应介质
  4. 最后,按 SD1、SD2、NAND、SPI、USB 的顺序,尝试已使能的外设

对于 USB,先以 USB host 方式,尝试 MSD (mass storage device) 、网口LAN951x(DHCP/TFTP boot)。如果不行的话再尝试 USB device 方式。

参考链接:Boot flow

bootcode.bin 和 start.elf

无论尝试从哪个外设启动,boot ROM 的目的都是从该外设读取执行代码到内部 128K L2 Cache 中执行(此时 SDRAM 还未配置,不可用)。

bootcode.bin 初始化 SDRAM,读取 config.txt 里的配置,以决定加载哪一个 start.elf 到 SDRAM 中执行:

  • start_x=1 会加载 start_x.elf 和 fixup_x.dat
  • start_debug=1 会加载 start_db.elf 和 fixup_db.dat
  • 否则会默认加载 start.elf 和 fixup.dat

start.elf 是 VideoCore 的 firmware,它实际上是一个完整的操作系统,叫作 VCOS (VideoCore OS)。

pi@raspberrypi:~ $ file /boot/start.elf 
/boot/start.elf: ELF 32-bit LSB executable, Broadcom VideoCore III, version 1 (SYSV), statically linked, stripped

start.elf 跑在 SDRAM 里,之后 linux kernel 也是跑在 SDRAM 里。它们共用 SDRAM,start.elf 使用高地址空间,剩下的留给 linux kernel。

可以在 config.txt 里用 gpu_mem 来指定 start.elf 使用多大的内存。比如 gpu_mem=16 指定 start.elf 使用 SDRAM 的最高 16MB 空间。

fixup.dat 用于告诉 start.elf 内存的布局。start.elf 要配合 fixup.dat 一起使用。在 /boot 里有几组 start.x/fixup.dat :

pi@raspberrypi:~ $ ls -lsh /boot/start* /boot/fixup*
3.0K -rwxr-xr-x 1 root root 2.6K 9月   7 16:40 /boot/fixup_cd.dat
7.0K -rwxr-xr-x 1 root root 6.6K 9月   7 16:40 /boot/fixup.dat
 10K -rwxr-xr-x 1 root root 9.7K 9月   7 16:40 /boot/fixup_db.dat
 10K -rwxr-xr-x 1 root root 9.7K 9月   7 16:40 /boot/fixup_x.dat
662K -rwxr-xr-x 1 root root 662K 9月   7 16:40 /boot/start_cd.elf
4.9M -rwxr-xr-x 1 root root 4.9M 9月   7 16:40 /boot/start_db.elf
2.8M -rwxr-xr-x 1 root root 2.8M 9月   7 16:40 /boot/start.elf
3.9M -rwxr-xr-x 1 root root 3.9M 9月   7 16:40 /boot/start_x.elf

它们的区别是:

  • start_db.elf 是 debug 版本,体积最大
  • start_x.elf 包含 camera 驱动和 codec,使用 camera 的话就用这个。体积也比 start.elf 大一点
  • start_cd.elf 是 cut-down 版本,裁剪掉了codec 和 3D 功能。占用内存最少,只需要 16MB。在 SDRAM 只有 256MB 时可以节省内存空间留给 linux 使用。

start.elf 的主要工作就是加载和引导 linux kernel,在这之前它会先读配置文件 config.txt 和 cmdline.txt。

可以在 config.txt 里用 kernel=xxx 参数来指定待加载的内核文件名。不指定时的默认选择是:

  • Pi 1, Pi Zero, and Compute Module use kernel.img
  • Pi 2, Pi 3, and Compute Module 3 iuse kernel7.img
  • If kernel8.img is present on the Pi 3 or Compute Module 3, it will be loaded in preference and entered in 64-bit mode.

参见 What are the default kernel image names?

cmdline.txt 里的内容就是引导 linux kernel 时传递给内核的参数。

pi@raspberrypi:~ $ dmesg | grep -i command
[    0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=640 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=PARTUUID=afaf5bd2-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

pi@raspberrypi:~ $ cat /proc/cmdline 
8250.nr_uarts=1 bcm2708_fb.fbwidth=640 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=PARTUUID=afaf5bd2-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

pi@raspberrypi:~ $ cat /boot/cmdline.txt 
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=afaf5bd2-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

有两个区别:

  1. linux kernel 里的 commandl line 多出了:8250.nr_uarts=1 bcm2708_fb.fbwidth=640 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 。这些应该是 start.elf 自动添加的,strings /boot/start.elf 可以看到 start.elf 里包含这些字符串
  2. cmdline.txt 里的 console=serial0,115200 变成了 console=ttyS0,115200。 /dev/serial0 实际上是 /dev/ttyS0 的软链接
pi@raspberrypi:~ $ ls -l /dev/serial0 
lrwxrwxrwx 1 root root 5 9月  13 19:17 /dev/serial0 -> ttyS0

sudo vcdbg log msg 可以看到 start.elf 执行的 log。我的 3B+ 板子的部分关键信息如下:

001651.702: brfs: File read: /mfs/sd/cmdline.txt
001651.806: Read command line from file 'cmdline.txt':
001651.870: 'dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=afaf5bd2-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles'
001652.179: brfs: File read: 187 bytes
002013.038: brfs: File read: /mfs/sd/kernel7.img
002013.102: Loading 'kernel7.img' to 0x8000 size 0x4b46b0
002017.497: No kernel trailer - assuming DT-capable
002017.584: brfs: File read: 4933296 bytes
002021.696: brfs: File read: /mfs/sd/bcm2710-rpi-3-b-plus.dtb

可以看到 start.elf 读了 cmdline.txt,把 kernel7.img 加载到 SDRAM 的 0x8000 地址,还读了 bcm2710-rpi-3-b-plus.dtb。

树莓派板子型号

树莓派有许多板子,每个都有唯一的型号。参考 RASPBERRY PI REVISION CODES 。

在3B+ 上执行 cat /proc/cpuinfo 可以看到硬件版本和序列号。

Hardware	: BCM2835
Revision	: a020d3
Serial		: 0000000037415f97

在 OTP 里 寄存器 28 是序列号,寄存器 30 是硬件版本号,参见 OTP register and bit definitions

pi@raspberrypi:~ $ vcgencmd otp_dump | grep ^28
28:37415f97
pi@raspberrypi:~ $ vcgencmd otp_dump | grep ^30
30:00a020d3

start.elf 会读硬件版本的型号,根据 Revision 来选择加载哪个 kernel.img 和 dtb 文件。我猜测这个逻辑是默认写在代码里的,因为从 strings /boot/start.elf 的输出中可以看到 start.elf 里面包含了许多固定的名字。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.