Blogs

愚蠢的嵌入式系统错误:运行错误的代码

史蒂夫·布拉南2021年2月14日

内容

介绍

在嵌入式系统开发,测试,部署,支持和维护过程中,我们有很多使自己陷入困境的方法。

这是有关我对嵌入式系统犯下的愚蠢错误的随机系列文章中的第一篇,以及处理这些错误的一些策略。我希望通过学习我的错误,可以避免这些错误。

这样可以节省您数分钟,数小时或数天的浪费时间和沮丧感,并使您免于撞到墙上。

这个错误

这里的错误是修改,乐橙云app,加载和运行一些代码,以为整个过程都成功了,而我的修改实际上是在目标嵌入式设备上运行的,而实际上在此过程中出现了一些失败,我没有注意到,并且设备未更改。然后,我开始进行测试或调试或其他任何操作,但它并没有达到我期望的方式。

会有一些变化,例如当其他人让我运行其乐橙云app时,或者从乐橙云app服务器或其他系统下载乐橙云app时。在支持和调试情况下,在人与人之间传递乐橙云app是很常见的。有时,我会将乐橙云app版本发送给供应商客户支持,以便他们可以尝试重新创建问题。

随着所有这些乐橙云app飞来飞去,很容易犯一个错误。

有时很明显,有些事情是不对的。那是最好的情况。但是有时我可能需要运行一段时间,或者将其他系统作为其中一部分进行一些涉及的设置,直到我浪费了所有时间和精力才意识到。

原因

造成此错误的原因有哪些?有时,这只是简单的疏忽。在匆忙完成工作时,我错过了一步,或者忽略了一条错误消息。

典型的开发人员周期是edit-build-load-run。这些步骤都可能失败。

Some possibilities:
  • 在代码修改期间,我从源代码管理中提取了错误的源代码。或者我忘记了将源文件保存在编辑器中(是的,我已经做到了!DOHHH!)。
  • 在乐橙云app期间,我错过了多步骤手动过程的步骤之一。或者我没有正确地重新配置乐橙云app。还是我没有注意到失败消息,并且因为我不是从一个干净的乐橙云app开始的(所以我可以节省一些时间!),所以我仍然有足够的乐橙云app输出,其余乐橙云app都可以运行,或者在最少出现。
  • 在加载期间(即,刷新设备或执行任何程序将代码部署到设备上),我选择了错误的乐橙云app映像。或者我没有将其登台到会导致其自动加载的正确位置。或者我没有注意到闪存写入失败。
  • 如果设备允许多个可运行副本(例如保留最后一个良好的备份副本或备用运行时目录),则我运行了错误的映像。

有时,这些事情会阴险地结合在一起。例如,在加载过程中我没有注意到闪存写入失败,从而损坏了主要的可运行映像,但是当我运行设备时,最后一个已知良好的副本就会启动并运行。所以我想我正在运行我的代码。

如果我试图运行别人提供给我的代码,那么他们可能犯了这些错误之一而没有意识到。

其中一些是乐橙云app过程不佳的症状。手动乐橙云app过程确实是一个危险信号。任何需要不止一个步骤的事情都是犯错的机会。甚至简单 CMake,制作 如果我在做这件事时被打断,组合可能会出错。

因此,我不断提出有关自动化所有可以自动化的建议。自动化,自动化,自动化!

缩短乐橙云app过程以节省时间也是常见的原因。在这里,我可能会使用良好且自动化良好的过程,但是我没有清洗所有输出并进行完整乐橙云app,而是进行了部分或增量乐橙云app。我只想更改此模块,为什么我要花时间从头开始重建所有内容?

确实可以节省时间。直到出错。也许自动化程序不能很好地处理这些情况。或者,也许我误解了该过程,并且没有正确地进行部分乐橙云app。

多年来,其中一些错误使我养成了强迫症的习惯:

  • 编辑源文件后,我对它进行了比较以验证更改是否存在,并且在编辑和保存期间(尤其是如果我使用的是不熟悉的编辑器)我没有以某种方式弄乱它们。
  • 乐橙云app后,我检查源,对象,库和图像文件的时间戳和大小。我比较输出的MD5总和,以确保内容实际上不同。我用 grep 命令在其中查找我期望已更改的字符串。
  • 加载乐橙云app后,我也许可以在目标设备上执行类似的操作。

我想要任何可以迅速为我提供证据的证据,证明我已经完成了预期的更改,并且尽可能做到相互关联。

策略

我用于处理此错误的策略是标记该版本,即“雕刻我的名字”。我想在关键点用信息将其标记为可将其标识为自定义版本的信息,该信息由谁使用哪个分支(或其他源代码管理标识符)在什么日期和时间乐橙云app。

我希望标记点可以在系统初始化时以及可能受到定制影响的任何不同点上快速显示。这些点是特定于系统的,例如在Linux或RTOS引导控制台输出上。

我称其为“生命证明”,证明我已成功修改了正在运行的系统以包含所做的更改。

我的一般策略是寻找早期启动日志行,通过源代码grep来识别记录它们的模块和函数,然后修改这些函数以添加我自己的标记日志行。

多年来,我一直在手动进行某种形式的操作,但是我认为是时候编写一个脚本来自动化嵌入式Linux的文件修改了。然后,无论我需要标记多少文件,它都是容易,快速且可重复的。该脚本用作可以针对不同的特定内部版本进行自定义的模式。

我特别在寻找稳定的模块(即在开发过程中不会修改的模块)。这样,我仅出于标记目的就保留了对那些模块的任何更改。这简化了脚本中处理清除标记的部分:只需还原这些文件。

这也符合我学习新代码库或系统的一般策略,在该策略中,我将日志输出与源模块和功能相关联。看看事情在运行时如何真正融合在一起非常有启发性。包含源文件引用的日志记录使此操作变得更加容易,但是通常无论哪种方式,只要进行一些创造性的grepping操作就足够了。

本文的其余部分以在Ubuntu 18.04开发环境中乐橙云app的嵌入式Linux为例。但是,所有概念都可以适用于记录输出的其他嵌入式系统,例如各种RTOS或裸机,以及其他开发环境,例如Windows。

如果系统没有日志记录怎么办?这需要更多的创意标记,并且非常针对系统。可以使用逻辑分析仪捕获的独特的LED闪烁模式或声音或GPIO输出序列呢(我已经做到了)?您有某种检查内存内容的方法吗?您可以使用调试器查找嵌入在代码中的字符串吗?

标记提供了一种在系统中嵌入证据的方法。然后,您可以在该系统上以任何有意义的方式检索该证据。

标记嵌入式Linux

您用来自定义的嵌入式Linux乐橙云app buildroot 并且使用 忙箱 有五个不同的部分:

  • 核心: 开机时启动的linux内核映像。
  • Rootfs: 包含标准文件系统层次结构的根文件系统
  • 忙箱: busybox外壳程序,其中包含命令外壳程序和许多内置的命令行实用程序。
  • Rootfs叠加层: 您的自定义覆盖图以定制rootfs。
  • 应用: 您的应用程序特定的代码,包括内核空间和用户空间。

每个组件都有可在启动时登录到控制台的组件。特定乐橙云app中使用的实际组件是通过定制的 buildroot菜单配置忙箱 menuconfig.

值得标记每个部分,即使您没有自定义它们,因此无论您使用什么乐橙云app或加载过程(包括将不同的部分刷新到不同的存储分区),您都可以清楚地将每个部分标识为同一乐橙云app的一部分。 。

这有助于识别奇怪的情况,例如最终以新内核但旧rootfs刷新过的设备。当加载过程在准备对rootfs分区编程时遇到错误时,我就发生了这种情况。由于用户空间应用程序进入了rootfs,这意味着我的应用程序代码没有得到更新。

下面显示了从真实系统中清除的不同部分的早期日志输出:

核心:  [    0.000000] Linux version 5.4.45 (sbranam@builder) (gcc version 8.2.1 20180802 (Linaro GCC 8.2-2018.08~dev)) #1 SMP PREEMPT Tue Feb 9 01:14:23 UTC 2021
Overlay: Setup eth0...
Rootfs:  [    1.479273] pps_core: LinuxPPS API ver. 1 registered

在这种情况下,Busybox不会自行记录任何内容,也没有启动可加载应用程序的内核模块(LKM)或用户空间守护程序。

这些是产生这些输出的文件。一些细节也可能因内核版本而异,因此您需要参考所使用的​​特定版本。我的链接转到当前的主站点。

部分 文件
核心 初始化/main.c
Rootfs 驱动程序/pps/pps.c
覆盖 buildroot /板/.../rootfs_overlay/etc/init.d/S30eth0

Rootfs叠加层

overlay部分与其他部分不同,因为它基于init.d脚本。 init.d处理有不同的变体,具有不同程度的复杂性。

在此特定系统上,只需将bash脚本放入 /etc/init.d 目录,并且系统在启动时以词法顺序执行名称以S开头的所有脚本。在此示例中,将在S20something之后和S37something之前执行S30eth0脚本。

覆盖文件是本地文件,由乐橙云app文件与标准框架rootfs组合在一起,因此,有序脚本的最终集合是这两者的组合,包括覆盖替换框架中的文件。

Busybox是在目标上实际执行init.d脚本的东西,因为它具有bash shell。

要标记的文件

我如何选择这些特定文件?正如我所提到的,我希望某些东西能够早日记录在系统中并且是稳定的代码。这些是我为正在使用的特定Linux系统做出的选择。相同的思考过程适用于任何其他类型的系统。

对于内核, 初始化/main.c 是一个完美的候选人。这是登录控制台的第一件事,在我的工作中,我不会去涉及它。它内置在内核vmlinux映像中。

对于rootfs,很难找到合适的文件。看起来合适的某些东西实际上已内置在内核中。你怎么知道的?使用以下命令管道在乐橙云app输出中的vmlinux文件中搜索其日志字符串:

$ strings <pathToOutput>/vmlinux | grep <logString>

如果找到它们,则意味着它们已内置在内核中。

我想要的东西是标准Linux发行版的一部分,它是在引导过程中从rootfs加载的,而不是内置在内核中的。因此,某种驱动程序,即LKM(可识别为带有 .ko 后缀)。这 PPS驱动 是Linux发行版中不错的通用稳定模块。

如果您有自己的自定义LKM,则最好选择其中的一个。然后,您知道您的内核空间应用程序部分正在进入。

对于busybox,它的分发和乐橙云app方式使其更易于自定义。为简单起见,我决定不用打扰,因为我有足够的其他证据证明这是我的想法。所以我没有调查如何做。

对于rootfs覆盖,最简单的方法是添加一个虚拟对象 初始化 除了记录标记外什么都不做的脚本,该标记在初始化序列的早期进行排序。然后,只需删除文件即可清除标记。其他 初始化 系统可能需要更多涉及的修改。

对于用户空间应用程序,如果您有一个稳定且自动启动的守护程序,则它是一个不错的选择。或者,如果您的应用程序集包含稳定的命令行程序,则可以对其进行修改。这就是我在此处选择的操作,修改其用法输出以添加标记线。

标记线

我想以这种形式添加标记行,以便它们与上述日志输出同时记录:

[CUSTOMBUILD] part nickname branchname timestamp

在哪里 部分 是系统的一部分 昵称 是标识开发者的一些字符串, 分店名称 是一些字符串,用于标识git分支(或其他一些源代码管理标识符),并且 时间戳记 是乐橙云app组件的日期和时间(或标记为 初始化 script).

[CUSTOMBUILD]令牌提供了一个搜索目标,我可以在日志文件中grep或在终端输出中进行搜索。

例如,假设我有一个由吉拉车票管理的项目,项目名称为EMB,并且我正在一个分支上闪烁蓝色LED,我想要这样的东西:

[    0.000000] Linux version 5.4.45 (sbranam@builder) (gcc version 8.2.1 20180802 (Linaro GCC 8.2-2018.08~dev)) #1 SMP PREEMPT Tue Feb 9 01:14:23 UTC 2021
[    0.000000] [CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led Tue Feb 9 01:14:23 UTC
...
[CUSTOMBUILD] overlay sbranam EMB-1066/blink-blue-led Mon Oct 12 09:14:44 UTC 2020
Setup eth0...
...
[    1.479272] [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led Tue Feb 9 01:14:23 UTC
[    1.479273] pps_core: LinuxPPS API ver. 1 registered

脚本

当然,有许多方法可以使它自动化。您可以使用Python脚本代替bash。我发现bash足以应付此类事情。我将脚本保持非常简单和模块化,以易于适应,没有花哨的地方。您的脚本风格可能会有所不同。

该特定脚本假定Linux发行版和应用程序代码都已放置在同一个git repo中,因此清除Linux和应用程序标记只是一个恢复文件列表的命令。您的设置可能会有所不同。请注意,并非所有乐橙云app都可能具有rootfs覆盖。

该脚本定义了一组非常易于使用的功能,如下所示: 标记乐橙云app帮助。我可以设置标记,清除它们,重置它们(更新带有硬编码时间戳的文件中的时间戳),并找到所有包含某种形式的标记的文件,无论是文本格式还是二进制格式。

它用 sed 修改文件以添加标记线。 Sed非常强大。这是就地编辑( -一世 选项)以搜索目标字符串,然后将这些行附加在目标行之后,或将其插入到目标之前。

C / C ++源代码修改

对于C / C ++源代码修改,该脚本利用了编译时字符串连接的优势。这会将所有相邻的字符串标记合并为一个字符串。

这意味着作为预处理程序字符串的标记实际上会在编译时被评估并直接放入字符串中。

结果,时间戳宏的实际值作为字符串的一部分存储在对象,库和可执行文件中。然后搜索标记字符串将显示整个标记,包括时间戳。

的Linux修改

脚本编写的确切源代码行非常依赖于系统。即使在系统中,不同的部分可能也需要不同的线型。我还喜欢添加评论警告,不要将更改合并到存储库中。

对于一般的用户空间C / C ++源,脚本使用 打印。它使用标准的预定义宏 __日期____时间__ 捕获乐橙云app时间戳。这些行如下所示:

// DO NOT MERGE, THIS FILE IS MODIFIED FOR MARKED BUILD.
printf( "[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led " __DATE__" " __TIME__"\n");

对于内核源,脚本使用 pr_notice,这是的别名 版画。但是,它不能使用 __日期____时间__,因为它们会导致此错误: 错误:宏“ __DATE__”可能会阻止可复制的乐橙云app[-Werror = date-time].

而是,生成生成头文件 生成/编译 定义宏 UTS_VERSION 作为乐橙云app时间戳,因此脚本包括标头并使用该时间戳。这些行如下所示:

// DO NOT MERGE, THIS FILE IS MODIFIED FOR MARKED BUILD.
#include <generated/compile.h>
pr_notice( "[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led " UTS_VERSION"\n");

为了创建外壳脚本,该脚本使用 回声,并将日期和时间硬编码到标记行中。它还添加了一个 社bang 线。这些行如下所示:

#!/bin/sh
# DO NOT MERGE, THIS FILE IS MODIFIED FOR MARKED BUILD.
echo "[CUSTOMBUILD] overlay sbranam EMB-1066/blink-blue-led" Mon Feb  8 21:19:45 EST 2021

mark-build-myboard-linux.sh

这是脚本, mark-build-myboard-linux.sh。这是我板上的Linux特有的,它当前不启动任何自定义LKM或守护程序。您可以为要处理的每个板卡和操作系统以及乐橙云app配置中的变量创建特定的变量。

您还可以排除共同部分,并创建一整套引用该脚本的脚本,并根据想要获得的幻想为每个特定的乐橙云app量身定制功能。为了简单起见,在这里。

#!/bin/sh

mark-build-usage(){
cat <<END
  Define bash command-line functions for marking source files to indicate this
  is a custom build.

  Usage: source mark-build <userNickname> <branchName> <linuxSrc> <appSrc> [<overlaySrc>]
  Example: source mark-build.sh sbranam EMB-1066/blink-blue-led Linux app overlays

  Parameters:
    <userNickname>  - Nickname string to identify user in markers.
    <branchName>    - Git branch name (or other source control identifier).
    <linuxSrc>      - Path to Linux source.
    <appSrc>        - Path to application source.
    <overlaySrc>    - [Optional] Path to buildroot overlay source.

END
}

MB_NICKNAME=$1
MB_BRANCHNAME=$2
MB_LINUX=$3
MB_APPLICATION=$4
MB_OVERLAY=$5

# Check for required parameters.
if [[ -z "$MB_NICKNAME" || "$1" == "-h" || "$1" == "--help" ]] ; then
    # No arguments provided.
    mark-build-usage
    return 1
elif [[ -z "$MB_APPLICATION" ]] ; then
    # Not all required arguments provided.
    echo
    echo "  ERROR: insufficient arguments."
    echo
    mark-build-usage
    return 1
else
    echo "Ready. Enter mark-build-help for description and usage of command-line functions."
fi

mark-build-help() {
cat <<END
Description:
  Shell functions to set and clear marks for a custom build.

  Marks build with log lines in the form:
    [CUSTOMBUILD] <part> <userNickname> <branchName> <timestamp>

  Where:
    <part>         is the build part (kernel, rootfs, overlay, application)
    <userNickname> identifies the user who performed the build
                   (current value $MB_NICKNAME)
    <branchName>   identifies the git branch or other source control identifier
                   (current value $MB_BRANCHNAME)
    <timestamp>    records the date time when built or marked.

  User shell functions (supports tab-completion):
    mark-build-set - Set the build markers for all parts.
    mark-build-reset - Update build markers.
    mark-build-clear - Clear build markers.
    mark-build-find - Find all marked source and binary files and show their
                      marker lines.
    mark-build-mark-kernel - Set the kernel build marker.
    mark-build-mark-rootfs - Set the rootfs build marker.
    mark-build-mark-overlay - Set the overlay build marker.
    mark-build-mark-application - Set the application build marker.

END
}

###############################################################################
# Main user functions.
###############################################################################

mark-build-set(){
    mark-build-mark-kernel
    mark-build-mark-rootfs
    mark-build-mark-overlay
    mark-build-mark-application
    # Add more mark-build-mark-<part> functions here.
}

mark-build-reset(){
    mark-build-clear
    mark-build-set
}

mark-build-clear(){
    git checkout -- ${MB_GIT_FILES[@]}
    rm ${MB_ADD_FILES[@]}
}

mark-build-find(){
    echo "Current timestamp: `date` (`date -u UTC)"
    echo
    # Find all source and binary files with marker.
    grep -lr CUSTOMBUILD * > /tmp/mark-build-find.txt
    readarray -t FILES < /tmp/mark-build-find.txt
    # Print the marker for each file found.
    for f in ${FILES[@]}; do
        echo $f:
        strings -20 $f | grep CUSTOMBUILD
        echo
    done
    # Cleanup.
    rm /tmp/mark-build-find.txt
}

# To add more mark-build-mark-<part> functions, follow the pattern in
# these functions. You can also add more files to a function, but
# it's usually sufficient to mark one file per part.
mark-build-mark-kernel(){
    mark-build-mark-linux-ksrc 0 kernel
}

mark-build-mark-rootfs(){
    mark-build-mark-linux-ksrc 1 rootfs
}

mark-build-mark-application(){
    mark-build-mark-linux-usrc 2 application
}

mark-build-mark-overlay(){
    mark-build-write-sh-script 0 overlay
}

###############################################################################
# Constants.
###############################################################################

MB_WARNING="DO NOT MERGE, THIS FILE IS MODIFIED FOR MARKED BUILD."
MB_C_WARNING="// $MB_WARNING"
MB_SH_WARNING="# $MB_WARNING"
MB_LNX_INCLUDE="#include <generated/compile.h>"

# Tailor the following lists to your system.

# Git repo files to mark.
MB_GIT_FILES=(
    $MB_LINUX/init/main.c
    $MB_LINUX/drivers/pps/pps.c
    $MB_APPLICATION/my_app/myapp.c
    # Add more git repo files here.
)

# Git repo file sed match targets, "a" for append, "i" for insert.
MB_GIT_SED_MATCHES=(
    "/linux_banner/a"
    "/LinuxPPS API/i"
    "/Usage:/i"
    # Add more repo file sed match targets here.
)

# Files to add.
MB_ADD_FILES=(
    $MB_OVERLAY/overlay/etc/init.d/S29custombuild
    # Add more files here.
)

###############################################################################
# Helper functions.
###############################################################################

# Format the source code line to mark a file.
mark-build-get-marker-line(){
    local start=$1
    local part=$2
    local separator=$3
    local timestamp=$4
    local end=$5
    local marker="[CUSTOMBUILD] $part $MB_NICKNAME $MB_BRANCHNAME$separator"
    MB_COMMAND="$start \"$marker\" $timestamp$end"
}

# Mark a Linux kernelspace source file.
mark-build-mark-linux-ksrc(){
    local file=${MB_GIT_FILES[$1]}
    local match=${MB_GIT_SED_MATCHES[$1]}
    local part=$2
    mark-build-get-marker-line "pr_notice(" $part " " UTS_VERSION "\"\\\\n\");"
    sed -i "$match $MB_C_WARNING\n$MB_LNX_INCLUDE\n$MB_COMMAND" $file
}

# Mark a Linux userspace source file.
mark-build-mark-linux-usrc(){
    local file=${MB_GIT_FILES[$1]}
    local match=${MB_GIT_SED_MATCHES[$1]}
    local part=$2
    # The extra space between date and time means it's easier just
    # to build the command in 2 steps.
    mark-build-get-marker-line "打印(" $part " " __DATE__
    MB_COMMAND=$MB_COMMAND"\" \" __TIME__\"\\\\n\");"
    sed -i "$match $MB_C_WARNING\n$MB_COMMAND" $file
}

# Add a marker shell script.
mark-build-write-sh-script(){
    file=${MB_ADD_FILES[$1]}
    part=$2
    mark-build-get-marker-line echo $part "" "`date`"
    cat > $file <<EOF
#!/bin/sh
$MB_SH_WARNING
$MB_COMMAND
EOF
    chmod +x $file
}

使用脚本

采购脚本

在我处理存储库的shell会话中,我提供脚本来定义Shell函数,将用户名指定为昵称,git分支(或其他没有中间空格的源代码控制引用)以及相对路径Linux源代码,应用程序源代码和覆盖目录(如果有的话)。

这些路径都是相对于仓库的。我不需要进入回购源来获取脚本,但是我确实要使用这些功能。例如:

sbranam@ubuntu:~$ cd repos/emb-sys
sbranam@ubuntu:~/repos/emb-sys$ source ~/mark-build-myboard-linux.sh $USER EMB-1066/blink-blue-led linux-5.4 my-app buildroot/board/myboard/common
Ready. Enter mark-build-help for description and usage of command-line functions.

设置标记

要设置标记,我使用 标记乐橙云app集:

sbranam@ubuntu:~/repos/emb-sys$ mark-build-set

我可以用 git状态git diff 查看修改。现在,我进行乐橙云app。

寻找标记

乐橙云app结束后,要查看包含标记的所有文本和二进制文件以及实际标记,我使用 标记建立查找。它搜索从当前目录开始的所有目录。有些时间以当地时间报告,有些时间以UTC报告,因此该功能首先以两种形式显示当前时间。

我已经在这里清理了一些路径,但是很有趣的是,在源,对象,库,可执行文件,系统映像以及最终打包的ELF文件的暂存和输出位置之间,看到了各种标记文件最终在乐橙云app中的位置。闪烁到板上)。

其中一些取决于董事会供应商设置封装过程的方式,以及其组件和工具。因此,这对于了解乐橙云app和打包过程也很有用。

另一个值得注意的事情是 西葫芦。供应商在ELF中将最终的rootfs打包为squashfs映像,从而导致文件内容压缩。因此,在预压缩的rootfs中找到的大多数字符串都会被打乱,因此在 rootfs.squashfs 文件。但不是所有人。令我惊讶的是,在squashfs输出中可以找到任何标记信息,但这又一次为学习乐橙云app过程留下了有用的面包屑。

然后注意,在最终的ELF中找到了内核和部分rootfs标记 fwprog / bst_bld_lnx_rfs.elf,可以在将其闪现到板上之前提供一定程度的确认,以确保我拥有所需的内容。在所有ELF之前的文件中看到带有一致时间戳记的标记,使我确信(尽管不能保证)这些组件也包含在其中。由于编译各种源文件需要花费时间,因此时间戳中存在一些可变性。

sbranam@ubuntu:~/repos/emb-sys$ mark-build-find
Current timestamp: Mon Feb  8 21:43:01 EST 2021 (Tue Feb  9 02:43:01 UTC)

buildroot/board/myboard/common/overlay/etc/init.d/S29custombuild:
echo "[CUSTOMBUILD] overlay sbranam EMB-1066/blink-blue-led" Mon Feb  8 21:19:45 EST 2021

fwprog/.temp/lnx.fw:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

fwprog/.temp/lnx.bin:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

fwprog/.temp/rfs.fw:
[CUSTOMBUILD] rootfs sbraTW

fwprog/rfs.elf:
[CUSTOMBUILD] rootfs sbraTW

fwprog/lnx.elf:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

fwprog / bst_bld_lnx_rfs.elf:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021
[CUSTOMBUILD] rootfs sbraTW

fwprog/devfw/rfs.devfw:
[CUSTOMBUILD] rootfs sbraTW

fwprog/devfw/lnx_rfs_dtb.devfw:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021
[CUSTOMBUILD] rootfs sbraTW

fwprog/devfw/lnx.devfw:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

linux-5.4/init/main.c:
pr_notice( "[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led " UTS_VERSION"\n");

linux-5.4/drivers/pps/pps.c:
pr_notice( "[CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led " UTS_VERSION"\n");

output.oem/myboard/build/my-app/myapp.o:
[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led Feb  9 2021 02:26:21

output.oem/myboard/build/my-app/myapp.c:
printf( "[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led " __DATE__" " __TIME__"\n");

output.oem/myboard/build/my-app/myapp:
[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led Feb  9 2021 02:26:21

output.oem/myboard/build/linux-custom/init/main.o:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/vmlinux.o:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/.tmp_vmlinux.kallsyms1:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/drivers/pps/pps_core.o:
5pps_core: [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/drivers/pps/pps.o:
5pps_core: [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/drivers/pps/pps_core.ko:
5pps_core: [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/vmlinux:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/.tmp_vmlinux.kallsyms2:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/build/linux-custom/arch/arm64/boot/Image:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/images/rootfs.squashfs:
[CUSTOMBUILD] rootfs sbraTW

output.oem/myboard/images/Image:
5[CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

output.oem/myboard/target/etc/init.d/S29custombuild:
echo "[CUSTOMBUILD] overlay sbranam EMB-1066/blink-blue-led" Mon Feb  8 21:19:45 EST 2021

output.oem/myboard/target/usr/bin/example:
[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led Feb  9 2021 02:26:21

output.oem/myboard/target/lib/modules/5.4.45/kernel/drivers/pps/pps_core.ko:
5pps_core: [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021

my-app/myapp.c:
printf( "[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led " __DATE__" " __TIME__"\n");

在目标上奔跑

在目标板上,加载此乐橙云app并启动后,得到以下日志:

[    0.000000] Linux version 5.4.45 (sbranam@builder) (gcc version 8.2.1 20180802 (Linaro GCC 8.2-2018.08~dev)) #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021
[    0.000000] [CUSTOMBUILD] kernel sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021
...
[CUSTOMBUILD] overlay sbranam EMB-1066/blink-blue-led Mon Feb 8 21:19:45 EST 2021
Setup eth0...
...
[    1.872227] pps_core: [CUSTOMBUILD] rootfs sbranam EMB-1066/blink-blue-led #1 SMP PREEMPT Tue Feb 9 02:31:01 UTC 2021
[    1.882901] pps_core: LinuxPPS API ver. 1 registered

当我寻找应用程序时,我在rootfs中找到它。当我运行它并触发用法输出时,我看到了标记。

/ # which myapp
/usr/bin/myapp
/ # myapp -h
[CUSTOMBUILD] application sbranam EMB-1066/blink-blue-led Feb  9 2021 02:26:21
Usage: myapp [Options]
Options:
        -h: help
        -d: run as daemon mode
        -v: enable more verbose debug messages

清除标记

回到我的仓库中,要在执行任何实际更改之前清除所有源代码和覆盖标记,我使用 标记建立清晰:

sbranam@ubuntu:~/repos/emb-sys$ mark-build-clear

再一次,我可以使用 git状态 验证修改已不存在。

因为它既快速又容易,所以我可以随意设置和清除标记。

骇客

这仅仅是一群黑客吗?当然是。但是这是好的方面。

我将这种类型的事情称为“有用的黑客”,因为它既有帮助我工作的功能目的,又很有教育意义。

这就是我所谓的“黑客心态”的一部分,该思想侧重于通过积极探索,学习和运用我发现的内容来解决问题 在紧密的反馈循环中。

它结合了托马斯·爱迪生(Thomas Edison)的经验方法(“天才是百分之一的灵感和百分之九十九的出汗。”)和尼古拉·特斯拉(Nikola Tesla)的分析方法(“仅需一点理论和计算就可以为他节省百分之九十的劳动。” )。

在这种情况下,我学到了很多有关Linux的细节,以及以前认为理所当然的乐橙云app过程。我可以将同样有用的技巧应用于其他系统的学习。

这些知识使我更加灵活。我经常发现它在后续工作中非常有用。如果我不经历那个过程,那么我将没有可用的知识来帮助您。


要发布对评论的回复,请单击每个评论所附的“回复”按钮。要发布新评论(而不是回复评论),请查看评论顶部的“写评论”标签。

注册后,您可以参加所有相关网站上的论坛,并获得所有pdf下载的访问权限。

注册

我同意 使用条款隐私政策.

试试我们偶尔但很受欢迎的时事通讯。非常容易退订。
或登录