正在加载图片...
周立功单片机发展有限公司Tel:(020)38730916387309173873097638730977Fax:38730925 起动任务 TaskStart(优先级3) 初始化 PDIUSBD2 ∥创建各个任务 for( 4 err= ReadPortl(1, &Cmd, 200) 待主机命令 if if( Cmd=Oxon) OSSemPost( TaskRecI Sem),∥发送信号量给任务 OSSemPost(Task Rec2 Sem); 发送信号量给任务2 任务1 Task RecI(优先级1) 任务2 TaskRec2(优先级2) OSSemPend( TaskRecl Sem, 0, &err); OSSemPendcTaskRec2 Sem, 0, &err), ∥应答USB主机 Write PortI(1, &ack, 200); 应答USB主机 ReadPort2( RW NUMS,Bu,200),∥接收数据 ReadPort2( RW NUMS,Buf200),∥接收数据 OSTimeDly(1); Buff[0]=OSPrioCur, /际识任务优先级B= OSPrioCu 识任务优先级 WritePort2( RW NUMS,Bu200;,∥发送数据 WritePort2( RW NUMS,Bum1200),∥发送数捷 图4例子运行示意图 任务1和任务2发送1024个字节给PC机时,第一个字节为对应任务的优先级(Bum OSPriocur)。这样,主机就知道收到的数据来自哪一个任务了 任务1收到信号量以后,还要给主机一个应答,而不是立即就接收来自主机的1024个 字节,这是因为任务1收到信号量不一定就能很快取得运行的机会(可能它还在等待其它信 号量,而且任务切换还要花一定的时间,因此切换时间具有不确定性),而采用应答机制就确 保了 Read Port2( RW NUMS Bu;200)一定有机会运行了,该函数给出了接收数据的“地方(接 收缓冲区Buf”,有了地方存放数据,才能收取数据 任务1为什么要延时1个时钟周期才发送数据呢?这是为了显示两个任务争着发送 1024个字节的结果而特别使用的。因为 OSTimeDly(1)的延时是“不可靠”的,也就是说有 可能存在着抖动这一点在北京航空航天大学出版社出版的《嵌入式实时操作系统COS-I》 (第2版)的第2.32小节中详细分析了这一点。 由于ARM的执行速度很快,要使 OSTimeDly(1)抖动的可能性较大,就需要把μC/Os-I 每秒发生的中断次数减少,即改变 os cfg. h中宏定义 OS TICKS PER_SEC的值 #define OS TICKS PER SEC 100 那么怎样才看得出两个任务争着发送数据的结果呢?这就需要USB主机端程序的配合 2.PG机端程序分析 PC机端的编程必须与设备端紧密结合,在本例子中,PC机端程序的流程如图5所示。 图5的虚线表示USB主机(PC机)与 PDIUSBD12之间的发送与接收关系,箭头指向 接收的一方。图中,PC机为主机,主动发起了命令, PDIUSBD12设备对命令做出响应 图5的1和2,PC机使任务1就绪,并且收到了任务1的应答。 图5的3和4,PC机使任务2就绪,并且收到了任务2的应答。 图5的5和6,PC机向设备端发送了两次1024个字节,第1次被任务1接收到,第2广州周立功单片机发展有限公司 Tel: (020) 38730916 38730917 38730976 38730977 Fax: 38730925 //初始化PDIUSBD12 //创建各个任务 for (;;){ err = ReadPort1(1,&Cmd,200); //等待主机命令 if (err == OS_NO_ERR){ if (Cmd == 0x01) OSSemPost(TaskRec1_Sem); //发送信号量给任务1 else OSSemPost(TaskRec2_Sem); //发送信号量给任务2 } for (;;){ OSSemPend(TaskRec1_Sem,0,&err); WritePort1(1,&ack,200); //应答USB主机 ReadPort2(RW_NUMS,Buff,200); //接收数据 OSTimeDly(1); Buff[0] = OSPrioCur; //标识任务优先级 WritePort2(RW_NUMS,Buff,200); //发送数据 } for (;;){ OSSemPend(TaskRec2_Sem,0,&err); WritePort1(1,&ack,200); //应答USB主机 ReadPort2(RW_NUMS,Buff,200); //接收数据 Buff[0] = OSPrioCur; //标识任务优先级 WritePort2(RW_NUMS,Buff,200); //发送数据 } 起动任务TaskStart(优先级3) 任务1TaskRec1(优先级1) 任务2TaskRec2(优先级2) 图 4 例子运行示意图 任务 1 和任务 2 发送 1024 个字节给 PC 机时,第一个字节为对应任务的优先级(Buff[0] = OSPrioCur)。这样,主机就知道收到的数据来自哪一个任务了。 任务 1 收到信号量以后,还要给主机一个应答,而不是立即就接收来自主机的 1024 个 字节,这是因为任务 1 收到信号量不一定就能很快取得运行的机会(可能它还在等待其它信 号量,而且任务切换还要花一定的时间,因此切换时间具有不确定性),而采用应答机制就确 保了 ReadPort2(RW_NUMS,Buff,200)一定有机会运行了,该函数给出了接收数据的“地方(接 收缓冲区 Buff)”,有了地方存放数据,才能收取数据。 任务 1 为什么要延时 1 个时钟周期才发送数据呢?这是为了显示两个任务争着发送 1024 个字节的结果而特别使用的。因为 OSTimeDly(1)的延时是“不可靠”的,也就是说有 可能存在着抖动。这一点在北京航空航天大学出版社出版的《嵌入式实时操作系统 µC/OS-II》 (第 2 版)的第 2.32 小节中详细分析了这一点。 由于 ARM 的执行速度很快,要使 OSTimeDly(1)抖动的可能性较大,就需要把 µC/OS-II 每秒发生的中断次数减少,即改变 os_cfg.h 中宏定义 OS_TICKS_PER_SEC 的值: #define OS_TICKS_PER_SEC 100 那么怎样才看得出两个任务争着发送数据的结果呢? 这就需要 USB 主机端程序的配合 了。 2. PC 机端程序分析 PC 机端的编程必须与设备端紧密结合,在本例子中,PC 机端程序的流程如图 5 所示。 图 5 的虚线表示 USB 主机(PC 机)与 PDIUSBD12 之间的发送与接收关系,箭头指向 接收的一方。图中,PC 机为主机,主动发起了命令,PDIUSBD12 设备对命令做出响应。 图 5 的 1 和 2,PC 机使任务 1 就绪,并且收到了任务 1 的应答。 图 5 的 3 和 4,PC 机使任务 2 就绪,并且收到了任务 2 的应答。 图 5 的 5 和 6,PC 机向设备端发送了两次 1024 个字节,第 1 次被任务 1 接收到,第 2 - 9 -
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有