2020年12月28日月曜日

DE10-Nano編: Linux Desktop "Xfce" 環境構築 ー Terasic社提供 Reference Design を使って、Yocto (Linux Root File System Build) とLinux Kernel Build


(2021年1月1日時点の情報であることにご注意ください)

本ページで紹介する内容:


DE10-nano ボード(Intel FPGA Cyclone 5 SoC)を使用して、下記を実現したい時の手順

  1. Desktop環境 (Xfce) を有効にした Linux を Build したい
  2. ボード上の HDMI出力ポートから、モニターに出力したい
  3. とにかく無料でやりたい。個人使用なので、Copyright, GPL については気にしない。



手順概要:

  1. FPGAデザインを、terasic社 Web-site からダウンロード
  2. Intel社 Web-site からQuartus ツール(Version 20.1)をダウンロード & インストール
  3. https://github.com/altera-opensource/linux-socfpga (tag: socfpga-4.14.130-ltsi) から、"driver/video/fbdev/altvipfb.c" をダウンロード(tagに注意!)
  4. 以下の Rocketboards.org の手順に従い、Build を進めるが、いくつかのステップを変更 & いくつかのファイルを変更しながら作業を進める
    https://rocketboards.org/foswiki/Documentation/CycloneVSoCGSRD#Rebuilding_the_GSRD_Binaries

用意するもの:

  • Terasic社 DE10-nano ボード(付属のUSBケーブルと電源ケーブル)
  • Ubuntu 18.04 ホスト・パソコン
  • SD card (16GB)
  • HDMIモニター、HDMIケーブル

FPGAデザインを、terasic社 Web-site からダウンロード

  • DE-10 nano のページ中の "Resource" のページから、ボードの Revision A/B/C に対応した CDROM イメージをダウンロード
    http://de10-nano.terasic.com/







  • Rev. C の場合のダウンロードファイル名:
    ”DE10-Nano_v.1.3.8_HWrevC_SystemCD.zip”
  • 解凍して、以下のフォルダーを、作業 Directory (今回は、$HOME)にコピーする
    「Demonstrations/SoC_FPGA/DE10_NANO_SoC_FB」


Intel社 Web-site からQuartus ツール(Version 20.1)の「Linux版」をダウンロード & インストール

  • Quartus Prime ライト・エディッション Version 20.1 をダウンロード
    https://fpgasoftware.intel.com/20.1/?edition=lite
    • 個別ダウンロードをお勧めします。
  • ダウンロードした "*.run" ファイルを実行して、Home Directory ($HOME)にインストール(chmod +x *.run; ./*.run)

  • Ubuntu 18.04 ホスト・マシンの ~/.bashrc に以下の環境変数を設定しておく
    • export QUARTUS_ROOTDIR=~/intelFPGA_lite/20.1/quartus
    • export SOCEDS_DEST_ROOT=~/intelFPGA/20.1/embedded
    • export PATH=${PATH}:\
      ${QUARTUS_ROOTDIR}/bin:\
      ${QUARTUS_ROOTDIR}/soc_builder/bin


https://github.com/altera-opensource/linux-socfpga (tag: socfpga-4.14.130-ltsi) から、"driver/video/fbdev/altvipfb.c" をダウンロード(tagに注意!)


  • 生憎、linux-socfpga 5.* Version から "driver/video/fbdev/altvipfb.c" が削除されている。
  • しかし、Terasic社提供のハードウエア・デザインをそのまま使用する場合には、前述のドライバー(altvipfb.c)を使うのが手っ取り早い。
  • 一方、linux-socfpga 5.* 内で「altvipfb.c」を動作させるには、一部修正が必要(後述)



Build !

準備作業終了。ここから、Build 関連作業を進めていく。

基本的には、Rocketboards.org に記載されている公式の方法(下記URL)に沿って作業を進める。もちろん、以下のページは DE10-Nano向けの記載ではないので、一部手順は異なる。


Build Tool Chain のインストールと環境設定

  • この作業は、Rocketboards.org の記載そのまま。ここでは、$HOME (~/)にインストールしている。
    • cd ~/.
      wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-eabi/gcc-linaro-7.5.0-2019.12-x86_64_arm-eabi.tar.xz
      tar xf gcc-linaro-7.5.0-2019.12-x86_64_arm-eabi.tar.xz
      export PATH=~/gcc-linaro-7.5.0-2019.12-x86_64_arm-eabi/bin:$PATH
      export ARCH=arm
      export CROSS_COMPILE=arm-eabi-

U-Bootの Build

  • 先ほど terasic社のページからダウンロードした「DE10_NANO_SoC_FB」を使用する。以下は、DE10_NANO_SoC_FBを $HOMEにコピーした場合の例。
  • 以下に手順を記載するが、Rocketboards.org の手順との違いは、デザイン名(Directory)と、u-boot-socfpga の tag 名(2021年1月1日時点)
    • ~/intelFPGA/20.1/embedded/embedded_command_shell.sh
    • cd ~/DE10_NANO_SoC_FB/
      
      # Convert handoff data to device tree format 
      mkdir -p software/bootloader
      bsp-create-settings \
        --type spl \
        --bsp-dir software/bootloader \
        --preloader-settings-dir "hps_isw_handoff/soc_system_hps_0" \
        --settings software/bootloader/settings.bsp
      
      # Get the U-Boot source code 
      cd software/bootloader
      git clone https://github.com/altera-opensource/u-boot-socfpga
      cd u-boot-socfpga
      git checkout -b test socfpga_v2020.07
      
      # Generate handoff header files 
      ./arch/arm/mach-socfpga/qts-filter.sh cyclone5 ../../../ ../ ./board/altera/cyclone5-socdk/qts/
      
      # Configure and build U-Boot 
      make socfpga_cyclone5_defconfig
      make -j 24
    • cd ~/DE10_NANO_SoC_FB/../.
      wget https://releases.rocketboards.org/release/2020.07/gsrd/cv_gsrd/u-boot.txt
      ./DE10_NANO_SoC_FB/software/bootloader/u-boot-socfpga/tools/mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Cyclone V script" -d u-boot.txt u-boot.scr


Linux Kernel の Build

  • Rockerboards.org の手順に従って、ファイルをダウンロードする。
  • tag は、「socfpga-5.4.74-lts」に設定している (2021年1月1日時点)
    • # Get Linux source code
      cd ~/.
      git clone https://github.com/altera-opensource/linux-socfpga
      cd linux-socfpga
      git checkout -b test socfpga-5.4.74-lts

  • Device Tree ファイルを追加する。
    • cd ~/linux-socfpga/arch/arm/boot/dts/
      cp socfpga_cyclone5_de0_nano_soc.dts  socfpga_cyclone5_de0_nano_soc_FB.dts

  • 追加した Device Tree ファイル「socfpga_cyclone_de0_nano_soc_FB.dts」の最後に以下を追加する。
    • &base_fpga_region {
              ranges =  <0x00000000 0xff200000 0x00200000>;
      
              alt_vip_vfr_hdmi: vip@0x100031000 {
              compatible = "ALTR,vip-frame-reader-14.0", "ALTR,vip-frame-reader-9.1";
              reg = <0x00031000 0x00000080>;
              max-width = <1024>;
              max-height = <768>;
              bits-per-color = <8>;
              colors-per-beat = <4>;
              beats-per-pixel = <1>;
              mem-word-width = <128>;
          };
      };

  • 「socfpga_cyclone_de0_nano_soc_FB.dtb」を Makefile に追加する。line 952 付近に追加した例を記載する。
    • ~/linux-socfpga/arch/arm/boot/dts/Makefile
    • dtb-$(CONFIG_ARCH_SOCFPGA) += \
      socfpga_arria5_socdk.dtb \
      socfpga_arria10_socdk_nand.dtb \
      socfpga_arria10_socdk_qspi.dtb \
      socfpga_arria10_socdk_sdmmc.dtb \
      socfpga_cyclone5_chameleon96.dtb \
      socfpga_cyclone5_mcvevk.dtb \
      socfpga_cyclone5_socdk.dtb \
      socfpga_cyclone5_de0_nano_soc.dtb \ socfpga_cyclone5_de0_nano_soc_FB.dtb \
      socfpga_cyclone5_sockit.dtb \

  • 次に、先ほどダウンロードした「altvipfb.c」を以下の Directoryにコピーする。
    • ~/linux-socfpga/drivers/video/fbdev/.
  • altvipfb.c」を編集
    • line 220 の "dma_alloc_coherent()" の第一引数を NULL から &pdev->dev に変更
      • <  fbmem_virt = dma_alloc_coherent(NULL,
        ---
        >  fbmem_virt = dma_alloc_coherent(&pdev->dev,
    • line 177 に以下を追加
      • info->var.pixclock = 6734;
        info->var.left_margin = 148;
        info->var.right_margin = 88;
        info->var.upper_margin = 36;
        info->var.lower_margin = 4;
        info->var.hsync_len = 44;
        info->var.vsync_len = 5;

  • 「altvipfb.c」が Build されるように、Makefileを編集
    • ~/linux-socfpga/drivers/video/fbdev/Makefile
    • line 14 付近に下記を追加
    • obj-$(CONFIG_FB_ALTERA_VIP_FB) += altvipfb.o
      altvipfb_drv-objs := altvipfb.o

  • 「altvipfb.c」が有効になるように、「~/linux-socfpga/drivers/video/fbdev/Kconfig」「~/linux-socfpga/arch/arm/configs/socfpga_defconfig」ファイルも変更
    • ~/linux-socfpga/drivers/video/fbdev/Kconfig (line 222付近) に以下を追加
    • config FB_ALTERA_VIP_FB
      tristate "Altera VIP Frame Buffer framebuffer support"
      depends on FB
      select FB_CFB_FILLRECT
      select FB_CFB_COPYAREA
      select FB_CFB_IMAGEBLIT
      ---help---
      This driver supports the Altera Video and Image Processing(VIP)
      Frame Buffer. This core driver only supports Arria 10 HW and newer
      families of FPGA


    • ~/linux-socfpga/arch/arm/configs/socfpga_defconfig (line 121付近)に以下を追加
    • CONFIG_FB_ALTERA_VIP_FB=y

  • 次に、Kernel , Device Tree の Build を行う
    • cd ~/linux-socfpga/
      make socfpga_defconfig make -j 24 zImage dtbs modules make modules_install INSTALL_MOD_PATH=modules_install rm -rf modules_install/lib/modules/*/build rm -rf modules_install/lib/modules/*/source

  • 以下のファイルが生成されていることを確認する
  • ~/linux-socfpga/arch/arm/boot/zImage
  • ~/linux-socfpga/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc_FB.dtb
  • ~/linux-socfpga/modules_install



Root File System の Build


ここまでで、U-Boot, Linux Kernel, Driver/Module, Device Tree は作成できた。
次に、Root File System を作成する。
  • 基本操作は、Rocketboards.org と同じですが、一部、XFCE を有効にするために、操作を変更。
  • 赤字部分が、Rocketboards.org と異なる操作。
  • cd ~/
    mkdir yocto && cd yocto
    # Clone required Yocto git trees 
    git clone -b zeus https://git.yoctoproject.org/git/poky.git
    git clone -b zeus https://git.openembedded.org/meta-openembedded
    git clone -b master https://github.com/kraj/meta-altera.git
    git clone -b master https://github.com/altera-opensource/meta-altera-refdes.git

  • # meta-altera-refdes/conf/layers.conf を編集
    # LAYERSERIES_COMPAT_meta-altera-refdes に "zeus" を追加
    sed -i "s/dunfell gatesgarth/zeus dunfell gatesgarth/"
    \  meta-altera-refdes/conf/layer.conf

  • # Run script to initialize the build environment for bitbake
    # Note: You will be redirect to "build" folder once you execute the command below
    source poky/oe-init-build-env
    
    # Remove default settings imported from template
    sed -i /MACHINE\ \?\?=\ \"qemux86-64\"/d conf/local.conf
    
    # Use systemd
    echo 'DISTRO_FEATURES_append = " systemd"' >> conf/local.conf
    echo 'VIRTUAL-RUNTIME_init_manager = "systemd"' >> conf/local.conf
    
    # Use the LTS kernel and set version
    echo 'PREFERRED_PROVIDER_virtual/kernel = "linux-altera-lts"' >> conf/local.conf
    echo 'PREFERRED_VERSION_linux-altera-lts = "5.4%"' >> conf/local.conf
    
    # Build additional rootfs type
    echo 'IMAGE_FSTYPES += "tar.gz"' >> conf/local.conf
    
    # Settings for bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-altera "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-altera-refdes "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-oe "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-networking "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-python "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-xfce "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-gnome "' >> conf/bblayers.conf
    echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-multimedia "' >> conf/bblayers.conf


  • # Set the MACHINE, only at a time to avoid build conflict
    echo "MACHINE = \"cyclone5\"" >> conf/local.conf
    
    # Ensure we build in all kernel-modules
    echo "MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += \"kernel-modules\"" >> conf/local.conf
    
    # Build rootfs image (3時間前後かかります)
    bitbake  core-image-minimal-xfce

SD card への書き込み


あとは、SD card image ファイルを作成して、SD card に書き込む。
  • 基本操作は、Rocketboards.org と同じだが、一部、生成されたファイル名が異なるので、その部分の操作が異なる。
  • 異なる部分を赤字で示す。
  • # Create folder to keep the SD card binaries
    cd ~/
    mkdir sd_card && cd sd_card
    
    # Get SD card creation script#
    wget https://releases.rocketboards.org/release/2020.05/gsrd/tools/make_sdimage_p3.py
    chmod +x make_sdimage_p3.py
    
    # Get SPL image#
    cp ~/DE10_NANO_SoC_FB/software/bootloader/u-boot-socfpga/u-boot-with-spl.sfp .
    
    # Prepare FAT partition contents
    mkdir fat && cd fat
    cp ~/linux-socfpga/arch/arm/boot/zImage .
    cp ~/linux-socfpga/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc_FB.dtb ./socfpga_cyclone5_socdk.dtb
    cp ~/DE10_NANO_SoC_FB/output_files/*.rbf .
    cp
    ~/u-boot.scr . mkdir extlinux && cd extlinux wget https://releases.rocketboards.org/release/2020.07/gsrd/cv_gsrd/extlinux.conf cd ../.. # Prepare Rootfs partition contents# mkdir rootfs && cd rootfs sudo tar xf ~/yocto/build/tmp/deploy/images/cyclone5/core-image-minimal-xfce-cyclone5.tar.gz
    sudo rm -rf lib/modules/* sudo cp -r
    ~/linux-socfpga/modules_install/lib/modules/* lib/modules/ cd .. # Build SD card image# sudo python3 make_sdimage_p3.py -f \ -P u-boot-with-spl.sfp,num=3,format=raw,size=10M,type=A2 \ -P rootfs/*,num=2,format=ext2,size=1500M \ -P fat/*,num=1,format=fat32,size=500M -s 2G \ -n sdcard.img

生成された sdcard.img を、SDcard に書き込む。sdcard を umount 後に、ddコマンドで書き込む例。ここでは、SDcardが、/dev/sdc に割り当てられている例。
  • sudo umount /dev/sdc*
  • sudo dd  bs=4M  conv=sync  if=sdcard.img  of=/dev/sdc

その後、SD card をDE10-nanoに差し込んで、電源を入れれば、終了。
root でログイン後に、「startxfce4」と打ち込むと、XFCE desktop が起動する。




おまけ:


上記の操作だと、最小限のソフトウエアしかインストールされていない。Python等もインストールしておきたい場合には、Yocto の Recipe ファイルを作成して、Root File System を生成する。

1. recipe 追加


下記 Recipe ファイルを追加して、bitbake コマンドを以下のように実行する。生成される 「core-image-xfce-some2-cyclone5.tar.gz」には、Python などの各種ソフトが入っている。


File1:

~/yocto/meta-openembedded/meta-xfce/recipes-core/images/core-image-xfce-some2.bb

DESCRIPTION = "A XFCE demo image 2."

IMAGE_INSTALL = "packagegroup-core-boot \
    packagegroup-core-ssh-openssh \
    packagegroup-core-apt \
    packagegroup-core-buildessential2 \
    packagegroup-core-x11 \
    packagegroup-xfce-base \
    kernel-modules \
"

inherit distro_features_check
REQUIRED_DISTRO_FEATURES = "x11"

IMAGE_LINGUAS ?= " "

LICENSE = "MIT"

export IMAGE_BASENAME = "core-image-xfce-some2"


File 2:

~/yocto/poky/meta/recipes-core/packagegroups/packagegroup-core-buildessential2.bb

#
# Copyright (C) 2007 OpenedHand Ltd.
# Copyright (C) 2012 Red Hat, Inc.
#

SUMMARY = "Essential build dependencies2"

inherit packagegroup

RDEPENDS_packagegroup-core-buildessential2 = "\
    autoconf \
    automake \
    binutils \
    binutils-symlinks \
    cpp \
    cpp-symlinks \
    gcc \
    gcc-symlinks \
    g++ \
    g++-symlinks \
    gettext \
    make \
    cmake \
    libstdc++ \
    libstdc++-dev \
    libtool \
    pkgconfig \
    file \
    git \
    gdb \
    python \
    python3 \
    i2c-tools \
    "


bitbake コマンド

(「Root File System の Build」(前述)の最後のコマンド)

bitbake core-image-xfce-some2


生成されるファイル

~/yocto/build/tmp/deploy/images/cyclone5/core-image-xfce-some2-cyclone5.tar.gz
 
SD card イメージ生成時には、「core-image-minimal-xfce-cyclone5.tar.gz」の代わりに、今回作成した「core-image-xfce-some2-cyclone5.tar.gz」ファイルに対して、tar コマンドを実行する。これで、DE10-nano上の Linux で、Python が使えるようになる。 

(recipeの設定が原因などで、うまくいかない時等、一度、環境を Clean にしたくなる時がある。その時は、「bitbake  -c  clean  core-image-xfce-some2 」と打ち込むと Clean になる)



2. sshd 有効化設定


sshd も起動しておいて、他端末から ssh で入れるようにしておく。

他端末から ssh でログインする時は、「ssh root@DE10-nanoのip-address」と打ち込む(例:ssh  root@192.168.1.29)。 IP address は、Serial 端末か、HDMIモニターに表示しているターミナルから、ifconfig コマンドを打ち込めば確認できる。

* /etc/ssh/sshd_config (line 13) 編集(Port 22 有効化)

< #Port 22
----
> Port 22

* sshd 起動コマンド

systemctl start sshd

* 起動時に sshd 起動するように設定する(コマンド)

systemctl enable sshd


* IP address 確認方法  (DE10-nano上での操作)

Ethernet ケーブルを DE10-nano に接続後、起動。
root でログイン後に、ifconfig と打ち込む。赤字部分が IP address。

root@cyclone5:~# ifconfig


eth0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  

          inet addr:192.168.1.29  Bcast:192.168.1.255  Mask:255.255.255.0

          inet6 addr: xxxx::xxx:xxxx:xxxx:xxxx/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:149 errors:0 dropped:0 overruns:0 frame:0

          TX packets:155 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:14671 (14.3 KiB)  TX bytes:15577 (15.2 KiB)

          Interrupt:31 Base address:0xa000 





参照URLs:


2020年6月28日日曜日

FreeRTOS v10.3.1: NiosII 用デモを DE0-Nano + Quartus/NiosII EDS v18.1 で動作させる

 

 
FreeRTOS.org からリリースされている Demo Example の中に、Intel FPGA / NiosII 向け Example があります(FreeRTOS/Demo/NiosII_CycloneIII_DBC3C40_GCC/)。

生憎、この Example は非常に古いため、そのままでは最新の NiosII EDS では動作しません。

そこで、DE0-Nano で(とりあえず)動作させる手順を、以下に纏めましたので、参考までに、ご紹介します。
 
 
 
※FreeRTOS.org 提供のNiosII向け Exampleコード「全体」に対して、詳細な動作検証までは行っておりませんので、その点はご了承ください。

* FreeRTOS.org:  オープンソースの RTOS https://freertos.org/
* FreeRTOS v10.3 コード(含 Examle): Github, FreeRTOS donwload v10.3
* NiosII 向け Example: FreeRTOS/Demo/NiosII_CycloneIII_DBC3C40_GCC/
* DE0-Nano:  Terasic社製 Cyclone IV 低価格評価ボード  
* Intel Quartus Prime / NiosII EDS: 今回は、v18.1 を使用


※1:モチベーション:
手持ちの低価格評価ボード DE0-Nano を使用して、最小限の工数で、一先ず、FreeRTOS を動かしてみたい。

※2:CPU 及び Cyclone IV 上のハードウェア(HW):
CPU: NiosII
HW: ゴールデン・リファレンス・デザイン (Terasic提供)をカスタマイズ

※3:HAL / OS
HAL: NiosII EDS にて生成
OS: FreeRTOS


[1] FreeRTOS.org 提供の Example は、そのまま DE0-Nano のゴールデン・リファレンス・デザイン (GRD) で動作させることはできるのか?

 
 
 
残念ながら、次の理由で、動作させることはできません。
 
 
(a) FreeRTOS.org提供のExampleコードには、UART を使用する コードがある。しかし、GRD には UART ペリフェラルがない。→ Platform Designer (旧Qsys) + Quartus で、Hardware デザインを変更 + コンパイルする必要がある。
 

(b) 追加のマクロ定義をしないと、Compile エラーとなる。→ ソースコードの変更
 

(c) 古い Quartus / NiosII EDS を前提にコードが提供されているため、そのままではBSP (Board Support Package) / HAL を生成できない。→ Platform Designer (旧Qsys)からの出力ファイル *.socinfo ファイルと BSP Editor を使用して生成する。
 

(d) LED の記述を、DE0-Nano の GRD に合わせて変更する必要がある。
 

(e) vTaskDelay() 関数を使用すると、vTaskDelay() 以降の処理が実行されない。→ FreeRTOS 提供の NiosII 用 Exampleには、Exception Handler が含まれている。これが、最新の NiosII HAL/BSP の記述と相性が悪い(前提が異なる)。
 

(f) alt_irq_handler() 内部で無限ループとなる。→ 前述(e)と同じで、恐らく相性問題。詳細は追っていないが、とりあえずの回避策あり。
 
 


[2] 対策方法:

前述の(a)~(f) の対策を以下に記載します。

(a) Platform Designer (旧Qsys) + Quartus で、Hardware デザインを変更 + コンパイルする必要がある。


DE0-Nano 付属の CD-ROM に、各種ファイルがあります。"Demonstration” フォルダー以下に、「DE0_Nano_QSYS_DEMO」というデザインがありますので、これを変更して使用します。

Quartus の使用方法の詳細は割愛します。
*DE0_Nano.qpf を使用して、Quartus を開きます。
*DE0_Nano_SOPC.qsys を使用して、Platform Designer を開きます。
*"UART" を追加します。"Name" の箇所を "uart" に変更します(下図参照)。クロックはNiosIIと同じクロックで、IRQ もNiosIIに接続します。

*上記変更&ファイルを保存後、Platform上で Generate HDL を行います。また、Quartus 上で、Compile を行い、*.sof ファイルを生成します。Quartus Lite Edition を使用している場合には、生成される sof ファイル名は、「DE0_Nano_time_limited.sof」になります。
*この sof ファイルを、ソフトウェアを動作させる前に、Quartus の Programmer を使用して、NE0-Nanoボードにダウンロードします。
 


(b) 追加のマクロ定義をしないと、Compile エラーとなる。→ ソースコードの変更

以下のコードを、FreeRTOS Example コードに追加します。

FreeRTOSConfig.hファイル:
//Added 100MHz clock for NiosII
#define SYS_CLK_FREQ 100000000

portable/GCC/NiosII/port.cファイル:
#include "altera_avalon_timer.h"
#define  SYS_CLK_IRQ  0

//SYS_CLK_BASE を TIMER_BASE に変更(6箇所)
//例:
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );
 ↓
IOWR_ALTERA_AVALON_TIMER_CONTROL( TIMER_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );

 

(c) Platform Designer (旧Qsys)からの出力ファイル *.socinfo ファイルと BSP Editor を使用して生成する。

NiosII EDS 上で、前述(a)の操作で生成された *.socinfo ファイルを使用して、BSP を生成する。BSP Editor 上では、特に変更する設定は無い。Generate ボタンをクリックするだけ。
(BSP Editor 操作の詳細は割愛)
 


(d) LED の記述を、DE0-Nano の GRD に合わせて変更する必要がある。


ParTest/ParTest.c ファイル:

//LED_PIO_BASE を LED_BASE に変更(2箇所)
//
//1.
IOWR_ALTERA_AVALON_PIO_DIRECTION( LED_PIO_BASE, ALTERA_AVALON_PIO_DIRECTION_OUTPUT );
 ↓
IOWR_ALTERA_AVALON_PIO_DIRECTION( LED_BASE, ALTERA_AVALON_PIO_DIRECTION_OUTPUT );

//2.
IOWR_ALTERA_AVALON_PIO_DATA( LED_PIO_BASE, ulLedStates );
 ↓
IOWR_ALTERA_AVALON_PIO_DATA( LED_BASE, ulLedStates );
 


(e) vTaskDelay() 関数を使用すると、vTaskDelay() 以降の処理が実行されない。→ FreeRTOS 提供の NiosII 用 Exampleには、Exception Handler が含まれている。これが、最新の NiosII HAL/BSP の記述と相性が悪い(前提が異なる)。


(ここが原因を探るのに最も苦労したところ)


portable/GCC/NiosII/port_asm.S ファイル:
 

[call_scheduler オリジナル記述]
call_scheduler:
addi ea, ea, 4 # A trap was called, increment the program counter so it is not called again.
stw ea, 72(sp) # Save the new program counter to the context.
call vTaskSwitchContext # Pick the next context.
br restore_sp_from_pxCurrentTCB # Switch in the task context and restore. 


[call_scheduler 変更後(line 147 に、movia,ldw,ldw の3行を追加)]
call_scheduler:
addi ea, ea, 4 # A trap was called, increment the program counter so it is not called again.

#New lines (start)
movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
ldw et, (et) # Load the value of the pxCurrentTCB pointer
ldw sp, (et) # Load the stack pointer with the top value of the TCB
#New lines (end)

stw ea, 72(sp) # Save the new program counter to the context.
call vTaskSwitchContext # Pick the next context.
br restore_sp_from_pxCurrentTCB # Switch in the task context and restore. 

 
 

(f) alt_irq_handler() 内部で無限ループとなる。対策は以下。


※注意事項: BSP Editor で生成する度に、以下の対策を実行する必要あり(上書きされてしまう)。

*_bsp/HAL/src/alt_irq_handler.cファイル:
line 141行の do{ ~ } while(1) を、if (active) { ~ } で囲む。

    if (active) //added for FreeRTOS demo
    {
    do
    {
      if (active & mask)
      { 
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
        alt_irq[i].handler(alt_irq[i].context); 
#else
        alt_irq[i].handler(alt_irq[i].context, i); 
#endif
        break;
      }
      mask <<= 1;
      i++;

    } while (1);
    }

 


[3] 確認したFreeRTOS を含むソフトウェア・コード:


とりあえず、動作確認したコードを紹介します。ここでは、vTaskDelay() を使用したLEDの点滅動作を確認しています。ボード上のLED01 が点滅します。

#vTaskDelay()を動作させるには、前述(e) が不可欠ですのでご注意を!


Common_Demo_Tasks/flash.cファイル:

static portTASK_FUNCTION( debug_task, pvParameters ){
  for(;;) {
            vParTestToggleLED( 1 ); //LED01
    vTaskDelay(pdMS_TO_TICKS(50));
  }
}

void vStartLEDFlashTasks( UBaseType_t uxPriority )
{
if (xTaskCreate( debug_task, "DEBUGx", ledSTACK_SIZE, NULL, uxPriority + 1, ( TaskHandle_t * ) NULL ) != pdPASS) {
printf("debug: xTaskCreate failed, debug_task\n");
}
}



main.cファイル:

int main( void )
{
prvSetupHardware();
    
vStartLEDFlashTasks( tskIDLE_PRIORITY );

vTaskStartScheduler();

for( ;; );

return 0;
}



※その他1:

Makefile 中のALT_INCLUDE_DIRS変数の設定も忘れずに!

(設定例)
ALT_INCLUDE_DIRS := . FreeRTOS/include Common_Demo_Tasks/include FreeRTOS/portable/GCC/NiosII



※その他2:


UART を動作させるには、上記の他に、UART のTX/RX ピンを、GPIO に割り当てる処理が必要になります。こちらについては、今回の記載には含まれておりません。こちらは、別途更新しようと思います。


Enjoy !