基于STM32战舰开发板的USMART调试组件的使用

发布者:Volare最新更新时间:2022-05-31 来源: eefocus关键字:STM32  战舰开发板  USMART  调试组件 手机看文章 扫描二维码
随时随地手机看文章

USMART调试组件是什么?

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


USMART是干什么的?

USMART的功能就是改变了函数参数修改的方式,我们以前总是“修改函数参数->下载到开发板中执行”,但是使用USMART之后,我们不用在那样做了,而是“用串口进行函数参数的修改->开发板执行相应操作”。


在我看来,USMART就是一个函数调试助手,可以从串口发送参数也可以从串口接收函数返回值。


USMART的作用机理

这里我们要明白一下,函数的存储方式:

其中,函数体是一个数据处理的工具本身并不占用空间,只是在调用函数处理数据的时候在进行压栈出栈的一些逻辑操作。


USMART修改这些函数的参数值正是通过“访问函数参数的地址并且修改这些参数“实现的。


USMART调试功能的实现——定时器与串口的配合使用

注意我们这里的串口扫描函数的内容以及串口扫描函数的执行位置:


//usmart扫描函数  

//通过调用该函数,实现usmart的各个控制.该函数需要每隔一定时间被调用一次  

//以及时执行从串口发过来的各个函数.  

//本函数可以在中断里面调用,从而实现自动管理.  

//如果非ALIENTEK用户,则USMART_RX_STA和USMART_RX_BUF[]需要用户自己实现  

void usmart_scan(void)  

{  

    u8 sta,len;    

    if(USMART_RX_STA&0x8000)//串口接收完成?  

    {                        

        len=USMART_RX_STA&0x3fff;    //得到此次接收到的数据长度  

        USMART_RX_BUF[len]=''; //在末尾加入结束符.   

        sta=usmart_dev.cmd_rec(USMART_RX_BUF);//得到函数各个信息  

        if(sta==0)usmart_dev.exe(); //执行函数   

        else   

        {    

            len=usmart_sys_cmd_exe(USMART_RX_BUF);  

            if(len!=USMART_FUNCERR)sta=len;  

            if(sta)  

            {  

                switch(sta)  

                {  

                    case USMART_FUNCERR:  

                        printf("函数错误!rn");              

                        break;    

                    case USMART_PARMERR:  

                        printf("参数错误!rn");              

                        break;                

                    case USMART_PARMOVER:  

                        printf("参数太多!rn");              

                        break;        

                    case USMART_NOFUNCFIND:  

                        printf("未找到匹配的函数!rn");              

                        break;        

                }  

            }  

        }  

        USMART_RX_STA=0;//状态寄存器清空          

    }  

}  

 

扫描函数的功能其实包含两部分:


① 扫描串口接收的数据;


② 根据扫描结果,执行相应的功能。


//下面这两个函数,非USMART函数,放到这里,仅仅方便移植.   

//定时器4中断服务程序       

void TIM4_IRQHandler(void)  

{                                     

    if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//溢出中断  

    {  

        usmart_dev.scan();  //执行usmart扫描      

        TIM_SetCounter(TIM4,0);     //清空定时器的CNT  

        TIM_SetAutoreload(TIM4,100);//恢复原来的设置                                                             

    }                    

    TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //清除中断标志位      

}  

 


在TIMER4的中断服务函数中我们可以看到,当TIM4溢出,即达到1ms时,我们扫描串口并根据接收的命令执行相应的动作。


USMART调试组件的执行流程

USMART使用过程中的疑难

有返回值的函数在执行后,会通过串口返回函数返回值吗?

//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("rn%s(",sfname);//输出正要执行的函数名  

    for(i=0;i    {  

        if(usmart_dev.parmtype&(1<        {  

            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]);  

[1] [2]
关键字:STM32  战舰开发板  USMART  调试组件 引用地址:基于STM32战舰开发板的USMART调试组件的使用

上一篇:基于STM32的RTC实时时钟实验
下一篇:基于STM32战舰开发板的内部温度传感器实验

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved