Embedded Linux A-Z

Embedded Linux A-Z

    • About
    • Beaglebone Black
    • STM32MP157
  • Facebook
  • GitHub
  • LinkedIn

[Yocto-BBB] 9. Sử dụng devtool, tạo patch và cách cài file IPK

Ở bài 5 về thêm driver cho USB wifi mình đã từng hướng dẫn các bạn cách tạo recipes thủ công để lấy code từ git về build. ở bài 8 vừa rồi, mình cũng có để code main.c xử lý i2c trên git, tuy nhiên khi copy về board ta sẽ phải sửa lại I2C_DEV và I2C_ADDR cho đúng.

(Nếu các bạn gặp khó khăn trong quá trình thực hành theo blog, các bạn có thể tham khảo video thực hành của mình ở cuối bài )

Ở bài này mình sẽ hướng dẫn các bạn tương tác với source code git đã có sẵn recipes và cả tạo mới recipes sử dụng các command như devtool modify, devtool add, devtool finish. Sau đó mình sẽ hướng dẫn thêm về tạo patch

  1. 1. Sử dụng devtool
    1. 1.1 Devtool tạo recipes mới
    2. 1.2 Devtool sửa lại sửa code từ git
      1. 1.2.1 Bitbake thông thường
      2. 1.2.2 Devtool modify
  2. 2. Tạo patch
    1. 2.1 Tạo môi trường sạch :v
    2. 2.2 Thay đổi và tạo patch
      1. 2.3 Sửa recipes để build có apply patch
  3. 3. Sử dụng file IPK
    1. 3.1 Add thêm package opkg
    2. 3.2 Copy và cài đặt ipk vào board

1. Sử dụng devtool

1.1 Devtool tạo recipes mới

Giờ ta có code trên git là https://github.com/Zk47T/ssd1306 ta muốn tạo recipes lấy code này về.

Ta sẽ sử dụng command của devtool (mình hay nhớ là developement tool).

devtool add ssd1306 https://github.com/Zk47T/ssd1306.git --srcbranch main

Việc này sẽ tạo recipes ssd1306, source từ git, với branch main trong workspace tại thư mục build-bbb

zk47@ltu:~/Learning/yocto-bbb/build-bbb/workspace$ tree 
.
├── appends
│   └── ssd1306_git.bbappend
├── conf
│   └── layer.conf
├── README
├── recipes
│   └── ssd1306
│       └── ssd1306_git.bb
└── sources
    └── ssd1306
        ├── README.md
        └── src
            └── main.c

7 directories, 6 files

Mình sẽ đi vào từng file này có ý nghĩa như nào ở mục devtool modify sau bởi ý nghĩa của folder workspace này là giống nhau.

Và rồi tạm thời mình sẽ không thay đổi gì. Finish luôn

devtool finish ssd1306 ../meta-bbb/recipes-display/ssd1306 

Việc này sẽ copy ssd1306 recipes tới folder mục tiêu kia

├── recipes-display
│   └── ssd1306
│       └── ssd1306_git.bb

Vậy là đã xong bước add 1 recipes mới lấy source từ git.

1.2 Devtool sửa lại sửa code từ git

1.2.1 Bitbake thông thường

Bây giờ mình đã có recipes rồi cho cả SSD1306 và USB Wifi Driver

Nếu bình thường bạn bitbake luôn thì bitbake thông thường sẽ chạy 1 số task chính lần lượt như sau

  • do_fetch : fetch code từ git về
  • do_unpack : giải nén source code ra thư mục tại biến $S
  • do_patch : áp dụng các bản vá (.patch) từ recipe hoặc layer
  • do_compile : biên dịch source
  • do_install : cài đặt file output vào thư mục giả lập rootfs
  • do_package : đóng gói các file đã cài đặt thành các gói .ipk, .deb, hoặc .rpm tuỳ distro

Và rồi output sẽ ở đây

/build-bbb/tmp/work/armv7at2hf-neon-poky-linux-gnueabi/ssd1306/1.0+gitAUTOINC+b1397ef7ec-r0/git

Nếu các bạn muốn thấy rõ hơn lần lượt từng task làm gì thì có thể chạy như sau để theo dõi sự thay đổi

bitbake -c <task> <recipes>
bitbake -c fetch ssd1306

Tuy nhiên thì không nên thay đổi code từ git trong tmp, bởi tmp mà temporary thôi. Muốn nhanh ta sẽ vẫn dùng tạm dừng ở do_patch rồi sửa rồi do_package cũng ok nhưng không ai làm thế cả :v

1.2.2 Devtool modify

Cách hiệu quả để build package có sự thay đổi trong source code mà code lại nằm trên git đó là ta dùng devtool modify

devtool modify ssd1306

Sau đó ta sẽ làm việc trong build-bbb/workspace, thay đổi tùy ý, rồi bitbake để build.

Nhưng các bạn có thắc mắc là tại sao với lần này thì khi build bitbake không lấy source từ git mà lại lấy source từ workspace không ?

Ta đi vào từng file trong thư mục workspace

zk47@ltu:~/Learning/yocto-bbb/build-bbb/workspace$ tree 
.
├── appends
│   └── ssd1306_git.bbappend
├── conf
│   └── layer.conf
├── README
├── recipes
│   └── ssd1306
│       └── ssd1306_git.bb
└── sources
    └── ssd1306
        ├── README.md
        └── src
            └── main.c

7 directories, 6 files
appends/ssd1306_git.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
FILESPATH:prepend := "/home/zk47/Learning/yocto-bbb/build-bbb/workspace/sources/ssd1306/oe-local-files:"
# srctreebase: /home/zk47/Learning/yocto-bbb/build-bbb/workspace/sources/ssd1306

inherit externalsrc
# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND
EXTERNALSRC:pn-ssd1306 = "/home/zk47/Learning/yocto-bbb/build-bbb/workspace/sources/ssd1306"
EXTERNALSRC_BUILD:pn-ssd1306 = "/home/zk47/Learning/yocto-bbb/build-bbb/workspace/sources/ssd1306"

# initial_rev: b1397ef7ec704d8631b73b2c0521f9c804954d3a

Cái lưu ý nhất ở đây là ta thấy set 2 macro

EXTERNALSRC và EXTERNALSRC_BUILD : mang ý nghĩa là giờ build thì sẽ lấy từ external source chứ không phải từ git nữa.

Devtool sẽ lần lượt do_fetch, do_unpack, do_patch, do_configure tại thư mục workspace này, code từ git giờ đã ở workspace.

Branch main sẽ trở thành branch devtool sau khi đã apply patch đầy đủ.

zk47@ltu:~/Learning/yocto-bbb/build-bbb/workspace/sources/ssd1306$ git branch
* devtool
  main
conf/layer.conf
# ### workspace layer auto-generated by devtool ###
BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes/*/*.bb \
            ${LAYERDIR}/appends/*.bbappend"
BBFILE_COLLECTIONS += "workspacelayer"
BBFILE_PATTERN_workspacelayer = "^${LAYERDIR}/"
BBFILE_PATTERN_IGNORE_EMPTY_workspacelayer = "1"
BBFILE_PRIORITY_workspacelayer = "99"
LAYERSERIES_COMPAT_workspacelayer = "${LAYERSERIES_COMPAT_core}"

Lưu ý nhất ở đây là dòng

BBFILE_PRIORITY_workspacelayer = "99"

Việc này có nghĩa là workspace là layer có priority cao nhất, có khả năng ghi đè toàn bộ các layer thấp hơn.

zk47@ltu:~/Learning/yocto-bbb/build-bbb$ bitbake-layers show-layers 
NOTE: Starting bitbake server...
WARNING: Layer meta-bbb should set LAYERSERIES_COMPAT_meta-bbb in its conf/layer.conf file to list the core layer names it is compatible with.
layer                 path                                      priority
==========================================================================
meta                  /home/zk47/Learning/yocto-bbb/poky/meta   5
meta-poky             /home/zk47/Learning/yocto-bbb/poky/meta-poky  5
meta-yocto-bsp        /home/zk47/Learning/yocto-bbb/poky/meta-yocto-bsp  5
meta-oe               /home/zk47/Learning/yocto-bbb/meta-openembedded/meta-oe  5
meta-arm-toolchain    /home/zk47/Learning/yocto-bbb/meta-arm/meta-arm-toolchain  5
meta-arm              /home/zk47/Learning/yocto-bbb/meta-arm/meta-arm  5
meta-ti-bsp           /home/zk47/Learning/yocto-bbb/meta-ti/meta-ti-bsp  6
meta-ti-extras        /home/zk47/Learning/yocto-bbb/meta-ti/meta-ti-extras  6
meta-bbb              /home/zk47/Learning/yocto-bbb/meta-bbb    15
workspace             /home/zk47/Learning/yocto-bbb/build-bbb/workspace  99

—> Vậy khi chạy devtool modify ta sẽ thấy các tác dụng chính sau:

  • Kéo code từ git về local, đưa nó vào workspace
  • Tạo workspace layer với priority cao nhất, add vào build-bbb/bbblayers.conf
  • Set source giờ là EXTERNALSRC không còn dính dáng gì đến git nữa

Vậy là nếu các bạn đã sử dụng devtool thì các thay đổi trong layer hay git liên quan đến code không còn ý nghĩa nữa bởi ta đã cho nó thành local rồi :vv

2. Tạo patch

Việc tạo patch này sẽ có ích chính khi bạn tương tác với 1 recipes code lấy từ git mà git đó bạn không có quyền commit, hoặc đơn giản là đang chờ merge.

2.1 Tạo môi trường sạch :v

Thông thường khi tạo patch thì mình không hay dùng trong workspace nữa, nên mình sẽ xóa ssd1306 trong workspace đi.

Mình sẽ xóa các folder và file sau

/build-bbb/workspace/sources/ssd1306
/build-bbb/workspace/appends/ssd1306_git.bbappend

Mình không biết cách này chính quy không nhưng mình thường làm thế nếu muốn tương tác với code trên git thay vì trên local.

Hoặc các bạn xóa thư mục workspace rồi xóa workspace layer trong /build-bbb/conf/bblayers.conf

Rồi mình sẽ clean và build lại để có folder git trong build-bbb

bitbake -c cleanall ssd1306
bitbake ssd1306

2.2 Thay đổi và tạo patch

Mở git folder và check branch

zk47@ltu:~/Learning/yocto-bbb/build-bbb/tmp/work/armv7at2hf-neon-poky-linux-gnueabi/ssd1306/1.0+gitAUTOINC+b1397ef7ec-r0/git$ git branch
* main

Thay đổi code main.c, Như ở bài trước thì mình có lưu ý việc I2C_ADDR và I2C_DEV có thể khác nhau và đúng vậy. Code gốc mình chạy cho STM32MP157 nên với Beaglebone Black khác nhau duy nhất 1 cái nhỏ là BBB dùng i2c-2

zk47@ltu:~/Learning/yocto-bbb/build-bbb/tmp/work/armv7at2hf-neon-poky-linux-gnueabi/ssd1306/1.0+gitAUTOINC+b1397ef7ec-r0/git$ git diff src/main.c
diff --git a/src/main.c b/src/main.c
index 5e1136d..628dc29 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #define I2C_ADDR 0x3C
-#define I2C_DEV "/dev/i2c-1"
+#define I2C_DEV "/dev/i2c-2"
 
 int i2c_fd;

Sau khi sửa code, các bạn commit và tạo patch

git add src/main.c
git commit -m "ssd1306-bbb"
git format-patch HEAD~1

Thế là nó sẽ tạo ra patch với name lấy từ commit message, patch lấy từ HEAD-1 –> HEAD : 0001-ssd1306-bbb.patch

zk47@ltu:~/Learning/yocto-bbb/build-bbb/tmp/work/armv7at2hf-neon-poky-linux-gnueabi/ssd1306$ tree
.
└── 1.0+gitAUTOINC+b1397ef7ec-r0
    ├── git
    │   ├── 0001-ssd1306-bbb.patch
    │   ├── README.md
    │   └── src
    │       └── main.c

2.3 Sửa recipes để build có apply patch

Copy 0001-ssd1306-bbb.patch tới meta-bbb/recipes-display/ssd1306/ssd1306

meta-bbb/recipes-display/ssd1306$ tree
.
├── ssd1306
│   └── 0001-ssd1306-bbb.patch
└── ssd1306_git.bb

Ta sửa nội dung file ssd1306_git.bb như sau rồi build thôi

LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"

SRC_URI = "git://github.com/Zk47T/ssd1306.git;protocol=https;branch=main \
           file://0001-ssd1306-bbb.patch"

PV = "1.0+git${SRCPV}"
SRCREV = "b1397ef7ec704d8631b73b2c0521f9c804954d3a"

S = "${WORKDIR}/git"

do_compile() {
    ${CC} ${LDFLAGS} ${S}/src/main.c -o ssd1306
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 ssd1306 ${D}${bindir}/ssd1306
}

do_compile và do_install thì không khác gì việc bạn làm các hành vi sau trên board cả

gcc main.c -o ssd1306
cp ssd1306 /usr/bin
chmod 0755 /usr/bin/ssd1306 

Đây là output

  • patches 0001 đã được copy vào git directory
  • main.c đã được apply patch
  • thư mục image đã xuất hiện /usr/bin/ssd1306

3. Sử dụng file IPK

Với các bài trước để có thể add package này vào image, thì bạn chỉ việc thêm ssd1306 vào IMAGE_INSTALL:append. Tuy nhiên giả dụ mình build xong muốn test trên 1 board đã được flash rồi thì sao ?

Đó là lúc ta sử dụng file IPK. Các bạn dùng android từng nghe thấy file apk thì cái này cũng tương tự

3.1 Add thêm package opkg

Để cài được IPK ta cần add thêm package opkg vào board.

Nếu các bạn dùng ubuntu thì cũng quen với việc sử dụng dpkg để cài file .deb vậy. Ở đây tương tự thế. IPK là internet package, còn opkg là package manager

Build lại image rồi flash vào board

3.2 Copy và cài đặt ipk vào board

Ta thấy bức ảnh ở trên có deploy-ipks, các bạn copy cái ipk đầu tiên vào board. ssd1306_1.0+git0+b1397ef7ec-r0_armv7at2hf-neon.ipk Tiện nhất thì sẽ dùng scp

Mình vẫn chưa để mặc định nên mỗi lần khởi động lên đều phải kết nối mạng lại

ip link set wlan0 up
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
dhcpcd wlan0

Rồi scp để copy file đến board

zk47@ltu:~$ scp ssd1306_1.0+git0+b1397ef7ec-r0_armv7at2hf-neon.ipk root@172.20.10.3:~/
root@172.20.10.3's password: 
ssd1306_1.0+git0+b1397ef7ec-r0_armv7at2hf-neo 100% 2946   423.5KB/s   00:00

Giờ thì cài IPK thôi

mount -o rw,remount /
opkg install --force-reinstall --force-depends ssd1306_1.0+git0+b1397ef7ec-r0_armv7at2hf-neon.ipk
  • Thông thường trên board sẽ để read-only nên mình ở đây mount lại với quyền read-write
  • –force-reinstall : nếu trên board từng có package này rồi thì mình phải force reinstall thì nó mới cài lại
  • –force-depends: bỏ qua việc depends, ban đầu mình gặp lỗi mismatch glib version, nhưng code mình có gì đâu nên chênh lib không quan trọng :vv

Giờ bạn check trong /usr/bin là sẽ có ssd1306, và ta hoàn toàn có thể chạy trực tiếp từ bắt kỳ đâu

root@beaglebone:~# ls -l /usr/bin/ssd1306 
-rwxr-xr-x 1 root root 5916 Jul 17  2025 /usr/bin/ssd1306
root@beaglebone:~# ssd1306
root@beaglebone:~# 

Bài này mình viết khá dài vì mình muốn cái thực hành này xuyên suốt. Nếu có sai sót gì mong được các bạn đọc đóng góp.

Ở bài tiếp theo mình sẽ thêm support cho Boot từ eMMC

Chia sẻ:

  • Nhấp để chia sẻ trên X (Mở trong cửa sổ mới) X
  • Nhấn vào chia sẻ trên Facebook (Mở trong cửa sổ mới) Facebook
Thích Đang tải…
Trước đó
Kế tiếp

Bình luận về bài viết này Hủy trả lời

  • Facebook
  • GitHub
  • LinkedIn
 

Đang tải Bình luận...
 

    • Bình luận
    • Đăng lại
    • Theo dõi Đã theo dõi
      • Embedded Linux A-Z
      • Đã có tài khoản WordPress.com? Đăng nhập.
      • Embedded Linux A-Z
      • Theo dõi Đã theo dõi
      • Đăng ký
      • Đăng nhập
      • URL rút gọn
      • Báo cáo nội dung
      • Xem toàn bộ bài viết
      • Quản lý theo dõi
      • Ẩn menu
    %d