电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>电子资料>使用Pico的硬件引导选择开关

使用Pico的硬件引导选择开关

2023-06-16 | zip | 0.00 MB | 次下载 | 免费

资料介绍

描述

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

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

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

概念

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

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

因此,我们通过tinyUSB库将我们的树莓派 pico 枚举为大容量存储设备,该库将具有文件switch.cfg文件,pico 将向其中写入开关位置,即1 表示 ON 0 表示 OFF

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

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

总之,

  • pico 会将自己配置为大容量存储设备。
  • grub 菜单调用我们的脚本并询问特定的文件。
  • Pico 通过在switch.cfg文件中添加开关位置来响应读取请求。
  • grub 中的脚本从文件中提取信息并从提取的数据中设置默认选项。

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

我使用 tinyUSB 的cdc_msc示例来实现这一点。该示例将 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: Readme Content -------------//
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"

电路

poYBAGOIKrqASFJGAAAVOmGHIzE439.png
开关连接
 

 

pYYBAGOIOlOAQ1ZHAAoU_Ub3zR4889.jpg
 

读取开关位置并写入文件

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

  • 如果开关打开:设置 os_hw_switch=1\n
  • 如果开关关闭:设置 os_hw_switch=0\n

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

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

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

// read switch value 
uint8_t read_switch_value()
{
    return gpio_get(SWITCH_PIN) ? '1' : '0';
}

int main(void)
{
    gpio_init(SWITCH_PIN);

    //configure pin as INPUT
    gpio_set_dir(SWITCH_PIN, false); 

    //configure pin as PULL_DOWN
    gpio_set_pulls (SWITCH_PIN,false,true);

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

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

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

static char grubConfigStr[] = "set os_hw_switch=0\n";
static void readGrubConfig(uint8_t* output)
{
    // Modify config string with current switch value
    grubConfigStr[sizeof(grubConfigStr)-3] = read_switch_value();
    memcpy(output, &grubConfigStr, sizeof(grubConfigStr));
}

// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
    (void) lun;
    // when reading the file
    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

....
# Look for hardware switch device by its hard-coded filesystem ID
search --no-floppy --fs-uuid --set hdswitch 0000-1234

# If found, read dynamic config file and select appropriate entry for each position
if [ "${hdswitch}" ] ; then
  source ($hdswitch)/switch.cfg

  if [ "${os_hw_switch}" == 0 ] ; then
    # Boot Linux
    set default="0"
  elif [ "${os_hw_switch}" == 1 ] ; then
    # Boot Windows
    set default="2"
  else
    # Fallback to default
    set default="${GRUB_DEFAULT}"
  fi

else
  set default="${GRUB_DEFAULT}"
fi

首先,我们搜索我们的文件系统。GRUB 有一个子命令search就是为了这个。

  • -no-floppy选项防止搜索软盘设备
  • -fs--uuid 0000-1234搜索 UUID 为 0000-1234 的文件系统。

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

--set hdswitch hdswitch是我们的环境变量,如果找到,则使用磁盘名称进行设置。

接下来,如果设置了hdswitch变量 ,我们将获取 switch.cfg文件,这将创建另一个具有开关位置的环境变量,即 0/1。os_hw_switch

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

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

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

$ sudo update-grub

我们完成了。

测试

poYBAGOIOnuAFjStAAoQsrAlGo8584.jpg
 

在连接设备的情况下重新启动系统。

如果一切正常,打开按钮将选择 windows 或 ubuntu(如果关闭)。

pYYBAGOIOn2AZbgqAABpnnVPDEg185.jpg
当开关位置为 1 即 ON
 
pYYBAGOIOoCAGLslAABuKgmMA4w296.jpg
当开关位置为 0 即 OFF
 

 


下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1山景DSP芯片AP8248A2数据手册
  2. 1.06 MB  |  532次下载  |  免费
  3. 2RK3399完整板原理图(支持平板,盒子VR)
  4. 3.28 MB  |  339次下载  |  免费
  5. 3TC358743XBG评估板参考手册
  6. 1.36 MB  |  330次下载  |  免费
  7. 4DFM软件使用教程
  8. 0.84 MB  |  295次下载  |  免费
  9. 5元宇宙深度解析—未来的未来-风口还是泡沫
  10. 6.40 MB  |  227次下载  |  免费
  11. 6迪文DGUS开发指南
  12. 31.67 MB  |  194次下载  |  免费
  13. 7元宇宙底层硬件系列报告
  14. 13.42 MB  |  182次下载  |  免费
  15. 8FP5207XR-G1中文应用手册
  16. 1.09 MB  |  178次下载  |  免费

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234315次下载  |  免费
  3. 2555集成电路应用800例(新编版)
  4. 0.00 MB  |  33566次下载  |  免费
  5. 3接口电路图大全
  6. 未知  |  30323次下载  |  免费
  7. 4开关电源设计实例指南
  8. 未知  |  21549次下载  |  免费
  9. 5电气工程师手册免费下载(新编第二版pdf电子书)
  10. 0.00 MB  |  15349次下载  |  免费
  11. 6数字电路基础pdf(下载)
  12. 未知  |  13750次下载  |  免费
  13. 7电子制作实例集锦 下载
  14. 未知  |  8113次下载  |  免费
  15. 8《LED驱动电路设计》 温德尔著
  16. 0.00 MB  |  6656次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537798次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420027次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234315次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191187次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183279次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138040次下载  |  免费