嵌入式开发者社区

标题: 【分享】USB_HOST_MSC移植到BIOS详细步骤 [打印本页]

作者: lushidegreen    时间: 2015-6-4 14:31
标题: 【分享】USB_HOST_MSC移植到BIOS详细步骤
Step1.新建BIOS(选择Typical)工程,命名为USB_HOST_MSC_sysbios



作者: lushidegreen    时间: 2015-6-4 14:32
Step2. 把原USB_HOST_MSC工程中的main.c文件外的两个c文件复制到
USB_ HOST _MSC_sysbios工程中。

作者: lushidegreen    时间: 2015-6-4 14:33
Step3. 复制原工程的main.c文件中除main函数外的所有代码,粘贴到新工程的main.c文件中#include <ti/sysbios/knl/Task.h>语句后面

作者: lushidegreen    时间: 2015-6-4 14:33
Step4.把原工程main函数中do之前的语句复制,粘贴到新工程main函数
System_printf("enter main()\n");语句后面

作者: lushidegreen    时间: 2015-6-4 14:35
本帖最后由 lushidegreen 于 2015-6-4 14:37 编辑

Step5. 把原工程main函数中do{……}while(1);中的所有内容复制,粘贴到新工程main函数taskFxn()任务函数中,替代其原来的内容。并在do语句前加入变量定义int iStatus;。
Step6. 添加平台配置,如下图
作者: lushidegreen    时间: 2015-6-4 14:38
本帖最后由 lushidegreen 于 2015-6-4 14:39 编辑

Step7. 参考原工程添加包含路径[attach]301[/attach]
Step8. 参考原工程添加包含库文件
[attach]302[/attach]
需要注意的是,Step6Step7Step8的相关路径应该根据自己的文件夹结构进行设置。



作者: lushidegreen    时间: 2015-6-4 14:40
本帖最后由 lushidegreen 于 2015-6-4 14:41 编辑

Step9.编译工程,出现1个错误和23个警告。
双击警告并不能正确定位错误位置。
[attach]303[/attach]
错误原因是integer.h22行枚举类型BOOL的定义与xdc\std.h中对FALSETRUE有冲突。
根据错误信息..\..\..\Library\ThirdParty\fatfs\src\integer.h,找到Library\ThirdParty\fatfs\src文件夹,把其中的3h文件都复制到新工程目录下。
Step7中设置的包含路径../../../Library/ThirdParty/fatfs/src删除。
重新编译,依然出现1个错误和23个警告。
双击错误,可定位到integer.h文件的22行。
integer.h文件22行改为typedef enum {mFALSE = 0, mTRUE} BOOL;,把工程中ff.c文件中的所有FALSE替换成mFALSE,所有TRUE替换成mTRUE


作者: lushidegreen    时间: 2015-6-4 14:42
重新编译,注意此时要用Rebuild Project,没有错误,23个警告。
到工程选项中添加一个宏定义ewarm。
[attach]304[/attach]
重新编译,剩1个警告。这是由于InterruptInit()函数的声明和实体不一致造成的,在前面声明部分加上static即可。
应注意的是,在原工程USB_HOST_MSC中配置了一个宏DMA_MODE,该宏可能是用于控制USB的数据传输方式。因此在新工程中也应定义DMA_MODE,方法和添加ewarm定义相同。


作者: lushidegreen    时间: 2015-6-4 14:43
本帖最后由 lushidegreen 于 2015-6-4 14:44 编辑

Step10.删除DSP中断初始化函数InterruptInit(),因为BIOS启动后会对DSP中断进行初始化。
Step11.注册USB中断函数
USBInterruptInit()的功能是将USB中断映射到硬件中断INT5上,中断ID为SYS_INT_USB0(19),中断函数USB0HostIntHandler ()。
在BIOS中,到cfg文件中进行配置,如下图,配置完成后,将USBInterruptInit()函数删除。
[attach]305[/attach]


作者: lushidegreen    时间: 2015-6-4 14:45
Step12.接下来要处理的是DelayTimerSetup()等函数。
这是StarterWare中的函数,所在头文件为delay.h。到StarterWare目录
C:\ti\C6748_StarterWare_1_20_04_01下找到delay.c文件 (需事先安装StarterWare),将该文件复制到新建的工程中。
查看delay.c文件,可以发现其中的函数,都是直接调用了另外一个名字很像的函数。
delay.h文件所列函数如下图,上面的5个函数分别直接调用了下面的5个函数,即本质上只有5个函数。
[attach]306[/attach]
StarterWare目录搜索发现,下面的5个函数的实现是在sysdelay.c中。将sysdelay.c文件复制到新建工程中。
重新编,出现一个错误,将sysdelay.c中的#include "evmC6748.h"语句删除即可。


作者: lushidegreen    时间: 2015-6-4 14:46
本帖最后由 lushidegreen 于 2015-6-4 14:56 编辑

SysDelayTimerSetup()函数的功能是初始化定时器TMR0_TMR12,即TMR0的低32位,然后将TMR0_TMR12中断映射到硬件中断INT10上,中断号为SYS_INT_T64P0_TINT12 (4),中断函数为TimerIsr()。
Sysdelay()函数的功能是,设置定时时间、启动定时器TMR0_TMR12,并等待直到定时时间到,即实现延时功能。在BIOS下实现时,可直接使用Task_sleep()实现。因此,将Sysdelay()函数改为如下:
void Sysdelay(unsigned int milliSec)
{
        Task_sleep(milliSec);
}
再在文件头部加#include <ti/sysbios/knl/Task.h>语句。
SysStartTimer()函数用于设定定时时间,并启动定时器TMR0_TMR12。
SysStopTimer()函数用于停止定时器TMR0_TMR12。
SysIsTimerElapsed()函数用于检测定时时间是否已经到。

作者: lushidegreen    时间: 2015-6-4 14:46
本帖最后由 lushidegreen 于 2015-6-4 14:51 编辑

由于BIOS系统占用了TMR0,sysdelay.c中TMR0相关的操作都换成对TMR1的操作:把SOC_TMR_0_REGS全部替换成SOC_TMR_1_REGS;把SYS_INT_T64P0_TINT12全部替换成SYS_INT_T64P1_TINT12。
将TimerIsr()函数中的其它代码全部屏蔽,只保留留flagIsrCnt = 0;。
将AintcTimerIntrSetUp()函数整个注释,将SysDelayTimerSetup()函数内部代码全部屏蔽。
然后到cfg文件中配置TMR1,以实现SysDelayTimerSetup()函数的功能。配置步骤如下图:
[attach]307[/attach]
[attach]308[/attach]
[attach]309[/attach]

作者: lushidegreen    时间: 2015-6-4 14:49
本帖最后由 lushidegreen 于 2015-6-4 14:53 编辑

[attach]311[/attach]
重新编译,出现3个错误和2个警告。原因是TimerIsr()是局部函数,把TimerIsr()的static属性去掉即可。
重新编译程序,没有错误和警告。
将程序下载到TL6748开发板,其运行结果和裸奔的USB_HOST_MSC是一样的。
至此,USB_HOST_MSC例程成功移植到SYS/BIOS下。



作者: leeweer    时间: 2015-6-11 20:40
提示: 作者被禁止或删除 内容自动屏蔽
作者: pengchhui    时间: 2015-7-24 08:38
不错,可以学习下
作者: human    时间: 2016-1-26 15:09
感谢您的无私分享的,广州创龙决定给您奖励的
作者: lushidegreen    时间: 2016-1-27 08:46
human 发表于 2016-1-26 15:09
感谢您的无私分享的,广州创龙决定给您奖励的

是不是真的?准备奖励点啥?
作者: human    时间: 2016-2-29 11:01
lushidegreen 发表于 2016-1-27 08:46
是不是真的?准备奖励点啥?

给您奖励500代金券,直接使用!跟客服说明就行
作者: lushidegreen    时间: 2016-3-4 09:31
human 发表于 2016-2-29 11:01
给您奖励500代金券,直接使用!跟客服说明就行

非常感谢!
但是好像没什么可买的。
我现在做的是音频产品,创龙淘宝里面没发现音频相关的模块。
作者: lushidegreen    时间: 2016-3-4 09:49
本帖最后由 lushidegreen 于 2016-3-10 16:54 编辑

要不给我奖励点实物吧,这500代金券换成一个读卡器和3张8G的SD卡寄给我就可以了。
这个还实用点,我可以用在公司产品上,自己也可以用在相机上。
作者: zwl773993221    时间: 2016-3-27 15:46
lushidegreen 发表于 2015-6-4 14:49
重新编译,出现3个错误和2个警告。原因是TimerIsr()是局部函数,把TimerIsr()的static属性去掉即可。
重新 ...

大神,之所以是大神,就是因为他做了别人没有做的事儿,他才成为大神。今天加班,从早上到现在这一刻,我终于按着你说的移植成功,牛,给你32个赞,拿去,:kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss::kiss:
作者: zwl773993221    时间: 2016-3-27 15:49
而且我发现你的描述和用词相当准确,知道任何一个可能出错的步骤,高,高,的确高!!!!!
作者: lushidegreen    时间: 2016-4-15 18:03
lushidegreen 发表于 2015-6-4 14:49
重新编译,出现3个错误和2个警告。原因是TimerIsr()是局部函数,把TimerIsr()的static属性去掉即可。
重新 ...

后续的开发过程中发现本帖有个问题。
当把读卡器从USB OTG接口拔下时,串口会发送“...disconnect”信息,
但是如果保持读卡器和USB OTG的连接,只拔插SD卡,程序会就会卡死。
作者: lushidegreen    时间: 2016-4-15 18:12
经仿真跟踪,发现程序卡在了usbhostenum.c文件的USBHCDControlTransfer( )函数,卡在4222行语句:
while((g_sUSBHEP0State[ulIndex].eState != EP0_STATE_IDLE)&&(!IsTimerElapsed()))

硬件问题导致了while中的第一个条件总数成立。
然后就是IsTimerElapsed()函数了,该函数在工程的delay.c文件中。
该函数的返回值跟一个变量flagIsrCnt有关,而该变量被清零,才可能退出上述的while。

搜索文件,发现只有一个地方能将flagIsrCnt清零,那就是TimerIsr( )定时中断函数。
因此我判断,定时中断没有被正常调用。运行测试,发现果真如此。

作者: lushidegreen    时间: 2016-4-15 18:14
分析发现,是USB枚举超时了,而超时退出机制没有起作用。
控制USB枚举超时的函数都在工程的delay.c文件中,因此修改就行了。
作者: lushidegreen    时间: 2016-4-15 18:16
本帖最后由 lushidegreen 于 2016-4-15 18:19 编辑

修改第一步:修改定时器的配置。
既然是无法进入定时器中断函数引起的,而在此定时器的作用只是判定超时,改用其他方法,不用中断了。
.cfg文件中,将定时器配置改为下图:
[attach]734[/attach]
使用定时器1的低32位,周期赋值-1,其实就是0xFFFFFFFF,自动运行,周期性连续运行,中断号-1表示不启用,中断函数也写成null。


作者: lushidegreen    时间: 2016-4-15 18:27
修改第二步:修改delay.c中的函数。
先在开头定义两个变量:static volatile unsigned long tickstart, delaytime;
StartTimer函数改为:
void StartTimer(unsigned int milliSec)
{
        tickstart = TimerCounterGet(SOC_TMR_1_REGS, TMR_TIMER12);
        delaytime = (unsigned long)milliSec * TMR_PERIOD_LSB32;
}
将StopTimer函数内容清空。
IsTimerElapsed函数改为:
unsigned int IsTimerElapsed(void)
{
        unsigned long tickcurrent;
        tickcurrent = TimerCounterGet(SOC_TMR_1_REGS, TMR_TIMER12);
        if ((tickcurrent - tickstart) > delaytime) {
                return TRUE;
        } else {
                return FALSE;
        }
}
可以将TimerIsr函数删除。


作者: lushidegreen    时间: 2016-4-15 18:31
至此,修改完成。

在应用程序中,如果检测到SD卡操作失败,则可通过
USBHMSCDriveClose(g_ulMSCInstance);函数关闭USB MSC设备,
并清除变量iStatus = 0;

然后重新跳到USB MSC的初始化部分执行,程序即可继续运行。
作者: weihuahua123    时间: 2016-12-29 22:56
早点发这个啊,当初学的时候看了好多资料才弄懂了,支持一下
作者: xiaoluoshan    时间: 2018-1-29 21:41
很详细啊。厉害啊
作者: 1895    时间: 2019-9-19 10:52
太棒了吧,我想做VIPF_OV2640程序的迁移,先看看楼主的步骤学学




欢迎光临 嵌入式开发者社区 (https://51ele.net/) Powered by Discuz! X3.4