Blogs

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

史蒂夫布兰望2021年2月14日1条评论

内容

介绍

我们有很多方法可以在嵌入式系统开发,测试,部署,支持和维护期间绊倒自己。

这是我用嵌入式系统制作的愚蠢错误的随机系列帖子中的第一个,以及处理它们的一些策略。我希望通过从我的错误中学习,你可以避开它们。

这可能会节省您的几分钟,小时或几天的浪费时间和挫折,并让您远离墙壁撞击墙壁。

本文以PDF格式提供,便于打印

这个错误

这里的错误是修改,构建,加载和运行一些代码,认为整个过程已经成功,我的修改实际上在目标嵌入式设备上运行,当实际上,我没有注意到,我没有注意到,并且设备不变。然后我开始测试或调试或其他任何事情,它并不像我期望的方式一样。

有变体,例如别人让我的构建运行,或者我从构建服务器或其他系统下载构建。人们之间的建设在支持和调试情况下是常见的;有时我会向供应商客户支持发送我的版本,以便他们尝试重新创建问题。

随着所有这些建造的飞行,很容易弄错。

有时很明显有些东西不对。这是最好的情况。但有时我可能需要运行它一段时间,或者通过一些涉及的其他系统设置作为其中的一部分,并没有意识到,直到我浪费所有时间和努力。

原因

这个错误的一些原因是什么?有时它只是简单的注意力。在急于让事情完成,我错过了一步或忽略了错误消息。

典型的开发人员循环是编辑构建加载运行。任何这些步骤都可能失败。

Some possibilities:
  • 在代码修改期间,我从源控制中拔出了错误的来源。或者我忘记在我的编辑器中保存源文件(是的,我已经完成了!Dohhh!)。
  • 在建设期间,我错过了MultiSep手动过程的一个步骤。或者我没有正确重新配置构建。或者我没有注意到失败的消息,因为我没有从干净的构建开始(所以我可以节省一些时间!),我仍然有足够的构建输出躺在那个Build的其余部分运行,或者至少出现了。
  • 在加载期间(即,闪烁设备,或者任何程序将代码部署到它),我选择了错误的构建图像。或者我没有将其持续到正确的位置,这些位置会导致它自动加载。或者我没有注意到闪存写入失败。
  • 如果设备允许多个可逃副本(例如保留最后已知的备份副本或备用运行时目录),则我运行了错误的图像。

有时这些东西可以毫无意义地结合。例如,我在加载期间没有注意到闪存写入失败,损坏主要可抵押图像,但是当我运行设备时,最后一份已知的副本启用并运行。所以我想我正在运行我的代码。

如果我正在尝试运行别人给我的代码,他们可能已经犯了其中一个错误,而不是意识到这一点。

其中一些是糟糕的构建过程的症状。手动构建程序是真正的红旗。任何需要多一步的东西都是犯错误的机会。甚至是一个简单的 cmake,make 如果在这样做时,组合会出错。

因此,我不断建议,以自动化可以自动化的所有内容。自动化,自动化,自动化!

短割建筑过程以节省时间也是一个常见的原因。这里我可能正在使用良好,自动化的过程,而不是清洁所有输出并进行完整的构建,我做了某种类型的部分或增量构建。我只是想改变这个模块,为什么要花时间从头开始重建一切?

这真的可以是一个时光。直到出现问题。也许自动化程序不会很好地处理这些情况。或者我也许我误解了这个过程,并且没有正确地建立部分。

其中一些错误导致我多年来发展强迫习惯:

  • 编辑源文件后,我对此进行了差异来验证有变化是否存在,我没有在编辑和保存期间以某种方式混淆它们(特别是如果我使用不熟悉的编辑器)。
  • 构建后,我检查源,对象,库和图像文件时间戳和大小。我比较MD5的输出总和,以确保内容实际上不同。我用 Grep. 命令在他们期望改变的情况下寻找他们的字符串。
  • 加载构建后,我可能可以在目标设备上进行类似的东西。

我想要什么可以快速给我证据表明我已经完成了预期的变化,尽可能地交联。

战略

我用来处理这个错误的策略是标记构建,即将“雕刻我的名字”。我想在关键点将其标记为识别它作为自定义构建的信息,由谁建造,使用该分支(或其他源控制标识符),在什么日期和时间。

我喜欢在系统初始化上快速显示标记点,并且在任何可能受到自定义影响的任何不同点。该点是系统特定的,例如在Linux或RTOS引导控制台输出。

我称之为“生活证明”,证明我已成功修改了运行系统以包括我的更改。

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

多年来我一直在做一些手动形式,但我决定写一个脚本来自动化嵌入式Linux的文件修改了。然后,它很容易,快速,可重复,无论我需要多少文件都要标记。该脚本用作可以为不同特定构建自定义的模式。

我特别寻找稳定的模块(即我否则不会作为开发的一部分修改的模块)。这样,我纯粹对这些模块进行了任何更改以进行标记目的。这简化了处理清除标记的脚本的一部分:刚刚恢复这些文件。

这也与我的一般策略符合学习新的代码库或系统,其中我将日志输出与源模块和函数相关联。看看事情在运行时,这是非常有益的。包括源文件引用的日志记录使得更容易,但是一点创意Grepping通常是任何一种方式。

这篇文章的其余部分使用嵌入式Linux,内置于Ubuntu 18.04开发环境中,作为示例。但是,所有概念都可以适用于记录输出的其他嵌入式系统,例如各种RTOS或裸机,以及其他开发环境,例如Windows。

如果系统没有记录怎么办?这需要更具创意标记,并获得非常系统的。与逻辑分析仪(我完成了)可以捕获的独特LED闪烁模式或声音,或GPIO输出序列如何?你有一些检查内存内容的方法吗?您可以使用调试器查找嵌入在代码中的字符串吗?

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

标记嵌入式Linux

嵌入式Linux构建您自定义的 Buildroot. 而且使用 忙盒子 有五个不同的部分:

  • 核心: Linux内核图像在上电时靴子。
  • rootfs: 包含标准文件系统层次结构的根文件系统
  • BusyBox: BusyBox shell,包含命令shell和许多内置命令行实用程序。
  • rootfs覆盖: 您的自定义叠加rootfs。
  • 应用: 您的应用程序特定代码,包括内核空间和用户佩斯。

这些中的每一个都具有可以在引导上登录控制台的组件。进入特定构建的实际组件是自定义的 Buildroot. menuconfigBusybox Menuconfig.

它值得分别标记每个部分,即使您没有自定义它们,以便无论您的构建或加载过程(包括闪烁不同的零件到不同的存储分区),您都可以清楚地识别每个构建的一部分。

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

以下显示从不同部件的早期日志输出,从真实系统中消毒:

核心:  [    0.000000] Linux version 5.4.45 ([email protected]) (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)或用户空间守护进程。

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

部分 文件
核心 init / main.c.
rootfs. 司机/ PPS / PPS.C
覆盖 Buildroot / Board / ... / rootfs_overlay / etc / init.d / s30eth0

rootfs覆盖

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

在这个特定的系统上,它只是一个在掌握Bash脚本的问题 /etc/init.d. 目录,系统执行名称以启动顺序排列的所有脚本。在此示例中,S30ETH0脚本将在S20SOMETHETETHETHETHETHETHETHETHERTHERETHETHERTHERTETHERTHERETHETHERTHERETHETETHERTHERETHETHETHETHETHET之后执行。

覆盖文件是通过标准骨架rootfs的构建组合的本地文件,因此最终订购脚本集是两者的组合,包括覆盖骨架中文件的替代文件。

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

文件到标记

我是如何选择那些特定文件的?正如我所提到的,我想要在系统早期注销的东西,并且是稳定的代码。这些是我使用的特定Linux系统所做的选择。相同的思维过程适用于任何其他类型的系统。

对于内核, init / main.c. 是一个完美的候选人。它是首先要登录控制台,而且我不会作为我工作的一部分触摸它。它内置于内核vmlinux映像中。

对于rootfs,一个合适的文件有点难以找到。一些看起来他们可能是合适的一些东西实际上内在内核中。你怎么知道的?使用此命令流水线搜索构建输出中的VMLinux文件,以获取日志字符串:

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

如果您发现它们,这意味着它们内置于内核。

我想要一些是标准Linux发行版的一部分,它在引导期间从rootfs加载,没有内在内核。所以某种驱动程序,一个lkm(可识别为文件 .ko. 后缀)。这 PPS驾驶员 是Linux发行版的一个很好的通用稳定模块。

如果您拥有自己的自定义LKM,那么其中一个是一个很好的候选人。然后你知道你的内核空间应用部件正在进入。

对于BusyBox,它的分布式和构建方式使其更加涉及自定义。我决定简单,我不需要打扰,因为我有足够的其他证据告诉我这是我的建设。所以我没有调查如何做到这一点。

对于rootfs覆盖,最简单的是添加一个假人 init.d. 除了记录标记的脚本,只能在Init序列中提前订购。然后清除标记只是通过删除文件来完成。其他 init.d. 系统可能需要更多涉及的修改。

对于Userspace应用程序,如果您有一个稳定的守护程序并自动启动,那将是一个很好的候选人。或者如果您的应用程序集包含稳定的命令行程序,则可以修改该稳定命令行。这就是我选择在这里做的,修改其使用输出以添加标记线。

标记线

我想在此表单中添加标记线,以便它们与上面的日志输出同时记录:

[CUSTOMBUILD] part nickname branchname timestamp

在哪里 部分 是系统部分, 昵称 是一些标识开发人员的字符串, 分店名称 是一些字符串,用于标识git分支(或某些其他源控制标识符),以及 时间戳 是组件建造的日期和时间(或标记为 init.d. script).

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

例如,假设我有一个由JIRA票与项目名称MEAR管理的项目,我正在研究一个分支来眨眼,我想要这样的东西:

[    0.000000] Linux version 5.4.45 ([email protected]) (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。我发现了像这样的事情的抨击。我保持脚本非常简单和模块化,便于适应性,没有任何花哨。您的脚本风格可能会有所不同。

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

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

它用 SED. 修改文件以添加标记行。 SED非常强大。这是对理论编辑的非常基本的用法(the -一世 选项)要搜索目标字符串,然后在目标线之后追加行或在目标之前插入它们。

C / C ++源修改

对于C / C ++源代码修改,该脚本利用了编译时字符串连接。这将所有相邻的字符串令牌组合到一个字符串中。

这意味着作为预处理器字符串的令牌实际上会被评估并在编译时将其直接放入字符串中。

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

Linux.修改

脚本写入的确切源代码行非常依赖于系统。即使在系统内,也可能需要不同的线条样式。我也喜欢包含一个注释警告,不要将更改合并到repo中。

对于普通用户空间C / C ++来源,脚本使用 Printf.。它使用标准预定义的宏 __日期____时间__ 捕获构建时间戳。线条如下所示:

// 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__”可能会阻止可重复的构建[-werror =日期时间].

相反,构建生成标题文件 生成/编译 定义宏 UTS_version. 作为构建时间戳,所以脚本包括标题并使用该时间戳。线条如下所示:

// 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");

用于创建shell脚本,脚本使用 回声,并将日期和时间硬编码到标记线中。它还增加了一个 谢邦 线。线条如下所示:

#!/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或守护进程。您可以为您工作的每个板和操作系统创建特定变体,以及构建配置的变体。

您还可以考虑共同的部分并创建一个脚本系列,即引用每个特定构建的函数和定制函数,具体取决于您想要获得的幻想。在这里,我要简单。

#!/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 "Printf.(" $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源,应用程序源和叠加目录(如果有一个)。

路径都相对于回购。我不需要进入repo来源脚本,但我这样做了用来。例如:

[email protected]:~$ cd repos/emb-sys
[email protected]:~/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.

设定标记

设置标记,我使用 标记构建集:

[email protected]:~/repos/emb-sys$ mark-build-set

我可以用 git状态git diff. 要查看修改。现在我做了构建。

寻找标志

构建结束后,查看包含标记的所有文本和二进制文件,以及我使用的实际标记 Mark-Build-Find。它从当前目录开始搜索所有目录。有时候在当地时间报告,一些在UTC中,因此该功能首先显示了两种形式的当前时间。

我已经在这里消除了一些路径,但有趣的是要看到各种标记的文件最终在构建中,源,对象,库,可执行文件,系统映像和最终打包的ELF文件之间的分段和输出位置之间(将闪过电路板)。

其中一些取决于董事会供应商设置包装过程的方式,与其组件和工具相结合。因此,这也很有用,以了解构建和包装过程。

另一件有趣的事情是效果 Squashfs.。供应商将最终rootfs包装为ELF中的SquAshfs映像,这导致压缩文件内容。因此,在预压缩rootfs中发现的大多数字符串都被扰乱,所以找不到 rootfs.squashfs. 文件。但不是所有人。我很惊讶地看到任何标记信息都可以在Squashfs输出中找到,但再次留下了有用的面包屑,以了解构建过程。

然后请注意,在最终的精灵中找到内核和部分rootfs标记 fwprog / bst_bld_lnx_rfs.elf.,提供一定程度的确认,我在闪光到电路板之前我有所需的内容。在所有预先精灵文件中看到具有一致时间戳的标记给了我一些信心(虽然不是保证)那些组件也是如此。时间戳在时间戳中存在一些可变性,因为通过编译各种源文件来进展时间。

[email protected]:~/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");

在目标上运行

在目标板上,我加载此构建并启动后,我收到以下日志记录:

[    0.000000] Linux version 5.4.45 ([email protected]) (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

清算标记

回到我的回购中,清除所有源代码和覆盖标记,然后在我提交任何真实的更改之前,我使用 标记 - 康复:

[email protected]:~/repos/emb-sys$ mark-build-clear

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

因为它快速简便,我可以根据我想要的经常设置和清除标记。

黑客攻击

这只是一堆黑客攻击吗?当然是。但是这是好的方面。

我认为这种类型的东西是“有用的黑客”,因为它既适用于帮助我的工作,也是非常教育的。

这是我所说的“黑客心态”的一部分,它通过积极的探索,学习和应用我所发现的问题,专注于解决问题 在紧密的反馈循环中。

它结合了托马斯爱迪生的经验方法(“天才是一个百分之九十九百分之九十九的汗水”)。 )。

在这种情况下,我学习了关于Linux的一系列细节和我以前被授予的构建过程。我可以应用同样的喧嚣,以了解其他系统。

知识让我更加多样化。我经常发现它在随后的工作中有时很有用。如果我没有经历这个过程,我就不会有这种知识可以帮助。



[]
评论 Conelec.2021年3月12日
软件开发人员的事情是他们大约100年后的机械工程。软件开发人员主要思考2D,这就是为什么其输出结果主要是基于文本的。想象一下,如果机械舞机试图与工具制作人有关,他希望纯粹是一种基于文本的格式。没有立即了解手头的任务。嵌入式世界所需的是,对于一个真正聪明的人来提出3D图形标准的符号和结构。这样有人可以以视觉方式设计他们想要建立的内容,并了解它如何适应现实世界或现有的机械。

要发布回复评论,请单击连接到每个注释的“回复”按钮。发布新的评论(不是回复评论),请在评论的顶部查看“写评论”选项卡。

注册将允许您参加所有相关网站的论坛,并为您提供所有PDF下载。

注册

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

尝试我们偶尔但流行的时事通讯。非常容易取消订阅。
或登录