首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于嵌入式实时操作系统的现场总线网关的设计 03

基于嵌入式实时操作系统的现场总线网关的设计 03

2.堆栈单位及增长方向
  任务堆栈的数据类型必须和CPU的寄存器长度一致,通过为OS_STK声明正确的数据类型来完成的,在本设计中的声明如下:
  typedef unsigned int OS_STK;
  / * Each stack entrY is 32_bit wide */
  堆栈的增长用OS_STK_GROWTH来设置,OS_STK_GROWTH为O表示堆栈从下向上增长,为1表示堆栈从上向下增长,在本设计中的定义如下:
  #define OS_STK_GROWTH        l
  3.宏定义
  宏定义包括开关中断及任务切换的宏定义:
  #define OS_ENTER_CRITICAL(  )armDis-ableInt(    )
  #define OS_EXIT_CRITICAL(    )armEna-bleInt(    )
  #define OS_TASK_SW(    )OSCtXSw(    )
  (二)OS_CPU_C.C
  OS_CPU_C.C主要包括任务堆栈的初始化,及系统钩子函数的定义。在这个文件中包括以下6个函数:
  OSTaskStkInit(    )
  OSSTaskCreateHook(     )
  OSTaskDelHook(    )
  OSTaskSwHook(    )
  OSTaskStatHook(    )
  OSTimeTickHook(    )
  其中5个HOOK函数如果没有特殊要求,只需声明为空函数,必须修改的是OSTaskStkInit (  )。 OSTaskStkInit(   )的实现如下:
  void * OSTaskStkInit (void (* task)  (void * pd),void * pdata,void * ptos,INTl6Uopt)
  {
  unsigned  int * stk;
  opt=opt;
  stk= (unsigned int * ) Ptos;
  *--stk= (unsigned int) task;
  *- -stk=0;
  *--stk=0,
  *--stk=0,
  *--stk=0,
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0;
  *--stk=0 (unsigned int) Pdata;
  *--stk= (SVCMODE | OxO);
  *--stk= (SVCMODE | OxO);
  return( (void*) stk);
  在 OSTaskCreate(     )或 OSTaskCreateEXt(    )中调用该函数来初始化任务的堆栈,返回堆栈指针STK。
  (三)OS_CPU_A.S
  μC/OS-Ⅱ的移植工作的重点和难点主要体现在O_CPU_A.S文件的实现上,主要编写下面四个汇编语言函数:
  OSStanHighRdy(    )
  OSCtxSw(    )
  OSIntCtxSw(    )
  OSTickISR(    )
  其中最困难的工作又集申在OSIntCtxSw(  )和OSTickISR(    )两个函数,因为这两个函数不仅和相关硬件定时器、中断积存器的设置有关,而且集中体现了移植的思路。下面分别介绍(具体代码限于篇幅不详细列出)。
  1.OSStartHighRdy(    )
  此函数只在多任务启动时由OSStart(  )函数调用一次,功能是从最高优先级任务的TCB中得到该任务的堆栈指针sp,并用该指针恢复CPU现场,使得最高优先级任务处于就绪状态。
  2.OSCtxSw(    )
  该函数实现了任务级的任务切换,流程如图4所示。任务级的任务切换是通过发软中断指令来完成的,软中断矢量指向该函数。在μC/OS-Ⅱ系统中,如果一个任务调用了某个函数而使得更高优先级任务进入了就绪状态,系统就会通过发SWI来找到OSCtxSw(  );在该任务的最后,系统会调用OSShed(  )将最高优先级任务的地址加载到OSTCBHighRdy中,再调用OS_TASK_SW( )来执行软中断调用OSCtxSw( )进行任务切换。
  3.0SIntCtxSw(    )
  该函数实现了中断级任务切换,流程如图4(b)所示。在ISR中,可能会引起任务的切换,如果需要进行任务切换,则在ISR的最后通过0S_IntEXit(   )调用OSIntCtxSw(   )实现中断级任务切换。此函数和OSCtxSw(  )函数类似,不同的是该函数进行的是中断级任务切换,在系统进入中断时,CPU现场己被保存过了,因此在该函数中不再进行CPU现场保护,只需对堆栈指针做相应的调整即可。
  4.OSTickISR(   )
  该函数用来实现定时器时钟中断处理,但在本系统的设计过程中,把定时器中断设为IRQ中断模式,并且IRQ中断包括好多中断源。因引,把该函数作为IRQ中断的ISR,再根据中断号来调用具体的各个中断服务程序(如定时器中断、MAC中断等)。
  另外,在系统的启动文件中,需要建立每种异常的异常向量表,并强制arm处理器状态位svc管理模式。
  五、总 结
  本设计在s3c451Ob的硬件平台上成功移植了μC/OS-Ⅱ,并且移植了嵌入式TCP/IP协议栈LwIP,实现了WorldFIP现场总线和Internet之间的相互通信,使得WorldFIP现场总线成为真正开放的工业现场总线。在网关的整体设计中,由于系统比较大,任务数较多,用实时内核来管理调度这些任务,要消
耗较多的CPU使用率和系统的内存,具有一定的局限性,但在CPU足够快,内存足够大的情况下,使用嵌入式网关设计,在保证了工业现场总线的实时性和可靠性的基础上,更有利于系统的集成度和再次开发。
返回列表