dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2181回复:18

突然发现自己什么都不会...

楼主#
更多 发布于:2002-12-16 14:34
想写相应设备请求的子程序,突然发现不知道从何写起..也就是说不知道那几个子程序应该完成什么功能啊..
SET_CONFIGURATION()
GET_CONFIGURATION()
GET_INTERFACE()
SET_INTERFACE()
SET_DESCRIPTOR()

那个好心人给我讲一讲啊,,拜托了...哪怕讲一个也好啊

(PS:可不要告诉我看例子程序啊..我看不懂C51的程序,不知道什么意思... :()

最新喜欢:

skyeyeskyeye
qiezi
驱动小牛
驱动小牛
  • 注册日期2002-10-17
  • 最后登录2005-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-16 15:48
葱头大哥问你个问题,看了半天我突然发现不知道MCU怎么把数据送到D12里去!void ISRx_Main_RxDone(void) 感觉象是处理D12与主机之间的通讯的。MCU的数据能从这里进去吗?不好意思实在太菜,总是这样打扰你。
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-16 16:44
葱头大哥问你个问题,看了半天我突然发现不知道MCU怎么把数据送到D12里去!void ISRx_Main_RxDone(void) 感觉象是处理D12与主机之间的通讯的。MCU的数据能从这里进去吗?不好意思实在太菜,总是这样打扰你。


我才是菜呢...要不也不会总出不来了..

MCU要把想要传送的数据送到D12的端点缓冲区去,然后使能缓冲区就ok了..你写的那个是C51的,我看过,看不懂..:(

CObject
驱动大牛
驱动大牛
  • 注册日期2002-08-18
  • 最后登录2017-07-22
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望106点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2002-12-16 17:12
想写相应设备请求的子程序,突然发现不知道从何写起..也就是说不知道那几个子程序应该完成什么功能啊..
SET_CONFIGURATION()
GET_CONFIGURATION()
GET_INTERFACE()
SET_INTERFACE()
SET_DESCRIPTOR()

那个好心人给我讲一讲啊,,拜托了...哪怕讲一个也好啊

(PS:可不要告诉我看例子程序啊..我看不懂C51的程序,不知道什么意思... :()

控制端点根据中断值调用相应的函数来完成设备的枚举和培植用的呀!
[img=501x116]http://www.driverdevelop.com/forum//upload/CObject/2004-01-13_2.jpg[/img]
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-12-16 17:34
MCU于D12的通讯应该就是在该函数中的,我虽然没有过D12但是我现在在用2.0的ISP1581,与D12很相似。MCU访问D12就是写或读D12的寄存器,写数据有数据端口寄存器,先索引端点,然后将端口寄存器所在的地址写入16位数据即可,例如GET_INTERFACE()

#define UCHAR unsigned char
#define USHORT unsigned int

void Chap9_GetInterface(void)
{
//首先获得本次传输的方向,下面这几种的结构体储存的就是我们在
//SETUP阶段收到的那8个字节的数据
UCHAR dir = ControlData.DeviceRequest.bmRequestType & 080;
  if(!(dir))  //如果是0,即主机方往设备,则出错,停止端点
      Chap9_StallEP0InControlWrite();
  //下面检验收到的其他几个字节数据是否符合协议规定
  if (ControlData.DeviceRequest.wValue == 0&&
      ControlData.DeviceRequest.wIndex == 0 &&
      ControlData.DeviceRequest.wLength == 1)
  //如果是那就把用于替换的接口信息发给主机,下面这个函数的第
  //一个变量是在SetInterface()中设定的可替换的接口
  Chap9_SingleTransmitEP0(&bInterface_number, 1);
  else//否则说明出错,停止端点
      Chap9_StallEP0InControlRead();
}

上面用到的函数:
Chap9_StallEP0InControlWrite();
{
ISP1581_SetEndpointStatus(0x01, 0x01)//停止ep0in
ISP1581_SetEndpointStatus(0x00, 0x01);//停止ep0out
}
void ISP1581_SetEndpointStatus(UCHAR bEPIndex, UCHAR bStalled)
{
  //如果中断标志为0,关掉所有可屏蔽中断
  if(bISP1581flags.bits.At_IRQL1 == 0)
  disable();
  //设置端点索引寄存器,索引端点
  ISP1581_SetEPIndex(bEPIndex);
  //将0x01写入控制功能寄存器,停止端点
  outport(aport, rega_epctlfc);//地址
  outport(dport, bStalled);//数据
  //开中断
  if(bISP1581flags.bits.At_IRQL1 == 0)
  enable();
}
Chap9_StallEP0InControlRead();
{
  ISP1581_SetEndpointStatus(0x00, 0x01);//停止ep0out
  ISP1581_SetEndpointStatus(0x01, 0x01)//停止ep0in
}


不明白上述两个函数先停止IN后停止OUT和先停止OUT后停止IN有什么重要的原因,还往有明白的赐教哟

void Chap9_SingleTransmitEP0(PUCHAR buf, USHORT len)
{
  USHORT i;
  USHORT  c;
  if(bISP1581flags.bits.At_IRQL1 == 0)
      disable();
  //首先索引端点1in
  ISP1581_SetEPIndex(0x01);
  //将要写入端点的数据的数量len写入缓冲区尺寸寄存器,用来跟
  //踪数据是否写完
  outport(aport, rega_dcount);//地址放到地址线
  outport(dport, len);        //数据放到数据线
  
  //然后将数据端口寄存器的地址放到地址线
  outport(aport, rega_dport);
  //向端点中写入数据,一次16位,如果用8位需要变换一下
  for(i=0; i<len; i+=2, buf+=2 )
  {
      c = *buf;//获取数据
      outport(dport, c);//写入数据
  }
  if(bISP1581flags.bits.At_IRQL1 == 0)
     enable();
}

//写端点索引寄存器
void ISP1581_SetEPIndex(UCHAR bEPIndex)
{
  outport(aport, rega_epindex);//地址位端点索引寄存器的地址
  outport(dport, bEPIndex);//将要索引的端点号写进去
}

上面是我个人的见解,因为现在硬件还没做好,所以不能肯定能不能实现,如果有什么纰漏,请各位大虾指点出来,鄙人不胜感激!!
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-12-17 08:47
我想知道这些子程序在什么时候会被执行,也就是说主机什么时候会给出相应命令执行这些子程序阿..
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-12-17 13:20
这些命令是有主机方发起的,首先是控制传输的SETUP阶段,包括8个字节的数据,声明本次传输是干什么的,并指出第二阶段-数据阶段的传输方向以及传输什么数据。接着主机会向控制端点发送IN或OUT令牌来接收或发送数据,你在端点1的IN或OUT中断里完成数据阶段和握手阶段。你在SETUP中断中收到SETUP包后置标志位,退出中断后检查标志位,如果置位了就根据收到的命令运行和这些子函数。也就是说这些命令是主机上你的应用程序发起的。2.0总共11种标准请求,其中有一些是在枚举阶段必须进行的。而枚举的时候你主机上的应用程序可能还没有执行,所以这些命令就是你编写的驱动程序发动的了。我是这样理解的,因为我用开发板的时候只要插上电缆(应用程序还没执行)主机就会把驱动自动载入,而标准请求中的很多东西在枚举时主机是一定要的到的,所以就应该是驱动发动的了???????
  固件中你只要把这些需要返回或读取数据的子函数写好,就等待中断,然后处理。你觉得是不是这样呢?
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-12-17 14:44
这些命令是有主机方发起的,首先是控制传输的SETUP阶段,包括8个字节的数据,声明本次传输是干什么的,并指出第二阶段-数据阶段的传输方向以及传输什么数据。接着主机会向控制端点发送IN或OUT令牌来接收或发送数据,你在端点1的IN或OUT中断里完成数据
;
;
;
 


1,你的意思就是说应该在中断程序里把相应的程序的位置位,然后主程序里查询就好了.?(我也这么认为的)
2,我想知道到底那些子程序是在枚举阶段要执行的,也就是说主机在枚举过程中都会发出那些命令阿?
3,我不会写那些子程序,不知道它们应该完成什么功能啊?
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-12-17 15:20
看来你协议的第9章看的可不怎么样呀,虽然我比你好不了多少:)

你的上层驱动是不是你写的?如果是你应该知道里面都做了什么事情,有没有发送这些请求,因为我没做,所以我也不知道。

如果不是我们做的那层驱动里做的事情,那应该所有的11种标准请求都会产生(对于2.0的情况),也就是说你要写这11种标准请求的子程序,至少我看的固件程序里是这样处理的。每一种请求应该做什么你去看第9章的第3节以后的内容
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-12-17 16:01
看来你协议的第9章看的可不怎么样呀,虽然我比你好不了多少:)



呵呵.是呀.就是不怎么样啊..

我看了第9章了,(实际上是一直在看)关键是他说的太简单.我不知道如何是好了阿!

比如:GETCONFIGURATION()
此请求返回当前设备配置值.
如果返回0值表明设备未配置
如果WVALUE,WINDEX,WLENGTH的值与上表不同,设备相应无定义
缺省状态:该请求无定义
地址状态:返回0值
配置状态:非0的BCONFIGURATIONVALUE值被返回.

我该怎么写这个程序阿??我怎么判断当前设备有没有被配置阿?他说的那个地址状态.配置状态是什么意思.我该怎么处理阿..


所以我觉得我还不如干脆象我第一帖那样问得了呢. :)
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-12-17 17:10
    老哥呀,D12固件程序的C代码人家飞利浦公司都给你了,里面每种标准请求该怎么处理都写的清清楚楚,可是你说你看不懂C程序!!!我还没有看到过用汇编编的这些东西呢,我一上手就是C语言,你要是让我告诉你用汇编怎么做我可是压根不知道呀,当初汇编学的时候就学的挺烂的,才考了64分!我想你还是找一个做过D12的把C代码的意思给你详细解释一下吧,不过你要是翻译成汇编好像不是那么容易,光是那一堆结构体就够你受的了,下面说一下获得描述复函数里(是2.0的函数,我去掉了关于2.0的东西)都做了什么事,我只能把程序给你解释一下,我可没办法给你翻译成汇编!!!

void Chap9_GetDescriptor(void)
{
//获得描述的类型,确定是需要返回什么描述符
CHAR   bDescriptor = MSB(ControlData.DeviceRequest.wValue);
UCHAR  bDescriptorIndex = LSB  
                     (ControlData.DeviceRequest.wValue);

UCHAR   dir = ControlData.DeviceRequest.bmRequestType &0x80 if(!(dir))//如果传输方向是主机发往设备,则停止端点,因为发送
          //描述符的方向时设备到主机
    Chap9_StallEP0InControlWrite();
    //根据要返回的描述符类型返回相应的描述符
    switch(bDescriptor)
    {
        case USB_DEVICE_DESCRIPTOR_TYPE://如果是设备描述符
       {
        //发送设备描述符给主机,下面函数中的一个参数是要发送
        //的结构体的地址,第二个参数是该描述符结构体的大小,
        //结构体的定义我们后面会说
        Chap9_BurstTransmitEP0((PUCHAR)&DeviceDescr,
                             sizeof(USB_DEVICE_DESCRIPTOR));
        break;
        }
        //如果是配置描述符
         case USB_CONFIGURATION_DESCRIPTOR_TYPE:
        {
Chap9_BurstTransmitEP0((PUCHAR)&ConfigDescr,
                                CONFIG_DESCRIPTOR_LENGTH);
break;
          }
//如果是字符串描述符
case USB_STRING_DESCRIPTOR_TYPE:
//看是那种字符串,包括语言、厂商、产品、序列号、配置、接口
    switch(bDescriptorIndex)
    {
case STR_INDEX_LANGUAGE:
         Chap9_BurstTransmitEP0((PUCHAR) &strLanguage,
                    sizeof(USB_STRING_LANGUAGE_DESCRIPTOR));
break;

                      case STR_INDEX_MANUFACTURER:
Chap9_BurstTransmitEP0((PUCHAR)&strManufacturer,
                sizeof(USB_STRING_MANUFACTURER_DESCRIPTOR));
break;

case STR_INDEX_PRODUCT:
Chap9_BurstTransmitEP0((PUCHAR)&strProduct,
                    sizeof(USB_STRING_PRODUCT_DESCRIPTOR));
break;

case STR_INDEX_SERIALNUMBER:
Chap9_BurstTransmitEP0((PUCHAR)&strSerialNum,
                sizeof(USB_STRING_SERIALNUMBER_DESCRIPTOR));
break;

case STR_INDEX_CONFIGURATION:
          Chap9_BurstTransmitEP0((PUCHAR)&strConfiguration,
             sizeof(USB_STRING_CONFIGURATION_DESCRIPTOR) );
break;

case STR_INDEX_INTERFACE:
Chap9_BurstTransmitEP0((PUCHAR)&strInterface,
                 sizeof(USB_STRING_INTERFACE_DESCRIPTOR) );
break;

default:
   Chap9_StallEP0InControlRead();
   break;
}
break;

default:
Chap9_StallEP0InControlRead();

break;
}
}
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-12-17 17:30
//USB设备描述符
typedef struct _USB_DEVICE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT bcdUSB;
UCHAR bDeviceClass;
UCHAR bDeviceSubClass;
UCHAR bDeviceProtocol;
UCHAR bMaxPacketSize0;
USHORT idVendor;
USHORT idProduct;
    USHORT bcdDevice;
    UCHAR iManufacturer;
    UCHAR iProduct;
    UCHAR iSerialNumber;
    UCHAR bNumConfigurations;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;

//根据上面的设备描述符的内容设置的ISP1581开发板的设备描述符,你也可以参照它的写出你的设备描述符

USB_DEVICE_DESCRIPTOR DeviceDescr =
{
sizeof(USB_DEVICE_DESCRIPTOR),
USB_DEVICE_DESCRIPTOR_TYPE,//0X01表示设备描述符
0x0110,//版本号,1.1的值应该为0x0110 (我不确定)
0x00,  //设备类
0,
0,
EP0_PACKET_SIZE,//你的应该是16字节吧,那就是0x10
0X04CC,// Philips APIC Vendor ID
0x1B41, // ISP1581 ISA evaluation kit PID.
0X0000,// Reserved release number
           //下面3个我现在不明白
STRING_EN * STR_INDEX_MANUFACTURER,
STRING_EN * STR_INDEX_PRODUCT,
STRING_EN * STR_INDEX_SERIALNUMBER,
1
};
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-12-17 17:41
//配置描述符
typedef struct _USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;

下面是符合配置描述符规定的1581的配置描述
USB_CONFIGURATION_DESCRIPTOR ConfigDescr =
{
sizeof(USB_CONFIGURATION_DESCRIPTOR),//配置描述符的长度
USB_CONFIGURATION_DESCRIPTOR_TYPE,//类型,0x02
//下一项是配置描述符中所有内容的总长度,包括配置描述符,端点描述符等
SWAP(CONFIG_DESCRIPTOR_LENGTH),
1,
1,
STRING_EN * STR_INDEX_CONFIGURATION,
USB_Configureation_bmAttributes,//远程唤醒和自供电
0x1
};

还有端点描述符,什么厂商、语言等,我就不一一列举了,我想你应该有相应的1.1的资料,资料里肯定都有。你还是看一下吧,如果说你没学过c语言我可不太相信哟。是不是你以前不是学这个的
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-12-17 17:47
1.1的上述结构DDK里都有,你用MSDN可以查到它的有关用法,你就把结构里的每一个元素填上相应的内容发给主机就行了。

上面的东西仅做参考,具体用起来不一定能行,因为我没有试过,只是把别人的程序摘出来给你解释一下而已,如果有什么错误,那我十分抱歉!同时希望有做过的能指出来,我们共同进步!!!
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-12-17 17:56
我肚里就这么多货,全倒给你了!:)
也许不久的将来等我的东西调试成功了那我会有更大的发言权,不过那时你可能早就搞定了,强烈建议你看看用C编写的固件程序,如果你找不到用你需要的语言编写的程序的话,光看协议好象是做不出来的啦,因为协议里只是定义了这些东西,但并没有告诉你怎么用!!有什么问题再讨论。 :D :D :P
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-12-18 08:05
真的非常感谢你.我会好好看看的..
mikal
驱动牛犊
驱动牛犊
  • 注册日期2002-11-19
  • 最后登录2007-10-19
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-12-18 08:29
Device Descriptor:
bcdUSB:             0x0110
bDeviceClass:         0x00
bDeviceSubClass:      0x00
bDeviceProtocol:      0x00
bMaxPacketSize0:      0x08 (8)
idVendor:           0x3538
idProduct:          0x0001
bcdDevice:          0x0205
iManufacturer:        0x01
0x0409: \"PQI\"
iProduct:             0x02
0x0409: \"Travel Flash\"
iSerialNumber:        0x03
0x0409: \"4710765066451\"
bNumConfigurations:   0x01

ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed:     Full
Device Address:       0x02
Open Pipes:              2

Endpoint Descriptor:
bEndpointAddress:     0x81
Transfer Type:        Bulk
wMaxPacketSize:     0x0040 (64)
bInterval:            0x00

Endpoint Descriptor:
bEndpointAddress:     0x00
Transfer Type:     Control
wMaxPacketSize:     0x0507 (1287)
wInterval:          0x0202
bSyncAddress:         0x40

Configuration Descriptor:
wTotalLength:       0x0020
bNumInterfaces:       0x01
bConfigurationValue:  0x01
iConfiguration:       0x00
bmAttributes:         0x80 (Bus Powered )
MaxPower:             0x32 (100 Ma)

Interface Descriptor:
bInterfaceNumber:     0x00
bAlternateSetting:    0x00
bNumEndpoints:        0x02
bInterfaceClass:      0x08
bInterfaceSubClass:   0x06
bInterfaceProtocol:   0x50
iInterface:           0x04
0x0409: \"SMC CF SD\"

Endpoint Descriptor:
bEndpointAddress:     0x81
Transfer Type:        Bulk
wMaxPacketSize:     0x0040 (64)
bInterval:            0x00

Endpoint Descriptor:
bEndpointAddress:     0x02
Transfer Type:        Bulk
wMaxPacketSize:     0x0040 (64)
bInterval:            0x00


the above description is a successed \" read card device \"
you can refer the material ,maybe you can use the reference.
good luck to you !
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-12-18 11:56


the above description is a successed \" read card device \"
you can refer the material ,maybe you can use the reference.
good luck to you !  


thanks.
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-12-18 12:53
Device Descriptor:
Endpoint Descriptor:
bEndpointAddress:     0x02
Transfer Type:        Bulk
wMaxPacketSize:     0x0040 (64)
bInterval:            0x00


the above description is a successed \" read card device \"
you can refer the material ,maybe you can use the reference.
good luck to you !  


有了mikal给你的描述符,你应该可以参照编自己的描述符和子函数了吧,这些对我也有帮助,在此谢过了! 呵呵 :)
游客

返回顶部