亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

使用 Pico 的硬件启动选择开关

预先选择要启动的操作系统,甚至在通过切换开关打开计算机之前。现在您不必等待选择操作系统。

故事

在 Hackaday.io 的项目中徘徊,我偶然发现了 Stephen Holdaway 的这个项目(点击)。在这个项目中,他解决了每一个双启动用户面临的一个令人沮丧的任务,当我们想切换到windows时,他总是坐着等待从GRUB菜单中选择os(Windows)。他能够添加一个硬件开关来确定每次打开计算机时要启动的操作系统。

他通过将 STM32 微控制器配置为 USB 大容量存储设备来实现这一点。他在 hackaday 帖子(点击)中记录了他整个项目研究和实施的过程。请阅读他的帖子以更好地了解实现。

在这个项目中,我将展示我如何设法将更改移植到 Raspberry Pi Pico。你可以在这个 GitHub 存储库中找到我的版本(点击)。

概念

GNU GRUB 是一个在加载任何操作系统之前运行的程序。通过这个菜单,我们可以选择加载哪个操作系统。 GRUB 提供的模块非常有限。这意味着它无法从通过 USB 连接的微控制器读取数据。但它可以从存储磁盘读取数据。

因此,我们可以通过将我们的微控制器枚举为大容量存储设备来欺骗 GRUB 从微控制器读取数据。

因此,我们将我们的 raspberry pi pico 枚举为一个大容量存储设备,通过 TinyUSB 库,它将有一个文件 switch.cfg 文件,pico 会将开关位置写入该文件,即 1 表示 ON 0 表示 OFF .

我们必须在 GRUB 中添加一个脚本,即读取 switch.cfg 文件并设置 default 的函数 0(Ubuntu)/2(Windows)。

GRUB 加载时,运行我们的自定义脚本,它依次通过 UUID 标识符搜索我们的设备,如果退出,则读取 switch.cfg 文件。获取开关位置后分别设置默认的os选择。

总之,

将 Pico 配置为大容量存储设备

我使用了 cdc_msc tinyUSB 的示例来实现这一点。该示例将 pico 配置为大容量存储设备并创建 FAT12 文件系统并枚举 README.txt 文件。

我将 README.txt 更改为 switch.cfg 并在文件中添加了“set os_hw_switch=0\n”行。

#define SWITCH_CFG_CONTENTS \
"set os_hw_switch=0\n"

...
//----- -------- Block3:自述内容-------------//
SWITCH_CFG_CONTENTS

现在我们已将 pico 配置为大容量存储设备。将uf2文件复制到pico后,枚举为存储设备。我们将需要 GRUB 脚本的设备的 UUID id,即 UUID="0000-1234"。

$ sudo blkid
...
/dev/sda:SEC_TYPE="msdos" LABEL_FATBOOT="TinyUSB MSC" LABEL="TinyUSB MSC" UUID="0000-1234" BLOCK_SIZE="512" TYPE="vfat"

电路

读取开关位置并写入文件

现在我们需要读取开关位置并相应地更改 switch.cfg 文件的内容,即

我已经使用GPIO_PIN 28作为开关管脚,设置为下拉。

read_switch_value 返回开关位置,即“1”打开(拉高)和“0”关闭(拉低)。

//-------------------------main.c-------- -------------
#define SWITCH_PIN 28

// 读取开关值
uint8_t read_switch_value()
{
返回 gpio_get(SWITCH_PIN) ? '1' :'0';
}

int main(void)
{
gpio_init(SWITCH_PIN);

//配置引脚为输入
gpio_set_dir(SWITCH_PIN, false);

//配置引脚为PULL_DOWN
gpio_set_pulls (SWITCH_PIN,false,true);

要将开关位置写入 switch.cfg,我使用了 readGRUBConfig() 它调用 read_switch_value 功能,并用开关位置设置输出缓冲区。

我发现在阅读第三个block3时lba 设置为 3,因此拦截调用并调用 readGrubConfig 并传递文件内容将被复制的缓冲区。

//-------------------------msc_disk.c-------- -------------

static char grubConfigStr[] ="set os_hw_switch=0\n";
static void readGrubConfig(uint8_t* output)
{
// 用当前开关值修改配置字符串
grubConfigStr[sizeof(grubConfigStr)-3] =read_switch_value();
memcpy(output, &grubConfigStr, sizeof(grubConfigStr));
}

// 收到 READ10 命令时调用回调。
// 将磁盘数据复制到缓冲区(最多 bufsize)并返回复制的字节数。
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
(void) lun;
//读取文件时
if(lba ==3){
readGrubConfig(buffer);
return bufsize;
}
...
...
}

编译 Pico 代码

我们需要添加 pico stdlib 到我们的代码以获取 gpio 针访问。

//-------------------------main.c-------- ---------------------------
#include
#include
#include
#include "bsp/board.h"
#include "tusb.h"
...
#include "pico/ stdlib.h"

制作项目:

$ mkdir build
$ cd build
$ cmake ..
$ make

配置 GRUB 读取文件内容

我已经在我的 Ubuntu 20.10 中添加了这些更改。

$ sudo vim /etc/grub.d/40_custom

....
# 通过硬编码查找硬件开关设备filesystem ID
search --no-floppy --fs-uuid --set hdswitch 0000-1234

#如果找到,读取动态配置文件并为每个位置选择合适的条目
if [ "${hdswitch}" ]; then
source ($hdswitch)/switch.cfg

if [ "${os_hw_switch}" ==0 ]; then
# 启动 Linux
set default="0"
elif [ "${os_hw_switch}" ==1 ]; then
# 启动 Windows
set default="2"
else
# 回退到默认值
set default="${GRUB_DEFAULT}"
fi

else
set default="${GRUB_DEFAULT}"
fi

首先,我们搜索我们的文件系统。 GRUB 有一个子命令 <​​em>search 仅此而已。

如果找到任何设备,则将找到的第一个设备设置为环境变量的值。

–设置 hdswitch hdswitch 是我们的环境变量,如果找到则设置为磁盘名称。

接下来,如果 hdswitch 设置变量,这会创建另一个环境变量 os_hw_switch 开关位置,即 0/1。

我们读取 os_hw_switch 的值 并将默认值分别设置为 0 或 2。 0 因为在 GRUB 菜单中,Ubuntu 位于第 0 位,而 windows 位于第 2 位。

最后,如果hdswitch 未设置,我们将默认设置为 GRUB_DEFAULT。

现在我们需要更新我们的 grub:

$ sudo update-grub

来源: 使用 Pico 的硬件启动选择开关


制造工艺

  1. 脱毛设备
  2. C# switch 语句
  3. C# 使用
  4. 使用 Eclipse Vorto 协调特定设备有效载荷
  5. Raspberry Pi 2 气象站
  6. 使用 LM35 的基于温度的设备控制系统
  7. 使用树莓派远程监测天气
  8. SensorTag 到 Blynk 使用 Node-RED
  9. 使用 Raspberry Pi 的运动传感器
  10. 使用 Raspberry Pi 和 Bridge Shield 的机器人
  11. 使用 Raspberry Pi 的 Wifi 控制机器人
  12. IoT 设备嵌入式硬件黑客简介