산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

피코 구동 부팅 스위치: 전원 켜기 전 OS 선택하기

컴퓨터를 켜기 전에도 스위치 토글로 부팅할 OS를 미리 선택하세요. 이제 OS 선택을 위해 기다릴 필요가 없습니다.

시작하며

Hackaday.io에서 프로젝트를 둘러보다 Stephen Holdaway의 이 프로젝트(클릭)를 발견했습니다. 이 프로젝트에서 그는 모든 듀얼 부트 사용자가 겪는 답답한 작업, 즉 Windows로 전환하고 싶을 때마다 GRUB 메뉴에서 OS를 선택하려고 앉아서 기다리는 문제를 해결했습니다. 그는 하드웨어 스위치를 추가하여 컴퓨터가 켜질 때마다 부팅할 OS를 결정할 수 있게 했습니다.

그는 STM32 마이크로컨트롤러를 USB 대용량 저장 장치로 구성하여 이를 달성했습니다. 그는 연구부터 구현까지 전체 여정을 hackaday 포스트(클릭)에 문서화했습니다. 구현 이해를 위해 해당 포스트를 읽어보세요.

이 프로젝트에서는 라즈베리 파이 피코로 변경 사항을 포팅한 방법을 보여줍니다. 내 버전은 이 GitHub Repo(클릭)에서 확인 가능.

컨셉

GNU GRUB은 어떤 운영체제도 로드되기 전에 실행되는 프로그램입니다. 이 메뉴를 통해 어떤 OS를 로드할지 선택할 수 있습니다. GRUB은 작업에 사용할 수 있는 매우 제한된 모듈을 제공합니다. 즉, USB로 연결된 마이크로컨트롤러에서 데이터를 읽을 수 없습니다. 하지만 저장 디스크에서 데이터는 읽을 수 있습니다.

그래서 마이크로컨트롤러를 대용량 저장 장치로 열거하여 GRUB을 속여 마이크로컨트롤러에서 데이터를 읽게 할 수 있습니다.

따라서 tinyUSB 라이브러리를 통해 라즈베리 파이 피코를 대용량 저장 장치로 열거하며, 여기에 switch.cfg 파일이 있어 피코가 스위치 위치(즉 1은 ON, 0은 OFF)를 씁니다.

GRUB에 스크립트를 추가하여 switch.cfg 파일을 읽고 default를 0(Ubuntu)/2(Windows)로 설정합니다.

GRUB이 로드되면 커스텀 스크립트 실행, 이 스크립트가 UUID 식별자로 우리 장치 검색, 존재 시 switch.cfg 파일 읽기. 스위치 위치 획득 후 추출된 데이터로 기본 OS 선택 설정.

요약하면,

피코를 대용량 저장 장치로 구성

tinyUSB의 cdc_msc 예제로 이 구현. 예제는 피코를 대용량 저장 장치로 구성하고 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

이제 피코가 대용량 저장 장치로 구성됨. UF2 파일을 피코에 복사하면 저장 장치로 열거. 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

// 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에 스위치 위치 쓰기 위해 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)
{
    // 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;
    }
    ...
    ...
}

피코 코드 컴파일

코드에 피코 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 서브커맨드가 있습니다.

장치 발견 시 첫 번째 장치가 환경 변수 값으로 설정.

–set hdswitchhdswitch는 우리 환경 변수로, 발견 시 디스크 이름으로 설정.

다음, hdswitch 변수 설정 시 switch.cfg 파일 source, 또 다른 환경 변수 os_hw_switch 생성되어 스위치 위치(0/1) 저장.

os_hw_switch 값 읽고 default를 각각 0 또는 2로 설정. 0은 GRUB 메뉴에서 Ubuntu가 0번째, Windows가 2번째 위치이므로.

마지막으로 hdswitch가 설정되지 않았다면 default를 GRUB_DEFAULT로 설정.

이제 grub 업데이트:

$ sudo update-grub

출처: Hardware Boot Select Switch Using Pico

제조공정

  1. C# switch 문 마스터하기: 문법, 예제, 모범 사례
  2. C# using 문 마스터하기: 네임스페이스 임포트, 별칭, 정적 지시자
  3. 라즈베리 파이 2와 ADS-WS1로 야외 기상 관측소 구축하기
  4. AT89S52 마이크로컨트롤러와 LM35 센서를 이용한 온도 기반 기기 제어 시스템
  5. 라즈베리 파이 3와 PubNub로 원격 기상 모니터링하기
  6. TI SensorTag를 Node-RED로 Blynk와 연동하기: 라즈베리 파이 제로 구현
  7. 라즈베리 파이에서 PIR 모션 센서로 LED 제어하기
  8. 브리지 실드(Bridge Shield)로 스마트 로봇 만들기 - 라즈베리 파이 & 아두이노 통합
  9. 파이썬으로 와이파이 제어 라즈베리파이 로봇 만들기 – 단계별 가이드
  10. IoT 디바이스 임베디드 하드웨어 해킹: 도구, 기술, 비즈니스 시사점