欢迎来到唯一的 picoTCP 存储库。
picoTCP 是一种小型模块化 TCP/IP 堆栈,专为嵌入式系统和物联网而设计。它由Altran 智能系统公司积极开发。
该代码是根据 GNU GPL v2 和 GNU GPL v3 的条款发布的。保留一些权利。版权所有者可自行决定是否适用其他许可证。
通过阅读我们的 GitHub wiki 上的入门指南,了解如何在项目中使用 picoTCP。
如需了解更多信息,请发送电子邮件给我们,或通过 Twitter、Facebook 或 Reddit 联系我们。
想了解 picoTCP 的代码质量吗?查看我们的 TiCS 分数
功能测试: - 单元测试: - RFC 合规性: - TICS 质量: Coverity Scan 构建状态:
通过保持界面简单,向新平台和操作系统的移植工作量非常低。给你一个指示:移植到新平台可以在 3 天或更短的时间内完成,新操作系统可以在一天内完成,如果你真的很疯狂,你可以在一个晚上完成初始移植。不同的平台意味着不同的编译器,这就是为什么我们不断地使用一堆编译器来编译我们的堆栈。以下列表显示了一些当前支持的平台、设备驱动程序和编译器。
picoTCP 运行平台:ARM Cortex-M 系列(ST Micro STM、NXP LPC、TI Stellaris、Freescale K64F)、ARM ARM9 系列(ST Micro STR9)、Texas Instruments(MSP430)、Microchip(PIC24、PIC32)、Atmel( AVR 8位)、Linux(用户空间(TUN/TAP)、内核空间)、Windows(用户空间(TAP))
picoTCP 所使用的网络设备:BCM43362 (IEEE 802.11)、MRF24WG (IEEE 802.11)、LPC 以太网 ENET/EMAC (IEEE 802.3)、Stellaris 以太网 (IEEE 802.3)、STM32 以太网 (IEEE 802.3)、Wiznet W5100 (IEEE 802.3)、 USB CDC-ECM (CDC1.2)、PPP、虚拟驱动程序(TUN/TAP、VDE、Libpcap)
(RT)OSes picoTCP 已集成到:无操作系统/裸机、FreeRTOS、mbed-RTOS、Frosted、linux/POSIX、MS DOS、MS Windows
picoTCP 已与以下库集成:wolfSSL、mbedTLS、Mongoose RESTful 库、MicroPython
picoTCP 编译器:GCC、Clang、TCC、ARM-RCVT、IAR、XC-16、XC-32、MSP-GCC、AVR-GCC
不幸的是,我们无法发布所有代码,因为有些部分依赖于不兼容 GPL 的代码或二进制文件,有些部分是根据商业合同开发的,有些部分包含非常粗糙的概念验证代码。如果您想了解有关商业许可下的可用性的更多信息,或者使用我们的专家服务进行移植或驱动程序开发的可能性,请随时通过 [email protected] 与我们联系。
你最喜欢的不在列表中?查看 wiki,了解有关如何将 picoTCP 移植到新平台的信息和示例!
功能在 picoTCP 中作为模块开发,允许您在应用程序中选择所需的功能。这会产生尽可能最小的堆栈,同时仍符合互联网标准。下面的示意图概述了所有已实现的协议。
本示例使用 Ubuntu 14.04。它也适用于其他 Linux 发行版,但您可能需要更改一些包名称。请参阅设置环境以获取更多信息。
sudo apt-get install git check vde2 libvdeplug2-dev libpcap0.8-dev openvpn wireshark
git clone https://github.com/tass-belgium/picotcp
cd picotcp
make TAP=1
cd ..
然后创建一个新目录,例如example
,并创建一个包含以下内容的文件: //: # (下面的代码是通过我们的 CI 提取的 - 请保留代码提取器注释不变!) //: # (代码提取器启动)
#include
#include
#include
#include
#include
#define NUM_PING 10
static int finished = 0 ;
/* gets called when the ping receives a reply, or encounters a problem */
void cb_ping ( struct pico_icmp4_stats * s )
{
char host [ 30 ];
pico_ipv4_to_string ( host , s -> dst . addr );
if ( s -> err == 0 ) {
/* if all is well, print some pretty info */
printf ( "%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu msn" , s -> size ,
host , s -> seq , s -> ttl , ( long unsigned int ) s -> time );
if ( s -> seq >= NUM_PING )
finished = 1 ;
} else {
/* if something went wrong, print it and signal we want to stop */
printf ( "PING %lu to %s: Error %dn" , s -> seq , host , s -> err );
finished = 1 ;
}
}
int main ( void ){
int id ;
struct pico_ip4 ipaddr , netmask ;
struct pico_device * dev ;
/* initialise the stack. Super important if you don't want ugly stuff like
* segfaults and such! */
pico_stack_init ();
/* create the tap device */
dev = pico_tap_create ( "tap0" );
if (! dev )
return -1 ;
/* assign the IP address to the tap interface */
pico_string_to_ipv4 ( "192.168.5.4" , & ipaddr . addr );
pico_string_to_ipv4 ( "255.255.255.0" , & netmask . addr );
pico_ipv4_link_add ( dev , ipaddr , netmask );
printf ( "starting pingn" );
id = pico_icmp4_ping ( "192.168.5.5" , NUM_PING , 1000 , 10000 , 64 , cb_ping );
if ( id == -1 )
return -1 ;
/* keep running stack ticks to have picoTCP do its network magic. Note that
* you can do other stuff here as well, or sleep a little. This will impact
* your network performance, but everything should keep working (provided
* you don't go overboard with the delays). */
while ( finished != 1 )
{
usleep ( 1000 );
pico_stack_tick ();
}
printf ( "finished !n" );
return 0 ;
}
现在我们可以通过运行来编译它并链接它
gcc -c -o main.o -I../picotcp/build/include main.c
gcc -o main.elf main.o ../picotcp/build/lib/libpicotcp.a
接下来我们将创建一个持久的分流设备 - 一个虚拟网络端口。您不需要每次都重复此操作,设备将一直存在,直到您重新启动,或者直到您执行sudo tunctl -d tap0
sudo tunctl -u < username >
sudo ifconfig tap0 192.168.5.5
现在,您应该能够运行./main.elf
,并看到类似的输出
Protocol ethernet registered (layer: 2).
Protocol ipv4 registered (layer: 3).
Protocol ipv6 registered (layer: 3).
Protocol icmp4 registered (layer: 4).
Protocol icmp6 registered (layer: 4).
Protocol igmp registered (layer: 4).
Protocol udp registered (layer: 4).
Protocol tcp registered (layer: 4).
Device tap0 created.
Assigned ipv4 192.168.5.4 to device tap0
starting ping
64 bytes from 192.168.5.5: icmp_req=1 ttl=64 time=5 ms
64 bytes from 192.168.5.5: icmp_req=2 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=3 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=4 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=5 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=6 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=7 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=8 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=9 ttl=64 time=0 ms
64 bytes from 192.168.5.5: icmp_req=10 ttl=64 time=0 ms
finished !
当应用程序运行时,您还可以运行
ping 192.168.5.4
向另一个方向发送 ping。
运行wireshark,并嗅探tap0接口。然后再次运行./main.elf
,看看会发生什么。您应该看到从 picoTCP 到 Linux 的 ARP 请求以及回复。之后,您应该会看到来回的 ping 请求和回复。
请注意,有时您可能会看到很多其他内容,IPv6 路由器请求、各种广播、mDNS、DNS-SD 等 - 当您的 Linux 注意到新的网络接口已启动并开始各种发现时,您就会看到这些内容。对于持久 TAP 设备,这种情况通常仅在您第一次启动应用程序时发生。启动一个新的wireshark捕获,然后再次启动应用程序,现在应该干净多了。
现在您可以对main.c
文件进行一些更改,并进行一些实验!保留一些 ping 的统计数据(最大、最小、平均时间)。打开 UDP 套接字,将一些内容发送到 Linux 上的 netcat 实例。或者构建一个基本的端口扫描器,查看您的计算机上打开了哪些端口。
这只是一个非常快速的概述,更多信息可以在我们的 wiki 中找到。
非常欢迎贡献者。报告错误,提出改进文档的方法,或编写一些新代码。
但请注意,在接受您的代码之前,我们会要求您签署我们的贡献者许可协议。您的代码仍然受您的版权保护,并且将始终在 GPLv2 和 GPLv3 下可用。但是,此 CLA 使我们能够在其他许可证(包括我们的商业许可证)下使用 picoTCP(包括来自像您这样的外部贡献者的代码)。通过做商业项目,我们可以继续投资 picoTCP 的质量和功能。