打印
[应用相关]

关于usb的iap程序。

[复制链接]
6283|33
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lvpeng1979|  楼主 | 2007-11-23 17:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在st网站上下载了um0290。关于usb的iap程序。

其中有个GETSTATUS函数:
/********************************************************************
* Function Name  : GETSTATUS
* Description    :
* Input          : Length
* Output         : None
* Return         : Pointer to data
********************************************************************/
.........
if ( ((Pointer >= 0x40000000) && (Pointer <= 0x40006000)) ||
((Pointer >= 0x400C0000) && (Pointer <= 0x400C2000)))  /* 8K sectors */
{
    DeviceStatus[1]=0xE8;   /* 1 second */
    DeviceStatus[2]=0x03;
    DeviceStatus[3]=0x00;
}
else if ( Pointer == 0x40008000 ) /* 32K sector */
{
    DeviceStatus[1]=0xD0;  /* 2 seconds */
    DeviceStatus[2]=0x07;
    DeviceStatus[3]=0x00;
}
else if  ((Pointer >= 0x40010000) && (Pointer <= 0x40030000)) /* 64K sectors */
{
    DeviceStatus[1]=0xA0;  /* 4 seconds */
    DeviceStatus[2]=0x0F;
    DeviceStatus[3]=0x00;
}
#ifdef _STR710_EVAL
else if  ((Pointer >= 0x60000000) && (Pointer <= 0x6000E000)) /* 8K sectors */
{
    DeviceStatus[1]=0xE8;  /* 1 seconds */
    DeviceStatus[2]=0x03;
    DeviceStatus[3]=0x00;
}
else if  ((Pointer >= 0x60010000) && (Pointer <= 0x60400000)) /* 64K sectors */
{
DeviceStatus[1]=0xD0;  /* 2 seconds */
DeviceStatus[2]=0x07;
DeviceStatus[3]=0x00;
}
#endif
.........

在程序的其他地方看到DeviceStatus[1]=1;  /*bwPollTimeout = 1ms*/,按此计算以上时间1 second ,2 second,4 second  确实正确。

我在调试的过程中执行擦除操作时很长慢,但我在DeviceStatus[1]=0xE8;  /* 1 seconds */ 处设置断点控制程序执行时,程序可以很快地做擦除操作。

pc端使用的是自做的dfu软件。确定没有问题。不知道问题出在哪里?

请各位指教


沙发
浪淘沙| | 2007-11-23 18:05 | 只看该作者

没看明白你的问题在哪里,帖子里没有说是什么问题

只看到一些叙述。

使用特权

评论回复
板凳
lvpeng1979|  楼主 | 2007-11-26 08:40 | 只看该作者

不好意思。先请教一下这个问题

先请教一下这个问题:

 DeviceStatus[1]=0xE8;   /* 1 second */
 DeviceStatus[2]=0x03;
 DeviceStatus[3]=0x00;

为什么表示的是1 second 。这个时间做什么用的。

使用特权

评论回复
地板
浪淘沙| | 2007-11-26 10:04 | 只看该作者

对不起,请楼主能够说明白一点

你所说的这段代码是哪个文件中的,在第几行?我找了一下,很多地方都有这样的设置。

使用特权

评论回复
5
lvpeng1979|  楼主 | 2007-11-26 10:39 | 只看该作者

um0290.zip 里有个usb_prop.c文件,它里面有个GETSTATUS函数。

um0290.zip 里有个usb_prop.c文件,它里面有个GETSTATUS函数。大概在这个文件672行,因为怕你我看的不是一样的版本,只能说个大概。这个函数不大,可以查找这个函数GETSTATUS。函数GETSTATUS里面有下述一段代码。

/********************************************************************
* Function Name  : GETSTATUS
* Description    :
* Input          : Length
* Output         : None
* Return         : Pointer to data
********************************************************************/
.........
if ( ((Pointer >= 0x40000000) && (Pointer <= 0x40006000)) ||
((Pointer >= 0x400C0000) && (Pointer <= 0x400C2000)))  /* 8K sectors */
{
    DeviceStatus[1]=0xE8;   /* 1 second */
    DeviceStatus[2]=0x03;
    DeviceStatus[3]=0x00;
}
else if ( Pointer == 0x40008000 ) /* 32K sector */
{
    DeviceStatus[1]=0xD0;  /* 2 seconds */
    DeviceStatus[2]=0x07;
    DeviceStatus[3]=0x00;
}
else if  ((Pointer >= 0x40010000) && (Pointer <= 0x40030000)) /* 64K sectors */
{
    DeviceStatus[1]=0xA0;  /* 4 seconds */
    DeviceStatus[2]=0x0F;
    DeviceStatus[3]=0x00;
}
#ifdef _STR710_EVAL
else if  ((Pointer >= 0x60000000) && (Pointer <= 0x6000E000)) /* 8K sectors */
{
    DeviceStatus[1]=0xE8;  /* 1 seconds */
    DeviceStatus[2]=0x03;
    DeviceStatus[3]=0x00;
}
else if  ((Pointer >= 0x60010000) && (Pointer <= 0x60400000)) /* 64K sectors */
{
DeviceStatus[1]=0xD0;  /* 2 seconds */
DeviceStatus[2]=0x07;
DeviceStatus[3]=0x00;
}
#endif
.........

其中有关于 DeviceStatus[1]=0xE8;   /* 1 second */
           DeviceStatus[2]=0x03;
           DeviceStatus[3]=0x00;
这几行。这样赋值为什么表示的是1 second 这个时间做什么用的。



使用特权

评论回复
6
浪淘沙| | 2007-11-26 10:42 | 只看该作者

um0290.zip 里有多个usb_prop.c文件,你说的是STR7还是STR9

使用特权

评论回复
7
lvpeng1979|  楼主 | 2007-11-26 11:43 | 只看该作者

STR7

STR7

使用特权

评论回复
8
浪淘沙| | 2007-11-26 11:46 | 只看该作者

um0290.zip里共有21个usb_prop.c文件,好不容易找到你说的那个


因为你的问题具有普遍性,所以我才耐下心地找了一下,下次请说得清楚一些,这样可以节省每个人的时间。

关于楼主在3楼的问题,请参考下面的状态图,这在USB DFU文本的第28页,你所列出的那段程序,漏掉了关键的部分,就是之前的case语句,根据这个语句,这里是处理DNLOAD_SYNC状态,即下图中的状态3;再结合该GETSTATUS函数的功能,根据USB DFU文本的第20页中第6.1.2节,这个时间被定义为:Minimum time, in milliseconds, that the host should wait before sending a subsequent DFU_GETSTATUS request. (The purpose of this field is to allow the device to dynamically adjust the amount of time that the device expects the host to wait between the status phase of the next DFU_DNLOAD and the subsequent solicitation of the device’s status via DFU_GETSTATUS. This permits the device to vary
the delay depending on its need to erase memory, program the memory, etc.)

更详细的说明,请参考Device Firmware Upgrade 1.1 (new version 31-Aug-2004)

使用特权

评论回复
9
lvpeng1979|  楼主 | 2007-11-26 11:56 | 只看该作者

谢谢你耐心的回答

谢谢你耐心的回答,我的问题没有描述仔细。赫赫。谢谢你提供的文档。我得研究一下。

使用特权

评论回复
10
lvpeng1979|  楼主 | 2007-11-28 14:06 | 只看该作者

擦除和下载非常慢。

以上说的iap程序,和st网站上下载的str7的dfu软件一起使用时,擦除和下载非常慢。我是移植到str711上使用的。不知道是什么原因?请问如何才能加快速度。

使用特权

评论回复
11
浪淘沙| | 2007-11-28 15:12 | 只看该作者

不知道“擦除和下载非常慢”有多慢?

关于擦除和编程的时间,请参考STR71x的数据手册,如果你的擦除和下载时间与数据手册中的数值相仿,说明一切正常;如果相差很大(请详细说明相差多大),就要查查哪里出问题了?是擦除和编程的时间太长超出了数据手册的数值?还是在其他地方耽误了时间。

使用特权

评论回复
12
浪淘沙| | 2007-11-28 17:19 | 只看该作者

请问你自己写的PC端的DFU软件是否正确地等待了8楼所描述的

非常怀疑你的PC软件是否遵守了这个时间要求,因为之前你并没有搞清楚它的意义。

这个等待时间非常重要,要知道在DFU操作中,Flash的擦除和写入是不能被任何中断所打断;如果你的PC软件不遵守这个等待要求,在Flash的擦除或写入未完成之前就发出下一个USB包,而此时如Firmware响应了USB的中断,则Flash的操作将不能正常进行;若Firmware不响应USB的中断,则PC端将进入错误处理,同样会造成混乱。

请仔细确认PC端的DFU软件是否满足这些要求。

使用特权

评论回复
13
lvpeng1979|  楼主 | 2007-11-29 14:21 | 只看该作者

调用了st的STDFU library

PC端的DFU软件是根据st提供的dfu开发包写的,调用了st的STDFU library (STDFU.DLL)写的。根据文件UM0384 User manual - DfuSe Application Programming Interface 。里面的函数只能读不能写。后来我用了st提供的有个名为STDFU Tester的dfu软件,是一样的效果。您说的bwPollTimeout等待时间应该没问题。

使用特权

评论回复
14
浪淘沙| | 2007-11-29 14:47 | 只看该作者

请确认几件事情

十分怀疑你PC端的程序等待时间有没问题,请确认几件事情:

1)你使用的是UM0290的程序还是UM0384的程序?一楼说是UM0290而15楼说是UM0384,我没有看过这些程序,但不排除它们不能互用的可能。

2)最好能够得到USB线上的数据包的时序,因为从Firmware端的程序看,如果PC端也没有耽误时间,那么Firmware不可能在七、八分钟后才响应,否则PC端软件早已做超时处理了;而且Firmware端没有理由不响应中断,不知12楼的结论“中途中断程序的运行发现到了while(1)处(iap主程序的最后语句),没有响应usb中断。”是如何得到的?

使用特权

评论回复
15
lvpeng1979|  楼主 | 2007-11-29 17:33 | 只看该作者

Bus Hound软件侦测一部分usb数据


1)UM0290是iap的程序包;而PC端得dfu软件是由UM0412包解压安装所得,其安装后的目录里有个文件叫DfuSe Application Programming Interface,打开这个文件后看到文件第一页标题写的是UM0384 User manual - DfuSe Application Programming Interface 。您说的第一点没有弄错。 

2)从Bus Hound软件侦测一部分usb数据:
                                                            
  16.0  DI     00 e8 03 00  04 00   ....   1362.1.0        
   7.0  DI     03 01 00 00          ....   1363.1.0(5)     
  16.0  DI     00 e8 03 00  04 00   ...... 1368.1.0        
   7.0  DI     03 01 00 00          ....   1369.1.0(5)     
  16.0  DI     00 00 00 00  05 00   ...... 1374.1.0        
  16.0  DO     41 00 80 00  40      A...@  1375.1.0        
  16.0  DI     00 e8 03 00  04 00   ...... 1376.1.0        
   7.0  DI     03 01 00 00          ....   1377.1.0(5)     
  16.0  DI     00 e8 03 00  04 00   ...... 1382.1.0        
   7.0  DI     03 01 00 00          ....   1383.1.0(5)     
  16.0  DI     00 e8 03 00  04 00   ...... 1388.1.0        
   7.0  DI     03 01 00 00          ....   1389.1.0(5)     
  16.0  DI     00 e8 03 00  04 00   ...... 1394.1.0        
   7.0  DI     03 01 00 00          ....   1395.1.0(5)     
  16.0  DI     00 00 00 00  05 00   ...... 1400.1.0        
  16.0  DO     41 00 00 01  40      A...@  1401.1.0        
  16.0  DI     00 d0 07 00  04 00   ...... 1402.1.0        
   7.0  DI     03 01 00 00          ....   1403.1.0(10)    
  16.0  DI     00 d0 07 00  04 00   ...... 1413.1.0        
   7.0  DI     03 01 00 00          ....   1414.1.0(10)    
  16.0  DI     00 d0 07 00  04 00   ...... 1424.1.0        
   7.0  DI     03 01 00 00          ....   1425.1.0(10)    
  16.0  DI     00 d0 07 00  04 00   ...... 1435.1.0        
   7.0  DI     03 01 00 00          ....   1436.1.0(10)    
  16.0  DI     00 d0 07 00  04 00   ...... 1446.1.0        
   7.0  DI     03 01 00 00          ....   1447.1.0(10)    
  16.0  DI     00 d0 07 00  04 00   ....   1457.1.0        
   7.0  DI     03 01 00 00          ....   1458.1.0(10)    
                   
DO是pc送过来的,DI是设备送到pc的。发现时间耗在设备不断的发送给pc这个等待时间(擦除8k扇区时是1s,32k时是2s,64k时是4s)。就好像pc段软件没接收到一样。

使用特权

评论回复
16
浪淘沙| | 2007-11-29 18:24 | 只看该作者

请问你用ST提供的PC端软件也有这个问题吗?

看样子不是等待时间的问题,还是你PC端软件的问题。你用ST提供的PC端软件配合ST的Firmware也有这个问题吗?

描述一下你PC端软件是如何做的,请跟据我在8楼给出的状态图描述,尤其是状态2转到状态3、状态5转到状态3时wLength分别是多少?你是否一次传送太多数据造成Firmware端缓冲区溢出?

另外,在你认为编程结束的地方看看几个变量的数值是多少?
DeviceState
DeviceStatus <-- 所有的分量
wlength
wBlockNum

使用特权

评论回复
17
lvpeng1979|  楼主 | 2007-11-29 18:47 | 只看该作者

我用的是st网站上下的两个包

我用的是st网站上下的两个包,一个是pc端dfu软件um0412;一个是设备端iap程序um0290.zip。在一个str710开发板上使用也是这样的。两端都是st提供的。没有用我写的东西也是这样的。您能否试下这两个包。

根据您提的思路我在看看。

使用特权

评论回复
18
lvpeng1979|  楼主 | 2007-11-29 21:10 | 只看该作者

很难得到请求DFU_GETSTATUS


D:lvpengusb1.bmp
上图是做擦除操作时,程序耗时的时刻,此时设备不断的发送给pc等待时间(擦除8k扇区时是1s,32k时是2s,64k时是4s)。根据右边的变量来看,是因为USBbRequest是0x00,没有得到请求DFU_GETSTATUS。不知道为什么很难得到请求。

使用特权

评论回复
19
浪淘沙| | 2007-11-29 21:33 | 只看该作者

PC不发请求,设备不会自动发数据

因为设备所处的状态不对,当然PC端会陷入循环。而设备的状态不对,不是因为操作不对(你已经说擦除和编程都正确完成),也不是因为硬件有问题(USB可以正确地收发数据),所以我只能怀疑PC端软件有问题,要知道Firmware是不会检测PC命令是否错误。

你最好还是检查一下编程结束时几个变量的数值,这些数据非常重要,它们可以告诉我们现在Firmware运行到状态图中的什么地方了。只有知道了你的程序状态转换的路径才能有效地分析原因。

我没用过Bus Hound,不知道如何解读你抓到的数据,这里有时间的信息吗?能看见ACK或NAK吗?各个域的意义都是什么?

使用特权

评论回复
20
lvpeng1979|  楼主 | 2007-11-29 21:47 | 只看该作者

20楼叙述的图


做擦除操作时,程序耗时的时刻停留在iap主程序最后的while(1);处。此图显示了相应的变量。长期没有得到请求DFU_GETSTATUS,所以不能进入除程序
void DFU_Status_Out (void)
{
    DEVICE_INFO *pInfo = &Device_Info;
    u32 i,Addr,DATA;
    if(pInfo->USBbRequest == DFU_GETSTATUS)
    {  
        if(DeviceState ==STATE_dfuDNBUSY)
 {
     if (wBlockNum == 0 )   /* Decode the Special Command*/
            {
                if ( (Load_Buffer[0] ==  CMD_GETCOMMANDS) &&(wlength == 1) )
                {
                }
                else if  (( Load_Buffer[0] ==  CMD_SETADDRESSPOINTER )&&(wlength == 5))
                {
                    Pointer  = Load_Buffer[1];
                    Pointer += Load_Buffer[2] << 8;
                    Pointer += Load_Buffer[3] << 16;
                    Pointer += Load_Buffer[4] << 24;
                }
                else if (( Load_Buffer[0] ==  CMD_ERASE )&&(wlength == 5))
                {
                    Pointer  = Load_Buffer[1];
                    Pointer += Load_Buffer[2] << 8;
                    Pointer += Load_Buffer[3] << 16;
                    Pointer += Load_Buffer[4] << 24;
                    if  ( Pointer < 0x60000000 )  /* Internal Flash */
                    {
                        Internal_FLASH_WritePrConfig(Internal_FLASH_SectorMask(Pointer),DISABLE);
                        Internal_FLASH_SectorErase(Internal_FLASH_SectorMask(Pointer));
                    }
............................
 
 
 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

36

帖子

0

粉丝