嵌入式应用实例→电子产品量产工具→业务系统能支持配置文件中的command项(能运行command项中的脚本文件)

需求分件

配置文件如下:
在这里插入图片描述
我们现在让要程序能执行command列中的命令,即当某个按钮的状态发生变化时,它能去执行command中的脚本命令。
具体来说,这里当第一个名为led的按钮的状态发生变化时,它能去执行脚本led.sh

脚本文件led.sh

脚本文件led.sh的分析

#!/bin/sh
status=$1
if [ "$status" = "ok" ]
then
echo "led has been tested, it is ok"
fi

if [ "$status" = "err" ]
then
echo "led has been tested, it is fail"
fi

以下是对这个脚本文件的分析。

第一行代码#!/bin/sh

第一行 #!/bin/sh 称为 Shebang(或Sha-bang),它的作用是指明该脚本文件应该使用哪种解释器来执行。

具体解释:

  1. #! 组成的标记

    • #! 是特殊的标记,表示这是一个脚本文件的开头。
  2. /bin/sh

    • 指定了用 /bin/sh 作为解释器来运行该脚本。
    • /bin/sh 通常是指向 Bourne Shell 或其兼容版本(如 Dash)的符号链接。在多数现代 Linux 系统中,/bin/sh 通常较轻量,用于运行简单脚本。
  3. 作用

    • 当你运行这个脚本(例如通过 ./led.sh ok),系统会根据 #!/bin/sh 找到 /bin/sh 程序,然后使用它来解释和执行脚本的内容。
    • 如果没有这个 Shebang 标记,脚本可能无法正确执行,或需要明确指定解释器(例如 sh led.sh ok)。

简而言之#!/bin/sh 指定了该脚本应由 /bin/sh 解释器运行,是 Linux 脚本的标准开头,确保脚本能正确被系统识别和执行。

第二行代码status=$1【理解整个脚本文件功能的关键】

第二行代码 status=$1 的作用是将脚本运行时传递的第一个命令行参数赋值给变量 status

详细说明:
  1. $1

    • 表示脚本运行时传递的第一个参数。
    • 在 Shell 脚本中,$1 是一个 位置参数,代表命令行中的第一个参数。
    • 其他位置参数包括 $2(第二个参数),$3(第三个参数),以此类推。
  2. status=$1

    • $1 的值赋给变量 status
    • status 是一个普通的 Shell 变量,用于保存传递的参数值。
  3. 用法示例
    如果脚本 led.sh 是这样运行的:

    ./led.sh ok
    
    • $1 的值为 ok
    • 变量 status 被赋值为 ok,后续脚本中的 status 都会使用这个值。
示例分析:

以脚本内容为例,运行:

./led.sh ok
  • status 的值是 ok,因此脚本会执行以下分支:
    if [ "$status" = "ok" ]
    then
    echo "led has been tested, it is ok"
    fi
    

如果运行:

./led.sh err
  • status 的值是 err,脚本会执行另一分支:
    if [ "$status" = "err" ]
    then
    echo "led has been tested, it is fail"
    fi
    

脚本文件上板运行

我们要想咱们的程序能执行这个脚本文件,先要测试下这个脚本文件自身是否能够运行…
将脚本文件放于NFS文件的目录support_command

然后开发板上执行下面的运令:

cd /mnt/support_command
chmod +x led.sh
./led.sh ok

结果报下面的错:

-bash: /mnt/support_command/led.sh: /bin/sh^M: bad interpreter: No such file or directory

这是由于Linux和Windows下的换行格式不同造成的,具体的原因和转换方法见:https://blog.youkuaiyun.com/wenhao_ir/article/details/144856144

执行下面的命令进行转换:

dos2unix led.sh

然后再执行:

./led.sh ok

在这里插入图片描述
再执行

./led.sh err

在这里插入图片描述
这样就表示脚本文件led.sh没有问题了。

程序改进

其实就是对输入事件的处理,所以去修改page\main_page.c中的MainPageOnPressed()函数。
修改后的代码如下:

static int MainPageOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
	unsigned int dwColor = BUTTON_DEFAULT_COLOR;
	char name[100];
	char status[100];
	char *strButton;
	char *command_status[3] = {"err", "ok", "percent"};
	int command_status_index = 0;
	char command[1000];
	PItemCfg ptItemCfg;

	strButton = ptButton->name;
	
	/* 1. 对于触摸屏事件 */
	if (ptInputEvent->iType == INPUT_TYPE_TOUCH && ptInputEvent->iPressure != 0)
	{
		/* 1.1 分辨能否被点击 */
		if (GetItemCfgByName(ptButton->name)->bCanBeTouched == 0)
			return -1;

		/* 1.2 修改颜色 */
		ptButton->status = !ptButton->status;
		if (ptButton->status)
		{
			dwColor = BUTTON_PRESSED_COLOR;
			command_status_index = 1;
		}
	}
	else if (ptInputEvent->iType == INPUT_TYPE_NET)
	{
		/* 2. 对于网络事件 */
		
		/* 根据传入的字符串修改颜色 : wifi ok, wifi err, burn 70 */
		sscanf(ptInputEvent->str, "%s %s", name, status);
		if (strcmp(status, "ok") == 0)
		{
			command_status_index = 1;
			dwColor = BUTTON_PRESSED_COLOR;
		}
		else if (strcmp(status, "err") == 0)
		{
			command_status_index = 0;
			dwColor = BUTTON_DEFAULT_COLOR;
		}
		else if (status[0] >= '0' && status[0] <= '9')
		{			
			command_status_index = 2;
			dwColor = BUTTON_PERCENT_COLOR;
			strButton = status;			
		}
		else
			return -1;
	}
	else
	{
		return -1;
	}

	/* 绘制底色 */
	DrawRegion(&ptButton->tRegion, dwColor);

	/* 居中写文字 */
	DrawTextInRegionCentral(strButton, &ptButton->tRegion, BUTTON_TEXT_COLOR);

	/* flush to lcd/web */
	FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);

	/* 执行command */
	ptItemCfg = GetItemCfgByName(ptButton->name);
	if (ptItemCfg->command[0] != '\0')
	{
		sprintf(command, "%s %s", ptItemCfg->command, command_status[command_status_index]);
		system(command);
	}
	
	return 0;
}

支持能运行command项中的脚本文件的相关流程如下:

首先定义一个字符串指针数组command_status

char *command_status[3] = {"err", "ok", "percent"};

这里面存储的就是按钮的三种状态…当然前两个也可作为脚本文件led.sh的第1个参数。

然后对于触摸屏输入事件,当某个按钮的状态值为1时,则进行下面的操作:

		if (ptButton->status)
		{
			dwColor = BUTTON_PRESSED_COLOR;
			command_status_index = 1;
		}

也就是说令command_status_index的值为1,即指向数组command_status中的"ok"

对于网络输入事件,区分三种情况,相关代码如下:

	else if (ptInputEvent->iType == INPUT_TYPE_NET)
	{
		/* 2. 对于网络事件 */
		
		/* 根据传入的字符串修改颜色 : wifi ok, wifi err, burn 70 */
		sscanf(ptInputEvent->str, "%s %s", name, status);
		if (strcmp(status, "ok") == 0)
		{
			command_status_index = 1;
			dwColor = BUTTON_PRESSED_COLOR;
		}
		else if (strcmp(status, "err") == 0)
		{
			command_status_index = 0;
			dwColor = BUTTON_DEFAULT_COLOR;
		}
		else if (status[0] >= '0' && status[0] <= '9')
		{			
			command_status_index = 2;
			dwColor = BUTTON_PERCENT_COLOR;
			strButton = status;			
		}
		else
			return -1;
	}

通过上面就确定了启动脚本时添加的参数是什么了。

然后就是把解析配置文件得到的命令行提取出来,并加上参数构造成一个完整的命令:

	/* 执行command */
	ptItemCfg = GetItemCfgByName(ptButton->name);
	if (ptItemCfg->command[0] != '\0')
	{
		sprintf(command, "%s %s", ptItemCfg->command, command_status[command_status_index]);
		system(command);
	}

在这段代码中:

ptItemCfg = GetItemCfgByName(ptButton->name);

根据按钮名字将配置项取出。
然后利用函数sprintf构造出完整的命令行。
最后调用函数system运行构造出的命令行。

其实很简单…

交叉编译

源码复制进Ubuntu时,然后交叉编译

cd /home/book/mycode/C0016_improve_command
make

将生成的test文件重命名为 support_cmd_test

上板测试

准备好需要的文件和目录
在这里插入图片描述
:
先把配置文件复制到etc目录
【复制前请把用Notepad++转换成UNIX文件换行格式】

cp -ri /mnt/support_command/etc/* /etc/

如果没有事先用Notepad++转换成UNIX换行格式,可以用下面的命令操作:

dos2unix /mnt/support_command/etc/test_gui/gui.conf

进入有可执行程序的目录:

cd /mnt/support_command/

首先把自带的QT的GUI界面关掉【这次就必须关掉了,事实证明不关掉的话会影响后面的测试】:

/etc/init.d/S99myirhmi2 stop

然后把屏幕刷黑

./draw_lcd_black

然后运行咱们的业务系统的可执行程序【后台运行】

./support_cmd_test ./simsun.ttc &

当点击led按钮后,效果如下:

在这里插入图片描述
再点击一次,效果如下:
在这里插入图片描述

附完整工程源码

https://pan.baidu.com/s/1WHDVjZx5Hrl0xYoJkjwQUA?pwd=iu96

内容概要:本文介绍了一个基于多传感器融合的定位系统设计方案,采用GPS、里程计和电子罗盘作为定位传感器,利用扩展卡尔曼滤波(EKF)算法对多源传感器数据进行融合处理,最终输出目标的滤波后位置信息,并提供了完整的Matlab代码实现。该方法有效提升了定位精度与稳定性,尤其适用于存在单一传感器误差或信号丢失的复杂环境,如自动驾驶、移动采用GPS、里程计和电子罗盘作为定位传感器,EKF作为多传感器的融合算法,最终输出目标的滤波位置(Matlab代码实现)机器人导航等领域。文中详细阐述了各传感器的数据建模方式、状态转移与观测方程构建,以及EKF算法的具体实现步骤,具有较强的工程实践价值。; 适合人群:具备一定Matlab编程基础,熟悉传感器原理和滤波算法的高校研究生、科研人员及从事自动驾驶、机器人导航等相关领域的工程技术人员。; 使用场景及目标:①学习和掌握多传感器融合的基本理论与实现方法;②应用于移动机器人、无人车、无人机等系统的高精度定位与导航开发;③作为EKF算法在实际工程中应用的教学案例或目参考; 阅读建议:建议读者结合Matlab代码逐行理解算法实现过程,重点关注状态预测与观测更新模块的设计逻辑,可尝试引入真实传感器数据或仿真噪声环境以验证算法鲁棒性,并进一步拓展至UKF、PF等更高级滤波算法的研究与对比。
内容概要:文章围绕智能汽车新一代传感器的发展趋势,重点阐述了BEV(鸟瞰图视角)端到端感知融合架构如何成为智能驾驶感知系统的新范式。传统后融合与前融合方案因信息丢失或算力需求过高难以满足高阶智驾需求,而基于Transformer的BEV融合方案通过统一坐标系下的多源传感器特征融合,在保证感知精度的同时兼顾算力可行性,显著提升复杂场景下的鲁棒性与系统可靠性。此外,文章指出BEV模型落地面临大算力依赖与高数据成本的挑战,提出“数据采集-模型训练-算法迭代-数据反哺”的高效数据闭环体系,通过自动化标注与长尾数据反馈实现算法持续进化,降低对人工标注的依赖,提升数据利用效率。典型企业案例进一步验证了该路径的技术可行性与经济价值。; 适合人群:从事汽车电子、智能驾驶感知算法研发的工程师,以及关注自动驾驶技术趋势的产品经理和技术管理者;具备一定自动驾驶基础知识,希望深入了解BEV架构与数据闭环机制的专业人士。; 使用场景及目标:①理解BEV+Transformer为何成为当前感知融合的主流技术路线;②掌握数据闭环在BEV模型迭代中的关键作用及其工程实现逻辑;③为智能驾驶系统架构设计、传感器选型与算法优化提供决策参考; 阅读建议:本文侧重技术趋势分析与系统级思考,建议结合实际目背景阅读,重点关注BEV融合逻辑与数据闭环构建方法,并可延伸研究相关企业在舱泊一体等场景的应用实践。
内容概要:本文围绕“考虑灵活性供需不确定性的储能优化配置”展开,基于Matlab代码实现,研究在电力系统中因可再生能源出力波动和负荷变化带来的灵活性供需不确定性条件下,储能系统的优化配置方法。通过构建数学模型,结合智能优化算法(如粒子群、遗传算法等)对储能的位置、容量及运行策略进行联合优化,旨在提升系统对不确考虑灵活性供需不确定性的储能优化配置(Matlab代码实现)定性的适应能力,增强电网稳定性与经济性。文中还涉及多场景仿真分析与概率性建模,以应对风光出力与负荷需求的随机波动,确保优化结果具有鲁棒性和实用性。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、微电网、储能系统设计的工程技术人员;尤其适合研究能源系统优化、不确定性建模与智能算法应用的相关人员。; 使用场景及目标:①解决高比例可再生能源接入背景下电力系统灵活性不足的问题;②指导储能系统在配电网或微电网中的科学规划与配置;③掌握如何在不确定性环境下建立鲁棒优化或随机优化模型,并通过Matlab实现求解;④为综合能源系统、电动汽车集群调度等类似问题提供方法参考。; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注模型构建逻辑、不确定性处理方式(如场景生成、概率分布拟合)以及优化算法的选择与参数设置,同时可扩展学习YALMIP、CPLEX等工具在电力系统优化中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昊虹AI笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值