本文以mx231cc平台,cpu为avr为例,大致理清Contiki通信之数据接收过程。相关的代码在cpu\avr、core\net、platform\mx231cc目录下。
首先在platform\mx231cc目录下打开contiki-conf.h文件,里面配置了相关的网络协议栈: 说明:网络层驱动为 sicslowpan_driver ,MAC层的驱动为 nullmac_driver ,RDC层的驱动为 sicslowmac_driver ,802154包的生成和解析驱动为 framer_802154 ,RADIO层驱动为 rf230_driver 。这些驱动在系统源码中均有定义,不赘述。
接下来就来看看platform\mx231cc目录下的contiki-mx231cc-main.c主文件。我们注意到对各个网络中各个层的初始化: 我们来看看最重要的 NETSTACK_RADIO.init() ,正是这一初始化开始了Radio接收数据的进程,部分主要的代码如下: 通过语句 process_start(&rf230_process, NULL) 启动了 rf230_process ,我们来看看 rf230_process 的部分主要代码: 上述代码表明,当该进程收到 PROCESS_EVENT_POLL 事件时,就会从射频芯片读数据。射频芯片每收到一个frame,都会向cpu 发送一个中断,进而CPU将收到的数据读走。
中断函数部分主要代码如下: 所以 RADIO 层收包部分就结束了,读取数据后将数据交至 RDC 层进行处理。 NETSTACK_RDC.input() ;下面来看看 NETSTACK_RDC.input() 即 core\net\ma c目录 sicslowmac.c 下的 input_packet() 函数的部分主要代码: 提交给 mac 层继续处理。进入函数 nullmac_driver.input() ,即 core\net\mac 下的 nullmac.c 中的 packet_input ,代码如下: 因为 nullMAC 层对数据什么也不做,直接转接数据,故直接交由 6Lowpan 进行处理,进入函数 sicslowpan_driver.input() , 即 core/net/sicslowpan.c 中的 input() 函数,这是6LowPan适配层,主要负责对 mac 层数据进行压缩报头等数据分析和重组,部分主要代码如下: 接着 sicslowpan 将数据提交给网络层进行处理,进入函数 tcpip_input() 函数,即位于 core\net 下的 tcpip.c 文件。 此函数给 tcpip_process 进程发送了一个 packet_input 事件并激活这个线程。 接着进入 packet_input() 函数,同样在 tcpip.c 文件下,部分主要代码如下: 最后进入 uip_input() 函数,至此数据成功的转交到 uIP 协议栈进行处理,在 uip_porcess 会对网络层以及传输层的包头进行分析最后通过 UIP_APPCALL() 函数会把数据包分发到不同的应用程序接着由应用程序进行处理。
首先在platform\mx231cc目录下打开contiki-conf.h文件,里面配置了相关的网络协议栈: 说明:网络层驱动为 sicslowpan_driver ,MAC层的驱动为 nullmac_driver ,RDC层的驱动为 sicslowmac_driver ,802154包的生成和解析驱动为 framer_802154 ,RADIO层驱动为 rf230_driver 。这些驱动在系统源码中均有定义,不赘述。
接下来就来看看platform\mx231cc目录下的contiki-mx231cc-main.c主文件。我们注意到对各个网络中各个层的初始化: 我们来看看最重要的 NETSTACK_RADIO.init() ,正是这一初始化开始了Radio接收数据的进程,部分主要的代码如下: 通过语句 process_start(&rf230_process, NULL) 启动了 rf230_process ,我们来看看 rf230_process 的部分主要代码: 上述代码表明,当该进程收到 PROCESS_EVENT_POLL 事件时,就会从射频芯片读数据。射频芯片每收到一个frame,都会向cpu 发送一个中断,进而CPU将收到的数据读走。
中断函数部分主要代码如下: 所以 RADIO 层收包部分就结束了,读取数据后将数据交至 RDC 层进行处理。 NETSTACK_RDC.input() ;下面来看看 NETSTACK_RDC.input() 即 core\net\ma c目录 sicslowmac.c 下的 input_packet() 函数的部分主要代码: 提交给 mac 层继续处理。进入函数 nullmac_driver.input() ,即 core\net\mac 下的 nullmac.c 中的 packet_input ,代码如下: 因为 nullMAC 层对数据什么也不做,直接转接数据,故直接交由 6Lowpan 进行处理,进入函数 sicslowpan_driver.input() , 即 core/net/sicslowpan.c 中的 input() 函数,这是6LowPan适配层,主要负责对 mac 层数据进行压缩报头等数据分析和重组,部分主要代码如下: 接着 sicslowpan 将数据提交给网络层进行处理,进入函数 tcpip_input() 函数,即位于 core\net 下的 tcpip.c 文件。 此函数给 tcpip_process 进程发送了一个 packet_input 事件并激活这个线程。 接着进入 packet_input() 函数,同样在 tcpip.c 文件下,部分主要代码如下: 最后进入 uip_input() 函数,至此数据成功的转交到 uIP 协议栈进行处理,在 uip_porcess 会对网络层以及传输层的包头进行分析最后通过 UIP_APPCALL() 函数会把数据包分发到不同的应用程序接着由应用程序进行处理。