分类 技术 下的文章

/e/ 安卓操作系统是一个以隐私为导向的去谷歌化的移动操作系统,是 Lineage OS 的复刻,由 Mandrake Linux(现在的 Mandriva Linux)的创建者 Gaël Duval 于 2018 年中期创立。

尽管安卓在 2007 年成为了一个开源项目,但当安卓得到普及时,谷歌使用专有软件取代了一些操作系统元素。/e/ 基金会用 MicroG 取代了其中的专有的应用程序和服务,这是一个开源的替代框架,可以最大限度地减少跟踪和设备活动。

我们收到的 Fairphone 3 预装了 /e/ OS,这是一个来自 /e/ 基金会的 以道德的方式创造的智能手机。我使用了一个月这个设备,然后把它返还给了他们,我将分享我对这个隐私设备的体验。我忘了截图,所以我将分享来自官方网站的通用图片。

在道德的 Fairphone 设备上体验 /e/ 移动操作系统

在我进一步说明之前,让我澄清一下,Fairphone 3 并不是使用 /e/ 的唯一选择。如果你要从他们那里购买设备,/e/ 基金会会给你 一些智能手机的选择

你不需要购买设备来使用 /e/ OS。按照 /e/ 基金会的说法,你可以 在 100 多个支持的设备上使用它

尽管我很喜欢使用 Fairphone 3,而且我的个人信仰与 Fairphone 的宣言一致,但我不会把注意力放在设备上,而只是放在 /e/ OS 上。

有评级隐私的应用程序

我把 Fairphone 3 作为我的日常使用设备用了几天时间,以比较与我的“普通”安卓手机在现实中的使用情况。

首先,我想看看我使用的所有应用程序是否都可以在 /e/ 基金会创建的“应用商店”上找到。/e/ 应用商店包含有隐私评级的应用程序。

/e/ OS 应用商店有应用程序的隐私评级

我可以找到许多应用程序,包括来自谷歌的应用程序。这意味着,如果有人真的想使用一些谷歌的服务,它仍然可以作为一个选项来下载。尽管与其他安卓设备不同,没有强行将谷歌服务塞进你的嘴里。

虽然有很多应用程序,但我无法找到我在英国使用的手机银行应用程序。我不得不承认,手机银行应用程序可以在一定程度上促进便利。作为替代方案,我不得不在需要时进入电脑使用网上银行平台。

从可用性的角度来看,/e/ OS 可以取代我的“标准”安卓操作系统,但会有一些小插曲,比如银行应用程序。

如果不是谷歌的,那是什么?

想知道 /e/ OS 使用哪些基本的应用程序,而不是谷歌的那些?这里有一个快速列表:

  • 魔法地球 —— 逐向道路导航
  • 浏览器 —— Chromium 的一个非谷歌复刻版本
  • 邮件 —— K9-mail 的一个复刻
  • 短信 —— QKSMS 的一个复刻
  • 照相机 —— OpenCamera 的一个复刻
  • 天气 —— GoodWeather 的一个复刻
  • OpenTasks —— 任务组织者
  • 日历:Etar calendar 的一个复刻

Bliss Launcher 和整体设计

/e/ OS 的默认启动程序被称为 “Bliss Launcher”,其目的是为了获得有吸引力的外观和感觉。对我来说,这个设计感觉与 iOS 相似。

通过向左滑动面板,你可以访问 /e/ 选择的一些有用的小工具。

  • 搜索:快速搜索预装的应用程序或搜索 Web
  • APP 建议:前 4 个最常用的应用程序将出现在这个小部件上
  • 天气:天气小部件显示的是当地的天气。它不会自动检测位置,需要进行配置。
  • 编辑:如果你想在屏幕上有更多的小部件,你可以通过点击“编辑”按钮添加它们。

总而言之,用户界面是干净整洁的简单明了,增强了愉快的用户体验。 * 天气。天气小部件显示的是当地的天气。它不会自动检测位置,需要进行配置。

  • 编辑:如果你想在屏幕上有更多的小部件,你可以通过点击编辑按钮添加它们。

总而言之,用户界面干净整洁、简单明了,增强了愉快的用户体验。

去谷歌化和面向隐私的操作系统

如前所述,/e/ 操作系统是一个去谷歌化的操作系统,它基于 Lineage OS 的开源核心。所有的谷歌应用程序已经被删除,谷歌服务已经被 MicroG 框架所取代。/e/ OS 仍然与所有的安卓应用兼容。

主要的隐私功能:

  • 谷歌搜索引擎已被 DuckDuckGo 等替代品取代
  • 谷歌服务已被 microG 框架所取代
  • 使用替代的默认应用程序,而不是谷歌应用程序
  • 取消了对谷歌服务器的连接检查
  • NTP 服务器已被替换为标准的 NTP 服务:pool.ntp.org
  • DNS 默认服务器由 9.9.9.9 取代,可以根据用户的选择进行编辑
  • 地理定位是在 GPS 的基础上使用 Mozilla 定位服务

隐私声明

请注意,使用由 /e/ 基金会提供的智能手机并不自动意味着无论你做什么都能保证你的隐私。分享你的个人信息的社交媒体应用程序应在你的意识下使用。

结论

我成为安卓用户已经超过十年了。/e/ OS 给我带来了积极的惊喜。关注隐私的用户可以发现这个解决方案非常吸引人,而且根据所选择的应用程序和设置,可以再次感觉到使用智能手机的安全。

如果你是一个有隐私意识的技术专家,并且能够自己找到解决问题的方法,我向你推荐它。对于那些习惯于谷歌主流服务的人来说,/e/ 生态系统可能会让他们不知所措。

你使用过 /e/ OS 吗?你的使用经验如何?你怎么看这些关注隐私的项目?


via: https://itsfoss.com/e-os-review/

作者:Dimitrios 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

B-tree 文件系统(Btrfs)融合了文件系统和卷管理器。它为 Linux 操作系统提供了高级文件系统应当拥有的诸多不错的功能特性。

 title=

好几年前 Btrfs 就已经可以在 Linux 中使用了,所以你可能已经熟悉它了。如果没有,你可能对它尚有疑虑,尤其是如果你使用的是 Fedora 工作站 (Btrfs 现在是它的默认文件系统)。本文旨在帮助你熟悉它及其高级功能,例如 写时复制校验和

Btrfs 是 “B-Tree Filesystem” 的缩写,实际上是文件系统和卷管理器的结合体。它通常被视为对 ZFS 的回应,ZFS 早在 2005 年就被引入 Sun 微系统的 Solaris 操作系统中,现在基本上被一个名为 OpenZFS 的开源实现所取代。Ubuntu 和 FreeBSD 常常使用 OpenZFS。其他具有类似特性的示例有红帽的 Stratis 和 Linux 逻辑卷管理器 Logical Volume Manager (LVM)。

安装

为了尝试 Btrfs,我下载了 Fedora 33 工作站 ISO 文件 并将其安装到一个新的虚拟机(VM)中。安装过程与以前的版本没有变化。我没有自定义任何设置,包括驱动器分区和格式化,以保持本教程的准确“开箱即用”设置。当虚拟机启动并运行后,我安装并运行了 GNOME 分区编辑器(GParted),以获得一个良好的、工厂级的驱动器布局视图。

 title=

从安装这一点来说,与你以前所习惯的情况没什么不同;事实上,你可以正常使用该系统,甚至可能没有注意到文件系统是 Btrfs。然而,拥有这个新的默认文件系统使你能够利用几个很酷的特性。

检查 Btrfs 文件系统

我暂时没有找到特定于 Btrfs 的图形工具,尽管它的一些功能已经被合并到现有的磁盘管理工具中。

在命令行中,你可以更仔细地查看 Btrfs 格式:

# btrfs filesystem show
Label: 'fedora_localhost-live'  uuid: f2bb02f9-5c41-4c91-8eae-827a801ee58a
        Total devices 1 FS bytes used 6.36GiB
        devid    1 size 10.41GiB used 8.02GiB path /dev/vda3

修改 Btrfs 标签

我首先注意到的是安装程序设置的文件系统标签:fedora_localhost-live。这是不准确的,因为它现在是一个已安装的系统,不再是 livecd。所以我使用 btrfs filesystem label 命令对其进行了更改。

修改 Btrfs 标签非常的简单:

# btrfs filesystem label /
fedora_localhost-live
# btrfs filesystem label / fedora33workstation
# btrfs filesystem label /
fedora33workstation

管理 Btrfs 子卷

子卷看起来像是可以由 Btrfs 管理的标准目录。我的新 Fedora 33 工作站上有几个子卷:

# btrfs subvolume list /
ID 256 gen 2458 top level 5 path home
ID 258 gen 2461 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines

使用 btrfs subvolume Create 命令创建新的子卷,或使用 btrfs subvolume delete 删除子卷:

# btrfs subvolume create /opt/foo
Create subvolume '/opt/foo'
# btrfs subvolume list /
ID 256 gen 2884 top level 5 path home
ID 258 gen 2888 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines
ID 276 gen 2888 top level 258 path opt/foo
# btrfs subvolume delete /opt/foo
Delete subvolume (no-commit): '/opt/foo'

子卷允许设置配额、拍摄快照以及复制到其他位置和其他主机等操作。那么系统管理员如何利用这些功能?用户主目录又是如何操作的呢?

添加用户

就像从前一样,添加一个新的用户帐户会创建一个主目录供该帐户使用:

# useradd student1
# getent passwd student1
student1:x:1006:1006::/home/student1:/bin/bash
# ls -l /home
drwx------. 1 student1 student1  80 Oct 29 00:21 student1

传统上,用户的主目录是 /home 的子目录。所有权和操作权是为所有者量身定制的,但是特殊功能来没有管理它们。而企业服务器环境是另外一种情况。通常,目录是为特定的应用程序及其用户保留的。你可以利用 Btrfs 来管理和应用对这些目录的约束。

为了将 Btrfs 子卷作为用户主页,在 useradd 命令中有一个新选项:--Btrfs-subvolume-home。尽管手册页尚未更新(截至本文撰写之时),但你可以通过运行 useradd --help 来查看该选项。通过在添加新用户时传递此选项,将创建一个新的 Btrfs 子卷。它的功能与创建常规目录时的 -d 选项类似:

# useradd --btrfs-subvolume-home student2
Create subvolume '/home/student2'

使用 getent passwd student2 验证用户,它将显示为正常。但是,运行 btrfs subvolume 命令列出子卷,你将看到一些有趣的内容:新用户的主目录!

# btrfs subvolume list /
ID 256 gen 2458 top level 5 path home
ID 258 gen 2461 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines
ID 272 gen 2459 top level 256 path home/student2

探索企业服务器环境的第二个场景。假设你需要在 /opt 中安装一个 WildFly 服务器并部署一个 Java web 应用程序。通常,你的第一步是创建一个 wildfly 用户。使用新的 --btrfs-subvolume-home 选项和 -b 选项来指定 /opt 作为基本目录:

# useradd -b /opt --btrfs-subvolume-home wildfly
Create subvolume '/opt/wildfly'

于是,wildfly 用户可以使用了,并且主目录设置在了 /opt/wildfly

删除用户

删除用户时,有时需要同时删除该用户的文件和主目录。userdel 命令有 -r 选项,它可以同时删除 Btrfs 子卷:

# userdel -r student2
Delete subvolume (commit): '/home/student2'

设置磁盘使用配额

在我的一节计算机科学课上,一个学生运行了一个失控的 C 程序,然后写进了磁盘,将我们院的 Unix 系统上整个 /home 目录都填满了!在管理员终止失控进程并清除一些空间之前,服务器将无法使用。上述情况也是如此;那个 Wildfly 企业应用程序将为其用户提供越来越多的日志文件和内容存储。如何防止服务器因磁盘已满而死机?设置磁盘使用限制是个好主意。幸运的是,Btrfs 通过设置配额的方式支持这一点。

配置配额需要几个步骤。第一步是在 Btrfs 文件系统上启用配额:

# btrfs quota enable /

确保你知道每个子卷的配额组(qgroup)ID 号,该编号由 btrfs subvolume list 命令显示。每个子卷都需要基于 ID 号码来关联配额组。这可以通过 btrfs qgroup create 单独完成,但是,btrfs 维基提供了以下命令来加快为文件系统上的子卷创建配额组:

> btrfs subvolume list \<path> | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup destroy 0/{} \<path>

在新安装的 Fedora 33 工作站系统中,你在根文件系统路径上操作,/。用根路径替换 \<path>

# btrfs subvolume list / | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} /

然后运行 btrfs quota rescan,查看新的配额组:

# btrfs quota rescan /
quota rescan started
# btrfs qgroup show /
qgroupid         rfer         excl
--------         ----         ----
0/5          16.00KiB     16.00KiB
0/256       272.04MiB    272.04MiB
0/258         6.08GiB      6.08GiB
0/265        16.00KiB     16.00KiB
0/271        16.00KiB     16.00KiB
0/273        16.00KiB     16.00KiB

于是现在,你可以将配额分配给其中一个配额组,然后将配额应用于其关联的子卷。因此,如果要将 student3 的主目录使用限制为 1 GB,请使用 btrfs qgroup limit 命令:

# btrfs qgroup limit 1G /home/student3

查看特定子卷的配额:

# btrfs qgroup show -reF /home/student3
qgroupid         rfer         excl     max_rfer     max_excl
--------         ----         ----     --------     --------
0/271        16.00KiB     16.00KiB      1.00GiB         none

稍有不同的选项参数将显示所有配额组和设置的所有配额:

# btrfs qgroup show -re /
qgroupid         rfer         excl     max_rfer     max_excl
--------         ----         ----     --------     --------
0/5          16.00KiB     16.00KiB         none         none
0/256       272.04MiB    272.04MiB         none         none
0/258         6.08GiB      6.08GiB         none         none
0/265        16.00KiB     16.00KiB         none         none
0/271        16.00KiB     16.00KiB      1.00GiB         none
0/273        16.00KiB     16.00KiB         none         none

其他特性

这些例子提供了 Btrfs 特性的一些思考。运行 btrfs --help 查看命令的完整列表。还有许多其他值得注意的功能;例如,快照和发送/接收是两个值得学习的功能。

总结讨论

Btrfs 为向 Linux 提供高级文件系统特性集贡献了很多特性。这不是第一次;我知道 ZFS 在大约 15 年前引入了这种类型的文件系统,但是 Btrfs 是完全开源的,不受专利的限制。

如果你想探索这个文件系统,我建议从虚拟机或备用系统开始。

我想能够出现一些图形化的管理工具,为那些喜欢用图形工具的系统管理员提供便利。幸运的是,Btrfs 具有强大的开发活动,Fedora 33 项目决定将其设置为工作站上的默认值就证明了这一点。


via: https://opensource.com/article/20/11/btrfs-linux

作者:Alan Formy-Duval 选题:lujun9972 译者:Chao-zhi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索异常处理和其他未被充分利用但仍然有用的 Python 特性。

 title=

这是 Python 3.x 首发特性系列文章的第四篇。Python 3.3 于 2012 年首次发布,尽管它已经发布了很长时间,但它引入的许多特性都没有得到充分利用,而且相当酷。下面是其中的三个。

yield from

yield 关键字使 Python 更加强大。可以预见的是,人们都开始使用它来创建整个迭代器的生态系统。itertools 模块和 more-itertools PyPI 包就是其中两个例子。

有时,一个新的生成器会想要使用一个现有的生成器。作为一个简单的(尽管有点故意设计)的例子,设想你想枚举所有的自然数对。

一种方法是按照“自然数对的和,自然数对的第一项”的顺序生成所有的自然数对。用 yield from 来实现这个方法是很自然的。

yield from <x> 关键字是以下的简称:

for item in x:
    yield item
import itertools

def pairs():
    for n in itertools.count():
        yield from ((i, n-i) for i in range(n+1))
list(itertools.islice(pairs(), 6))
    [(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0)]

隐式命名空间包

假设有一个叫 Parasol 的虚构公司,它制造了一堆东西。它的大部分内部软件都是用 Python 编写的。虽然 Parasol 已经开源了它的一些代码,但其中一些代码对于开源来说过于专有或专业。

该公司使用内部 DevPI 服务器来管理内部软件包。对于 Parasol 的每个 Python 程序员来说,在 PyPI 上找一个未使用的名字是没有意义的,所以所有的内部包都被称为 parasol.<business division>.<project>。遵守最佳实践,开发人员希望包的名字能反映出这个命名系统。

这一点很重要!如果 parasol.accounting.numeric_tricks 包安装了一个名为 numeric_tricks 的顶层模块,这意味着依赖这个包的人将无法使用名为 numeric_tricks 的 PyPI 包,不管它写的有多好。

然而,这给开发者留下了一个两难的选择:哪个包拥有 parasol/__init__.py 文件?从 Python 3.3 开始,最好的解决办法是把 parasol,可能还有 parasol.accounting,变成没有 __init__.py 文件的 命名空间包

抑制异常的上下文

有时,在从异常中恢复的过程中出现的异常是一个问题,有上下文来跟踪它是很有用的。然而,有时却不是这样:异常已经被处理了,而新的情况是一个不同的错误状况。

例如,想象一下,在字典中查找一个键失败后,如果不能分析它,则希望失败并返回 ValueError()

import time

def expensive_analysis(data):
    time.sleep(10)
    if data[0:1] == ">":
        return data[1:]
    return None

这个函数需要很长的时间,所以当你使用它时,想要对结果进行缓存:

cache = {}

def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data)
        cached[data] = analyzed
    return analyzed[-1]

不幸的是,当出现缓存没有命中时,回溯看起来很难看:

last_letter_analyzed("stuff")
    ---------------------------------------------------------------------------

    KeyError                                  Traceback (most recent call last)

    <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
          4     try:
    ----> 5         analyzed = cache[data]
          6     except KeyError:


    KeyError: 'stuff'

在处理上述异常的过程中,发生了另一个异常:

    ValueError                                Traceback (most recent call last)

    <ipython-input-17-40dab921f9a9> in <module>
    ----> 1 last_letter_analyzed("stuff")
   

    <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
          7         analyzed = expensive_analysis(data)
          8         if analyzed is None:
    ----> 9             raise ValueError("invalid data", data)
         10         cached[data] = analyzed
         11     return analyzed[-1]


    ValueError: ('invalid data', 'stuff')

如果你使用 raise ... from None,你可以得到更多可读的回溯:

def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data) from None
        cached[data] = analyzed
    return analyzed[-1]
last_letter_analyzed("stuff")
    ---------------------------------------------------------------------------

    ValueError                                Traceback (most recent call last)

    <ipython-input-21-40dab921f9a9> in <module>
    ----> 1 last_letter_analyzed("stuff")
   

    <ipython-input-20-5691e33edfbc> in last_letter_analyzed(data)
          5         analyzed = expensive_analysis(data)
          6         if analyzed is None:
    ----> 7             raise ValueError("invalid data", data) from None
          8         cached[data] = analyzed
          9     return analyzed[-1]


    ValueError: ('invalid data', 'stuff')

欢迎来到 2012 年

尽管 Python 3.3 在十年前就已经发布了,但它的许多功能仍然很酷,而且没有得到充分利用。如果你还没有,就把它们添加到你的工具箱中吧。


via: https://opensource.com/article/21/5/python-33

作者:Moshe Zadka 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在将嵌入式系统操作系统移植到不同的芯片架构时,RT-Thread 的维护者们从中学到了什么。

 title=

曾经有人问我,为什么计算机被称为“计算机”,它们做的事情可远不止计算数字。一台现代的个人电脑可以浏览互联网、播放音频和视频、为视频游戏和电影生成漂亮的图形、模拟和预测复杂的天气模式和流行病风险、将建筑和工程蓝图变为现实等等。

计算机之所以能做到这些,是因为所有这些问题都可以归结为数字方程,而计算机的 CPU —— 其中央处理单元 —— 实际上不过是一个简单的计算器。

为了让 CPU 向硬盘驱动器发送信号以写入数据,或向显示器发送信号以显示图像,它必须接收指令。这些指令是以 “代码” 的形式出现的,这是一种简明的说法,即必须有人写一个 程序 ,与CPU “说” 同样的语言。CPU 理解的是 机器语言,这是一个大多数人都无法理解的比特阵列,大多数人都不可能手动写出来。相反,我们使用像 C、C++、Java、Python 等编程语言。这些语言被解析并编译成机器语言,然后交付给 CPU。

如果你试图用一种它不理解的语言来指示 CPU,它不知道该怎么做。你可以通过尝试用 x86\_64 RHEL 镜像启动 树莓派 来体验这种误传尝试的尴尬结果。如果它能工作就好了,但是不能。

将一个操作系统移植到一个新的架构上

RT-Thread 项目 为嵌入式系统程序员提供了一个开源的操作系统(OS)。嵌入式领域是非常多样化的,有很多物联网(IoT)、定制工业和业余设备。RT-Thread 的目标是使嵌入式编程对每个人来说都很容易,无论你使用什么设备。有时,这意味着要将一个操作系统移植到一个新的架构上,不管是用于相同架构但指令集略有不同的的芯片,还是用于全新的架构。

一开始处理这个问题可能会有点吓人 —— 你可能不知道从哪里开始或如何开始。这篇文章收集了 RT-Thread 维护者在将 RTOS 移植到新的芯片架构时学到的经验。

你在开始之前需要知道什么

这里是一个看似难以逾越的过程的高屋建瓴的观点。这对你的项目来说可能有所不同,但从概念上来说,这是相对普遍的,即使一些具体的细节是不同的:

  1. 准备好一个 C 语言的执行环境
  2. 确认可以通过串行端口发送和接收字符
  3. 确认上下文切换代码可以工作
  4. 获取支持的硬件定时器
  5. 确认中断程序可以通过串口接收和解析数据

执行模式

对于大多数先进的体系结构,操作系统和用户应用程序运行在不同的权限级别上。这可以防止有功能故障的代码影响操作系统的集成和安全。例如,在 ARMv7-A 架构中,操作系统通常在系统模式下运行,而在 ARMv8-A 中,操作系统可以在 EL2 或 EL3 权限级别上运行。

通常情况下,芯片在通电时以最高权限级别执行启动代码。但在此之后,操作系统会将特权级别切换到其目标模式。

1、执行 C 代码

这一步的关键动作是将 块起始符号 block starting symbol (.bss)部分设置为零,并设置堆栈指针。

在 C 语言的实现中,未初始化的全局变量和静态变量通常存储在 .bss 部分,它不占用存储设备的任何空间。当程序被加载时,相应的空间被分配到内存中,并被初始化为零。当操作系统启动时,它必须自己做这项工作。

另一方面,操作系统必须初始化堆栈空间并设置堆栈指针。由于 C 语言程序在进入和退出函数时在堆栈上保存和恢复局部变量,所以在调用任何 C 函数之前必须设置堆栈指针。RT-Thread 必须为每个新创建的线程做这个步骤。

2、至少使用一个串行驱动器

RT-Thread 通过串口输出信息和日志,这也有助于在移植过程中对代码进行调试。在这个阶段,通过串口 接收 数据是不必要的。当我们第一次在串口上看到我们友好的、熟悉的 RT-Thread 的标志时,我们就知道我们走对了路!

3、确认上下文切换逻辑

一个任务的上下文是它的整个执行环境,它包含通用寄存器、程序计数器、堆栈帧的位置等等。当一个新的线程被创建时,RT-Thread 必须手动分配和设置它的上下文,这样调度器就可以切换到新的线程,就像它对其他线程一样。

有三件事需要注意:

  • 首先,当 RT-Thread 启动时,默认情况下中断是禁用的。当任务调度器第一次被启用时,它们就会被启用;这个过程是在上下文切换期间用汇编语言实现的。
  • 第二,当一个线程退出时,下一个调度将开始,这时拥有的资源会被空闲的线程回收。
  • 第三,数据被推入堆栈的顺序必须与从堆栈中弹出数据的顺序一致。

一般来说,你希望正常进入主函数和 msh 控制台。然而,在这个阶段无法实现输入控制,因为串行输入中断还没有实现。当串行中断实现后,就可以进行 msh 输入了。

4、设置定时器

RT-Thread 需要一个定时器来定期产生中断;它被用来计算自系统启动以来所经过的“滴答”。计数器的编号用于提供软件中断功能,并指示内核何时开始调度一个任务。

设置时间片的值可能是一件棘手的事情。它通常是 10ms 到 1ms。如果你在一个慢速的 CPU 上选择一个小的时间片,大部分时间就会花在任务切换上 —— 不利于完成其他事情。

5、确认串口工作正常

在这一步,我们通过串口与 RT-Thread msh 进行交互。我们发送命令,按回车键,然后看着 msh 执行命令并显示结果。

这个过程通常不难实现。不过,有一点要提醒大家。在某些平台上,在处理完串口中断后,别忘了清除中断标志。

一旦串口工作正常,移植过程基本上就完成了。

实践

为了将你的项目移植到不同的芯片架构上,你需要非常清楚地了解你所针对的芯片的架构。熟悉你的项目中最关键的部分的底层代码。通过对照芯片的手册结合大量的实际工作经验,你会了解芯片的特权模式、寄存器和编译方法。

如果你没有需要移植到新芯片的项目,请加入我们;RT-Thread 项目总是需要帮助将 RTOS 移植到新的芯片上!作为一个开源项目,RT-Thread 正在改变开源嵌入式编程的面貌。请在 RT-Thread 俱乐部介绍你自己并寻求帮助!


本文基于 DEV 社区上的 如何将操作系统移植到不同的芯片架构上?,并经许可转载。


via: https://opensource.com/article/21/5/port-chip-architectures

作者:Alan Smithee 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索一些未被充分利用但仍然有用的 Python 特性。

 title=

这是 Python 3.x 首发特性系列文章中的第三篇。其中一些 Python 版本已经推出了一段时间。例如,Python 3.2 是在 2011 年首次发布的,但其中引入的一些很酷、很有用的特性仍然没有被使用。下面是其中的三个。

argparse 子命令

argparse 模块首次出现在 Python 3.2 中。有许多用于命令行解析的第三方模块。但是内置的 argparse 模块比许多人认为的要强大。

要记录所有的 argparse 的特性,那需要专门写系列文章。下面是一个例子,说明如何用 argparse 做子命令。

想象一下,一个命令有两个子命令:negate,需要一个参数,multiply,需要两个参数:

$ computebot negate 5
-5
$ computebot multiply 2 3
6
import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

add_subparsers() 方法创建一个对象,你可以向其添加子命令。唯一需要记住的技巧是,你需要添加通过 set_defaults() 调用的子命令:

negate  = subparsers.add_parser("negate")
negate.set_defaults(subcommand="negate")
negate.add_argument("number", type=float)
multiply  = subparsers.add_parser("multiply")
multiply.set_defaults(subcommand="multiply")
multiply.add_argument("number1", type=float)
multiply.add_argument("number2", type=float)

我最喜欢的一个 argparse 功能是,因为它把解析和运行分开,测试解析逻辑特别令人愉快。

parser.parse_args(["negate", "5"])
    Namespace(number=5.0, subcommand='negate')
parser.parse_args(["multiply", "2", "3"])
    Namespace(number1=2.0, number2=3.0, subcommand='multiply')

contextlib.contextmanager

上下文是 Python 中一个强大的工具。虽然很多人 使用 它们,但编写一个新的上下文常常看起来像一门黑暗艺术。有了 contextmanager 装饰器,你所需要的只是一个一次性的生成器。

编写一个打印出做某事所需时间的上下文,就像这样简单:

import contextlib, timeit

@contextlib.contextmanager
def timer():
    before = timeit.default_timer()
    try:
        yield
    finally:
        after = timeit.default_timer()
        print("took", after - before)

你可以这样使用:

import time

with timer():
    time.sleep(10.5)
    took 10.511025413870811`

functools.lru\_cache

有时,在内存中缓存一个函数的结果是有意义的。例如,想象一下经典的问题:“有多少种方法可以用 25 美分、1 美分、2 美分和 3 美分可以来换取 1 美元?”

这个问题的代码可以说是非常简单:

def change_for_a_dollar():
    def change_for(amount, coins):
        if amount == 0:
            return 1
        if amount &lt; 0 or len(coins) == 0:
            return 0
        some_coin = next(iter(coins))
        return (
            change_for(amount, coins - set([some_coin]))
            +
            change_for(amount - some_coin, coins)
        )
    return change_for(100, frozenset([25, 10, 5, 1]))

在我的电脑上,这需要 13ms 左右:

with timer():
    change_for_a_dollar()
    took 0.013737603090703487`

事实证明,当你计算有多少种方法可以做一些事情,比如用 50 美分找钱,你会重复使用相同的硬币。你可以使用 lru_cache 来避免重复计算。

import functools

def change_for_a_dollar():
    @functools.lru_cache
    def change_for(amount, coins):
        if amount == 0:
            return 1
        if amount &lt; 0 or len(coins) == 0:
            return 0
        some_coin = next(iter(coins))
        return (
            change_for(amount, coins - set([some_coin]))
            +
            change_for(amount - some_coin, coins)
        )
    return change_for(100, frozenset([25, 10, 5, 1]))
with timer():
    change_for_a_dollar()
    took 0.004180959425866604`

一行的代价是三倍的改进。不错。

欢迎来到 2011 年

尽管 Python 3.2 是在 10 年前发布的,但它的许多特性仍然很酷,而且没有得到充分利用。如果你还没使用,那么将他们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-32

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索一些未被充分利用但仍然有用的 Python 特性。

 title=

这是 Python 3.x 首发特性系列文章的第二篇。Python 3.1 于 2009 年首次发布,尽管它已经发布了很长时间,但它引入的许多特性都没有被充分利用,而且相当酷。下面是其中的三个。

千位数格式化

在格式化大数时,通常是每三位数放置逗号,使数字更易读(例如,1,048,576 比 1048576 更容易读)。从 Python 3.1 开始,可以在使用字符串格式化函数时直接完成:

"2 to the 20th power is {:,d}".format(2**20)
'2 to the 20th power is 1,048,576'

,d 格式符表示数字必须用逗号格式化。

Counter 类

collections.Counter 类是标准库模块 collections 的一部分,是 Python 中的一个秘密超级武器。它经常在 Python 的面试题的简单解答中首次遇到,但它的价值并不限于此。

例如,在 Humpty Dumpty 的歌 的前八行中找出五个最常见的字母:

hd_song = """
In winter, when the fields are white,
I sing this song for your delight.

In Spring, when woods are getting green,
I'll try and tell you what I mean.

In Summer, when the days are long,
Perhaps you'll understand the song.

In Autumn, when the leaves are brown,
Take pen and ink, and write it down.
"""
import collections

collections.Counter(hd_song.lower().replace(' ', '')).most_common(5)
[('e', 29), ('n', 27), ('i', 18), ('t', 18), ('r', 15)]

执行软件包

Python 允许使用 -m 标志来从命令行执行模块。甚至一些标准库模块在被执行时也会做一些有用的事情;例如,python -m cgi 是一个 CGI 脚本,用来调试网络服务器的 CGI 配置。

然而,直到 Python 3.1,都不可能像这样执行 软件包。从 Python 3.1 开始,python -m package 将执行软件包中的 __main__ 模块。这是一个放调试脚本或命令的好地方,这些脚本主要是用工具执行的,不需要很短。

Python 3.0 在 11 年前就已经发布了,但是在这个版本中首次出现的一些功能是很酷的,而且没有得到充分利用。如果你还没使用,那么将它们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-31-features

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出