USMART

article/2025/8/30 1:25:43

USMART是正点原子团队为其STM32开发平台开发的一种类似linux的shell的调试工具。具体工作过程是通过串口发送命令给单片机,然后单片机收到命令之后调用单片机里面对应的相关函数,并执行,同时支持返回结果。

普通的做法:写函数 ->修改参数->下载->看结果->不满意->修改参数->下载->看结果->不满意….不停的循环,直到满 意为止。这样做很麻烦不说,单片机也是有寿命的啊,老这样不停的刷,很折寿的。而利用 USMART,则只需要在串口调试助手里面输入函数及参数,然后直接串口发送给单片机,就执 行了一次参数调整,不满意的话,你在串口调试助手修改参数在发送就可以了,直到你满意为 止。这样,修改参数十分方便,不需要编译、不需要下载
 

USMART调试过程

USMART特点:

开发过程中,经常需要修改函数入口参数,查看运行效果的情况下应用非常方便。不用多次下载代码,或者多次用JLINK调试。

1、 可以调用绝大部分用户直接编写的函数。
2、 资源占用极少(最少情况: FLASH:4K SRAM:72B )。
3、 支持参数类型多(数字(包含 10/16 进制)、字符串、函数指针等)。
4、 支持函数返回值显示。
5、 支持参数及返回值格式设置。
6、 支持函数执行时间计算( V3.1 版本新特性)。
7、 使用方便。

USMART文件组

USMART分为几个模块的文件组:

usmart.c负责与外部互交等。

usmat_str.c主要负责命令和参数解析。

usmart_config.c主要由用户添加需要由usmart管理的函数。

usmart.husmart_str.h是两个头文件,其中usmart.h里面含有几个用户配置宏定义,可以用来配置usmart的功能及总参数长度(直接和SRAM占用挂钩)、是否使能定时器扫描、是否使用读写函数等。

 USMART配置步骤

USMART 包添加到工程中,头文件要包含到 path
添加需要调用的函数到 usmart_config.c 文件中。
主函数中调用 usmart_dev.init 函数初始化 usmart

           即可通过助手发送命令,调用在usmart注册过的函数。

USMART系统命令

USMART有7个系统命令:

?:      获取帮助信息

help:   获取帮助信息

list:   可用的函数列表

id:     可用函数的ID列表

hex:    参数16进制显示,后跟空格+数字即执行进制转换

dec:    参数10进制显示,后跟空格+数字即执行进制转换

runtime 1,开启函数运行计时;0,关闭函数运行计时;

请按照程序编写格式输入函数名及参数并以回车键结束.

usmart控制管理器定义的结构如下

//usmart控制管理器
struct _m_usmart_dev
{struct _m_usmart_nametab *funs;	//函数名指针void (*init)(u8);				//初始化u8 (*cmd_rec)(u8*str);			//识别函数名及参数void (*exe)(void); 				//执行 void (*scan)(void);             //扫描u8 fnum; 				  		//函数数量u8 pnum;                        //参数数量u8 id;							//函数idu8 sptype;						//参数显示类型(非字符串参数):0,10进制;1,16进制;u16 parmtype;					//参数的类型u8  plentbl[MAX_PARM];  		//每个参数的长度暂存表u8  parm[PARM_LEN];  			//函数的参数u8 runtimeflag;					//0,不统计函数执行时间;1,统计函数执行时间,注意:此功能必须在USMART_ENTIMX_SCAN使能的时候,才有用u32 runtime;					//运行时间,单位:0.1ms,最大延时时间为定时器CNT值的2倍*0.1ms
};
//函数控制管理器初始化
//得到各个受控函数的名字
//得到函数总数量
struct _m_usmart_dev usmart_dev=
{usmart_nametab,usmart_init,usmart_cmd_rec,usmart_exe,usmart_scan,sizeof(usmart_nametab)/sizeof(struct _m_usmart_nametab),//函数数量0,	  	//参数数量0,	 	//函数ID1,		//参数显示类型,0,10进制;1,16进制0,		//参数类型.bitx:,0,数字;1,字符串	    0,	  	//每个参数的长度暂存表,需要MAX_PARM个0初始化0,		//函数的参数,需要PARM_LEN个0初始化
};//函数名列表	 
struct _m_usmart_nametab
{void* func;			//函数指针const u8* name;		//函数名(查找串)	 
};struct _m_usmart_nametab usmart_nametab[]=
{
#if USMART_USE_WRFUNS==1 	//如果使能了读写操作(void*)read_addr,"u32 read_addr(u32 addr)",(void*)write_addr,"void write_addr(u32 addr,u32 val)",	 
#endif(void*)delay_ms,"void delay_ms(u16 nms)",(void*)delay_us,"void delay_us(u32 nus)",	(void*)LCD_Clear,"void LCD_Clear(u16 Color)",(void*)LCD_Fill,"void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)",(void*)LCD_DrawLine,"void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)",(void*)LCD_DrawRectangle,"void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)",(void*)LCD_Draw_Circle,"void Draw_Circle(u16 x0,u16 y0,u8 r)",(void*)LCD_ShowNum,"void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)",(void*)LCD_ShowString,"void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)",(void*)led_set,"void led_set(u8 sta)",(void*)test_fun,"void test_fun(void(*ledset)(u8),u8 sta)",				  	    (void*)LCD_ReadPoint,"u16 LCD_ReadPoint(u16 x,u16 y)",
};	

usmart_scan
本函数,通过对串口接收的数据进行判断,如果有数据,那么执行函数cmd_rec,是一个结构体,成员是函数指针,那么也就是相当于运行函数usmart_cmd_rec,该函数获取函数名,id,参数个数,然后执行函数
usmart_exe,这个函数的功能是执行一些函数,比如执行延时函数delay_ms,最多允许10个参数的传递。

void usmart_scan(void)
{u8 sta,len;  if(USART_RX_STA&0x8000)//串口接收完成?{					   len=USART_RX_STA&0x3fff;	//得到此次接收到的数据长度USART_RX_BUF[len]='\0';	//在末尾加入结束符. sta=usmart_dev.cmd_rec(USART_RX_BUF);//得到函数各个信息if(sta==0)usmart_dev.exe();	//执行函数 else {  len=usmart_sys_cmd_exe(USART_RX_BUF);	//成功返回0if(len!=USMART_FUNCERR)sta=len;				//sta = 0if(sta){switch(sta){case USMART_FUNCERR:printf("函数错误!\r\n");   			break;	case USMART_PARMERR:printf("参数错误!\r\n");   			break;				case USMART_PARMOVER:printf("参数太多!\r\n");   			break;		case USMART_NOFUNCFIND:printf("未找到匹配的函数!\r\n");   			break;		}}}USART_RX_STA=0;//状态寄存器清空	    }
}

usmart_cmd_rec
本函数能够解析串口传入的字符串,比如delay_ms(u16 nms),这样,然后将函数名,参数分离。首先,通过调用函数usmart_get_fname得到函数名和参数个数,然后从本地函数中遍历,如果函数名和参数一致,那么记录该函数在本地函数中位置,并返回退出。其中usmart_get_fparam是得到函数参数的个数。

//从str中获取函数名,id,及参数信息
//*str:字符串指针.
//返回值:0,识别成功;其他,错误代码.
u8 usmart_cmd_rec(u8*str) 
{u8 sta,i,rval;//状态	 u8 rpnum,spnum;u8 rfname[MAX_FNAME_LEN];//暂存空间,用于存放接收到的函数名  u8 sfname[MAX_FNAME_LEN];//存放本地函数名sta=usmart_get_fname(str,rfname,&rpnum,&rval);//得到接收到的数据的函数名及参数个数//读取成功,sta返回0if(sta)return sta;//错误for(i=0;i<usmart_dev.fnum;i++){//遍历这么多函数sta=usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&spnum,&rval);//得到本地函数名及参数个数if(sta)return sta;//本地解析有误	  if(usmart_strcmp(sfname,rfname)==0)//相等{if(spnum>rpnum)return USMART_PARMERR;//参数错误(输入参数比源函数参数少)usmart_dev.id=i;//记录函数ID.break;//跳出.}	}if(i==usmart_dev.fnum)return USMART_NOFUNCFIND;	//未找到匹配的函数sta=usmart_get_fparam(str,&i);					//得到函数参数个数	if(sta)return sta;											//返回错误usmart_dev.pnum=i;									//参数个数记录return USMART_OK;
}

usmart_get_fparam
本函数是通过对串口传入的参数进行解析,一开始先偏移到( 后的第一个字节进行解析判断,首先,调用函数usmart_get_aparm,得到第一个参数,之后再调用,肯定是第二个,第三个参数这样;比如第一个参数是delay_ms(1000),也就是延时1000ms。那么把1000保存下来即可。usmart_get_parmpos得到指定参数的起始地址,参数表示第几个参数,返回该参数的起始地址。plentbl保存参数的长度,这样,在一块连续的地址中,存的都是参数。
 

//从str中得到函数参数
//str:源字符串;
//parn:参数的多少.0表示无参数 void类型
//返回值:0,成功;其他,错误代码.
//得到函数参数个数
u8 usmart_get_fparam(u8*str,u8 *parn)
{	u8 i,type;  u32 res;u8 n=0;u8 len;u8 tstr[PARM_LEN+1];//字节长度的缓存,最多可以存放PARM_LEN个字符的字符串for(i=0;i<MAX_PARM;i++)usmart_dev.plentbl[i]=0;//清空参数长度表while(*str!='(')//偏移到参数开始的地方{str++;											    if(*str=='\0')return USMART_FUNCERR;//遇到结束符了}str++;//偏移到"("之后的第一个字节while(1){//1000,2000,str函数名,delay_msi=usmart_get_aparm(str,tstr,&type);	//得到第一个参数  str+=i;								//偏移switch(type){case 0:	//数字if(tstr[0]!='\0')				//接收到的参数有效{					    i=usmart_str2num(tstr,&res);	//记录该参数,字符串转int if(i)return USMART_PARMERR;		//参数错误.*(u32*)(usmart_dev.parm+usmart_get_parmpos(n))=res;//记录转换成功的结果.usmart_dev.parmtype&=~(1<<n);	//标记数字usmart_dev.plentbl[n]=4;		//该参数的长度为4  n++;							//参数增加  if(n>MAX_PARM)return USMART_PARMOVER;//参数太多}break;case 1://字符串	 	len=usmart_strlen(tstr)+1;	//包含了结束符'\0'usmart_strcopy(tstr,&usmart_dev.parm[usmart_get_parmpos(n)]);//拷贝tstr数据到usmart_dev.parm[n]usmart_dev.parmtype|=1<<n;	//标记字符串 usmart_dev.plentbl[n]=len;	//该参数的长度为len  n++;if(n>MAX_PARM)return USMART_PARMOVER;//参数太多break;case 0XFF://错误return USMART_PARMERR;//参数错误	  }if(*str==')'||*str=='\0')break;//查到结束标志了.}*parn=n;	//记录参数的个数return USMART_OK;//正确得到了参数
}

usmart_get_fname
本函数,也是分析str,首先分析的是函数的返回值类型,一般有char,string,int,void等不超过5个长度的返回值类型,因此,若函数是void型,则标记不返回值;接着,找到函数名真正起始的位置,fname保存函数名,fover的作用是括号匹配,fpname应该只保存第一个参数,其它的没有保存;而且传入的参数也有可能是void,因此也进行了判断。
 

//从str中得到函数名
//*str:源字符串指针
//*fname:获取到的函数名字指针
//*pnum:函数的参数个数
//*rval:是否需要显示返回值(0,不需要;1,需要)
//返回值:0,成功;其他,错误代码.
//usmart_get_fname((u8*)usmart_dev.funs[id].name,sfname,&pnum,&rval);//得到本地函数名,及参数个数
//funs[id] = 具体哪一个函数,funs[id].name = 函数的名字,sfname = 一个u8类型的数组
//作用,记录函数名,参数个数和返回值
u8 usmart_get_fname(u8*str,u8*fname,u8 *pnum,u8 *rval)
{u8 res;u8 fover=0;	  //括号深度u8 *strtemp;u8 offset=0;  u8 parmnum=0;u8 temp=1;u8 fpname[6];//void+X+'/0'u8 fplcnt=0; //第一个参数的长度计数器u8 pcnt=0;	 //参数计数器u8 nchar;//判断函数是否有返回值//str = "void delay_ms(u16 nms)"strtemp=str;while(*strtemp!='\0')//没有结束{if(*strtemp!=' '&&(pcnt&0X7F)<5)//最多记录5个字符{	if(pcnt==0)pcnt|=0X80;//置位最高位,标记开始接收返回值类型if(((pcnt&0x7f)==4)&&(*strtemp!='*'))break;//最后一个字符,必须是*fpname[pcnt&0x7f]=*strtemp;//记录函数的返回值类型pcnt++;}else if(pcnt==0X85)break;	//0x85 = 1000 0101,高位标记,那么就是5strtemp++; } //返回类型,void,string,int,char等等,这里判断有没有返回值if(pcnt)//接收完了{fpname[pcnt&0x7f]='\0';//加入结束符if(usmart_strcmp(fpname,"void")==0)*rval=0;//不需要返回值else *rval=1;							   //需要返回值pcnt=0;} res=0;strtemp=str;//str = "void delay_ms(1000)"while(*strtemp!='('&&*strtemp!='\0') //此代码找到函数名的真正起始位置{  strtemp++;res++;if(*strtemp==' '||*strtemp=='*')		//空格,或者*{nchar=usmart_search_nextc(strtemp);		//获取下一个字符if(nchar!='('&&nchar!='*')offset=res;	//跳过空格和*号}}strtemp=str;if(offset)strtemp+=offset+1;//跳到函数名开始的地方	   res=0;nchar=0;//是否正在字符串里面的标志,0,不在字符串;1,在字符串;while(1){//str = "void delay_ms(1000)"/* 	*fname = delay_ms* 	遇到(,fover++ = 1,这里fover的作用应该是括号匹配* 	*/if(*strtemp==0){res=USMART_FUNCERR;//函数错误break;}else if(*strtemp=='('&&nchar==0)fover++;//括号深度增加一级	 else if(*strtemp==')'&&nchar==0){if(fover)fover--;else res=USMART_FUNCERR;//错误结束,没收到'('if(fover==0)break;//到末尾了,退出	    }else if(*strtemp=='"')nchar=!nchar;if(fover==0)//函数名还没接收完{if(*strtemp!=' ')//空格不属于函数名{*fname=*strtemp;//得到函数名fname++;}}else //已经接受完了函数名了.{if(*strtemp==','){temp=1;		//使能增加一个参数pcnt++;	}else if(*strtemp!=' '&&*strtemp!='('){if(pcnt==0&&fplcnt<5)		//当第一个参数来时,为了避免统计void类型的参数,必须做判断.{fpname[fplcnt]=*strtemp;//记录参数特征.fplcnt++;}temp++;	//得到有效参数(非空格)}if(fover==1&&temp==2){temp++;		//防止重复增加parmnum++; 	//参数增加一个}}strtemp++; 			}   if(parmnum==1)//只有1个参数.{fpname[fplcnt]='\0';//加入结束符if(usmart_strcmp(fpname,"void")==0)parmnum=0;//参数为void,表示没有参数.}*pnum=parmnum;	//记录参数个数*fname='\0';	//加入结束符return res;		//返回执行结果
}

usmart_get_aparm

本函数是获取一个参数。可能是字符型,也有可能是string类型的。

//从str中得到一个函数的参数
//*str:源字符串指针
//*fparm:参数字符串指针
//*ptype:参数类型 0,数字;1,字符串;0XFF,参数错误
//返回值:0,已经无参数了;其他,下一个参数的偏移量.
//1000,2000,str函数名,delay_ms,但是应该是1000,2000,因为已经移位到第一个字节了
u8 usmart_get_aparm(u8 *str,u8 *fparm,u8 *ptype)
{/*		void delay_ms(1500)* 		delay_ms(0X5DC);* 		Function Run Time:1500.0ms* 		* */u8 i=0;u8 enout=0;u8 type=0;//默认是数字u8 string=0; //标记str是否正在读while(1){		    if(*str==','&& string==0)enout=1;			//暂缓立即退出,目的是寻找下一个参数的起始地址if((*str==')'||*str=='\0')&&string==0)break;//立即退出标识符if(type==0)//默认是数字的{if((*str>='0' && *str<='9')||(*str>='a' && *str<='f')||(*str>='A' && *str<='F')||*str=='X'||*str=='x')//数字串检测{if(enout)break;					//找到了下一个参数,直接退出.if(*str>='a')*fparm=*str-0X20;	//小写转换为大写else *fparm=*str;		   		//小写或者数字保持不变fparm++;}else if(*str=='"')//找到字符串的开始标志{if(enout)break;//找到,后才找到",认为结束了.type=1;string=1;//登记STRING 正在读了}else if(*str!=' '&&*str!=',')//发现非法字符,参数错误{type=0XFF;break;}}else//string类{ if(*str=='"')string=0;if(enout)break;			//找到了下一个参数,直接退出.if(string)				//字符串正在读{	if(*str=='\\')		//遇到转义符(不复制转义符){ str++;			//偏移到转义符后面的字符,不管什么字符,直接COPYi++;}					*fparm=*str;		//小写或者数字保持不变fparm++;}	}i++;//偏移量增加str++;}*fparm='\0';	//加入结束符*ptype=type;	//返回参数类型return i;		//返回参数长度
}

usmart_get_runtime

若产生定时器溢出,则运行时间加0xffff。

//获得runtime时间
//返回值:执行时间,单位:0.1ms,最大延时时间为定时器CNT值的2倍*0.1ms
//需要根据所移植到的MCU的定时器参数进行修改
u32 usmart_get_runtime(void)
{if(TIM_GetFlagStatus(TIM4,TIM_FLAG_Update)==SET)//在运行期间,产生了定时器溢出{usmart_dev.runtime+=0XFFFF;}usmart_dev.runtime+=TIM_GetCounter(TIM4);return usmart_dev.runtime;		//返回计数值
}

usmart_exe

//usamrt执行函数
//该函数用于最终执行从串口收到的有效函数.
//最多支持10个参数的函数,更多的参数支持也很容易实现.不过用的很少.一般5个左右的参数的函数已经很少见了.
//该函数会在串口打印执行情况.以:"函数名(参数1,参数2...参数N)=返回值".的形式打印.
//当所执行的函数没有返回值的时候,所打印的返回值是一个无意义的数据.
void usmart_exe(void)
{u8 id,i;u32 res;		   u32 temp[MAX_PARM];//参数转换,使之支持了字符串 u8 sfname[MAX_FNAME_LEN];//存放本地函数名u8 pnum,rval;id=usmart_dev.id;if(id>=usmart_dev.fnum)return;//不执行.usmart_get_fname((u8*)usmart_dev.funs[id].name,sfname,&pnum,&rval);//得到本地函数名,及参数个数 printf("\r\n%s(",sfname);//输出正要执行的函数名for(i=0;i<pnum;i++)//输出参数{if(usmart_dev.parmtype&(1<<i))//参数是字符串{printf("%c",'"');			 printf("%s",usmart_dev.parm+usmart_get_parmpos(i));printf("%c",'"');temp[i]=(u32)&(usmart_dev.parm[usmart_get_parmpos(i)]);}else						  //参数是数字{temp[i]=*(u32*)(usmart_dev.parm+usmart_get_parmpos(i));if(usmart_dev.sptype==SP_TYPE_DEC)printf("%lu",temp[i]);//10进制参数显示else printf("0X%X",temp[i]);//16进制参数显示 	   }if(i!=pnum-1)printf(",");}printf(")");usmart_reset_runtime();	//计时器清零,开始计时//正确以后,执行相应的函数。switch(usmart_dev.pnum){case 0://无参数(void类型)											  res=(*(u32(*)())usmart_dev.funs[id].func)();break;case 1://有1个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0]);break;case 2://有2个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1]);break;case 3://有3个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2]);break;case 4://有4个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3]);break;case 5://有5个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4]);break;case 6://有6个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\temp[5]);break;case 7://有7个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\temp[5],temp[6]);break;case 8://有8个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\temp[5],temp[6],temp[7]);break;case 9://有9个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\temp[5],temp[6],temp[7],temp[8]);break;case 10://有10个参数res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\temp[5],temp[6],temp[7],temp[8],temp[9]);break;}usmart_get_runtime();//获取函数执行时间if(rval==1)//需要返回值.{if(usmart_dev.sptype==SP_TYPE_DEC)printf("=%lu;\r\n",res);//输出执行结果(10进制参数显示)else printf("=0X%X;\r\n",res);//输出执行结果(16进制参数显示)	   }else printf(";\r\n");		//不需要返回值,直接输出结束if(usmart_dev.runtimeflag)	//需要显示函数执行时间{ printf("Function Run Time:%d.%1dms\r\n",usmart_dev.runtime/10,usmart_dev.runtime%10);//打印函数执行时间 }	
}

usmart_str2num

//把字符串转为数字
//支持16进制转换,但是16进制字母必须是大写的,且格式为以0X开头的.
//不支持负数 
//*str:数字字符串指针
//*res:转换完的结果存放地址.
//返回值:0,成功转换完成.其他,错误代码.
//1,数据格式错误.2,16进制位数为0.3,起始格式错误.4,十进制位数为0.
u8 usmart_str2num(u8*str,u32 *res)
{//比如str = 12u32 t;u8 bnum=0;	//数字的位数u8 *p;		  u8 hexdec=10;//默认为十进制数据p=str;*res=0;//清零.while(1){if((*p<='9'&&*p>='0')||(*p<='F'&&*p>='A')||(*p=='X'&&bnum==1))//参数合法{if(*p>='A')hexdec=16;	//字符串中存在字母,为16进制格式.bnum++;					//位数增加.}else if(*p=='\0')break;	//碰到结束符,退出.else return 1;				//不全是十进制或者16进制数据.p++; } p=str;			    //重新定位到字符串开始的地址.if(hexdec==16)		//16进制数据{if(bnum<3)return 2;			//位数小于3,直接退出.因为0X就占了2个,如果0X后面不跟数据,则该数据非法.if(*p=='0' && (*(p+1)=='X'))//必须以'0X'开头.{p+=2;	//偏移到数据起始地址.bnum-=2;//减去偏移量	 }else return 3;//起始头的格式不对}else if(bnum==0)return 4;//位数为0,直接退出.	  while(1){//bnum = 2,bnum = 1,t = 1.res+=1*10=10,res+=10+2=12if(bnum)bnum--;if(*p<='9'&&*p>='0')t=*p-'0';	//得到数字的值else t=*p-'A'+10;				//得到A~F对应的值	    *res+=t*usmart_pow(hexdec,bnum);//返回值:m^n次方	   p++;if(*p=='\0')break;//数据都查完了.	}return 0;//成功转换
}


http://chatgpt.dhexx.cn/article/A7bT8V3c.shtml

相关文章

USMART调试组件

什么是USMART? USMART是正点原子团队为其STM32开发平台开发的一种类似linux的shell的调试工具。具体工作过程是通过串口发送命令给单片机,然后单片机收到命令之后调用单片机里面对应的相关函数,并执行,同时支持返回结果。 USMART调试过程:&#xff1a; USMART应用场景&#x…

2021-07-13 Charles破解

Charles破解码&#xff1a;https://play.golang.org/p/Qtt2CmHbTzU 使用方法&#xff1a;浏览器打开运行代码&#xff0c;复制name和key即可 注&#xff1a;如有侵权请联系删除&#xff01;

charles破解历程

题记 看文章看到javassist可以直接修改java字节码&#xff0c;之前没有尝试过&#xff0c;因为charles是用java写的跨平台抓包工具&#xff0c;之前我也用过&#xff0c;所以拿来进行测试&#xff01; 简介 Javassist是一个开源的分析、编辑和创建Java字节码的类库。 Javas…

Charles4.62破解版本下载

第一种方式&#xff1a; 这种方式下载后&#xff0c;还要自己输入许可证 链接 提取码&#xff1a;2vb0 添用激活码计算器生成激活码 点击这个&#xff0c;把刚才创建的名字和许可证输入进去即可 然后关闭软件&#xff0c;重新打开即可 第二种方式&#xff1a; https://ww…

charles破解 mac

下载charles并安装 https://www.charlesproxy.com/latest-release/download.do 下载charles破解包charles.jar https://www.zzzmode.com/mytools/charles/ 然后用下载的charles.jar替换原先的charles即可 文件路径/contents/java/charles.jar

charles破解https请求

当你的app包从http升级到https的时候&#xff0c;是不是忽然间发现你的请求抓不到了呢&#xff1f;别担心&#xff0c;只是因为你们的app加密升级了&#xff0c;但是我们还是可以正常破解的。接下来直接谈破解步骤啦&#xff1a; 1&#xff1a;首先打开charles,在其主tab栏点击…

Charles破解方法

// Charles Proxy License // 适用于Charles任意版本的注册码&#xff0c;谁还会想要使用破解版呢。 // Charles 4.2目前是最新版&#xff0c;可用。 Registered Name: https://zhile.io License Key: 48891cf209c6d32bf4 本方法通杀charlse系列激活问题。 破解方式&#…

mac抓包工具charles破解版安装及简单使用

在windows上一般使用fiddler进行抓包&#xff0c;但是在mac上就显得很僵硬&#xff0c;所以通过查阅资料&#xff0c;总算安装并且配置好了同样强大的charles&#xff0c;遂在此总结。 首先附上破解版的下载地址 链接:https://pan.baidu.com/s/1yHH-958uLiuXvQbdvGegOQ 密码:y…

Charles破解三十分钟重启

使用charles的用户应该都知道&#xff0c;这个charles是一款收费软件&#xff0c;启动时得等待十秒&#xff0c;然后每过半个小时还会重启&#xff0c;真难受 下面时解决的方法&#xff0c;这个方法不是原厂&#xff0c;指示本人了解到的&#xff0c;一切与本人无关哦&#xf…

MAC安装Charles破解版简易教程

Charles&#xff1a;青花瓷抓包工具。 官网下载&#xff1a;https://www.charlesproxy.com/download/&#xff08;可惜限制了30天的使用期限&#xff09; 破解版下载&#xff1a;https://download.csdn.net/download/fifteen718/10774499 破解版安装方式&#xff1a; 通过上…

MAC Charles 抓包工具安装以及使用方法(带破解)

1.Charles客户端下载&#xff1a; 官网地址&#xff1a;https://www.charlesproxy.com/download/ 选择适合自己的系统版本下载 2.下载安装完成后激活 激活网站地址&#xff1a;https://www.zzzmode.com/mytools/charles/ 打开安装好的Charles&#xff0c;菜单栏 Help->Re…

抓包工具Charles —— 破解、抓包入门

2019独角兽企业重金招聘Python工程师标准>>> Charles工具官网&#xff1a;https://www.charlesproxy.com/ Charles工具下载地址&#xff1a;https://www.charlesproxy.com/download/ Charles破解包下载地址&#xff1a;http://pan.baidu.com/s/1boV4w2r 密码:kqtj 一…

一招破解抓包工具Charles,并进行移动APP抓包分析

一、简介 Charles是目前最强大最流行的http抓包调试工具&#xff0c;Mac、Unix、Windows各个平台都支持。特别是做APP开发&#xff0c;调试与服务端的通信&#xff0c;Charles是必备工具。 目前Charles是收费的&#xff0c;不过可以破解。 1.Charles下载地址&#xff1a; ht…

charles 抓包软件 安装、使用

记录一下charles的简单使用 安装 charles 官网下载&#xff0c;点击跳转到官网下载地址 我使用的是v4.6.3 windows版 破解 链接: 点击跳转到破解页面 在charles里面点击 HELP —>REGISTER 输入名称和生成的密钥即可 安装证书&#xff08;用于抓取https请求&#xff0…

Charles的破解以及Charles乱码问题处理

一. 简介及安装 一、charles的使用 1.1 charles的说明 Charles其实是一款代理服务器&#xff0c;通过过将自己设置成系统&#xff08;电脑或者浏览器&#xff09;的网络访问代理服务器&#xff0c;然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的&#xff0…

串级调节系统参数整定方法(串级调节器参数整定)

串级调节系统参数整定方法&#xff08;串级调节器参数整定&#xff09; 两步法整定串级调节系统PID参数一步整定法整定串级调节系统PID参数 串级控制系统由单回路PID调节器(作为主调节器)和外给定调节器(作为副调节器)彼此串接组成双回路调节系统&#xff0c;主调节器的控制输出…

基于Simulink的Ziegler-Nichols PID参数经验整定法

Ziegler-Nichols整定法适用对象为带纯延迟的一阶惯性环节&#xff0c;即G(s)K*e^(-τs)/(Ts1) 其中&#xff0c;K为比例系数&#xff1b;T为惯性时间常数&#xff1b;τ为纯延迟时间常数。 当被控对象的单位阶跃响应曲线看起来近似一条S形曲线时&#xff0c;可用Ziegler-Nicho…

PID控制参数整定口诀

0. PID控制系统 1. PID调参口诀 参数整定找最佳&#xff0c;从小到大顺序查 先是比例后积分&#xff0c;最后再把微分加。 P-I-D 曲线振荡很频繁&#xff0c;比例度盘要放大 曲线漂浮绕大湾&#xff0c;比例度盘往小扳 曲线偏离回复慢&#xff0c;积分时间往下降 曲线波…

PID参数自整定

说明&#xff1a;根据B站上的视频学习的&#xff0c;以下内容仅作为笔记&#xff0c;方便自己查看。 simulink模型 方法一&#xff1a; 1、双击PID模块。 2、显示PID参数值。 3、调节与撤回。&#xff08;看图像&#xff0c;调到合适程度即可&#xff09; 4、将PID的参数值输…