Windows 10에서 Raid에서 AHCI 모드로 변경하기

Intel RST 모드를 사용하게 되면, Ubuntu 20.04 설치시에 다음과 같은 창이 나타나면서 더이상 설치가 진행이 되지 않는다.

그렇다고, 막바로 바이오스 설정에서 AHCI로 변경을 하게 되면, 그 유명한 블루스크린이 발동하면서 윈도우 부팅이 진행되지 않는다. 다음과 같은 절차로 진행하면 쉽게 AHCI 모드로 변경이 가능하다.

먼저 RST (Raid) 상태에서, 윈도우10을 부팅하고, 커맨드 창을 관리자 모드로 연다 (커맨드 창 아이콘에서 오른쪽 버튼을 눌러 관리자 모드로 열면 됨).

다음과 같이 입력하고 재부팅.

bcdedit /set {current} safeboot minimal

이때 PC의 바이오스 설정으로 들어가서 (F2 or Del 등 제조사마다 다름). IDE 모드를 Raid에서 AHCI로 변경한다.

이제 다시 윈도우10으로 부팅하면, 안전모드로 부팅이 되게 되고 다시 커맨드 창을 관리자 모드로 연 다음, 다음과 같이 다시 입력

bcdedit /deletevalue {current} safeboot

그런 다음 재부팅.

이제 정상적으로 부팅이 되는 것을 확인할 수 있다.

장치관리에서 IDE 부분을 확인해보면,

정상적으로 적용이 되어 있음을 볼 수 있다.

Ubuntu에서 한글 및 한자 입력하기

Ubuntu 20.04든 그 하위 버전이든 모두 적용됨.

fcitx 한글 입력기 설치

$ sudo apt install fcitx-hangul

설정 > 지역 및 언어 (Region & Language) > Manage Installed Languages 버튼을 눌러 언어 설정으로 이동.

키보드 입력 방법 시스템 (Keyboard input method system)에서 fcitx를 선택.

혹시 한글 관련 폰트나 그런 것들이 설치되어 있지 않은 경우, Install/Remove Languages 버튼을 눌러, Korean 선택.

시스템을 재부팅하고 나면, 상단 트레이바에 fcitx가 실행되어 있음을 볼수 있음.

아이콘을 눌러, Configure Current Input Method 선택.

하단의 + 버튼을 눌러 Add input method 창을 띄운 뒤, Only Show Current Language를 체크 해제하고 Hangul을 입력해 한글 입력기 추가.

다음으로 하단 키보드 모양을 클릭하여, 기본 키보드 레이아웃을 Korean – Korean (101/104 compatible)으로 선택.

다음으로 Global Config 탭으로 이동. Trigger Input Method의 왼쪽 버튼을 클릭한 후, 한영키 입력.

다시, Input Method로 이동, Hangul을 더블클릭하면,

Word Commit 활성화, 한자모드 토글키의 왼쪽 버튼을 클릭, 한자키를 입력.

이제 한영키로 한글 입력 활성화, 한글 입력 후 한자키를 누르면 한자 입력 창 나옴.

Installation Docker on Ubuntu 18.04

Install the packages for dependencies.

$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

Add Docker’s official GPG key

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK

Add repository for installation

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Install

$ sudo apt-get install docker-ce docker-ce-cli containerd.io

Verify the installation

$ sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Add user to docker group for execute without sudo command

$ sudo usermod -aG docker `whoami`

Reboot!

$ groups
<user-name> adm tty dialout cdrom sudo dip plugdev lpadmin sambashare docker

Now, you can run docker without sudo command

$ docker run hello-world

Ubuntu에서 HEIC 이미지를 jpg로 변환

HEIC 이미지는 아이폰에서 고효율로 설정하여 사진을 찍게되면 생성되는 파일입니다. 내보내기를 할때 호환성 모드로 하면 자동으로 png나 jpg로 변환되긴 하는데, 파일을 직접 전송해서 사용하는 경우 HEIC 확장자의 이미지로 보내지게 됩니다.

Ubuntu에서는 아직 HEIC 이미지를 지원하지 않아서, 이를 보기 위해선 jpg로 변환해서 봐야 합니다. 변경할 수 있는 툴은 다음과 같이 설치가 가능합니다.

$ sudo apt install libheif-examples

다음으로 HEIC 이미지가 있는 디렉토리로 이용하여

$ heif-convert IMG_6326.HEIC IMG_6326.HEIC.jpg

와 같이 변경할 수 있습니다.

변경해야 할 이미지가 여러장이라면, 간단한 쉘 스크립트를 사용하면 됩니다.

$ find *.HEIC | xargs -n1 -I {} /bin/bash -c 'heif-convert {} {}.jpg'

이렇게 하면 현재 디렉토리 내에 있는 HEIC 파일을 전부 읽어들여, jpg 이미지로 변경할 수 있습니다.

끝!.

STM32F746G-DISCO with TouchGFX 프로젝트 생성

보드를 구입한 본래의 목적이었던 TouchGFX를 사용하기 위해서 프로젝트 생성. 여러가지 유투브나 문서를 찾아봤지만, 한번에 매끄럽게 되는건 없는듯하다. ST에서 TouchGFX를 인수하였다곤 하지만 하나의 개발도구로 합치는데는 꽤 시간이 걸릴듯 한데… 뭐 그거야 나중 일이고.. 일단은 프로젝트를 생성하고 개발하기 위한 준비단계까지는 되어야 하니….

프로젝트 생성은 예전 데모와 마찬가지로 File > New > STM32 Project 로 시작한다. 보드도 역시 현재 보유한 32F746GDISCOVERY를 선택하고 다음으로 진행.

프로젝트 이름을 입력하고, 개발 언어는 C++로 선택. Finish를 선택하여 생성 시작. 이후 나오는 다이얼로그창에선 모두 Yes로 답하면 됨.

예전 데모와 같이 디바이스 설정을 위한 화면이 나타나면… 이제부터 설정 시작. (앞선 포스팅에선 편하다고 했었는데, 편하긴 개뿔… 좀더 한방에 되면 얼마나 좋아….)


(1) System Core > CORTEX_M7

(2) Connectivity > ETH

(3) Connectivity > QUADSPI

(4) Multimedia > LTDC

(5) TouchGFX 관련

이건 먼저, Additional Software를 클릭하고, 다음의 화면과 같이 TouchGFX를 선택.

그러면, 좌측에 Additional Software 탭과, TouchGFX 관련 설정 항목이 생성됨. Graphics Application를 체크하고 다음과 같이 설정.

(6) Middleware > FREERTOS

스택크기만 4096으로 변경.


이제 Project > Generate Code (Alt+K)를 실행하여 코드 생성. 생성이 완료되면, 프로젝트 창이 다음과 같이 되어야 함.

이제 TouchGFX의 ApplicationTemplate.touchgfx.part를 더블클릭하여 TouchGFX 디자이너를 실행한다. 만약 기존에 설치가 안되어있을 경우, 홈디렉토리 아래의 다음 주소를 가보면, 설치 파일이 존재한다.

C:\Users\bkahn\STM32Cube\Repository\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.13.0\Utilities\PC_Software\TouchGFXDesigner

설치를 완료하고 다시 저 파일을 더블클릭하면…

와 같이 디자이너가 실행되고, UI를 디자인할 수 있음. 일단은 Blank UI를 선택한다. 다음과 같이 빈 UI 화면이 나오고 왼쪽의 위젯 화면에서 원하는 컴포넌트를 가져다 붙이면 됨.

테스트용도이니 대충 디자인하고… (이 툴 또한 익숙해져야 하는 것이기에….)

다 되었으면, 오른쪽 상단의 Generate Code를 클릭한다. 아래쪽 상태바에 Generate Done이 뜨면, 다시 CubeIDE로 이동한다. 프로젝트에서 오른쪽 버튼을 누르고 Refresh (F5)를 클릭하면, 파일이 추가됨을 볼 수 있다.

이제 몇가지 코드를 추가 및 수정 필요.

(2-1) STM32F746NGHX_FLASH.ld를 수정

그래픽 등 리소스가 제법 큰 크기를 차지하므로, FLASH 영역에는 다 들어가지 못함. 따라서 보드에 부착된 외장 플래시에 저장해야 하는데, 이를 위해 저 파일을 수정해야 함. 다른 부분만 표시하면…

...
/* Memories definition */
MEMORY
{
  RAM     (xrw)  : ORIGIN = 0x20000000,  LENGTH = 320K
  FLASH   (rx)   : ORIGIN = 0x8000000,   LENGTH = 1024K
  QUADSPI (r)    : ORIGIN = 0x90000000,  LENGTH = 16M
}

...

.ARM.attributes 0 : { *(.ARM.attributes) }

  ExtFlashSection :
	{
		*(ExtFlashSection ExtFlashSection.*)
		*(.gnu.linkonce.r.*)
        . = ALIGN(0x4);
	} >QUADSPI

  FontFlashSection :
	{
		*(FontFlashSection FontFlashSection.*)
		*(.gnu.linkonce.r.*)
        . = ALIGN(0x4);
	} >QUADSPI

  TextFlashSection :
	{
		*(TextFlashSection TextFlashSection.*)
		*(.gnu.linkonce.r.*)
        . = ALIGN(0x4);
	} >QUADSPI

...

(2-2) Drivers에 BSP와 Components 추가.

해당 파일은 TouchGFX 디자이너에서 빈프로젝트를 생성하면 얻을 수 있음. 추가한 다음 C++ 빌드 옵션에 해당 디렉토리 추가.

총 4개의 디렉토리를 추가해야 함.

(2-3) main.c 파일 수정

Core > Src > main.c 를 열고 다음과 같이 추가.

...

/* USER CODE BEGIN Includes */
#include <stm32746g_discovery_qspi.h>
/* USER CODE END Includes */

...

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define REFRESH_COUNT        1835

#define SDRAM_TIMEOUT                            ((uint32_t)0xFFFF)
#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)
/* USER CODE END PD */

...

/* USER CODE BEGIN PV */
static FMC_SDRAM_CommandTypeDef Command;
/* USER CODE END PV */



static void MX_QUADSPI_Init(void)
{
...
  /* USER CODE BEGIN QUADSPI_Init 2 */
  BSP_QSPI_Init();

  BSP_QSPI_MemoryMappedMode();
  HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
  /* USER CODE END QUADSPI_Init 2 */
}


static void MX_FMC_Init(void)
{
...
  /* USER CODE BEGIN FMC_Init 2 */
  __IO uint32_t tmpmrd = 0;

      /* Step 1: Configure a clock configuration enable command */
      Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
      Command.CommandTarget          =  FMC_SDRAM_CMD_TARGET_BANK1;
      Command.AutoRefreshNumber      = 1;
      Command.ModeRegisterDefinition = 0;

      /* Send the command */
      HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

      /* Step 2: Insert 100 us minimum delay */
      /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
      HAL_Delay(1);

      /* Step 3: Configure a PALL (precharge all) command */
      Command.CommandMode            = FMC_SDRAM_CMD_PALL;
      Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
      Command.AutoRefreshNumber      = 1;
      Command.ModeRegisterDefinition = 0;

      /* Send the command */
      HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

      /* Step 4: Configure an Auto Refresh command */
      Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
      Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
      Command.AutoRefreshNumber      = 8;
      Command.ModeRegisterDefinition = 0;

      /* Send the command */
      HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

      /* Step 5: Program the external memory mode register */
      tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | \
               SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL    | \
               SDRAM_MODEREG_CAS_LATENCY_3            | \
               SDRAM_MODEREG_OPERATING_MODE_STANDARD  | \
               SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

      Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
      Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
      Command.AutoRefreshNumber      = 1;
      Command.ModeRegisterDefinition = tmpmrd;

      /* Send the command */
      HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

      /* Step 6: Set the refresh rate counter */
      /* Set the device refresh rate */
      HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);

      //Deactivate speculative/cache access to first FMC Bank to save FMC bandwidth
      FMC_Bank1->BTCR[0] = 0x000030D2;

  /* USER CODE END FMC_Init 2 */
}


void StartDefaultTask(void const * argument)
{
...
  /* USER CODE BEGIN 5 */
  MX_TouchGFX_Process();
...
}

이제 저장하고 프로젝트 빌드 Project -> Build Project. 에러없이 빌드가 완료되면 다음과 같이 각 메모리 영역의 사용량 등이 나옴.

Run > Run을 눌러 보드에 다운로드하고 실행.

이때, Debugger 항목에서 External Loader를 체크하고, 현재보드에 연결된 외장 FLASH 모델을 선택. Apply하고 확인을 눌러 계속 진행.

다운로드가 완료되고 자동으로 보드가 리셋이 되면서 아까 디자인 했던 그대로 화면이 나오는 것을 확인할 수 있음.

이렇게 일단은 셋업을 해놓고 하나씩 붙여나가면 될듯. 끝!