<Spec>

  • Ubuntu version : ubuntu-18.04.5-desktop-amd64
  • stm32mpu Major ecosystem releases version : v3.0.0

현재 부팅 가능한 microSD card까지 만들어 보았다. eMMC로 부팅하도록 하겠다.

 

먼저 보드의 부트 스위치 정보를 알아본다.

https://wiki.st.com/stm32mpu/wiki/STM32MP157x-EV1_-_hardware_description#Boot_related_switches

 



eMMC

microSD card

 

1. eMMC partitions 정보 확인

SD card 부팅을 시작으로 한다. 아래와 같은 명령어로 확인할 수 있다.

$ fdisk -l | grep mmcblk*
$ lsblk
$ cat /proc/partitions

eMMC는 mmcblk1이다.

 

2. Remove Partitions and format

$ partx -d /dev/mmcblk1		# remove partitions
$ sgdisk -o /dev/mmcblk1	# format

 

3. Create and Resize Partitions

$ sgdisk --resize-table=128 -a 1 \
        -n 1:1058:9249 -c 1:fip    \
        -n 2:9250:140321 -c 2:boot  \
        -n 3:140322:173089 -c 3:vendorfs  \
        -n 4:173090:1700897 -c 4:rootfs  \
        -n 5:1700898:3145694 -c 5:userfs  \
        -p /dev/mmcblk1

partition3 name은 'fip'로 해야만 한다. (first boot에서 fip name을 찾음 (v3.0.0으로 되면서 ssbl -> fip로 변경됨)

eMMC Register에 PARTITION_CONFIG가 setting 되어 있어서 first bootloader는 mmcblk1bootX를 사용한다.

 

$	# disable the forced read-only access
$ echo 0 > /sys/class/block/mmcblk1boot0/force_ro
$	# copy
$ dd if=USB/tf-a-stm32mp157f-ev1-emmc.stm32 of=/dev/mmcblk1boot0 conv=fdatasync
$	# mmc bootpart enable <boot0 OR boot1?> <mmcblk1pX partition number> /dev/mmcblk1
$ mmc bootpart enable 1 1 /dev/mmcblk1

microSD card에서 first bootloader가 partition1, 2에 저장하여 select하여 사용하는 것과 같이 mmcblk1boot0, mmcblk1boot1에 copy후 select 하여 사용한다. 그리고 그다음은 partition1(fip)로 넘어가도록 설정한다.

 

4. copy to eMMC

$ dd if=USB/fip-stm32mp157f-ev1-trusted.bin of=/dev/mmcblk1p1
$ dd if=USB/st-image-bootfs-openstlinux-weston-stm32mp1-20210708094827.bootfs.ext4 of=/dev/mmcblk1p2 conv=fdatasync  bs=512
$ dd if=USB/st-image-vendorfs-openstlinux-weston-stm32mp1-20210708094827.vendorfs.ext4 of=/dev/mmcblk1p3 conv=fdatasync  bs=512
$ dd if=USB/st-example-image-qtwayland-openstlinux-weston-stm32mp1-20210708094827.rootfs.ext4 of=/dev/mmcblk1p4 conv=fdatasync  bs=512
$ dd if=USB/st-image-userfs-openstlinux-weston-stm32mp1-20210708094827.userfs.ext4 of=/dev/mmcblk1p5 conv=fdatasync  bs=512

yocto image를 사용하여 eMMC 부팅하도록 해보겠다.

USB에 필요한 image를 넣어 target board에 mount하여 파일을 copy한다.

 

5. eMMC Booting

eMMC 부트 스위치를 변경하고 부팅한다. 

먼저 부팅하면 rootfs나 bootfs partition이 제대로 설정되어있지 않다. 먼저 수동으로 부팅되는지 확인한다.

STM32> setenv bootargs root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200
STM32> ext4load mmc 1:2 0xc2000000 uImage
STM32> ext4load mmc 1:2 0xc4000000 stm32mp157f-ev1.dtb
STM32> bootm 0xc2000000 - 0xc4000000

 

6. uboot 수정

kernel image가 있는 partition을 못 찾고 있다. mmc 1:2를 scanning 하도록 수정해준다.

STM32> setenv distro_bootpart 2
STM32> saveenv

 

 

rootfs를 지정해주거나 PARTUUID를 수정해준다.

PC> vi /media/USB/bootfs/mmc1_extlinux/stm32mp157f-ev1_extlinux.conf
-APPEND root=PARTUUID=491f6117-415d-4f53-88c9-6e0de54deac6 rootwait rw console=ttySTM0,115200
+APPEND setenv bootargs root=/dev/mmcblk1p6 rootwait rw console=ttySTM0,115200

$ # OR blkid 명령어로 PARTUUID확인하여 바꿔주면 된다.

 

<Spec>

  • Ubuntu version : ubuntu-18.04.5-desktop-amd64
  • stm32mpu Major ecosystem releases version : v3.0.0(openstlinux-5.10-dunfell-mp1-21-03-31)
  • kernel : Linux® kernel v5.10 (LTS)

 

이번에는 galcore.ko moduel을 넣어 보도록 한다. 

 

-Working path

$ pwd
~/STM/Developer-Package/stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.10.10-r0/linux-5.10.10

 

1. galcore version 확인

yocto source에서 다음과 같이 version 및 사용한 galcore가 무엇인지 확인할 수 있다.

해당 내용의 galcore를 올려 보도록 하자.

$ vi ~/STM/openstlinux-5.10-dunfell-mp1-21-03-31/layers/meta-st/meta-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-binary.inc

 

먼저 ①kernel 외부에서 빌드하여 수동으로 올리는 방법과 ②kernel modules make시 포함하도록 하는 방법 두 가지를 해보도록 하겠다.

 

-Working path

2. 수동으로 galcore 올리기

 - 압축 풀기 및 패치

$ git clone https://github.com/STMicroelectronics/gcnano-binaries
$ cd gcnano-binaries
$ tar -xvf gcnano-driver-6.4.3.tar.xz
$ cd gcnano-driver-6.4.3

 

 - modules build

$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ export KERNEL_DIR=$PWD/../../
$ make
$ make install

사용하는 kernel source의 경로를 잡아준다.

 

 - output copy

$ sudo mkdir -p /media/whatmam/rootfs/lib/modules/5.10.10/extra
$ sudo cp -rfvp galcore.ko  /media/whatmam/rootfs/lib/modules/5.10.10/extra
$ sudo vi /media/whatmam/rootfs/lib/modules/5.10.10/modules.dep
 + extra/galcore.ko:

SD 카드를 삽입 후 rootfs Partition에 module을 넣는다.

 

 

 - target board 실행하여 depmod 실행 후 reboot

TARGET> depmod
TARGET> reboot

아래와 같이 디버그에서 확인할 수 있고 lsmod 명령어를 사용하여 확인할 수 있다.

# debug message
# lsmod 명령 실행

 

3. kernel source에 driver 추가

 - Source download

$ git clone https://github.com/STMicroelectronics/gcnano-binaries
$ cd gcnano-binaries
$ tar -xvf gcnano-driver-6.4.3.tar.xz
$ cp -rfvp gcnano-driver-6.4.3 ../drivers/gpu/gcnano
$ cd ../drivers/gpu/gcnano

새로운 driver를 생성한다.

 

 - Source 수정

$ vi Kbuild
+AQROOT := $(srctree)/drivers/gpu/gcnano
-include $(AQROOT)/config

$ vi ../Makefile
+ obj-y                   += drm/ vga/ gcnano/

 

 - Kernel module build

$ make ARCH=arm modules
$ make ARCH=arm INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH="$PWD/../build_kernel_modules"  modules_install

 

 - output copy

$ cd ../build_kernel_modules/lib/modules/5.10.10/
$	# 필요없는 파일 제거
$ rm -rf build source
$ cd ..
$ sudo cp -rfvp 5.10.10 /media/whatmam/rootfs/lib/modules/

SD 카드를 삽입 후 rootfs Partition에 module을 넣는다.

# debug message
# lsmod 명령 실행

 

[   72.795553] galcore: module verification failed: signature and/or required key missing - tainting kernel
위와 같은 에러가 나오면 kernel defconfig 수정해 준다 ->  CONFIG_MODULE_SIG_ALL=n

'STM32' 카테고리의 다른 글

4. STM32mp157 u-boot 분석  (0) 2021.07.20
3. STM32mp157 eMMC Booting  (1) 2021.07.19
2-2. STM32mp157 Distibution Package - Kernel  (0) 2021.07.13
2-1. STM32mp157 Developer Package - uBoot  (0) 2021.07.13
1. STM32mp157 Yocto build  (0) 2021.07.13

<Spec>

  • Ubuntu : ubuntu-18.04.5-desktop-amd64
  • stm32mpu Major ecosystem releases version : v3.0.0
  • kernel : Linux® kernel v5.10 (LTS)

 

 

-Working path

$ pwd
~/STM/Developer-Package

 

1. Kernel build

 - 압축 풀기 및 패치

$ tar -xvf en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
$ cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.10.10-r0
$ tar -xvf linux-5.10.10.tar.xz
$ cd linux-5.10.10
$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
$ make ARCH=arm multi_v7_defconfig "fragment*.config"
$ for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
$ yes '' | make ARCH=arm oldconfig

 

 - <my>_defconfig, <my>.dts 생성

$ cp -rfvp .config arch/arm/configs/stm32_whatmam_defconfig
$ cp -rfvp arch/arm/boot/dts/stm32mp157f-ev1.dts arch/arm/boot/dts/stm32mp157f-whatmam-ev1.dts
$ vi arch/arm/boot/dts/Makefile 
$	# stm32mp157f-whatmam-ev1.dts추가

 

 

 - Build

$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ make stm32_whatmam_defconfig
$ make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040

 

 - output copy

$ sudo cp -rfvp arch/arm/boot/dts/stm32mp157f-whatmam-ev1.dtb  /media/whatmam/bootfs/
$ sudo cp -rfvp arch/arm/boot/uImage  /media/whatmam/bootfs/

SD 카드를 삽입 후 bootfs Partition에 image를 넣는다.

 

 - extlinux.conf 수정

$ sudo vi /media/whatmam/bootfs/mmc0_extlinux/stm32mp157f-ev1_extlinux.conf
LABEL OpenSTLinux
+FDT /stm32mp157f-whatmam-ev1.dtb

OpenSTLinux 레이블에 FDT를 지정하도록 추가해준다.

 

 - uboot 수동으로 부팅

STM32> setenv bootargs root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
STM32> ext4load mmc 0:4 0xc2000000 uImage
STM32> ext4load mmc 0:4 0xc4000000 stm32mp157f-whatmam-ev1.dtb
STM32> bootm 0xc2000000 - 0xc4000000

extlinux.conf를 수정하거나 uboot로 수동으로 부팅해 주면된다.

 

SD카드를 Target에 삽입하고 부팅시켜주어 디버그 내용을 확인한다.

 

2. kernel modules build

 - 압축 풀기 및 패치

$ make ARCH=arm modules
$ make ARCH=arm INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH="$PWD/../build_kernel_modules"  modules_install

INSTALL_MOD_STRPI=1 

kernel modules Size를 줄이기 위해서 모든 디버깅 기호가 제거되어 약 90%까지 줄일 수 있다.

 

 - output copy

$ cd ../build_kernel_modules/lib/modules/5.10.10/
$ rm -rf build source
$ cd ..
$ sudo cp -rfvp 5.10.10 /media/whatmam/rootfs/lib/modules/

SD 카드를 삽입 후 bootfs Partition에 kerne modules을 넣는다.

 

 

 

부팅을 하면 다음과 같이 GPU Driver가 없다고 나온다. 다음장에서 GPU Driver module을 넣어보자

'STM32' 카테고리의 다른 글

4. STM32mp157 u-boot 분석  (0) 2021.07.20
3. STM32mp157 eMMC Booting  (1) 2021.07.19
2-3. STM32mp157 Distibution Package - galcore  (0) 2021.07.13
2-1. STM32mp157 Developer Package - uBoot  (0) 2021.07.13
1. STM32mp157 Yocto build  (0) 2021.07.13

<Spec>

  • target Board : STM32mp157f-ev1, STM32mp157d-dk1
  • Ubuntu : ubuntu-18.04.5-desktop-amd64
  • stm32mpu Major ecosystem releases version : v3.0.0
  • U-Boot : v2020.10
  • TF-A : v2.4
  • OP-TEE : v3.12.0

 

STM32MP1에서 제공되는 Developer Package를 이용해 개발 환경을 구축할 것이다.

uboot name을 customizing 하여 빌드 및 부팅되는지 확인한다.

 

-Working path

$ pwd 
~/STM/Developer-Package

 

1. Source download

https://wiki.st.com/stm32mpu/wiki/STM32MP1_Developer_Package

├── en.SDK-x86_64-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
├── en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
├── en.SOURCES-optee-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
├── en.SOURCES-tf-a-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
└── en.SOURCES-u-boot-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz

 

2. SDK 설치 

$ tar -xvf en.SDK-x86_64-stm32mp1-openstlinux-20-02-19.tar.xz
$ cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sdk/
$ ./st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-openstlinux-5.10-dunfell-mp1-21-03-31.sh -d ../../SDK

 

3. tf-a(fwconfig, bl32) build

 - 압축 풀기 및 패치

$ tar -xvf en.SOURCES-tf-a-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
$ cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-2.4.r1-r0
$ tar -xvf tf-a-stm32mp-2.4.r1-r0.tar.gz
$ cd tf-a-stm32mp-2.4.r1
$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

 

 - 소스 변경 및 추가

$ vi ../Makefile.sdk
$	# Makefile.sdk에 stm32mp157f-whatmam-ev1 추가
$ cp -rfvp fdts/stm32mp157f-ev1.dts fdts/stm32mp157f-whatmam-ev1.dts
$ cp -rfvp fdts/stm32mp157f-ev1-fw-config.dts fdts/stm32mp157f-whatmam-ev1-fw-config.dts
$	# stm32mp157f-whatmam-ev1 dtb 추가

 

 - Makefile.sdk 사용

$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ export DEPLOYDIR=$PWD/../../FIP_artifacts/arm-trusted-firmware
$ make -f $PWD/../Makefile.sdk clean
$ make -f $PWD/../Makefile.sdk TF_A_DEVICETREE=stm32mp157f-whatmam-ev1 TF_A_CONFIG=trusted ELF_DEBUG_ENABLE='1' stm32

 

 - output files

$ tree -L 2 $DEPLOYDIR
├── bl32
│   ├── debug
│   └── stm32mp157f-whatmam-ev1-bl32.dtb
├── debug
└── fwconfig
    └── stm32mp157f-whatmam-ev1-fw-config-trusted.dtb

 

4. u-boot build

 - 압축풀기 및 패치

$ cd ~/STM/Developer-Package
$ tar -xvf en.SOURCES-u-boot-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
$ cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-2020.10.r1-r0
$ tar -xvf u-boot-stm32mp-2020.10.r1-r0.tar.gz
$ cd u-boot-stm32mp-2020.10.r1
$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

 

 - 소스 변경 및 추가

$ vi ../Makefile.sdk
$ vi arch/arm/dts/Makefile
$	# Makefile.sdk에 stm32mp157f-whatmam-ev1 추가
$ cp -rfvp arch/arm/dts/stm32mp157f-ev1.dts arch/arm/dts/stm32mp157f-whatmam-ev1.dts
$ cp -rfvp arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi arch/arm/dts/stm32mp157f-whatmam-ev1-u-boot.dtsi
$	# *-u-boot.dtsi 없으면 빌드는 되나, 부팅이 안됨.
$	# dtb model명 변경하여 디버그에서 변경 되는지 확인 하도록 수정

 

 - Makefile.sdk 사용

$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ export DEPLOYDIR=$PWD/../../FIP_artifacts/u-boot
$ make -f $PWD/../Makefile.sdk clean
$ make -f $PWD/../Makefile.sdk UBOOT_CONFIGS=stm32mp15_trusted_defconfig,trusted,u-boot.dtb DEVICE_TREE="stm32mp157f-whatmam-ev1" uboot

 

 - output files

$ tree -L 1 $DEPLOYDIR
├── debug
├── u-boot-nodtb-stm32mp15.bin
└── u-boot-stm32mp157f-whatmam-ev1-trusted.dtb

 

아래와 같은 make 실행하여 .config 생성된 상태라면 make mrproper 꼭 해줘야 한다.

 

 - Makefile 사용

$ make stm32mp15_trusted_defconfig
$ make DEVICE_TREE=stm32mp157f-ev1 all

 > Makefile.sdk 사용 시 하지 않아도 된다.

 

5. optee build

 - 압축 풀기 및 패치

$ cd ~/STM/Developer-Package
$ tar -xvf en.SOURCES-optee-stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31.tar.xz
$ cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/optee-os-stm32mp-3.12.0.r1-r0
$ tar -xvf optee-os-stm32mp-3.12.0.r1-r0.tar.gz
$ cd optee-os-stm32mp-3.12.0.r1
$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

 

 - 소스 변경 및 추가

$ vi ../Makefile.sdk
$	# Makefile.sdk에 stm32mp157f-whatmam-ev1 추가
$ cp -rfvp core/arch/arm/dts/stm32mp157f-ev1.dts core/arch/arm/dts/stm32mp157f-whatmam-ev1.dts

 

- Makefile.sdk 사용

$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ export DEPLOYDIR=$PWD/../../FIP_artifacts/optee
$ make -f $PWD/../Makefile.sdk clean
$ make -f $PWD/../Makefile.sdk CFG_EMBED_DTB_SOURCE_FILE=stm32mp157f-whatmam-ev1 optee

 

 - output files

$ tree -L 1 $DEPLOYDIR
├── debug
├── tee-header_v2-stm32mp157f-whatmam-ev1.bin
├── tee-pageable_v2-stm32mp157f-whatmam-ev1.bin
└── tee-pager_v2-stm32mp157f-whatmam-ev1.bin

 

6. fip build

fip는 tf-a, uboot, optee 어디든 빌드가 가능하다.

빌드된 파일들이 모여있는 FIP_artifacts의 폴더를 지정하고 tf-a에 있는 Makefile.sdk을 사용하도록 하겠다.

$ cd ~/STM/Developer-Package/stm32mp1-openstlinux-5.10-dunfell-mp1-21-03-31/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-2.4.r1-r0/tf-a-stm32mp-2.4.r1
$ source ~/STM/Developer-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$ export DEPLOYDIR=$PWD/../../FIP_artifacts/arm-trusted-firmware
$ export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts
$ make -f $PWD/../Makefile.sdk TF_A_DEVICETREE=stm32mp157f-whatmam-ev1 ELF_DEBUG_ENABLE='1' fip

 

 - output files

$ tree -L 1 $FIP_DEPLOYDIR_ROOT/fip
├── fip-stm32mp157f-whatmam-ev1-optee.bin
└── fip-stm32mp157f-whatmam-ev1-trusted.bin
$ tree -L 1 $DEPLOYDIR
├── bl32
├── debug
├── fwconfig
├── tf-a-stm32mp157f-whatmam-ev1-emmc.stm32
├── tf-a-stm32mp157f-whatmam-ev1-nand.stm32
├── tf-a-stm32mp157f-whatmam-ev1-nor.stm32
├── tf-a-stm32mp157f-whatmam-ev1-sdcard.stm32
├── tf-a-stm32mp157f-whatmam-ev1-uart.stm32
└── tf-a-stm32mp157f-whatmam-ev1-usb.stm32

 

7. FIP_artifacts 확인

$ cd $FIP_DEPLOYDIR_ROOT
$ find . -name "debug" -type d | xargs rm -rf
$ tree -L 3
├── arm-trusted-firmware
│   ├── bl32
│   │   ├── stm32mp157f-whatmam-ev1-bl32.dtb
│   │   └── tf-a-bl32-stm32mp15.bin
│   ├── fwconfig
│   │   ├── stm32mp157f-whatmam-ev1-fw-config-optee.dtb
│   │   └── stm32mp157f-whatmam-ev1-fw-config-trusted.dtb
│   ├── tf-a-stm32mp157f-whatmam-ev1-emmc.stm32
│   ├── tf-a-stm32mp157f-whatmam-ev1-nand.stm32
│   ├── tf-a-stm32mp157f-whatmam-ev1-nor.stm32
│   ├── tf-a-stm32mp157f-whatmam-ev1-sdcard.stm32
│   ├── tf-a-stm32mp157f-whatmam-ev1-uart.stm32
│   └── tf-a-stm32mp157f-whatmam-ev1-usb.stm32
├── fip
│   ├── fip-stm32mp157f-whatmam-ev1-optee.bin
│   └── fip-stm32mp157f-whatmam-ev1-trusted.bin
├── optee
│   ├── tee-header_v2-stm32mp157f-whatmam-ev1.bin
│   ├── tee-pageable_v2-stm32mp157f-whatmam-ev1.bin
│   └── tee-pager_v2-stm32mp157f-whatmam-ev1.bin
└── u-boot
    ├── u-boot-nodtb-stm32mp15.bin
    └── u-boot-stm32mp157f-whatmam-ev1-trusted.dtb

 - 빌드 순서 요약 : tf-a, uboot, optee는 독립적으로 빌드 후 최종 fip빌드는 3중 아무곳에서 해도 됩니다.

 

8. Create SD Card

$ cd $FIP_DEPLOYDIR_ROOT/arm-trusted-firmware
$ sudo dd if=tf-a-stm32mp157f-whatmam-ev1-sdcard.stm32 of=/dev/sdb1 conv=fdatasync
$ sudo dd if=tf-a-stm32mp157f-whatmam-ev1-sdcard.stm32 of=/dev/sdb2 conv=fdatasync

$ cd $FIP_DEPLOYDIR_ROOT/fip
$ sudo dd if=/dev/zero of=/dev/sdb3 conv=fdatasync
$ sudo dd if=fip-stm32mp157f-whatmam-ev1-trusted.bin of=/dev/sdb3 conv=fdatasync
$ umount /media/whatmam/*

 sd Card의 Partitions 1,2에 tf-a-stm32mp157f-whatmam-ev1-sdcard.stm32

               Partitions 3에 fip-stm32mp157f-whatmam-ev1-trusted.bin

'STM32' 카테고리의 다른 글

4. STM32mp157 u-boot 분석  (0) 2021.07.20
3. STM32mp157 eMMC Booting  (1) 2021.07.19
2-3. STM32mp157 Distibution Package - galcore  (0) 2021.07.13
2-2. STM32mp157 Distibution Package - Kernel  (0) 2021.07.13
1. STM32mp157 Yocto build  (0) 2021.07.13

<Spec>

  • target Board : STM32mp157f-ev1, STM32mp157d-dk1
  • Ubuntu : ubuntu-18.04.5-desktop-amd64
  • stm32mpu Major ecosystem releases version : v3.0.0
  • yocto version : OpenEmbedded v3.1 (Dunfell)

 

1. Install Pakage

	# Packages required by OpenEmbedded/Yocto
$ sudo apt-get update
$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 pylint xterm
$ sudo apt-get install make xsltproc docbook-utils fop dblatex xmlto
$ sudo apt-get install libmpc-dev libgmp-dev

	# Packages needed for some "Developer Package" use cases
$ sudo apt-get install libncurses5 libncurses5-dev libncursesw5-dev libssl-dev linux-headers-generic u-boot-tools device-tree-compiler bison flex g++ libyaml-dev libmpc-dev libgmp-dev

	# For Ubuntu 20.04
$ sudo apt install python-is-python3

https://wiki.st.com/stm32mpu/wiki/Getting_started/STM32MP1_boards/STM32MP157x-DK2/Develop_on_Arm%C2%AE_Cortex%C2%AE-A7/Install_the_SDK#

 

2. Install The Repo Utility

$ mkdir ~/bin
$ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
$ PATH=${PATH}:~/bin

 > repo init을 하기 위해서 최근 버그가 수정된 repo를 설치해야 한다.

 

3. STM32 yocto Download

$ mkdir -p STM/openstlinux-5.10-dunfell-mp1-21-03-31
$ cd STM/openstlinux-5.10-dunfell-mp1-21-03-31
$ repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.10-dunfell-mp1-21-03-31
$ repo sync

error.GitError: manifests var: 에러

 

$ git config --global user.name "whatmam"
$ git config --global user.email "whatmam@google.com"

 

4. bitbake 실행

$ DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
$ bitbake st-image-weston
$		#qt5 build
$ bitbake st-example-image-qtwayland
$ bitbake st-example-image-qtwayland -c populate_sdk

build 완료

 > 한 번에 에러 없이 잘된다.. 다행이다.

 

Error: The OE SDK/ADT was detected as already being present in this shell

environment. Please use a clean shell when sourcing this environment script.

 

 > 기존에 쓰던 쉘 프롬프트를 새로 열어서 하면 잘된다. 이유는 자세히 모르겠지만 환경변수 충돌 느낌인 듯하다..

 

5. 부팅 Sd 카드 생성

$ cd build-openstlinuxweston-stm32mp1/tmp-glibc/deploy/images/stm32mp1/scripts/
$ ./create_sdcard_from_flashlayout.sh ../flashlayout_st-image-weston/trusted/FlashLayout_sdcard_stm32mp157f-ev1-trusted.tsv
$	# FlashLayout_sdcard_stm32mp157f-ev1-trusted.raw 생성됨.

$ cat /proc/partitions 	#SD card 확인 (mmcblkX OR sdX)
$ sudo umount `lsblk --list | grep sdb | grep part | gawk '{ print $7 }' | tr '\n' ' '`
$	# umount all partitions 
$ sudo dd if=../FlashLayout_sdcard_stm32mp157f-ev1-trusted.raw of=/dev/sdb bs=8M conv=fdatasync status=progress

$	## Partition에 image 직접넣기 예시
$ sudo dd if=/dev/zero of=/dev/sdb3 conv=fdatasync
$ sudo dd if=tf-a-stm32mp157f-ev1-sdcard.stm32 of=/dev/sdb1 conv=fdatasync
$ sudo dd if=tf-a-stm32mp157f-ev1-sdcard.stm32 of=/dev/sdb2 conv=fdatasync
$ sudo dd if=fip-stm32mp157f-ev1-trusted.bin of=/dev/sdb3 conv=fdatasync

 > 빌드가 완료되면 deploy 폴더가 생성된다. uboot, kernel, filesystem 등이 생성된고 부팅 SD card를 만들 수 있는 스크립트를 제공한다. 이를 이용해 만들어서 부팅까지 완료한다.

 

 

<참고>

https://koansoftware.com/yocto-project-meta-layer-for-stm32mp1-by-koan/

https://wiki.st.com/stm32mpu/wiki/How_to_build_and_use_an_SDK_for_QT

https://wiki.st.com/stm32mpu/wiki/How_to_create_your_own_machine

https://wiki.st.com/stm32mpu/wiki/STM32MP1_Distribution_Package#Initializing_the_OpenEmbedded_build_environment

'STM32' 카테고리의 다른 글

4. STM32mp157 u-boot 분석  (0) 2021.07.20
3. STM32mp157 eMMC Booting  (1) 2021.07.19
2-3. STM32mp157 Distibution Package - galcore  (0) 2021.07.13
2-2. STM32mp157 Distibution Package - Kernel  (0) 2021.07.13
2-1. STM32mp157 Developer Package - uBoot  (0) 2021.07.13

■LCD

1.     회로도를 본다.

 

RS는 Instruction mode OR Data mode, E는 Enable 등.. 인걸 알 수 있다.

2.     DataSheet를 본다 - 타이밍

1. R/W : High, E : Low
2. RS : High or Low
3. R/W : High -> Low
 ------- 40nSec이상 delay
4. E : Low -> High
 ------- 150nSec이상 delay
 5. Data Bus
 ------- 80nSec이상 delay
 6. E : High -> Low
 ------- 10nSec이상 delay

데이터시트를 보면 Max가 없기에 Critical하게 꼭 맞춰줄 필요는 없어 보인다.

이러한 최소한의 딜레이가 필요하다. 그렇지 않으면 원하는 값으로 이루어지지 않음. Read mode에서는 RW쪽만 다르다.

 

3.     Instructions 해석

Note : Fiunction Set 5x11 dots는 4BIT일 경우만 사용 가능하다. 현재는 8bit,2-line,5x8로 set

그리고 실제 LCD는 5x7처럼 보이는데 커서가 1을 차지하여 5x8이다.

또한 Instruction후 딜레이 필요.

AND DDRAM은 DB7은 항상 set이여서 시작주소가 0x80이다. 1-Line과 2-Line이 bit수와 주소가 다르다.

#include "avr/io.h"
#include "avr/iom128.h"
#include "util/delay.h"
/*
	RS : Instruction mode VS Data mode?
	(LCD_controller VS LCD_data)
	E : Enable
*/
void LCD_controller(unsigned char control)
{
	_delay_ms(40);
	PORTG = 0x00; // clear.
	_delay_us(0.04); //RW & RS Setup time is 40ns min.
	PORTG |= 0x01; // G set.			Enable
	_delay_us(0.15); //Data Setup time is 80ns min.
	PORTA = control; // Data input.
	_delay_us(0.08); // valid data is 130ns min.
	PORTG = 0x0;// RS set. RW set. G clear.
	_delay_us(0.01);
}

void LCD_data(unsigned char Data)
{
	_delay_ms(1);
	PORTG = 0x04; //RS set. RW clear. G clear.
	_delay_us(0.04); //RW & RS Setup time is 40ns min.
	PORTG = 0x05; // E set.
	_delay_us(0.15); //Data Setup time is 80ns min.
	PORTA = Data; // Data input.
	_delay_us(0.08); // valid data min is 130ns.
	PORTG = 0x0; // RS clear. RW set. G clear.
	_delay_us(0.01);
}

void LCD_string(unsigned char address, unsigned char *ptr)
{
	int i=0;
	LCD_controller(address); // LCD display start position
	while(*ptr)
	{
		if(address+i == 0x90)
		LCD_controller(0xc0); // second line display
		
		LCD_data(*ptr);
		i++;
		ptr++;
	}
}

void LCD_initialize(void)
{

	/* 8bit interface mode */
	LCD_controller(0x38); // Function set. Use 2-line, display on.
	_delay_us(40); // wait for more than 39us.
	LCD_controller(0x0f); // Display ON/OFF Control. display,cursor,blink on
	_delay_us(40); // wait for more than 39us.
	LCD_controller(0x01); // Display Clear.
	_delay_ms(1.53); // wait for more than 1.53ms.
	LCD_controller(0x06); // Entry Mode Set. I/D increment mode, entire shift off
}

int main()
{
	DDRG = 0x07; // Control_bit
	DDRA = 0xff; // Data_bit

	LCD_initialize(); 
	LCD_string(0x80, "Hello World!!!! LCD TEST..12345678987654321"); // Start address is 0x80(0,0)

	
	while(1)
	{
	/*
	LCD_controller(0x1c);//화면 그대로 right
	LCD_controller(0x18);//화면 그대로 left
	_delay_ms(5000);
	*/
	}
	return 0;
}

'kernel Driver' 카테고리의 다른 글

[Atmega128]PWM(Buzzer)  (0) 2019.04.30
GPIO를 이용한 I2C구현  (0) 2019.04.24

■PWM

 Timer기능 안에 PWM mode가 있다. 주로 쓰는 것이 Fast Pwm mode.

PWM(Pulse Width Modulation) 신호는 디지털 소스를 사용하여 아날로그 신호를 생성하는 방법입니다. PWM 신호는 듀티 사이클과 주파수라는 가지 주요 구성 요소로 구성됩니다.

 듀티 사이클은 신호가 하이(또는 켜짐) 상태에 있는 시간을 1 사이클을 완료하는 걸리는 시간의 백분율로 나타냅니다.

 

, Buzzer에서 PWM 높은 것은 음향이 높은 , 듀티 사이클이 짧을수록 높은 음이 나옵니다.

PWM 신호는 다양한 제어 어플리케이션에 사용됩니다. 용도는 DC 모터 제어이지만 밸브, 펌프, 유압 장치 기타 기계 부품을 제어하는 ​​곳에도 사용할 있습니다.

 

 

TCCR0 prescale TCNT0,OCR0 값으로 클럭이 조정된다

TCNT0 주파수(Frequency) 조절할 있다.

OCR0 듀티 사이클 조절할 있다.

 

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>


volatile int state, tone;
char f_table[8] = {17, 43, 66, 77, 97, 114, 117, 137};


ISR(TIMER0_OVF_vect)                               
{
	 PORTB ^= 1 << 4;

     TCNT0 = f_table[tone];
}

int main()
{
	DDRD = (0x00 << 7);
             int i=0;
             DDRB = 0x10;                    
             TCCR0 = 0x03;                  
             TIMSK = 0x01;                 
        
             sei();                               
             while(1) {
				  if (!(PIND & ( 1<<PIND7 )) )//버튼이 눌러졌다면
				  {
					   tone = f_table[rand()%8]; 
					   OCR0 = rand()%255;          
				  }
                         
             };                  
}

'kernel Driver' 카테고리의 다른 글

[Atmega128]Character LCD  (0) 2019.04.30
GPIO를 이용한 I2C구현  (0) 2019.04.24

TODO : GPIO 이용하여 RTC 디바이스를 사용하기 위해 RTC I2C통신을 한다.(, 실제 I2C통신을 사용할 주어진 함수를 이용한다.)

 

*SDA: data, SCL : 디바이스 신호 동기화에 사용되는 클럭.

*SCL high data 읽고 Low SDA 바뀐다. 이런식으로 통신

(i2c 데이터 통신 중에는 클럭이 high 시그널일 때에는 데이터(SDA) 시그널이 변경되면 안된다. 이러한 규칙으로 인해 클럭이 high 상태에서는 데이터를 안정적으로 읽는 것을 보장한다.)

 

*Master cpu, slave 디바이스들

 

*Ack 응답 Ack : 0, 무응답 Ack :1(? – Need to check)

 

1. 회로도 분석

 

 

2. Data Sheet 보고 set configuration

 

DDKIomuxSetPinMux DDKGpioSetConfig 등등

3.RTC chip DataSheet 분석

 

=> Slave address를 알 수 있다.

=> data를 보낼 때 여러개의 data를 연달아 보낼 수 있다. 단 1 < 1s 조건 ->1s이상 해본 결과 처음Write 할때 만 이상하게 들어가고 다시 Write하면 제대로잘 들어감

=> R/W mode 방식

=>  data 보낼 여러개의 data 연달아 보낼 있다. 1 < 1s 조건

=>  Lasty data byte 지금은 쓰지 않았지만 레지스터에 여러 데이터를 넣는 경우도 있는 같다.

그리고 Read mode에서 set register read data 사이에 Start, Stop 존재 해야하며 10초정도의

시간이 지나도 읽을 있더라.(자세히 모르겟다)

 

 

 

 

 **주요 이슈

1. DataPin Read 없었음

-> DDK_GPIO_DIR_IN 설정하지 않았음, R/W 마다 신경 써야한다

2. Data Read하는 부분 여러 Read하는데 방법을 잘모르겠으며 처음 한번만 잘나오고 뒤에는 쓰래기값이 나온다.

 - 문제점 1 : 

      int bin[8]={0,};

           =>bin 배열이 clear 되지 않아서 전에 쓰던 값이 들어가는 문제, 전역변수에서 지역변수로 바꿔줌

 - 문제점 2 : Write와 Read의 Data를 읽을 때 Regiter의 주소는 시작하는 주소 하나만 넣어서 8bit씩 읽으면 순차적으로 읽거나 쓸 수 있다.

 

#define myd_speed (10)



void Start()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, 0);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

        Sleep(myd_speed);

        //Start 신호-> SCL이High 상태일때, SDA이Low로변하면Start

}

void Stop()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, 1);

        Sleep(myd_speed);

        //Stop 신호-> SCL이High 상태일때, SDA이High로변하면Stop

}

void SCL_Clock()

{

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

        Sleep(myd_speed);

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

        Sleep(myd_speed);

}





//SDA 8bit Data

void Clock_data(int data)

{

    int bin[8]={0,};    //주소를역순으로보내기위한배열



    int position = 7;

    while(data != 0){//bin 배열Clear후저장

        bin[position] = data %2;

        data /= 2;

        position--;

    }

            

    for(int i=0;i<8;i++){

        DDKGpioWriteDataPin(DDK_GPIO_PORT4, 13, bin[i]);

        SCL_Clock();

    }

}



void Read_data(int reg_addr)

{

        UINT32 pinVal;

        RETAILMSG(1, (L"[ I2C Read !!! ] "));

        Start();



        Clock_data(0xD0);//1101000 (Slave address + Write bit)(7bit + 1bit)

        SCL_Clock();//Ack



        Clock_data(reg_addr);//input data(data address)

        SCL_Clock();//Ack



        Stop();





        for(int i=0;i<3;i++){//03h ~ 05h만읽는다.

            Start();



            Clock_data(0xD1);//1101001 (Slave address + Read bit)

            SCL_Clock();//Ack





            /*            print            */

            RETAILMSG(1, (L"Read Data : ["));

            for(int i=0;i<8;i++){

                DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 1);

                Sleep(myd_speed);

                DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_IN, DDK_GPIO_INTR_NONE);

                //Set DDK_GPIO_DIR_IN For Read mode enable



                DDKGpioReadDataPin(DDK_GPIO_PORT4, 13, &pinVal);

                RETAILMSG(1, (L"%d",pinVal));



                DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

                DDKGpioWriteDataPin(DDK_GPIO_PORT4, 12, 0);

                Sleep(myd_speed);

            }

            RETAILMSG(1, (L"]"));

            SCL_Clock();//Ack



            Stop();

        }

}



BOOL MYD_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, 

                   DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,

                   PDWORD pdwActualOut)

{

    BOOL bRet = FALSE;



    switch(dwCode){

        case 1:

            /*                Init            */

            DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_PIN_MUXMODE_ALT5, DDK_IOMUX_PIN_SION_REGULAR);

            //datasheet -> IOMUXC_SW_MUX_CTL_PAD_KEY_COL3 의gpio4_12(SCL)( ALT5) 설정(enable)

            DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_PIN_MUXMODE_ALT5, DDK_IOMUX_PIN_SION_REGULAR);

            //datasheet -> IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3 의gpio4_13(SDA)( ALT5) 설정(enable)



            DDKGpioSetConfig(DDK_GPIO_PORT4, 12, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

            DDKGpioSetConfig(DDK_GPIO_PORT4, 13, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);

            //12, 13 bit Write mode enable

            



            RETAILMSG(1, (L"[ I2C Write !!! ] "));//Slave address : 1101000(RTC -> Chip : PCF8523TS/1 ) , Read : 1 Write : 0

            Start();

            

            Clock_data(0xD0);//1101000 (Slave address + Write bit)(7bit + 1bit)

            SCL_Clock();//Ack



            /*

            03h : Seconds(data address)

            04h : Minutes(data address)

            05h : Hours(data address)

            */

            Clock_data(0x03);

            SCL_Clock();//Ack





            Clock_data(0x00);//0초[7]:clock integrity is guaranteed, [6-0] 

            SCL_Clock();//Ack

            Clock_data(0x10);//10분[7]: unused, [6-4]: ten's place, [3-0]: unit place

            SCL_Clock();//Ack

            Clock_data(0x13);//13시[7-6]: unused, 12mode [5] : 0-AM,1-PM, [4]: ten's place,[3-0]: unit place

            SCL_Clock();//Ack                       24mode [5-4]: ten's place,[3-0]: unit place



            Stop();

            

            break;

        case 2:

            Read_data(0x03);



            break;

        case 3:



            break;



    }

      return bRet;

}

'kernel Driver' 카테고리의 다른 글

[Atmega128]Character LCD  (0) 2019.04.30
[Atmega128]PWM(Buzzer)  (0) 2019.04.30

+ Recent posts