diff --git a/smartperf_device/device_command/README_zh.md b/smartperf_device/device_command/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..296a1734f31e158b29d373e924b01a1212768ea5
--- /dev/null
+++ b/smartperf_device/device_command/README_zh.md
@@ -0,0 +1,256 @@
+## 简介
+# SP_daemon
+
+- OpenHarmony性能测试工具SmartPerf 命令行版本,可采集CPU、GPU、Temperature、Power、应用RAM、FPS等指标,通过设置采集指标,对采集数据进行实时打印、导出csv。
+
+- 性能较差或无屏幕设备请使用命令行版本,带屏幕的设备且性能较好的设备推荐使用[UI版本](../device_ui/README_zh.md)。
+
+## 代码目录
+```
+developtools/smartperf_host/smartperf_device/device_command
+├── include # 头文件目录
+├── BUILD.gn # SP_daemon bin打包配置文件
+├── ByTrace.cpp # trace抓取代码文件
+├── Capture.cpp # 截图代码文件
+├── CPU.cpp # CPU采集代码文件
+├── DDR.cpp # DDR采集代码文件
+├── FPS.cpp # FPS采集代码文件
+├── GPU.cpp # GPU采集代码文件
+├── GpuCounter.cpp # GpuCounter采集代码文件
+├── GpuCounterCallback.cpp # GpuCounterCallback采集代码文件
+├── Network.cpp # 网络上下行速率采集代码文件
+├── Power.cpp # 功耗采集代码文件
+├── RAM.cpp # 内存采集代码文件
+├── smartperf_command.cpp # 程序执行文件
+├── smartperf_main.cpp # 程序入口文件
+├── sp_log.cpp # log文件
+├── sp_factory.cpp # 采集工厂文件
+├── sp_server_socket.cpp # 与SmartPerf hap通讯代码文件
+├── sp_task.cpp # 与SmartPerf editor通讯代码文件
+├── sp_utils.cpp # 工具类
+├── Temperature.cpp # 温度采集代码文件
+```
+
+## 约束条件
+ SmartPerf应用在3.2系统版本后开始预制使用。
+
+## 功能特性
+
+**1. 参数说明**
+**1.1 基础采集命令参数**
+
+| 命令 | 功能 |必选|
+| :-----| :--------------------- |:-----|
+| -N | 设置采集次数(一秒采集一次)|是|
+| -PKG | 设置包名 | 否|
+| -c | 采集cpu的频点和使用率,设置应用包名:采集整机和应用CPU信息,不设置应用包名:采集整机CPU信息 | 否|
+| -g | 采集gpu的频点和负载信息 |否|
+| -f | 采集指定应用的fps,必须设置应用包名 |否|
+| -profilerfps | 采集当前界面fps |否|
+| -t | 采集电池等温度 |否|
+| -p | 采集电流 |否|
+| -r | 采集内存,设置应用包名:采集整机和应用内存信息,不设置应用包名:采集整机内存信息 |否|
+| -snapshot | 屏幕截图 |否|
+| -net | 采集网络速率 |否|
+| -VIEW | 设置图层,需要先获取应用图层名 |否|
+| -screen | 采集屏幕分辨率和刷新率 |否|
+| -d | 采集DDR |否|
+| -sections| 设置分段采集 |否|
+
+**1.2 启停采集命令参数**
+| 命令 | 功能 |必选|
+| :-----| :--------------------- |:-----|
+| -start | 开始采集,该命令后可添加基础采集命令 |是|
+| -stop | 结束采集,执行后会生成采集报告 |是|
+---
+
+**2. 使用方式**
+1)目前命令行版本已系统预制,可以进入shell,执行SP_daemon --help查看。
+
+```bash
+C:\Users\test>hdc_std shell
+# SP_daemon --help
+OpenHarmony performance testing tool SmartPerf command-line version
+Usage: SP_daemon
+options:
+ -N set the collection times(default value is 0) range[1,2147483647], for example: -N 10
+ -PKG set package name, must add, for example: -PKG ohos.samples.ecg
+ -c get device CPU frequency and CPU usage, process CPU usage and CPU load ..
+ -g get device GPU frequency and GPU load
+ -f get app refresh fps(frames per second) and fps jitters and refreshrate
+ -profilerfps get refresh fps and timestamp
+ -sections set collection time period(using with profilerfps)
+ -t get remaining battery power and temperature..
+ -p get battery power consumption and voltage
+ -r get process memory and total memory
+ -snapshot get screen capture
+ -net get uplink and downlink traffic
+ -start collection start command
+ -stop collection stop command
+ -VIEW set layler, for example: -VIEW DisplayNode
+ -OUT set csv output path.
+ -d get device DDR information
+ -ci get cpu instructions and cycles
+ -screen get screen resolution
+ -deviceinfo get device information
+ -server start a process to listen to the socket message of the start and stop commands
+ -clear clear the process ID
+ -ohtestfps used by the vilidator to obtain the fps, the collection times can be set
+ -editorServer start a process to listen to the socket message of the editor
+ -recordcapacity get the battery level difference
+ --version get version
+ --help get help
+ -editor scenario-based collection identifier, parameter configuration items can be added later
+ responseTime get the page response delay after an application is operated
+ completeTime get the page completion delay after an application is operated
+ fpsohtest used by the vilidator to obtain the fps
+ example1:
+ SP_daemon -N 20 -c -g -t -p -r -net -snapshot -d
+ SP_daemon -N 20 -PKG ohos.samples.ecg -c -g -t -p -f -r -net -snapshot -d
+ SP_daemon -start -c
+ SP_daemon -stop
+ example2: These parameters need to be used separately
+ SP_daemon -screen
+ SP_daemon -deviceinfo
+ SP_daemon -server
+ SP_daemon -clear
+ SP_daemon -ohtestfps
+ SP_daemon -editorServer
+ SP_daemon -recordcapacity
+ example3: These parameters need to be used separately
+ SP_daemon -editor responseTime ohos.samples.ecg app name
+ SP_daemon -editor completeTime ohos.samples.ecg app name
+ SP_daemon -editor fpsohtest
+
+command exec finished!
+#
+```
+2)执行示例命令:SP_daemon -N 20 -PKG ohos.samples.ecg -c -g -t -p -f -r -d -net -snapshot
+```
+----------------------------------Print START------------------------------------
+order:0 timestamp=1710916175201
+order:1 ProcAppName=ohos.samples.ecg
+order:2 ProcCpuLoad=0.0015567
+order:3 ProcCpuUsage=0.000000
+order:4 ProcId=18510
+order:5 ProcSCpuUsage=0.000000
+order:6 ProcUCpuUsage=0.000000
+order:7 cpu0Frequency=418000
+order:8 cpu0Usage=0.000000
+order:9 cpu0idleUsage=0.000000
+order:10 cpu0ioWaitUsage=0.000000
+order:11 cpu0irqUsage=0.000000
+order:12 cpu0niceUsage=0.000000
+order:13 cpu0softIrqUsage=0.000000
+order:14 cpu0systemUsage=0.000000
+order:15 cpu0userUsage=0.000000
+...
+order:115 gpuFrequency=279000000
+order:116 gpuload=61.000000
+order:117 Battery=28.000000
+order:118 shell_back=31.529000
+order:119 shell_frame=30.529000
+order:120 shell_front=30.548000
+order:121 soc_thermal=49.624000
+order:122 system_h=30.150000
+order:123 currentNow=278
+order:124 voltageNow=4250532
+order:125 fps=3
+order:126 fpsJitters=881659966;;108846354;;8289583
+order:127 refreshrate=120
+order:128 memAvailable=6354252
+order:129 memFree=5971776
+order:130 memTotal=11530092
+order:131 pss=78045
+order:132 arktsHeapPss=13394
+order:133 gpuPss=280
+order:134 graphicPss=0
+order:135 heapAlloc=48080
+order:136 heapFree=2576
+order:137 heapSize=50788
+order:138 nativeHeapPss=41897
+order:139 privateClean=67232
+order:140 privateDirty=12848
+order:141 sharedClean=76224
+order:142 sharedDirty=12848
+order:143 stackPss=1096
+order:144 swap=0
+order:145 swapPss=0
+order:146 ddrFrequency=1531000000
+order:147 networkDown=0
+order:148 networkUp=0
+order:149 capture=data/local/tmp/capture/screenCap_1711190737580.png
+
+
+----------------------------------Print END--------------------------------------
+----------------------------------Print START------------------------------------
+order:0 timestamp=1710916175201
+order:1 ProcAppName=ohos.samples.ecg
+order:2 ProcCpuLoad=0.001379
+order:3 ProcCpuUsage=0.008162
+order:4 ProcId=18510
+order:5 ProcSCpuUsage=0.008162
+order:6 ProcUCpuUsage=0.000000
+order:7 cpu0Frequency=418000
+order:8 cpu0Usage=16.346154
+order:9 cpu0idleUsage=83.653846
+order:10 cpu0ioWaitUsage=0.961538
+order:11 cpu0irqUsage=4.807692
+order:12 cpu0niceUsage=0.000000
+order:13 cpu0softIrqUsage=0.000000
+order:14 cpu0systemUsage=5.769231
+order:15 cpu0userUsage=4.807692
+...
+order:115 gpuFrequency=279000000
+order:116 gpuload=61.000000
+order:117 Battery=28.000000
+order:118 shell_back=31.529000
+order:119 shell_frame=30.529000
+order:120 shell_front=30.548000
+order:121 soc_thermal=47.810000
+order:122 system_h=30.200000
+order:123 currentNow=303
+order:124 voltageNow=4251570
+order:125 fps=12
+order:126 fpsJitters=122794860;;8372396;;8375521;;8448958;;16691667;;8357812;;8367188;;8364062;;8383855;;8514062;;8238542;;849062
+order:127 refreshrate=120
+order:128 memAvailable=6370048
+order:129 memFree=5990136
+order:130 memTotal=11530092
+order:131 pss=78217
+order:132 arktsHeapPss=13586
+order:133 gpuPss=280
+order:134 graphicPss=0
+order:135 heapAlloc=48156
+order:136 heapFree=2648
+order:137 heapSize=50780
+order:138 nativeHeapPss=41877
+order:139 privateClean=67404
+order:140 privateDirty=2920
+order:141 sharedClean=76224
+order:142 sharedDirty=12848
+order:143 stackPss=1096
+order:144 swap=0
+order:145 swapPss=0
+order:146 ddrFrequency=1531000000
+order:147 networkDown=0
+order:148 networkUp=0
+order:149 capture=data/local/tmp/capture/screenCap_1711190738589.png
+
+command exec finished!
+#
+----------------------------------Print END--------------------------------------
+```
+3)执行完毕后会在data/local/tmp生成data.csv文件,每次执行命令覆盖写入,可导出到本地查看。
+```bash
+c:\Users\xxx>hdc file recv data/local/tmp/data.csv D:\
+[I][2024-03-20 18:27:07] HdcFile::TransferSummary success
+FileTransfer finish, Size:7306, File count = 1, time:377ms rate:19.38kB/s
+---
+
+## 发布版本
+
+**3.2.0.0版本发布内容:预制SP_daemon bin文件,支持以下功能:**
+1. 支持RK3568、Hi3516。
+2. 支持Shell启动。
+3. 支持采集整机CPU、GPU、POWER、TEMPERATURE、应用的FPS、RAM、CPU等
\ No newline at end of file
diff --git a/smartperf_device/device_command/heartbeat.cpp b/smartperf_device/device_command/heartbeat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70f270235cd5efdc0a910107adacf256c516ff27
--- /dev/null
+++ b/smartperf_device/device_command/heartbeat.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "include/heartbeat.h"
+#include "include/sp_utils.h"
+#include "sp_log.h"
+#include "include/startup_delay.h"
+#include "include/common.h"
+namespace OHOS {
+namespace SmartPerf {
+void Heartbeat::KillSpId()
+{
+ std::string str;
+ std::string resultPid;
+ std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP);
+ SPUtils::LoadCmd(cmd, resultPid);
+ std::vector vec;
+ std::string token;
+ size_t pos = resultPid.find(' ');
+ do {
+ token = resultPid.substr(0, pos);
+ vec.push_back(token);
+ resultPid.erase(0, pos + 1);
+ } while ((pos = resultPid.find(' ')) != std::string::npos);
+ if (vec.size() > 0) {
+ std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
+ for (size_t i = 0; i < vec.size(); i++) {
+ SPUtils::LoadCmd(killCmd + vec[i], str);
+ }
+ }
+}
+
+void Heartbeat::HeartbeatRule()
+{
+ while (isrunning) {
+ auto end = std::chrono::steady_clock::now();
+ auto duration = std::chrono::duration_cast(end - updateStart).count();
+ if (duration > timeout) {
+ LOGD("Socket disconnected!");
+ KillSpId();
+ }
+ sleep(checkMessageTime);
+ }
+}
+
+void Heartbeat::UpdatestartTime()
+{
+ std::unique_lock lock(mtx);
+ updateStart = std::chrono::steady_clock::now();
+}
+
+}
+}
\ No newline at end of file
diff --git a/smartperf_device/device_command/smartperf_main.cpp b/smartperf_device/device_command/smartperf_main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..167dc370c3d6cc9a79372bd4b74e45c633b75d18
--- /dev/null
+++ b/smartperf_device/device_command/smartperf_main.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include "unistd.h"
+#include
+#include
+#include "include/smartperf_command.h"
+#include "include/editor_command.h"
+#include "include/FPS.h"
+#include "include/client_control.h"
+#include "include/sp_utils.h"
+#include "include/sp_log.h"
+#include "include/common.h"
+#include "parameters.h"
+#include "task_manager.h"
+#include "include/startup_delay.h"
+
+constexpr const char *VERSION_TYPE = "const.logsystem.versiontype";
+static std::string GetOptions(const std::vector &argv)
+{
+ std::string str = "";
+ std::string strFlag;
+ bool isFill = false;
+ for (std::size_t i = 0; i < argv.size(); i++) {
+ if (!isFill) {
+ strFlag = argv[i];
+ if (strFlag.find("SP_daemon") != std::string::npos) {
+ isFill = true;
+ }
+ } else {
+ str += argv[i];
+ if (i + 1 != argv.size()) {
+ str += " ";
+ }
+ }
+ }
+ return str;
+}
+static void KeyInsert(std::set &keysMap)
+{
+ keysMap.insert("editor");
+ keysMap.insert("profilerfps");
+ keysMap.insert("start");
+ keysMap.insert("stop");
+ keysMap.insert("screen");
+ keysMap.insert("clear");
+ keysMap.insert("clearAll");
+ keysMap.insert("server");
+ keysMap.insert("sections");
+ keysMap.insert("deviceinfo");
+ keysMap.insert("ohtestfps");
+ keysMap.insert("editorServer");
+ keysMap.insert("deviceServer");
+ keysMap.insert("recordcapacity");
+}
+static bool g_checkCmdParam(std::vector &argv, std::string &errorInfo)
+{
+ std::string str = GetOptions(argv);
+ std::set keys; // Includes three parts "SP_daemon" CommandType and CommandHelp
+ if (str.empty()) {
+ return true;
+ }
+ // 'help' and 'version' start with "--" and are processed separately
+ if (str.find("--help") != std::string::npos || str.find("--version") != std::string::npos) {
+ std::vector out;
+ OHOS::SmartPerf::SPUtils::StrSplit(str, "-", out);
+ if (out.size() != 1) {
+ errorInfo = "--help and --version cannot be used together with other options";
+ return false;
+ } else {
+ return true;
+ }
+ }
+ if (str.find("-PKG") != std::string::npos && str.find("-PID") != std::string::npos) {
+ errorInfo = "-PKG and -PID cannot be used together with";
+ return false;
+ }
+ KeyInsert(keys);
+ // editor 与 device 的拉起命令与 token 一起加入白名单
+ if (argv[1].find("editorServer:") != std::string::npos ||
+ argv[1].find("deviceServer:") != std::string::npos
+ ) {
+ keys.insert(argv[1].substr(1).c_str());
+ }
+ for (auto& a : OHOS::SmartPerf::COMMAND_MAP) {
+ keys.insert(a.first.substr(1)); // No prefix required '-'
+ }
+
+ /* ************The command line for the following parameters is not implemented****************** */
+ keys.erase("f1");
+ keys.erase("f2");
+ keys.erase("fl");
+ keys.erase("ftl");
+ return OHOS::SmartPerf::SPUtils::VeriyParameter(keys, str, errorInfo);
+}
+
+static void SocketStopCommand()
+{
+ OHOS::SmartPerf::ClientControl cc;
+ cc.SocketStop();
+}
+
+static void RecordCapacity()
+{
+ const std::string capacityRmPath = "/sys/class/power_supply/Battery/capacity_rm";
+ const std::string rkCapacityRmPath = "/data/service/el0/battery/battery/capacity";
+ const std::string capacitySavePath = "/data/local/tmp/powerLeftRecord.csv";
+ std::string capacityString;
+ std::ifstream infile(capacitySavePath.c_str());
+ if (infile.is_open()) {
+ std::stringstream buffer;
+ int capacityLine = 0;
+ std::string line;
+ const int MAX_RECORD_COUNT = 100;
+ buffer << infile.rdbuf();
+ capacityString = buffer.str();
+ infile.close();
+
+ while (std::getline(buffer, line)) {
+ capacityLine++;
+ }
+ if (capacityLine == MAX_RECORD_COUNT) {
+ std::size_t pos = capacityString.find('\n');
+ if (pos != std::string::npos) {
+ capacityString = capacityString.substr(pos + 1);
+ }
+ }
+ }
+ std::ofstream outFile(capacitySavePath.c_str(), std::ios::out | std::ios::trunc);
+ if (!outFile.is_open()) {
+ std::cout << "Error opening capacity file!" << std::endl;
+ return;
+ }
+ std::string recordPower;
+ auto recordTime = std::to_string(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
+ OHOS::SmartPerf::SPUtils::LoadFile(capacityRmPath, recordPower);
+ if (recordPower.empty()) {
+ std::string rkRecordPower;
+ int maxBat = 60;
+ OHOS::SmartPerf::SPUtils::LoadFile(rkCapacityRmPath, rkRecordPower);
+ recordPower = std::to_string(OHOS::SmartPerf::SPUtilesTye::StringToSometype(rkRecordPower) * maxBat);
+ }
+ std::cout << "recordTime: " << recordTime << std::endl << "recordPower: " << recordPower << std::endl;
+ capacityString += recordTime + "," + recordPower;
+ outFile << capacityString << std::endl;
+ if (outFile.fail()) {
+ const int bufSize = 256;
+ char buf[bufSize] = { 0 };
+ std::cout << "Error writing capacity failed:" << strerror_r(errno, buf, bufSize) << std::endl;
+ }
+ outFile.close();
+}
+
+static int ProcessSpecificParameter(int argc, char *argv[], std::vector &vec)
+{
+ if (argc > 1 && strcmp(argv[1], "-editor") == 0) {
+ OHOS::SmartPerf::EditorCommand(argc, vec);
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-profilerfps") == 0) {
+ OHOS::SmartPerf::FPS::GetInstance().GetFPS(vec);
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-start") == 0) {
+ OHOS::SmartPerf::SPUtils::KillStartDaemon();
+ std::string startStr = "";
+ std::string endStr = "";
+ std::string pidCmd = OHOS::SmartPerf::CMD_COMMAND_MAP.at(OHOS::SmartPerf::CmdCommand::PIDOF_SP);
+ OHOS::SmartPerf::SPUtils::LoadCmd(pidCmd, startStr);
+ OHOS::SmartPerf::ClientControl cc;
+ cc.StartSPDaemon();
+ OHOS::SmartPerf::SPUtils::LoadCmd(pidCmd, endStr);
+ std::vector startParams;
+ std::vector endParams;
+ OHOS::SmartPerf::SPUtils::StrSplit(startStr, " ", startParams);
+ OHOS::SmartPerf::SPUtils::StrSplit(endStr, " ", endParams);
+ std::string result;
+ const int maxExpectedArgs = 100;
+ for (int i = 2; i < argc && i < maxExpectedArgs; i++) {
+ result += argv[i];
+ if (i != argc - 1) {
+ result += " ";
+ }
+ }
+ if (startParams.size() == endParams.size()) {
+ std::cout << "The last collection is interrupted." << std::endl;
+ std::cout << "SP_daemon -start " << result << " started collecting..." << std::endl;
+ }
+ cc.SocketStart(result);
+ std::cout << "command exec finished!" << std::endl;
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-stop") == 0) {
+ SocketStopCommand();
+ std::cout << "command exec finished!" << std::endl;
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-deviceinfo") == 0) {
+ std::cout << OHOS::SmartPerf::SPUtils::GetDeviceInfoMap() << std::endl;
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-ohtestfps") == 0) {
+ OHOS::SmartPerf::FPS::GetInstance().GetOhFps(vec);
+ return 0;
+ } else if (argc > 1 && strcmp(argv[1], "-recordcapacity") == 0) {
+ RecordCapacity();
+ return 0;
+ }
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ if (OHOS::system::GetParameter(VERSION_TYPE, "Unknown") != "beta") {
+ if (!OHOS::system::GetBoolParameter("const.security.developermode.state", true)) {
+ std::cout << "Not a development mode state" << std::endl;
+ return 0;
+ }
+ }
+ const int maxExpectedArgs = 100;
+ std::string errorInfo;
+ std::vector vec;
+ if (argc < 0 || argc > maxExpectedArgs) {
+ std::cout << "Invalid argument count" << std::endl;
+ return -1;
+ }
+ for (int i = 0; i < argc; i++) {
+ vec.push_back(argv[i]);
+ }
+ if (!g_checkCmdParam(vec, errorInfo)) {
+ std::cout << "SP_daemon:" << errorInfo << std::endl <<
+ "Usage: SP_daemon [options] [arguments]" << std::endl << std::endl <<
+ "Try `SP_daemon --help' for more options." << std::endl;
+ return 0;
+ }
+ OHOS::SmartPerf::SPUtils::SetRkFlag();
+ if (ProcessSpecificParameter(argc, argv, vec) == 0) {
+ return 0;
+ }
+
+ OHOS::SmartPerf::SmartPerfCommand cmd(vec);
+ OHOS::SmartPerf::StartUpDelay sd;
+ sd.KillSpProcess();
+ std::cout << cmd.ExecCommand() << std::endl;
+ return 0;
+}