打印
[应用相关]

VSF中的PT线程实例:USB主机协议栈OHCI_HCD的初始化代码

[复制链接]
1667|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Simon21ic|  楼主 | 2014-12-23 00:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Simon21ic 于 2014-12-23 01:37 编辑

我是来秀代码的逗比

OHCI是全速USB使用的主机控制器标准,这里就以各种不同的代码对比看看哪个好玩。

linux2.2:
1721 static int hc_reset (ohci_t * ohci)
1722 {
1723         int timeout = 30;
1724         int smm_timeout = 50; /* 0,5 sec */
1725                 
1726         if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
1727                 writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
1728                 dbg("USB HC TakeOver from SMM");
1729                 while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
1730                         wait_ms (10);
1731                         if (--smm_timeout == 0) {
1732                                 err("USB HC TakeOver failed!");
1733                                 return -1;
1734                         }
1735                 }
1736         }      
1737                 
1738         /* Disable HC interrupts */
1739         writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
1740
1741         dbg("USB HC reset_hc: %x ;", readl (&ohci->regs->control));
1742
1743         /* Reset USB (needed by some controllers) */
1744         writel (0, &ohci->regs->control);
1745         
1746         /* HC Reset requires max 10 ms delay */
1747         writel (OHCI_HCR,  &ohci->regs->cmdstatus);
1748         while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
1749                 if (--timeout == 0) {
1750                         err("USB HC reset timed out!");
1751                         return -1;
1752                 }      
1753                 udelay (1);
1754         }        
1755         ohci->disabled = 0;
1756         return 0;
1757 }
linux是多任务操作系统,作为高帅富,可以肆无忌惮的调用wait_ms。我等DS只能羡慕妒忌恨。

当然,对于我的非阻塞状态机,这么调用是致命的,那就列一下传统状态机的实现方式:
static vsf_err_t vsfohci_init_nb(struct vsfohci_t *vsfohci)
{
        uint32_t temp;
        struct ohci *ohci = vsfohci->ohci;

        switch (vsfohci->init_state)
        {
                case VSFOHCI_INITSTAT_UNINITED:
                        temp = readl(&ohci->regs->control);
                        if (temp & OHCI_CTRL_IR)
                        {
                                /* request ownership */
                                writel(OHCI_OCR, &ohci->regs->cmdstatus);
                                vsfohci->init_state = VSFOHCI_INITSTAT_POLL_OCR;
                                vsfohci->loops = 50;
                        }
                        else
                        {
                                vsfohci->init_state = VSFOHCI_INITSTAT_DISABLE_INT;
                        }
                        break;

                case VSFOHCI_INITSTAT_POLL_OCR:
                        /* quiry ownership */
                        temp = readl(&ohci->regs->control);
                        if (temp & OHCI_CTRL_IR)
                        {
                                writel(OHCI_OCR, &ohci->regs->cmdstatus);
                                vsfohci->loops--;
                                if (vsfohci->loops <= 0)
                                {
                                        vsfohci->init_state = VSFOHCI_INITSTAT_UNINITED;
                                        return VSFERR_FAIL;
                                }

                                vsfohci_init_delay_nb(vsfohci, 10, VSFOHCI_INITSTAT_POLL_OCR);
                        }
                        else
                        {
                                vsfohci->init_state = VSFOHCI_INITSTAT_DISABLE_INT;
                        }
                        break;

                case VSFOHCI_INITSTAT_DISABLE_INT:
                        /* Disable HC interrupts */
                        writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);

                        /* Reset USB (needed by some controllers) */
                        ohci->hc_control = 0;
                        writel(ohci->hc_control, &ohci->regs->control);

                        /* HC Reset requires max 10 us delay */
                        writel(OHCI_HCR,  &ohci->regs->cmdstatus);
                        temp = readl(&ohci->regs->cmdstatus);
                        if (temp & OHCI_HCR)
                                vsfohci_init_delay_nb(vsfohci, 2, VSFOHCI_INITSTAT_POLL_HCR);
                        else
                                vsfohci->init_state = VSFOHCI_INITSTAT_HC_START;
                        break;

                case VSFOHCI_INITSTAT_POLL_HCR:
                        temp = readl(&ohci->regs->cmdstatus);
                        if (temp & OHCI_HCR)
                        {
                                vsfohci->init_state = VSFOHCI_INITSTAT_UNINITED;
                                return VSFERR_FAIL;
                        }

                        vsfohci->init_state = VSFOHCI_INITSTAT_HC_START;
                        break;

                case VSFOHCI_INITSTAT_HC_START:
....
关键的延时函数:
static void vsfohci_init_delay_nb(struct vsfohci_t *vsfohci, uint32_t ms,
                                                                                           enum ohci_init_state next_state)
{
        vsfohci->tickcnt = interfaces->tickclk.get_count();
        vsfohci->delayms = ms;
        vsfohci->init_next_state = next_state;
        vsfohci->init_state = VSFOHCI_INITSTAT_DELAY;
}
延时只是进入一个叫VSFOHCI_INITSTAT_DELAY的状态对应的时间长度,时间到后,再进入下一状态
系统可以正常运行,也是非阻塞的,只是代码。。。。。。

下面是EDA构架的PT线程:
static vsf_err_t vsfohci_init_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
        vsf_err_t err;
        struct vsfusbh_t *usbh = (struct vsfusbh_t *)pt->user_data;

        vsfsm_pt_begin(pt);

        /* init HCD timer */
        usbh->hcd_timer.sm = pt->sm;

        /* get resource for OHCI controller */
        if (VSFERR_NONE != vsfohci_get_resource(usbh, CONFIG_SYS_USB_OHCI_REGS_BASE))
                return VSFERR_FAIL;

        /* request ownership */
        if (VSFERR_NOT_READY == vsfohci_init_request_ownership(usbh->hcd_data))
        {
                do
                {
                        /* delay 10 ms, then check OCR */
                        usbh->hcd_timer.interval = 10;
                        usbh->hcd_timer.evt = VSFSM_EVT_HCD_WAIT_OCR;
                        vsftimer_register(&usbh->hcd_timer);
                        vsfsm_pt_wfe(pt, VSFSM_EVT_HCD_WAIT_OCR);

                        /* timer expired, unregister it */
                        vsftimer_unregister(&usbh->hcd_timer);

                        /* check OCR */
                        err = vsfohci_init_check_ocr(usbh->hcd_data);
                        if (err < 0)
                                return err;
                } while (err == VSFERR_NOT_READY);
        }

        /* disable HCD interrupt */
        if (VSFERR_NOT_READY == vsfohci_init_disable_interrupt(usbh->hcd_data))
        {
                /* delay 2ms, then check HCR */
                usbh->hcd_timer.interval = 2;
                usbh->hcd_timer.evt = VSFSM_EVT_HCD_WAIT_HCR;
                vsftimer_register(&usbh->hcd_timer);
                vsfsm_pt_wfe(pt, VSFSM_EVT_HCD_WAIT_HCR);

                /* timer expired, unregister it */
                vsftimer_unregister(&usbh->hcd_timer);

                /* check HCR */
                err = vsfohci_init_check_hcr(usbh->hcd_data);
                if (err < 0)
                        return err;
        }

        /* delay XX ms before the HCD is ready */
        usbh->hcd_timer.interval = vsfohci_init_hc_start(usbh->hcd_data);
        usbh->hcd_timer.evt = VSFSM_EVT_HCD_WAIT_HCD;
        vsftimer_register(&usbh->hcd_timer);
        vsfsm_pt_wfe(pt, VSFSM_EVT_HCD_WAIT_HCD);

        /* timer expired, unregister it */
        vsftimer_unregister(&usbh->hcd_timer);

        vsfsm_pt_end(pt);
        return VSFERR_NONE;
}
当然,这个代码还只是一个刚刚接触PT线程的人写的,还不是最终代码。
那么问题来了,这个PT线程的代码,是阻塞的吗?
沙发
mmuuss586| | 2014-12-23 19:11 | 只看该作者

不错,谢谢楼主分享;

使用特权

评论回复
板凳
monkeypony| | 2014-12-30 21:53 | 只看该作者

使用特权

评论回复
地板
icecut| | 2014-12-30 22:20 | 只看该作者
看起来是阻塞的.直接让 cpu 歇菜了....

使用特权

评论回复
5
周董| | 2014-12-30 22:43 | 只看该作者
对linux操作系统不是很熟悉。。帮顶一下!!

使用特权

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

本版积分规则

个人签名:www.versaloon.com --- under construction

266

主题

2597

帖子

104

粉丝