OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6541|回复: 4

usmart的对接收函数名处理的函数异或

[复制链接]

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
发表于 2014-5-23 09:32:18 | 显示全部楼层 |阅读模式
5金钱
在学习usmart一章中,下面这个函数有些看不懂啊,上位机向stm32发送函数名时,仅仅是发了个函数名啊,并不把返回值类型符号也加上和函数名一起发啊,这里怎么会判断返回值呢?而且  “ if(((pcnt&0x7f)==4)&&(*strtemp!='*'))break;//最后一个字符,必须是* ”这句话为什么会说最后一个字符必须是“*”号呢?云里雾里的,请各位老师指教啊

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;
 //判断函数是否有返回值
 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;
  }
  strtemp++;
 }
 if(pcnt)//接收完了
 {
  fpname[pcnt&0x7f]='\0';//加入结束符
  if(usmart_strcmp(fpname,"void")==0)*rval=0;//不需要返回值
  else *rval=1;          //需要返回值 其他类型的函数
  pcnt=0;
 }
 res=0; //本来就是0
 strtemp=str;
 while(*strtemp!='('&&*strtemp!='\0') //此代码找到函数名的真正起始位置void* 函数名(,"",)
 { 
  strtemp++;
  res++;
  if(*strtemp==' '||*strtemp=='*')
  {
   nchar=usmart_search_nextc(strtemp);  //获取下一个字符 跳过'\0'和空格(' ')
   if(nchar!='('&&nchar!='*')offset=res; //跳过空格和*号
  }
 } 
 strtemp=str;
 if(offset)strtemp+=offset+1;//跳到函数名开始的地方   
 res=0;
 nchar=0;//是否正在字符串里面的标志,0,不在字符串;1,在字符串;
 while(1)
 {
  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;  //返回执行结果
}

最佳答案

查看完整内容[请看2#楼]

这个要结合函数在哪里调用的来理解! 我们输入的只是函数名没错,但是函数的第一个参数u8 usmart_get_fname(u8*str,u8*fname,u8 *pnum,u8 *rval)使用的是结构体第二个元素 [mw_shl_code=c,true]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 (v ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

63

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2013-1-23
在线时间
4 小时
发表于 2014-5-23 09:32:19 | 显示全部楼层
这个要结合函数在哪里调用的来理解!
我们输入的只是函数名没错,但是函数的第一个参数u8 usmart_get_fname(u8*str,u8*fname,u8 *pnum,u8 *rval)使用的是结构体第二个元素
[mw_shl_code=c,true]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 LCD_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_Fast_DrawPoint,"void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)", (void*)LCD_ReadPoint,"u16 LCD_ReadPoint(u16 x,u16 y)", (void*)LCD_Display_Dir,"void LCD_Display_Dir(u8 dir)", (void*)LCD_ShowxNum,"void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode)", }; [/mw_shl_code]
而“最后一个字符必须是'*'”这句,直接看也不好理解,(pcnt&0x7f)==4)满足后,看参数列表知道,只能是void,而接下来的字符既不是‘\0’也不是‘ ’,那么只能是‘*’,即返回参数是void*类型的,才是合理的返回参数,不过参数列表里面没有void*,让人看着莫名其妙,所以这句永远不会执行,只是可以作为以后的扩展添加返回类型为void*的函数列表。


回复

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
 楼主| 发表于 2014-5-23 09:33:49 | 显示全部楼层
标题打错了,是疑惑,该死的智能输入%>_<%
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-23 23:19:17 | 显示全部楼层
回复【2楼】heiselpy:
---------------------------------

这个,你会用就好了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
 楼主| 发表于 2014-5-26 11:11:55 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
谢谢原子
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-7 17:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表