(1)停止传送;
(2)发送32bit的jam序列;
(3)等待载波空闲;
(4)产生随机延迟;
(5)返回,重传条件集。
在接收帧,每个接收ISR检查接收到的包尾EOP(End Of Packet)。一帧接收到时,接收函数执行以下操作:
(1)帧校验序列;
(2)地址检查,单址通信和多址通信;
(3)检查保留地址;
(4)帧长度(太长或太短)检查。
冲突检测是通过监听载波侦听指示位来进行的。最大的延迟为16bit的时间。
在MAC层应用程序接口,MAC客户(上层)通过初始化数据指针和缓冲区长度发送一个包。然后调用“Transmit_Packet”函数,返回值是发送的结果。主程序通过轮询调用一个“Receive_ Packet”函数接收一个包。非零返回值指示接收到一个有效的包。
在网络缓冲区(Netbuffer),较高层定义一个叫netbuffer的数据结构。这是访问TCP/UDP数据报不同元素的最好方法。与原始IP包一起,有一些分配给数据包元素(例如:源IP地址、目的IP地址、选项等)的指针。这些指针是静态的。与指针相关的还有长度域,这样很容易改变netbuffer的选项数目。为了构成一个MAC帧,发送程序必须根据指针和长度域从netbuffer中把数据级联起来。
4 ipOS应用程序的编写
ipOS操作系统可工作在单任务模式或多任务模式下。在大多数情况下单任务模式的程序足以满足实时应用需求。利用Ubicom的Unity IDE开发环境生成的一个工程,最基本的有3个文件:entry.s、isr.s和main.c。
4.1引导程序代码
所有引导程序代码都放在entry.s文件中。这段代码在复位向量处加载了一个占位程序。当IP2022上电时,IP2022跳到复位向量处执行引导程序代码。该代码完成以下功能:
(1)更新FCFG寄存器,这样代码执行速度对时钟频率而言是优化的;
(2)设置堆栈指针指向数据存储器的末端;
(3)通用寄存器初始化为0;
(4)把.data段从FLASH中加载到数据存储器的开始处;
(5)将.data段之后的数据存储器区域设置为0来容纳.bss段;
(6)把.pram段从FLASH加载到程序SRAM的开始处;
(7)将程序SRAM区域设置为0来容纳.pram_data段;
(8)引导程序完成,跳到main()主函数。
注意:用户的任何初始化代码应该加入到main()函数中,不应该加到entry.s文件中。
4.2中断服务函数
isr.s是中断服务函数(1SR)文件。当一个异步事件发生时,就会执行对应的ISR。在大多数使用虚拟外设的应用中,都要用到定时器timer0中断来控制周期性的进程。有两种ISR模板用于帮助基于timer0虚拟外设的开发。第一种是“Simple ISR template using timer0”,另一种是“Complex ISR Template”。
如果仅有一个虚拟外设或所有的虚拟外设需要以同样的频率执行,那么使用第一个模板是很合适的。对于较为复杂的应用,可以使用“Complex ISR template”模板。详细的例子可参考其SDK帮助文件。
4.3主体结构
main.c文件是应用程序的主体结构,主要包括配置块(CONFIC_BLOCK)和main()函数。
配置块是系统配置参数的信息,它存储在IP2022的FLASH存储器中,控制着系统时钟、PLL分频系数和其它的一些系统参数。
在main()函数中,主程序的结构非常简单。首先是调用debug_init()、heap add()和timer_init()这3个函数对操作系统进行初始化;然后是创建虚拟外设实例进行监听,用户的回调函数(Callback Function)作为监听函数的参数;接着是设置中断服务函数并使其开始运行;最后是对虚拟外设的端口进行轮询。当轮询函数检测到相应的状态时,就会调用相应的回调函数。一般来说,这些叵调函数是用户自己设计的处理函数。
下面是一个使用UART虚拟外设的例子: