CS140e (0) 点亮树莓派

栏目: 软件资讯 · 发布时间: 6年前

内容简介:开看上去好像需要准备很多东西,但是仔细一看这是上这门课发的

CS140e 的坑主要原因还是想学习一下 Rust,正好想起来年初有这么一个非常有意思的课,不如跟着做吧。

准备硬件

Check that your Raspberry Pi kit includes all of the following materials:

  • 1 Raspberry Pi 3
  • 1 1⁄2-sized breadboard
  • 1 4GiB microSD card
  • 1 microSD card USB adapter
  • 1 CP2102 USB TTL adapter w/4 jumper cables
  • 10 multicolored LEDs
  • 4 100 ohm resistors
  • 4 1k ohm resistors
  • 10 male-male DuPont jumper cables
  • 10 female-male DuPont jumper cables

看上去好像需要准备很多东西,但是仔细一看这是上这门课发的 Raspberry Pi kit 里面的东西。我往后翻了一翻,好像并不需要这么多东西呀。第一次作业是点灯,让你熟悉一下树莓派硬件,有一种以前刚开始玩单片机时候的感觉。搞电子玩嘛,感觉精髓就在于“捡垃圾”,除了从淘宝上买了个树莓派,剩下的都从家里捡到了:

CS140e (0) 点亮树莓派

先翻出来以前玩单片机时候的开发版,获得了若干杜邦线,其实上面还有个面包板,不过感觉用不到,毕竟这个作业只要点个灯就好了。

CS140e (0) 点亮树莓派

以前刷路由器的时候把路由器刷成了砖,当时买了一个USB转TTL线回来,看了一下上面的字,芯片是 PL-2303HX ,网上搜了一下,竟然还有最新的 macOS 驱动,美滋滋。

CS140e (0) 点亮树莓派

接下来从老爸一大堆的“宝贝”里面捡了一个LED灯。

CS140e (0) 点亮树莓派

感觉要从刚刚的抽屉里面找到一个合适大小的电阻还是很蛋疼的,一是已经忘了色环电阻的颜色 排序 了,二是色环电阻这么小看久了眼睛真的瞎啊,不如拿新的。找到一包51Ω的,拿两个,102Ω在3.3V的输出下差不多可以用。

CS140e (0) 点亮树莓派

把两个电阻绑在LED灯脚上,非常完美!正好可以插到杜邦线里面。

好吧,老爸觉得这还不够完美,要加上一个绝缘壳。感觉这个操作我学不来。

CS140e (0) 点亮树莓派

准备好了东西以后,还是得确定一下刚才捡的LED灯能不能亮。把LED灯插到 Pin 1 3.3V PWR 和 Pin 6 GND 上面,插上电源,亮了。

至此,硬件一切就绪。

运行样例程序

当时买树莓派3B+的时候就在担心会不会启动不了课程给的程序,果然最不幸的事情就发生了。还好这个问题好解决,用 官方固件 里面新的 start.elf 替换就能运行了。

不过我还蛮好奇这个启动过程是怎样的,为什么往TF卡里面拷贝几个文件就行了?查到了 这么个资料 ,感觉树莓派启动方式还是很魔性的:

  • SoC竟然是让 VideoCore 4 GPU 而不是 Cortex-A53 CPU 负责启动,真的是迷
  • 第一阶段的 bootloader 是写死在SoC里面的,来读取TF卡里面的 bootcode.bin
  • 第二阶段是 bootcode.bin ,依然是GPU执行,引导进 start.elf
  • 第三阶段是 start.elf ,根据 config.txt 初始化CPU,然后载入 kernel8.img
  • 最后终于轮到了CPU开始运行内核 kernel8.img 了,我猜这个 8 的意思是 ARMv8
  • config.txt 就相当于以前电脑上的 CMOS 保存着 BIOS 的设置信息

感觉还是一种非常便利的启动方式的,只需要拷贝文件就行。

用 C 语言点灯

首先是要安装交叉编译的 工具 链,但是这里只给了个二进制包。搜索了一下怎么自己编译,似乎还是挺复杂的,以后用到了再研究研究吧。

写程序前要先看 datasheet,其实作业页面上都告诉你看哪一页了,还是非常轻松的。非常有意思的是,这份 datasheet 是从 BCM2835 魔改而来的,我试着查了下 BCM2837 和 BCM2837B0,发现都查不到对应的 datasheet。看来 Broadcom 还是把资料藏得很严啊。

BCM2837的GPIO和以前用的PIC16F877A单片机的GPIO还是有点类似的,可能嵌入式开发都是这样的吧,就是有一个GPIO功能选择的寄存器,比方说这里叫做 GPFSELx 而PIC16叫做 TRISx ,先选好引脚是用来输入的还是输出的。

和以前PIC16不太一样的是,这里把输出0和输出1分开成了两个寄存器 GPCLRxGPSETx 。往相应的位写0没有效果,往 GPCLRx 写1会输出0,往 GPSETx 写1会输出1。datasheet 上面是这么解释这个事情的:

Separating the set and clear functions removes the need for read-modify-write operations.

可惜我没有体会出来这个点。

用 Rust 语言点灯

照道理来说只要把几行 C 翻译成 Rust 就好了,然而因为我秉承了作死的传统,使用了最新版的编译器 rustc 1.28.0-nightly (cd494c1f0 2018-06-27) ,编译起来就出了两个错误

一个是 error[E0522]: definition of an unknown language item: `panic_fmt` 。找到了 这个帖子 以及 RFC2070 ,新版本里面把原先的

#![feature(lang_items)]

use core::intrinsics;

#[lang = "panic_fmt"]
unsafe extern "C" fn panic_fmt(
    _args: core::fmt::Arguments,
    _file: &'static str,
    _line: u32,
    _col: u32,
) -> ! {
    intrinsics::abort()
}

替换成

#![feature(panic_implementation)]

use core::intrinsics;
use core::panic::PanicInfo;

#[panic_implementation]
fn panic(_info: &PanicInfo) -> ! {
    unsafe { intrinsics::abort() }
}

另外一个错误是 error[E0259]: the name `compiler_builtins` is defined multiple times 。这个错误我倒是没有找到相关的 issue,而且 The Unstable Book 上面的写法也跟目前的代码一致的。

我试着把 extern crate compiler_builtins; 去掉,就能成功编译了,另外我试着去掉 #![feature(compiler_builtins_lib)] 也能正常编译。有点不明所以。

另外还有一个小问题,我编译成功之后发现LED灯常亮,不会闪。这让我折腾了好久。

不过我隐约觉得LED灯有微微的频闪而且亮度似乎下降了,拿手机摄像头一看更加明显。把 Rust 代码和 C 代码拿来对比了一下,果然给的代码里面出现了不一致:

static void spin_sleep_us(unsigned int us) {
  for (unsigned int i = 0; i < us * 6; i++) {
    asm volatile("nop");
  }
}

static void spin_sleep_ms(unsigned int ms) {
  spin_sleep_us(ms * 1000);
}
#[inline(never)]
fn spin_sleep_ms(ms: usize) {
    for _ in 0..(ms * 600) {
        unsafe { asm!("nop" :::: "volatile"); }
    }
}

仔细看,Rust 里面 sleep 的时间是 C 里面的十分之一!于是乎本来一个闪烁效果愣是变成了低频PWM调光……

600 后面加了个 0 就解决问题了。

总结

对于我这样不搞硬件的人,每次折腾硬件总是非常的兴奋。这次作业让我回想起了小时候折腾单片机的时光,还是非常好玩的。第0次作业基本上跟 Rust 还没太关系,不过我根据 Syllabus 上面的安排把 The Rust Programming Language 的第1~11章又读了一遍,这次是倒着读的,感觉又学习/回想起了好多 Rust 的语法,还是非常有效果的。


以上所述就是小编给大家介绍的《CS140e (0) 点亮树莓派》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法引论

算法引论

[美]乌迪·曼博(Udi Manber) / 黄林鹏、谢瑾奎、陆首博、等 / 电子工业出版社 / 2010-1 / 36.00元

本书是国际算法大师乌迪·曼博(Udi Manber)博士撰写的一本享有盛誉的著作。全书共分12章:第1章到第4章为介绍性内容,涉及数学归纳法、算法分析、数据结构等内容;第5章提出了与归纳证明进行类比的算法设计思想;第6章到第9章分别给出了4个领域的算法,如序列和集合的算法、图算法、几何算法、代数和数值算法;第10章涉及归约,也是第11章的序幕,而后者涉及NP完全问题;第12章则介绍了并行算法;最后......一起来看看 《算法引论》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具