IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 自己动手实现命令行解析器 -> 正文阅读

[系统运维]自己动手实现命令行解析器

一、介绍
嵌入式里面经常会自己做命令行,这里分享一个命令解析器代码实现,比如单片机串口命令行,或者网络命令行,这里测试使用的是ubuntu linux

二、代码实现

mycmd.c

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		头文件区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <stdio.h>
#include <string.h>

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		接口定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef struct 
{
	char *cmd;
	void (*cmd_func)();
}mycmd_def;

#define MAX_CMD_NUM 30
#define CMD_BUFF_SIZE 1024
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		变量定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
mycmd_def mycmd_queue[MAX_CMD_NUM] = {0};
static volatile short cur_cmd_num = 0;
static char cmd_buff[CMD_BUFF_SIZE] = {0};
static volatile int input_cmd_len = 0;
static volatile char cmd_input_flag = 0;

enum {
	CMD_RESOLVER_IDLE = 0,
	CMD_RESOLVER_INPUT,
	CMD_RESOLVER_BUSY,
	CMD_RESOLVER_DONE
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		函数定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void print_version_Executive_function()
{
	const char software_version[] = "v0.1";

	printf("software version:%s\n",software_version);
	//---
}

void download_Executive_function()
{
	printf("download app\n");
	//---
}

//cmd:String command  
//cmd_fun:the callback function
int addcmd(char *cmd, void (*cmd_func)())
{
	if(cur_cmd_num >= MAX_CMD_NUM)
		return -1;
	mycmd_queue[cur_cmd_num].cmd = cmd;
	mycmd_queue[cur_cmd_num].cmd_func = cmd_func;
	cur_cmd_num++;

	return 0;
}

void Mycmd_Init(void)
{
	//init parameter
	cmd_input_flag = CMD_RESOLVER_IDLE;
	memset(cmd_buff, 0, CMD_BUFF_SIZE);
	memset(mycmd_queue, 0, sizeof(mycmd_def)*MAX_CMD_NUM);
	cur_cmd_num = 0;
	//add cmd to cmd queue
	addcmd("print ver", print_version_Executive_function);
	addcmd("download", download_Executive_function);
}

int mystrcmp(char *s1, char *s2, int len)
{
	int i; 

	printf("s1 %s s2 %s len %d\n", s1, s2, len);
	for(i = 0; i < len; i++)
	{
		if(s1[i] == '\0' || s2[i] == '\0')
			break;
		if(s1[i] != s2[i])
			return 0;
	}
	if(s1[i] != s2[i])
		return 0;
	else
		return 1;
}

void Mycmd_Run(void)
{
	int i = 0;
	if(cmd_input_flag == CMD_RESOLVER_IDLE)
		return ;
	cmd_input_flag = CMD_RESOLVER_BUSY;
	for(i = 0; i < cur_cmd_num; i++)
	{
		if(mystrcmp(mycmd_queue[i].cmd, cmd_buff, input_cmd_len) == 1)
		{
			mycmd_queue[i].cmd_func();
			cmd_input_flag = CMD_RESOLVER_IDLE;
			input_cmd_len = 0;
			return;
		}
	}
	printf("no surport cmd\n");
	cmd_input_flag = CMD_RESOLVER_IDLE;
	input_cmd_len = 0;
}

int input_cmd(char *cmd, int len)
{
	if( cmd == NULL || 
		len == 0 ||
		cmd_input_flag == CMD_RESOLVER_BUSY
	)
	{
		return -1;
	}
	memset(cmd_buff, 0, CMD_BUFF_SIZE);
	memcpy(cmd_buff, cmd, len);
	input_cmd_len = len;
	cmd_input_flag = CMD_RESOLVER_INPUT;

	return 0;
}

mycmd.h

#ifndef __MYCMD_H
#define __MYCMD__H

void Mycmd_Init(void);
void Mycmd_Run(void);
void input_cmd(char *cmd, int len);

#endif

main.c

#include <stdio.h>
#include "mycmd.h"

int main()
{
    char buff[100] = {0};
    Mycmd_Init();

    while(1)
    {
        printf("请输入命令\n");
        scanf("%s", buff);
        input_cmd(buff, strlen(buff));
        Mycmd_Run();
    }
    
    return 0;
}

编译脚本
build.sh

echo "delet main"

rm -rf main

gcc main.c mycmd.c -o main -w

echo "build ok"
echo "run..."

./main

结果
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 17:05:23  更:2021-08-12 17:07:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 10:45:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码