FreeRTOS使用任务通知实现命令行解释器

目录
  • 前言
  • 1.编码风格
  • 2.一些准备工作
    • 2.1串口硬件驱动
    • 2.2一个类printf函数
    • 3.使用任务通知
  • 4.数据结构
    • 4.1与命令有关的数据结构
    • 4.2与分析命令有关数据结构
  • 5.串口接收中断处理函数
  • 6.命令行分析任务
    • 6.1去除无效字符和控制字符
    • 6.2参数分析
    • 6.3定义命令回调函数
      • 6.3.1不带参数的命令回调函数举例
      • 6.3.2带参数的命令行回调函数举例
    • 6.5命令行分析任务实现
  • 7.使用的串口工具
    • 7.1设置串口参数
    • 7.2设置新行模式
    • 7.3设置本地回显
  • 8.测试
    • 8.1无参数命令测试
    • 8.2带参数命令测试

前言

虽然这是介绍FreeRTOS系列的文章,但这篇文章偏重于命令行解释器的实现。这一方面是因为任务通知使用起来非常简单,另一方面也因为对于嵌入式程序来说,使用命令行解释器来辅助程序调试是非常有用的。程序调试是一门技术,基本上我们需要两种调试手段,一种是可以单步仿真的硬件调试器,另外一种是可以长期监视程序状态的状态输出,可以通过串口、显示屏等等手段输出异常信息或者某些关键点。这里的命令行解释器就属于后者。

本文实现的命令行解释器具有以下特性:

支持十进制参数,识别负号;

支持十六进制参数,十六进制以‘0x’开始;

命令名长度可定义,默认最大20个字符;

参数数目可定义,默认最多8个参数;

命令名和参数之间以空格隔开,空格个数任意;

整条命令以回车换行符结束;

整条命令最大长度可定义,默认64字节,包括回车换行符;

如果使用SecureCRT串口工具(推荐),支持该软件的控制字符,比如退格键、左移键、右移键等。

一个带参数的命令格式如下所示:

参数名 <参数1> <参数2> … <参数3>[回车换行符]

1.编码风格

FreeRTOS的编码标准及风格见FreeRTOS编码标准及风格指南,但我自己的编码风格跟FreeRTOS并不相同,并且我也不打算改变我当前坚持使用的编码风格。所以在这篇或者以后的文章中可能会在一个程序中看到两种不同的编码风格,对于涉及FreeRTOS的代码,我尽可能使用FreeRTOS建议的编码风格,与FreeRTOS无关的代码,我仍然使用自己的编码风格。我可以保证,两种编码风格决不会影响程序的可读性,编写良好可读性的代码,是我一直注重并坚持的。

2.一些准备工作

2.1串口硬件驱动

命令行解释器使用一个硬件串口,需要外部提供两个串口底层函数:一个是串口初始化函数init_cmd_uart(),用于初始化串口波特率、中断等事件;另一个是发送单个字符函数my_putc()。此外,命令行为串口接收中断服务程序提供函数fill_rec_buf(),用于保存接收到的字符,当收到回车换行符后,该函数向命令行分析任务发送通知。

2.2一个类printf函数

类printf函数用来格式化输出,我一般用来辅助调试,为了方便的将调试代码从程序中去除,需要将类printf函数进行封装。我的文章《编写优质嵌入式C程序》第5.2节给出了一个完整的类printf函数实现和封装代码,最终我们使用到的类printf函数是如下形式的宏:

MY_DEBUGF(CMD_LINE_DEBUG,("第%d个参数:%d\n",i+1,arg[i])); 

3.使用任务通知

我们将会创建一个任务,用来分析接收到的命令,如果命令有效则调用命令实现函数。这个任务名字为vTaskCmdAnalyze()。串口接收中断用于接收命令,如果接收到回车换行符,则向任务vTaskCmdAnalyze()发送任务通知,表明已经接收到一条完整命令,任务可以去处理了。

示意框图如图3-1所示。

4.数据结构

命令行解释器程序需要涉及两个数据结构:一个与命令有关,包括命令的名字、命令的最大参数数目、命令的回调函数类型、命令帮助信息等;另一个与分析命令有关,包括接收命令字符缓冲区、存放参数缓冲区等。

4.1与命令有关的数据结构

定义如下:

   typedef struct {
        char const *cmd_name;                        //命令字符串
        int32_t max_args;                            //最大参数数目
        void (*handle)(int argc,void * cmd_arg);     //命令回调函数
        char  *help;                                 //帮助信息
    }cmd_list_struct;

需要说明一下命令回调函数的参数,argc保存接收到的参数数目,cmd_arg指向参数缓冲区,目前只支持32位的整形参数,这在绝大多数嵌入式场合是足够的。

4.2与分析命令有关数据结构

定义如下:

#define ARG_NUM     8          //命令中允许的参数个数
#define CMD_LEN     20         //命令名占用的最大字符长度
#define CMD_BUF_LEN 60         //命令缓存的最大长度
typedef struct {
    char rec_buf[CMD_BUF_LEN];            //接收命令缓冲区
    char processed_buf[CMD_BUF_LEN];      //存储加工后的命令(去除控制字符)
    int32_t cmd_arg[ARG_NUM];             //保存命令的参数
}cmd_analyze_struct;

缓冲区的大小使用宏来定义,通过更改相应的宏定义,可以设置整条命令的最大长度、命令参数最大数目等。

5.串口接收中断处理函数

本文使用的串口软件是SecureCRT,在这个软件下敲击的任何键盘字符,都会立刻通过串口硬件发送出去,这与Telnet类似。所以我们无需使用串口的FIFO,每接收到一个字符就产生一次中断。串口中断与硬件关系密切,所以命令行解释器提供了一个与硬件无关的函数fill_rec_buf(),每当串口中断接收到一个字符,就以收到的字符为参数调用这个函数。 fill_rec_buf()函数主要操作变量cmd_analyze,变量的声明原型为:

cmd_analyze_struct cmd_analyze;

函数fill_rec_buf()的实现代码为:

/*提供给串口中断服务程序,保存串口接收到的单个字符*/
void fill_rec_buf(char data)
{
    //接收数据
    static uint32_t rec_count=0;
    cmd_analyze.rec_buf[rec_count]=data;
    if(0x0A==cmd_analyze.rec_buf[rec_count] && 0x0D==cmd_analyze.rec_buf[rec_count-1])
    {
       BaseType_t xHigherPriorityTaskWoken = pdFALSE;
       rec_count=0;
       /*收到一帧数据,向命令行解释器任务发送通知*/
       vTaskNotifyGiveFromISR (xCmdAnalyzeHandle,&xHigherPriorityTaskWoken);

       /*是否需要强制上下文切换*/
       portYIELD_FROM_ISR(xHigherPriorityTaskWoken );
    }
    else
    {
       rec_count++;
       /*防御性代码,防止数组越界*/
       if(rec_count>=CMD_BUF_LEN)
       {
           rec_count=0;
       }
    }
}

6.命令行分析任务

命令行分析任务大部分时间都会因为等待任务通知而处于阻塞状态。当接收到一个通知后,任务首先去除命令行中的无效字符和控制字符,然后找出命令名并分析参数数目、将参数转换成十六进制数并保存到参数缓冲区中,最后检查命令名和参数是否合法,如果合法则调用命令回调函数处理本条命令。

6.1去除无效字符和控制字符

串口软件SecureCRT支持控制字符。比如在输入一串命令的时候,发现某个字符输入错误,就要使用退格键或者左右移动键定位到错误的位置进行修改。这里的退格键和左右移动键都属于控制字符,比如退格键的键值为0x08、左移键的键值为0x1B0x5B 0x44。我们之前也说过,在软件SecureCRT中输入字符时,每敲击一个字符,该字符立刻通过串口发送给我们的嵌入式设备,也就是所有键值都会按照敲击键盘的顺序存入到接收缓冲区中,但这里面可能有我们不需要的字符,我们首先需要利用控制字符将不需要的字符删除掉。这个工作由函数get_true_char_stream()实现,代码如下所示:

/**
* 使用SecureCRT串口收发工具,在发送的字符流中可能带有不需要的字符以及控制字符,
* 比如退格键,左右移动键等等,在使用命令行工具解析字符流之前,需要将这些无用字符以
* 及控制字符去除掉.
* 支持的控制字符有:
*   上移:1B 5B 41
*   下移:1B 5B 42
*   右移:1B 5B 43
*   左移:1B 5B 44
*   回车换行:0D 0A
*  Backspace:08
*  Delete:7F
*/
static uint32_t get_true_char_stream(char *dest,const char *src)
{
   uint32_t dest_count=0;
   uint32_t src_count=0;
    while(src[src_count]!=0x0D && src[src_count+1]!=0x0A)
    {
       if(isprint(src[src_count]))
       {
           dest[dest_count++]=src[src_count++];
       }
       else
       {
           switch(src[src_count])
           {
                case    0x08:                          //退格键键值
                {
                    if(dest_count>0)
                    {
                        dest_count --;
                    }
                    src_count ++;
                }break;
                case    0x1B:
                {
                    if(src[src_count+1]==0x5B)
                    {
                        if(src[src_count+2]==0x41 || src[src_count+2]==0x42)
                        {
                            src_count +=3;              //上移和下移键键值
                        }
                        else if(src[src_count+2]==0x43)
                        {
                            dest_count++;               //右移键键值
                            src_count+=3;
                        }
                        else if(src[src_count+2]==0x44)
                        {
                            if(dest_count >0)           //左移键键值
                            {
                                dest_count --;
                            }
                           src_count +=3;
                        }
                        else
                        {
                            src_count +=3;
                        }
                    }
                    else
                    {
                        src_count ++;
                    }
                }break;
                default:
                {
                    src_count++;
                }break;
           }
       }
    }
   dest[dest_count++]=src[src_count++];
    dest[dest_count++]=src[src_count++];
    return dest_count;
}

6.2参数分析

接收到的命令中可能带有参数,我们需要知道参数的数目,还需要把字符型的参数转换成整形数并保存到参数缓冲区(这是因为命令回调函数需要这两个参数)。这个工作由函数cmd_arg_analyze()实现,代码如下所示:

/**
* 命令参数分析函数,以空格作为一个参数结束,支持输入十六进制数(如:0x15),支持输入负数(如-15)
* @param rec_buf   命令参数缓存区
* @param len       命令的最大可能长度
* @return -1:       参数个数过多,其它:参数个数
*/
static int32_t cmd_arg_analyze(char *rec_buf,unsigned int len)
{
   uint32_t i;
   uint32_t blank_space_flag=0;    //空格标志
   uint32_t arg_num=0;             //参数数目
   uint32_t index[ARG_NUM];        //有效参数首个数字的数组索引

    /*先做一遍分析,找出参数的数目,以及参数段的首个数字所在rec_buf数组中的下标*/
    for(i=0;i<len;i++)
    {
       if(rec_buf[i]==0x20)        //为空格
       {
           blank_space_flag=1;
           continue;
       }
        else if(rec_buf[i]==0x0D)   //换行
       {
           break;
       }
       else
       {
           if(blank_space_flag==1)
           {
                blank_space_flag=0;
                if(arg_num < ARG_NUM)
                {
                   index[arg_num]=i;
                    arg_num++;
                }
                else
                {
                    return -1;      //参数个数太多
                }
           }
       }
    }

    for(i=0;i<arg_num;i++)
    {
        cmd_analyze.cmd_arg[i]=string_to_dec((unsigned char *)(rec_buf+index[i]),len-index[i]);
    }
    return arg_num;
}

在这个函数cmd_arg_analyze()中,调用了字符转整形函数string_to_dec()。我们只支持整形参数,这里给出一个字符转整形函数的简单实现,可以识别负号和十六进制的前缀’0x’。在这个函数中调用了三个C库函数,分别是isdigit()、isxdigit()和tolower(),因此需要包含头文件#include <ctype.h>。函数string_to_dec()实现代码如下:

/*字符串转10/16进制数*/
static int32_t string_to_dec(uint8_t *buf,uint32_t len)
{
   uint32_t i=0;
   uint32_t base=10;       //基数
   int32_t  neg=1;         //表示正负,1=正数
   int32_t  result=0;
   if((buf[0]=='0')&&(buf[1]=='x'))
    {
       base=16;
       neg=1;
       i=2;
    }
    else if(buf[0]=='-')
    {
       base=10;
       neg=-1;
       i=1;
    }
    for(;i<len;i++)
    {
       if(buf[i]==0x20 || buf[i]==0x0D)    //为空格
       {
           break;
       }

       result *= base;
       if(isdigit(buf[i]))                 //是否为0~9
       {
           result += buf[i]-'0';
       }
       else if(isxdigit(buf[i]))           //是否为a~f或者A~F
       {
            result+=tolower(buf[i])-87;
       }
       else
       {
           result += buf[i]-'0';
       }
    }
    result *= neg;
    return result ;
}

6.3定义命令回调函数

我们举两个例子:第一个是不带参数的例子,输入命令后,函数返回一个“Helloworld!”字符串;第二个是带参数的例子,我们输入命令和参数后,函数返回每一个参数值。我们在讲数据结构的时候特别提到过命令回调函数的原型,这里要根据这个函数原型来声明命令回调函数。

6.3.1不带参数的命令回调函数举例

/*打印字符串:Hello world!*/
void printf_hello(int32_t argc,void *cmd_arg)
{
   MY_DEBUGF(CMD_LINE_DEBUG,("Hello world!\n"));
}

6.3.2带参数的命令行回调函数举例

/*打印每个参数*/
void handle_arg(int32_t argc,void * cmd_arg)
{
   uint32_t i;
   int32_t  *arg=(int32_t *)cmd_arg;

    if(argc==0)
    {
       MY_DEBUGF(CMD_LINE_DEBUG,("无参数\n"));
    }
    else
    {
       for(i=0;i<argc;i++)
       {
           MY_DEBUGF(CMD_LINE_DEBUG,("第%d个参数:%d\n",i+1,arg[i]));
       }
    }
}

6.4定义命令表

在讲数据结构的时候,我们定义了与命令有关的数据结构。每条命令需要包括命名名、最大参数、命令回调函数、帮助等信息,这里要将每条命令组织成列表的形式。

/*命令表*/
const cmd_list_struct cmd_list[]={
/*   命令    参数数目    处理函数        帮助信息                         */
{"hello",   0,      printf_hello,   "hello                      -打印HelloWorld!"},
{"arg",     8,      handle_arg,      "arg<arg1> <arg2> ...      -测试用,打印输入的参数"},
};

如果要定义自己的命令,只需要按照6.3节的格式编写命令回调函数,然后将命令名、参数数目、回调函数和帮助信息按照本节格式加入到命令表中即可。

6.5命令行分析任务实现

有了上面的基础,命令行分析任务实现起来就非常轻松了,源码如下:

/*命令行分析任务*/
void vTaskCmdAnalyze( void *pvParameters )
{
   uint32_t i;
   int32_t rec_arg_num;
    char cmd_buf[CMD_LEN];
    while(1)
    {
       uint32_t rec_num;
       ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
    rec_num=get_true_char_stream(cmd_analyze.processed_buf,cmd_analyze.rec_buf);
       /*从接收数据中提取命令*/
       for(i=0;i<CMD_LEN;i++)
       {
           if((i>0)&&((cmd_analyze.processed_buf[i]==' ')||(cmd_analyze.processed_buf[i]==0x0D)))
           {
                cmd_buf[i]='\0';        //字符串结束符
                break;
           }
           else
           {
                cmd_buf[i]=cmd_analyze.processed_buf[i];
           }
       }
       rec_arg_num=cmd_arg_analyze(&cmd_analyze.processed_buf[i],rec_num);
       for(i=0;i<sizeof(cmd_list)/sizeof(cmd_list[0]);i++)
       {
           if(!strcmp(cmd_buf,cmd_list[i].cmd_name))       //字符串相等
           {
                if(rec_arg_num<0 || rec_arg_num>cmd_list[i].max_args)
                {
                    MY_DEBUGF(CMD_LINE_DEBUG,("参数数目过多!\n"));
                }
                else
                {
                    cmd_list[i].handle(rec_arg_num,(void *)cmd_analyze.cmd_arg);
                }
                break;
           }
       }
       if(i>=sizeof(cmd_list)/sizeof(cmd_list[0]))
       {
           MY_DEBUGF(CMD_LINE_DEBUG,("不支持的指令!\n"));
       }
    }
}

7.使用的串口工具

推荐使用SecureCRT软件,这是我觉得最适合命令行交互的串口工具。此外,这个软件非常强大,除了支持串口,还支持SSH、Telnet等。对于串口,SecureCRT工具还支持文件发送协议:Xmodem、Ymodem和Zmodem。这在使用串口远程升级时很有用,可以用来发送新的程序二进制文件。我曾经使用Ymodem做过远程升级,以后有时间再详细介绍SecureCRT的Ymodem功能细节。

要用于本文介绍的命令行解释器,要对SecureCRT软件做一些设置。

7.1设置串口参数

选择Serial功能、设置端口、波特率、校验等,特别要注意的是不要勾选任何流控制选项,如图2-1所示。

图2-1:设置串口参数

7.2设置新行模式

依次点击菜单栏的“选项”---“会话选项”,在弹出的“会话选项”界面中,点击左边树形菜单的“终端”---“仿真”---“模式”,在右边的仿真模式区域选中“换行”和“新行模式”,如图2-2所示。

图2-2:设置新行模式

7.3设置本地回显

依次点击菜单栏的“选项”---“会话选项”,在弹出的“会话选项”界面中,点击左边树形菜单的“终端”---“仿真”---“高级”,在右边的“高级仿真”区域,选中“本地回显”,如图2-3所示。

图2-3:设置本地回显

8.测试

我们通过6.3节和6.4接定义了两个命令,第一条命令的名字为”hello”,这是一个无参数命令,直接输出字符串”Hello world!”。第二条命令的名字为”arg”,是一个带参数命令,输出每个参数的值。下面对这两个命令进行测试。

8.1无参数命令测试

设置好SecureCRT软件,输入字符”hello”后,按下回车键,设备会返回字符串”Hello world!”。如图8-1所示。

图8-1:无参数命令测试

8.2带参数命令测试

设置好SecureCRT软件,输入字符”arg 1 2 -3 0x0a”后,按下回车键,设备会返回每个参数值。如图8-2所示。

图8-2:带参数命令测试

以上就是FreeRTOS使用任务通知实现命令行解释器的详细内容,更多关于FreeRTOS任务通知命令行解释器的资料请关注我们其它相关文章!

(0)

相关推荐

  • FreeRTOS实时操作系统的任务创建和删除

    目录 前言 1.任务创建 1.1函数描述 1.2参数描述 1.3返回值 1.4用法举例 2.任务删除 2.1任务描述 2.2参数描述 前言 在FreeRTOS移植到Cortex-M3硬件平台的文章中,我们已经见过任务创建API,但那篇文章的重点在于如何移植FreeRTOS,本文将重点放在任务的创建和删除API函数上面. 任务创建和删除API函数位于文件task.c中,需要包含task.h头文件. 1.任务创建 1.1函数描述 BaseType_t xTaskCreate( TaskFunctio

  • FreeRTOS实时操作系统的任务创建与任务切换

    目录 任务控制块数据结构 任务创建函数 定义就绪表 就绪表初始化 启动调度器 任务切换 任务控制块数据结构 任务控制块数据结构在task.c声明 typedef struct tskTaskControlBlock { volatile StackType_t * pxTopOfStack; //栈顶指针 ListItem_t xStateListItem; //任务节点 StackType_t * pxStack; //任务栈起始地址 char pcTaskName[configMAX_TAS

  • FreeRTOS实时操作系统多任务管理基础知识

    目录 什么是多任务系统? FreeRTOS  任务与协程 1.任务(Task) 的特性 2.协程(Co-routine)的特性 任务状态 运行态 就绪态 阻塞态 挂起态 任务优先级 任务实现 任务控制块 任务堆栈 RTOS 系统的核心就是任务管理,FreeRTOS 也不例外,而且大多数学习 RTOS 系统的工程师或者学生主要就是为了使用 RTOS 的多任务处理功能,初步上手 RTOS 系统首先必须掌握的也是任务的创建.删除.挂起和恢复等操作,由此可见任务管理的重要性. 什么是多任务系统? 回想一

  • FreeRTOS实时操作系统的任务通知方法

    目录 前言 1.发送通知-方法1 1.1函数描述 1.2参数描述 1.3返回值 2.发送通知-方法2 2.1函数描述 2.2参数描述 2.3用法举例 3.获取通知 3.1函数描述 3.2参数描述 3.3返回值 4.等待通知 4.1函数描述 4.2参数描述 4.3返回值 4.4用法举例 5.任务通知并查询 5.1函数描述 5.2参数描述 5.3返回值 前言 注:本文介绍任务通知的基础知识,详细源码分析见FreeRTOS进阶<FreeRTOS高级篇8---FreeRTOS任务通知分析> 每个RTO

  • freertos实时操作系统空闲任务阻塞延时示例解析

    阻塞态:如果一个任务当前正在等待某个外部事件,则称它处于阻塞态. rtos中的延时叫阻塞延时,即任务需要延时的时候,会放弃CPU的使用权,进入阻塞状态.在任务阻塞的这段时间,CPU可以去执行其它的任务(如果其它的任务也在延时状态,那么 CPU 就将运行空闲任务),当任务延时时间到,重新获取 CPU 使用权,任务继续运行. 空闲任务:处理器空闲的时候,运行的任务.当系统中没有其他就绪任务时,空闲任务开始运行,空闲任务的优先级是最低的. 空闲任务 定义空闲任务: #define portSTACK_

  • FreeRTOS实时操作系统的任务概要讲解

    目录 1. 任务和协程(Co-routines) 1.1任务的特性 1.2任务概要 2. 任务状态 3.任务优先级 4.实现一个任务 5.空闲任务和空闲任务钩子(idle task和Idle Task hook) 5.1空闲任务 5.2空闲任务钩子 1. 任务和协程(Co-routines) 应用程序可以使用任务也可以使用协程,或者两者混合使用,但是任务和协程使用不同的API函数,因此在任务和协程之间不能使用同一个队列或信号量传递数据. 通常情况下,协程仅用在资源非常少的微处理器中,特别是RAM

  • FreeRTOS任务控制API函数的功能分析

    目录 1.相对延时 1.1函数描述 1.2参数描述 1.3用法举例 2.绝对延时 2.1函数描述 2.2参数描述 2.3用法举例 3.获取任务优先级 3.1函数描述 3.2参数描述 3.3返回值 3.4用法举例 4.设置任务优先级 4.1函数描述 4.2参数描述 4.3用法举例 5.任务挂起 5.1函数描述 5.2参数描述 5.3用法举例 6.恢复挂起的任务 6.1函数描述 6.2参数描述 7.恢复挂起的任务(在中断服务函数中使用) 7.1函数描述 7.2参数描述 7.3返回值 7.4用法举例

  • FreeRTOS实时操作系统的任务应用函数详解

    目录 1.获取任务系统状态 1.1函数描述 1.2参数描述 1.3返回值 1.4用法举例 2.获取当前任务句柄 2.1函数描述 2.2返回值 3.获取空闲任务句柄 3.1函数描述 3.2返回值 4.获取任务堆栈最大使用深度 4.1函数描述 4.2参数描述 4.3返回值 4.4用法举例 5.获取任务状态 5.1函数描述 5.2参数描述 5.3返回值 6.获取任务描述内容 6.1函数描述 6.2参数描述 6.3返回值 7.获取系统节拍次数 7.1函数描述 7.2返回值 8.获取调度器状态 8.1函数

  • FreeRTOS实时操作系统空闲任务的阻塞延时实现

    目录 什么是阻塞延时.为什么需要空闲任务 空闲任务的实现 阻塞延时的实现 xTicksToDelay 递减 SysTick初始化 仿真 什么是阻塞延时.为什么需要空闲任务 RTOS中的延时叫阻塞延时,即任务需要延时时,任务会放弃cpu使用权,cpu转而去做其他的事,当任务延时时间到后,任务重新请求获得cpu使用权.但当所有的任务都处于阻塞后,为了不让cpu空闲没事干就需要一个空闲任务让cpu干活. 空闲任务的实现 空闲任务实现和创建普通任务没区别,空闲任务在调用vTaskStartSchedul

  • FreeRTOS使用任务通知实现命令行解释器

    目录 前言 1.编码风格 2.一些准备工作 2.1串口硬件驱动 2.2一个类printf函数 3.使用任务通知 4.数据结构 4.1与命令有关的数据结构 4.2与分析命令有关数据结构 5.串口接收中断处理函数 6.命令行分析任务 6.1去除无效字符和控制字符 6.2参数分析 6.3定义命令回调函数 6.3.1不带参数的命令回调函数举例 6.3.2带参数的命令行回调函数举例 6.5命令行分析任务实现 7.使用的串口工具 7.1设置串口参数 7.2设置新行模式 7.3设置本地回显 8.测试 8.1无

  • Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现

    1 命令行窗口 开始栏搜索command,打开命令提示符,即为命令行窗口. 运行一个Python程序,需要输入:Python + 程序地址 + 程序名.py 如图: 2 Python解释器 开始栏搜索command,打开命令提示符 命令提示符输入"pyhton",出现">>>"即进入Python解释器 此时输入的代码可直接反馈结果 退出Python解释器需要输入exit() 以上过程如图: 二者区别 文件运行: 文件运行要在命令行窗口,而非Pyth

  • CMD命令行高级教程精选合编合集

    目录第一章 批处理基础第一节 常用批处理内部命令简介1.REM 和 ::2.ECHO 和 @3.PAUSE4.ERRORLEVEL5.TITLE6.COLOR7.mode 配置系统设备8.GOTO 和 :9.FIND10.START11.assoc 和 ftype12.pushd 和 popd13.CALL14.shift15.IF16.setlocal 与 变量延迟(ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION启动或停用延缓环境变量扩展名.)

  • Windows使用cmd命令行查看、修改、删除与添加环境变量

    您可以在cmd中使用SET,显示或设置环境变量. 一.查看环境变量 1.查看当前所有可用的环境变量 输入 set 即可查看. 2.查看某个环境变量 输入 “set 变量名”即可.比如想查看path变量的值,即输入 set path 二.修改环境变量 注意:所有的在cmd命令行下对环境变量的修改只对当前窗口有效,不是永久性的修改.也就是说当关闭此cmd命令行窗口后,将不再起作用. 永久性修改环境变量的方法有两种:一种是直接修改注册表,另一种是通过我的电脑-〉属性-〉高级,来设置系统的环境变量(查看

  • 网络基础版各种命令行集锦

    Switching 命令大全 Switching 命令大全 1. 在基于IOS的交换机上设置主机名/系统名: switch(config)# hostname hostname 在基于CLI的交换机上设置主机名/系统名: switch(enable) set system name name-string 2.在基于IOS的交换机上设置登录口令: switch(config)# enable password level 1 password 在基于CLI的交换机上设置登录口令: switch(

  • Perl命令行应用程序详解

    perl - Practical Extraction and Report Language,Perl有很多命令行参数,通过它可以让你的程序更简练,并且可以写出很多只有一行命令的perl.在这篇文章里我们来了解一些常用的命令行参数. 命令行调用 复制代码 代码如下: perl [ -sTtuUWX ] [ -hv ] [ -V[:configvar] ] [ -cw ] [ -d[t][:debugger] ] [ -D[number/list] ] [ -pna ] [ -Fpattern

  • node通过npm写一个cli命令行工具

    前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要新建一些页面,逻辑样式等文件,每次都手动new一个,然后复制一些基本代码进去非常的麻烦,所以就有了这篇文章.接下来就让po主为大家一步一步演示怎么做一个npm命令行插件. 注册npm账户 发布npm插件,首先肯定要有个npm帐号了,过程就不啰嗦了,走你. npm官网 有了账号后,我们通过npm in

  • 使用.NET命令行编译器编译项目(如ASP.NET、C#等)

    源程序最好有.csproj或.vbproj文件,没有的话,要花些时间调试 下面我以VB.NET做示例讲解一下: 从proj我们可以获取以下有用信息 Settings小节中有很多配置选项,对应一些编译器选项 <References>小节中是项目的引用,第3方类库最好用绝对路径 <Imports>小节中是要导入的一些命名空间 <Files>小节中有项目的所有文件,选取 BuildAction = "Compile"的文件 用vbc测试了一下,很容易,注意

  • Java程序员必须知道的5个JVM命令行标志

    本文是Neward & Associates的总裁Ted Neward为developerworks独家撰稿"你不知道5个--"系列中的一篇,JVM是多数开发人员视为理所当然的Java功能和性能背后的重负荷机器.然而,我们很少有人能理解JVM是如何进行工作的-像任务分配和垃圾收集.转动线程.打开和关闭文件.中断和/或JIT编译Java字节码,等等. 不熟悉JVM将不仅会影响应用程序性能,而且当JVM出问题时,尝试修复也会很困难. 本文将介绍一些命令行标志,您可以使用它们来诊断和

  • 简单就是美,网络命令行的使用和范例

    1.最基本,最常用的,测试物理网络的 ping 192.168.0.8 -t ,参数-t是等待用户去中断测试 2.查看DNS.IP.Mac等 A.Win98:winipcfg B.Win2000以上:Ipconfig/all C.NSLOOKUP:如查看河北的DNS C:\>nslookup Default Server: ns.hesjptt.net.cn Address: 202.99.160.68 >server 202.99.41.2 则将DNS改为了41.2 > pop.pcp

随机推荐