Yocto variable not defined but set with _ operator - stm32

I'm struggling with something I'm not sure to address correctly.
In a Yocto environment (for STM32MP1 by the way) I have to configure a new target.
Hence I added to meta-st/meta-st-stm32mp/conf/machine/include/st-machine-extlinux-config-stm32mp.inc this section, that looks like the other already available:
EXTLINUX_BOOTDEVICE_EMMC = "mmc1"
EXTLINUX_BOOTDEVICE_SDCARD = "mmc0"
EXTLINUX_ROOT_EMMC = "${#bb.utils.contains('ST_VENDORFS','1','root=/dev/mmcblk1p4','root=/dev/mmcblk1p3',d)}"
EXTLINUX_ROOT_NAND = "ubi.mtd=UBI rootfstype=ubifs root=ubi0:rootfs"
# Define available targets to use
UBOOT_EXTLINUX_CONFIGURED_TARGETS += "mp151a_sdcard"
UBOOT_EXTLINUX_CONFIGURED_TARGETS += "mp151a_emmc"
# Define bootprefix for each target
UBOOT_EXTLINUX_BOOTPREFIXES_mp151a_sdcard = "${EXTLINUX_BOOTDEVICE_SDCARD}_stm32mp151a_"
UBOOT_EXTLINUX_BOOTPREFIXES_mp151a_emcc = "${EXTLINUX_BOOTDEVICE_EMCC}_stm32mp151a_"
# Define labels for each target
UBOOT_EXTLINUX_LABELS_mp151a_sdcard = "stm32mp151a-sdcard"
UBOOT_EXTLINUX_LABELS_mp151a_emcc = "stm32mp151a-emcc"
# Define default boot config for each target
UBOOT_EXTLINUX_DEFAULT_LABEL_mp151a_sdcard ?= "stm32mp151a-sdcard"
UBOOT_EXTLINUX_DEFAULT_LABEL_mp151a_emcc ?= "stm32mp151a-emcc"
# Define FDT overrides for all labels
UBOOT_EXTLINUX_FDT_stm32mp151a-sdcard = "/stm32mp151a.dtb"
UBOOT_EXTLINUX_FDT_stm32mp151a-emcc = "/stm32mp151a.dtb"
# Define ROOT overrides for all labels
UBOOT_EXTLINUX_ROOT_stm32mp151a-sdcard = "${EXTLINUX_ROOT_SDCARD}"
UBOOT_EXTLINUX_ROOT_stm32mp151a-emcc = "${EXTLINUX_ROOT_EMCC}"
But when I bitbake <image> (that includes the file above) I get this output:
DEBUG: Executing python function update_extlinuxconf_targets
NOTE: UBOOT_EXTLINUX_CONFIGURED_TARGETS: mp157a-dk1_sdcard mp157a-dk1_sdcard-optee mp157c-dk2_sdcard mp157c-dk2_sdcard-optee mp157c-ed1_emmc mp157c-ed1_emmc-optee mp157c-ed1_sdcard mp157c-ed1_sdcard-optee mp157c-ev1_emmc mp157c-ev1_emmc-optee mp157c-ev1_nand mp157c-ev1_nor-sdcard mp157c-ev1_nor-emmc mp157c-ev1_sdcard mp157c-ev1_sdcard-optee mp151a_sdcard mp151a_emmc
NOTE: UBOOT_EXTLINUX_CONFIG_FLAGS: emmc sdcard
NOTE: *** Loop for config_label: emmc
NOTE: *** Loop for devicetree: stm32mp151a
NOTE: >>> New target label: mp151a_emmc
NOTE: >>> Append mp151a_emmc to UBOOT_EXTLINUX_TARGETS
NOTE: *** Loop for config_label: sdcard
NOTE: *** Loop for devicetree: stm32mp151a
NOTE: >>> New target label: mp151a_sdcard
NOTE: >>> Append mp151a_sdcard to UBOOT_EXTLINUX_TARGETS
NOTE: >>> UBOOT_EXTLINUX_TARGETS (updated): mp151a_emmc mp151a_sdcard
DEBUG: Python function update_extlinuxconf_targets finished
DEBUG: Executing python function do_create_multiextlinux_config
ERROR: UBOOT_EXTLINUX_ROOT not defined
DEBUG: Python function do_create_multiextlinux_config finished
ERROR: Function failed: do_create_multiextlinux_config
As you can see, the file is actually processed because it added the targets I've defined.
But it doesn't find the UBOOT_EXTLINUX_ROOT even if it's "set" with the _ operator:
UBOOT_EXTLINUX_ROOT_stm32mp151a-sdcard = "${EXTLINUX_ROOT_SDCARD}"
UBOOT_EXTLINUX_ROOT_stm32mp151a-emcc = "${EXTLINUX_ROOT_EMCC}"
I also tried to set the main variable to something like:
UBOOT_EXTLINUX_ROOT = ""
or
UBOOT_EXTLINUX_ROOT = "root=/dev/mmcblk1p4"
to see if it was the problem but it doesn't change nothing.
Is this something related to Yocto itself (I mean, something wrong in my syntax) or it's very specific to the SDK (meta-st) ?
The error above should be raised by this file:
root = localdata.getVar('UBOOT_EXTLINUX_ROOT')
if not root:
bb.fatal('UBOOT_EXTLINUX_ROOT not defined')
UPDATE
I checked the (huge) output of bitbake -e and among other targets I see:
# $UBOOT_EXTLINUX_ROOT [41 operations]
[...]
# "${EXTLINUX_ROOT_NOREMMC}"
# override[stm32mp157c-ev1-m4-examples-sdcard]:set /local/STM32MP15-Ecosystem-v1.1.0/Distribution-Package/openstlinux-4.19-thud-mp1-19-10-09/layers/meta-st/meta-st-stm32mp/conf/machine/include/st-machine-extlinux-config-stm32mp.inc:274
# "${EXTLINUX_ROOT_SDCARD}"
# override[stm32mp157c-ev1-m4-examples-sdcard-optee]:set /local/STM32MP15-Ecosystem-v1.1.0/Distribution-Package/openstlinux-4.19-thud-mp1-19-10-09/layers/meta-st/meta-st-stm32mp/conf/machine/include/st-machine-extlinux-config-stm32mp.inc:275
# "${EXTLINUX_ROOT_SDCARD_OPTEE}"
# override[stm32mp151a-sdcard]:set /local/STM32MP15-Ecosystem-v1.1.0/Distribution-Package/openstlinux-4.19-thud-mp1-19-10-09/layers/meta-st/meta-st-stm32mp/conf/machine/include/st-machine-extlinux-config-stm32mp.inc:296
# "${EXTLINUX_ROOT_SDCARD}"
# override[stm32mp151a-emcc]:set /local/STM32MP15-Ecosystem-v1.1.0/Distribution-Package/openstlinux-4.19-thud-mp1-19-10-09/layers/meta-st/meta-st-stm32mp/conf/machine/include/st-machine-extlinux-config-stm32mp.inc:297
[...]
# pre-expansion value:
# ""
UBOOT_EXTLINUX_ROOT=""
# $UBOOT_EXTLINUX_ROOT_cubemx-nor-sdcard
UBOOT_EXTLINUX_ROOT_cubemx-nor-sdcard="root=/dev/mmcblk0p3"
# $UBOOT_EXTLINUX_ROOT_cubemx-sdcard
UBOOT_EXTLINUX_ROOT_cubemx-sdcard="root=/dev/mmcblk0p6"
# $UBOOT_EXTLINUX_ROOT_stm32mp151a-emcc
UBOOT_EXTLINUX_ROOT_stm32mp151a-emcc="\${EXTLINUX_ROOT_EMCC}"
# $UBOOT_EXTLINUX_ROOT_stm32mp151a-sdcard
UBOOT_EXTLINUX_ROOT_stm32mp151a-sdcard="root=/dev/mmcblk0p6"
So far, if I understand correctly, the override values are correctly assigned (but not the ${EXTLINUX_ROOT_EMCC} - I don't understand where the \ comes from) but the main variable is still empty.
Adding UBOOT_EXTLINUX_ROOT = "root=/dev/mmcblk1p4" at the beginning of the above file, seems to do the trick (even if before I wrote the opposite, perhaps I forgot to clear the cache?) but I don't think it's the right way to do it.

You should specify the wanted name of the machine as a target to build, i.e.:
MACHINE=stm32mp151a-sdcard bitbake <image>
This way, the UBOOT_EXTLINUX_ROOT gets the non-empty value "root=/dev/mmcblk0p6" (from the UBOOT_EXTLINUX_ROOT_stm32mp151a-sdcard variant of the variable).

Related

STM32MP1 OpenSTLinux - bitbake cross-compilation for custom machine does not generate sdcard.stm32 file

I am trying to deploy the st-image-core image on a custom machine board, following this approach described in the ST wiki. The custom device tree files were generated with the STM32CubeMX tool.
I have already managed to boot my custom machine, using the binaries generated within the DeveloperPackage with the STM32CubeIDE fed with my custom device tree files; the output of the build includes:
arm-trusted-firmware/tf-a-stm32mp157c-custom-board-mx-usb.stm32
fip/fip-stm32mp157c-custom-board-mx-trusted.bin
arm-trusted-firmware/tf-a-stm32mp157c-custom-board-mx-sdcard.stm32
arm-trusted-firmware/metadata.bin
Now, I am trying to build the same binaries with the bitbake approach within the DistributionPackage.
Unfortunately, when the build is completed, only the tf-a-stm32mp157c-custom-board-mx-usb.stm32 and the tf-a-stm32mp157c-custom-board-mx-uart.stm32 are generated under the arm-trusted-firmware build directory. The binary filetf-a-stm32mp157c-custom-board-mx-sdcard.stm32 is not generated in the build directory.
The recipe for the custom machine custom-board.conf is included within my custom layer meta-custom.
The content of the machine recipe custom-board.conf:
##TYPE: Machine
##NAME: stm32mp15-mx
##DESCRIPTION: Configuration for STM32CubeMX generated project
##NEEDED_BSPLAYERS: layers/meta-openembedded/meta-oe layers/meta-openembedded/meta-python layers/meta-st/meta-st-stm32mp-addons
###########################################################################
#
# Default machine configuration sections
#
###########################################################################
include conf/machine/include/st-machine-common-stm32mp.inc
include conf/machine/include/st-machine-providers-stm32mp.inc
# Define specific common machine name
MACHINEOVERRIDES .= ":stm32mpcommonmx:stm32mp15commonmx"
MACHINEOVERRIDES .= ":stm32mp1common:stm32mp15common"
MACHINEOVERRIDES .= ":custom-board"
# =========================================================================
# Chip architecture
# =========================================================================
DEFAULTTUNE = "cortexa7thf-neon-vfpv4"
include conf/machine/include/arm/armv7a/tune-cortexa7.inc
# =========================================================================
# Machine settings
# =========================================================================
STM32MP_DEVICETREE = "${CUBEMX_DTB}"
# =========================================================================
# Machine features (default for stm32mp1 like)
# =========================================================================
#MACHINE_FEATURES += "splashscreen"
MACHINE_FEATURES += "watchdog"
MACHINE_FEATURES += "${#'gpu' if d.getVar('ACCEPT_EULA_'+d.getVar('MACHINE')) == '1' else ''}"
#MACHINE_FEATURES += "m4copro"
# =========================================================================
# Device Storage
# =========================================================================
# Enable the board device storage support with CUBEMX_DTB according to BOOTDEVICE_LABELS
#DEVICE_BOARD_ENABLE_NAND += "${#bb.utils.contains('BOOTDEVICE_LABELS', 'nand-4-256', '${CUBEMX_DTB}', '', d)}"
#DEVICE_BOARD_ENABLE_NOR += "${#bb.utils.contains('BOOTDEVICE_LABELS', 'nor-sdcard' , '${CUBEMX_DTB}', '', d)}"
#DEVICE_BOARD_ENABLE_EMMC += "${#bb.utils.contains('BOOTDEVICE_LABELS', 'emmc', '${CUBEMX_DTB}', '', d)}"
DEVICE_BOARD_ENABLE_SDCARD += "${#bb.utils.contains('BOOTDEVICE_LABELS', 'sdcard', '${CUBEMX_DTB}', '', d)}"
# =========================================================================
# Flashlayout
# =========================================================================
# Set the FLASHLAYOUT_TYPE_LABELS to CUBEMX_DTB according to BOOTDEVICE_LABELS
#FLASHLAYOUT_TYPE_LABELS_emmc = "${#bb.utils.contains('BOOTDEVICE_LABELS', 'emmc', '${CUBEMX_DTB}', '', d)}"
#FLASHLAYOUT_TYPE_LABELS_nand-4-256 = "${#bb.utils.contains('BOOTDEVICE_LABELS', 'nand-4-256', '${CUBEMX_DTB}', '', d)}"
#FLASHLAYOUT_TYPE_LABELS_nor-sdcard = "${#bb.utils.contains('BOOTDEVICE_LABELS', 'nor-sdcard' , '${CUBEMX_DTB}', '', d)}"
FLASHLAYOUT_TYPE_LABELS_sdcard = "${#bb.utils.contains('BOOTDEVICE_LABELS', 'sdcard', '${CUBEMX_DTB}', '', d)}"
# Specific settings for 'extensible' and 'deleteall' configurations
#FLASHLAYOUT_CONFIG_LABELS_deleteall = "cubemx"
FLASHLAYOUT_TYPE_LABELS_deleteall_cubemx = "${CUBEMX_DTB}"
FLASHLAYOUT_TYPE_LABELS_extensible = "${CUBEMX_DTB}"
# =========================================================================
# CubeMX extra config
# =========================================================================
#ENABLE_CUBEMX_DTB ?= "1"
ENABLE_CUBEMX_DTB = "1"
CUBEMX_DTB_PATH_TFA = "tf-a"
CUBEMX_DTB_PATH_TFA_SB = "tf-a"
CUBEMX_DTB_PATH_UBOOT = "u-boot"
CUBEMX_DTB_PATH_LINUX = "kernel"
CUBEMX_DTB_PATH_OPTEEOS = "optee-os"
###########################################################################
#
# User machine customization sections
#
###########################################################################
# Boot Scheme
# =========================================================================
BOOTSCHEME_LABELS += "trusted"
#BOOTSCHEME_LABELS += "optee"
# Boot Device Choice
# =========================================================================
# Define the boot device supported
BOOTDEVICE_LABELS += "sdcard"
#BOOTDEVICE_LABELS += "emmc"
#BOOTDEVICE_LABELS += "nand-4-256"
#BOOTDEVICE_LABELS += "nor-sdcard"
# Support Feature Choice
# =========================================================================
# Define the features to enable on board
MACHINE_FEATURES += "bluetooth"
MACHINE_FEATURES += "wifi"
# Specific firmwares and kernel modules configuration
# =========================================================================
# Set the list of kernel module to be auto-loaded during boot
#KERNEL_MODULE_AUTOLOAD += ""
# Set Bluetooth related package list needed when 'bluetooth' feature is enabled
BLUETOOTH_LIST += "linux-firmware-bluetooth-bcm4343"
# Set Wifi related package list needed when 'wifi' feature is enabled
WIFI_LIST += "linux-firmware-bcm43430"
# CubeMX Project Config
# =========================================================================
# Assign CubeMX Board devicetree and project path name
CUBEMX_DTB = "stm32mp157c-custom-board-mx"
CUBEMX_PROJECT = "mx/custom-board"
# Indicate which STM32MP package are used: 'A', 'C', 'D' or 'F'
CUBEMX_SOC_PACKAGE = "C"
# Indicate the size of DDR available on BOARD: 512 or 1024 (size in MB unit)
CUBEMX_BOARD_DDR_SIZE = "1024"
# Indicate if you like to disable the DVFS which are activated by default
#CUBEMX_SOC_DVFS_OFF = "0"
And the content of layer.conf:
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "meta-custom"
BBFILE_PATTERN_meta-custom = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-custom = "5"
EULA_FILE_ST_custom-board = "${LAYERDIR}/conf/eula/${MACHINE}"
EULA_FILE_ST_MD5SUM_custom-board = "8b505090fb679839cefbcc784afe8ce9"
#Inform bitbake for adding another location to search for licenses
LICENSE_PATH += "${LAYERDIR}/files/licenses"
# Set a variable to get the STM32MP MX BSP location
CUSTOM_BOARD_BASE = "${LAYERDIR}"
# This should only be incremented on significant changes that may
# cause compatibility issues with other layers
LAYERVERSION_meta-custom = "1"
LAYERDEPENDS_meta-custom = "core stm-st-stm32mp-mx"
# OpenEmbedded compatibility information
# This should only be incremented on significant changes that will
# cause compatibility issues with other layers
LAYERVERSION_meta-custom = "1"
LAYERSERIES_COMPAT_meta-custom = "kirkstone"
Although BOOTDEVICE_LABELS += "sdcard" is specified in the custom-board.conf machine recipe file, the tf-a-stm32mp157c-custom-board-mx-sdcard.stm32 is not being generated (or it is being deleted by something I am not controlling). I am quite sure the custom-board.conf is correctly referenced by the cross-compilation, since the bcm4343 drivers are included in the built kernel (I am using the sdcard.stm32 file from the DeveloperPackage to flash the board via OTG and do the check).
Am I missing something for the generation of the sdcard.stm32?
Any help is greatly appreciated, so thank you for taking the time to read this.
P.S. I asked this on the ST Community Forum, but no answer reached me in 15 days.
The issue was caused by the new naming convention introduced in yocto kirkstone (old suffix separator _ vs new suffix separator :) of the variables in the custom machine conf file. See this answer for further details.

object not found when creating targets list programmatically

I'm trying to generate a {targets} list programmatically, via a function in an R package.
get_pipeline <- function(which_countries) {
countries <- NULL # avoid R CMD CHECK warning
print(which_countries) # Shows that which_countries is available
list(
targets::tar_target(
name = countries,
command = which_countries # But here, which_countries is not found
)
)
}
The _targets.R file looks like this:
library(targets)
couns <- c("USA", "GBR")
TargetsQuestions::get_pipeline(couns)
I see the following error:
> tar_make()
[1] "USA" "GBR"
Error in enexpr(expr) : object 'which_countries' not found
Error in `tar_throw_run()`:
! callr subprocess failed: object 'which_countries' not found
Note that the which_countries variable is printable, but not found in the call to tar_target.
How can I get create the countries target successfully so that it contains the vector c("USA", "GBR")?
This code is in a GitHub repository at https://github.com/MatthewHeun/TargetsQuestions. To reproduce:
git clone https://github.com/MatthewHeun/TargetsQuestions
Build the package in RStudio.
targets::tar_make() at the Console.
Thanks in advance for any suggestions!
Thanks to #landau for pointing to https://wlandau.github.io/targetopia/contributing.html#target-factories which in turn points to the metaprogramming section of Advanced R at https://adv-r.hadley.nz/metaprogramming.html.
The solution turned out to be:
get_pipeline <- function(which_countries) {
list(
targets::tar_target_raw(
name = "countries",
# command = which_countries # which_countries must have length 1
# command = !!which_countries # invalid argument type
command = rlang::enexpr(which_countries) # Works
)
)
}
With _targets.R like this:
library(targets)
couns <- c("USA", "GBR")
TargetsQuestions::get_pipeline(couns)
the commands tar_make() and tar_read(countries), give
[1] "USA" "GBR"
as expected!

GraphMachine doesn't generate graph for NarcolepticSuperhero quickstart example

I tried creating a Diagram using the NarcolepticSuperhero machine defined in the GitHub documentation but it only outputs this:
Steps to recreate:
Create a file named test.py, with this content:
from transitions import Machine
from transitions.extensions import GraphMachine
import random
class NarcolepticSuperhero(object):
# Define some states. Most of the time, narcoleptic superheroes are just like
# everyone else. Except for...
states = ['asleep', 'hanging out', 'hungry', 'sweaty', 'saving the world']
def __init__(self, name):
# No anonymous superheroes on my watch! Every narcoleptic superhero gets
# a name. Any name at all. SleepyMan. SlumberGirl. You get the idea.
self.name = name
# What have we accomplished today?
self.kittens_rescued = 0
# Initialize the state machine
self.machine = Machine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
# Add some transitions. We could also define these using a static list of
# dictionaries, as we did with states above, and then pass the list to
# the Machine initializer as the transitions= argument.
# At some point, every superhero must rise and shine.
self.machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out')
# Superheroes need to keep in shape.
self.machine.add_transition('work_out', 'hanging out', 'hungry')
# Those calories won't replenish themselves!
self.machine.add_transition('eat', 'hungry', 'hanging out')
# Superheroes are always on call. ALWAYS. But they're not always
# dressed in work-appropriate clothing.
self.machine.add_transition('distress_call', '*', 'saving the world',
before='change_into_super_secret_costume')
# When they get off work, they're all sweaty and disgusting. But before
# they do anything else, they have to meticulously log their latest
# escapades. Because the legal department says so.
self.machine.add_transition('complete_mission', 'saving the world', 'sweaty',
after='update_journal')
# Sweat is a disorder that can be remedied with water.
# Unless you've had a particularly long day, in which case... bed time!
self.machine.add_transition('clean_up', 'sweaty', 'asleep', conditions=['is_exhausted'])
self.machine.add_transition('clean_up', 'sweaty', 'hanging out')
# Our NarcolepticSuperhero can fall asleep at pretty much any time.
self.machine.add_transition('nap', '*', 'asleep')
def update_journal(self):
""" Dear Diary, today I saved Mr. Whiskers. Again. """
self.kittens_rescued += 1
#property
def is_exhausted(self):
""" Basically a coin toss. """
return random.random() < 0.5
def change_into_super_secret_costume(self):
print("Beauty, eh?")
batman = NarcolepticSuperhero("Batman")
batman.wake_up()
batman.state
machine = GraphMachine(model=batman)
batman.get_graph().draw("test.png", prog='dot')
Install the requirements (Ubuntu 20.10, I tested on it's docker image) and run the script:
$ apt install graphviz graphviz-dev
$ pip3 install transitions graphviz pygraphviz
$ python3 test.py
Check the generated image
You are instantiating a GraphMachine without any states and transitions here:
machine = GraphMachine(model=batman)
You basically reuse NarcolepticSuperhero as a model for that new machine but what you should do instead is changing the NarcolepticSuperhero's machine into a GraphMachine:
# Initialize the state machine
self.machine = GraphMachine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
# [...]
batman.state
# this is not required anymore
# machine = GraphMachine(model=batman)
batman.get_graph().draw("test.png", prog='dot')

How to integrated mender within lk-bootloader base-on Yocto Project

I am new for yocto ,now I use a MTK-demo-board to build a linux-distro base on Yocto. I want to realize OTA by mender followed this tutorial:https://docs.mender.io/1.0/Devices/Integrating-with-U-Boot.
but Mender support u-boot as bootloader by default, the MTK use lk bootloader,Then how to realize this function?
The AP which I used is MT8183,The steps I have done list below:
1. /meta/meta-mediatek/recipes-bsp/lk/lk_2.0.0.0.bb . add follow code:
require recipes-bsp/u-boot/u-boot-mender.inc
PROVIDES += "u-boot"
RPROVIDES_{PN} += "u-boot"
2.cp lk_2.0.0.0 lk-fw-utils_2.0.0.0,and changed the file as behind:
a. delete do_genkey{} function;
b. add EXTRA_OEMAKE_class-target = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${CC} ${CFLAGS} ${LDFLAGS}" V=1'
c. add "oe_runmake env" in function do_compile()
d. add PROVIDES_${PN} = "lk-fw-utils"
RPROVIDES_${PN} = "lk-fw-utils"
DEPENDS += "mtd-utils"
3./build/local.conf,add these code
MENDER_ARTIFACT_NAME = "release-1"
INHERIT += "mender-full"
MACHINE = "aiv8183m1v2"
PREFERRED_VERSION_pn-mender = "1.0.%"
PREFERRED_VERSION_pn-mender-artifact = "1.0.%"
PREFERRED_VERSION_pn-mender-artifact-native = "1.0.%"
DISTRO_FEATURES_append = "systemd"
VIRTUAL-RUNTIME_init_manager = "systemed"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""
IMAGE_FSTYPES = "ext4"
4.execute bitbake-layers add-layer /meta/meta-mender/meta-mender-core
5.bitbake-layers create-layer meta-mylayer,in this layer,I mkdir -p /recipes-mender/mender/files, in directory mender,I touch mender_%.bbappend file as bellow:
FILESEXTARPATHS_prepend := "${THISDIR}/file:"
SRC_URI_append = "file://server.crt"
and put servert.crt in the the file directory.
6.in the mancine.conf(aiv8183m1v2.conf),I have added
PREFERRED_PROVIDER_u-boot-fw-utils = "lk-fw-utils"
PREFERRED_PROVIDER_u-boot = "lk"
IMAGE_INSTALL_append = "kernel-modules"
MENDER_STORAGE_DEVICE = "/dev/mmcblk0"
7./meta-mender/meta-mender-core/classes/mender-full.bbclass
MENDER_FEATURES_ENABLE_append_arm = ""
MENDER_FEATURES_ENABLE_append_aarch64 = ""
the result I expected is the linux can OTA over mender.
But,actual results is the project can't cross build.the log says:
DEBUG: Executing shell function soft_link_to_rootfs
| ln: target ‘mender.bmap’ is not a directory
| WARNING: /home/yewkui/yocto-linux/build/tmp/work/aiv8183m1v2-poky-linux/mtk-image-openmm-aiv/1.0-r0/temp/run.soft_link_to_rootfs.1347217:1 exit 1 from 'ln -nfs mtk-image-openmm-aiv-aiv8183m1v2-20181224064735.rootfs.ext4 mender mender.bmap /home/yewkui/yocto-linux/build/tmp/deploy/images/aiv8183m1v2/rootfs.ext4 mender mender.bmap'
| DEBUG: Python function do_rootfs finished
| ERROR: Function failed: soft_link_to_rootfs (log file is located at /home/yewkui/yocto-linux/build/tmp/work/aiv8183m1v2-poky-linux/mtk-image-openmm-aiv/1.0-r0/temp/log.do_rootfs.1347217)
ERROR: Task (/home/yewkui/yocto-linux/meta/poky/../meta-mediatek-mt8183/recipes-aiv/images/mtk-image-openmm-aiv.bb:do_rootfs) failed with exit code '1'
NOTE: Tasks Summary: Attempted 2392 tasks of which 2391 didn't need to be rerun and 1 failed.
NOTE: Writing buildhistory
Maybe I am wrong at first step,but how to realize the OTA by yocto base on MTK lk-bootloader,please help! thanks a lot!

Examples of using SCons with knitr

Are there minimal, or even larger, working examples of using SCons and knitr to generate reports from .Rmd files?
kniting an cleaning_session.Rmd file from the command line (bash shell) to derive an .html file, may be done via:
Rscript -e "library(knitr); knit('cleaning_session.Rmd')".
In this example, Rscript and instructions are fed to a Makefile:
RMDFILE=test
html :
Rscript -e "require(knitr); require(markdown); knit('$(RMDFILE).rmd', '$(RMDFILE).md'); markdownToHTML('$(RMDFILE).md', '$(RMDFILE).html', options=c('use_xhtml', 'base64_images')); browseURL(paste('file://', file.path(getwd(),'$(RMDFILE).html'), sep=''
In this answer https://stackoverflow.com/a/10945832/1172302, there is reportedly a solution using SCons. Yet, I did not test enough to make it work for me. Essentially, it would be awesome to have something like the example presented at https://tex.stackexchange.com/a/26573/8272.
[Updated] One working example is an Sconstruct file:
import os
environment = Environment(ENV=os.environ)
# define a `knitr` builder
builder = Builder(action = '/usr/local/bin/knit $SOURCE -o $TARGET',
src_suffix='Rmd')
# add builders as "Knit", "RMD"
environment.Append( BUILDERS = {'Knit' : builder} )
# define an `rmarkdown::render()` builder
builder = Builder(action = '/usr/bin/Rscript -e "rmarkdown::render(input=\'$SOURCE\', output_file=\'$TARGET\')"',
src_suffix='Rmd')
environment.Append( BUILDERS = {'RMD' : builder} )
# define source (and target files -- currently useless, since not defined above!)
# main cleaning session code
environment.RMD(source='cleaning_session.Rmd', target='cleaning_session.html')
# documentation of the Cleaning Process
environment.Knit(source='Cleaning_Process.Rmd', target='Cleaning_Process.html')
# documentation of data
environment.Knit(source='Code_Book.Rmd', target='Code_Book.html')
The first builder calls the custom script called knit. Which, in turn, takes care of the target file/extension, here being cleaning_session.html. Likely the suffix parameter is not needed altogether, in this very example.
The second builder added is Rscript -e "rmarkdown::render(\'$SOURCE\')"'.
The existence of $TARGETs (as in the example at Command wrapper) ensures SCons won't repeat work if a target file already exists.
The custom script (whose source I can't retrieve currently) is:
#!/usr/bin/env Rscript
local({
p = commandArgs(TRUE)
if (length(p) == 0L || any(c('-h', '--help') %in% p)) {
message('usage: knit input [input2 input3] [-n] [-o output output2 output3]
-h, --help to print help messages
-n, --no-convert do not convert tex to pdf, markdown to html, etc
-o output filename(s) for knit()')
q('no')
}
library(knitr)
o = match('-o', p)
if (is.na(o)) output = NA else {
output = tail(p, length(p) - o)
p = head(p, o - 1L)
}
nc = c('-n', '--no-convert')
knit_fun = if (any(nc %in% p)) {
p = setdiff(p, nc)
knit
} else {
if (length(p) == 0L) stop('no input file provided')
if (grepl('\\.(R|S)(nw|tex)$', p[1])) {
function(x, ...) knit2pdf(x, ..., clean = TRUE)
} else {
if (grepl('\\.R(md|markdown)$', p[1])) knit2html else knit
}
}
mapply(knit_fun, p, output = output, MoreArgs = list(envir = globalenv()))
})
The only thing, now, necessary is to run scons.