mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-08 19:30:39 +00:00
Added first draft of a part15-tcpip write-up
This commit is contained in:
parent
3e8f5bed75
commit
907068000b
5 changed files with 66 additions and 4 deletions
63
part15-tcpip/README.md
Normal file
63
part15-tcpip/README.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
Writing a "bare metal" operating system for Raspberry Pi 4 (Part 15)
|
||||
====================================================================
|
||||
|
||||
Adding a TCP/IP stack
|
||||
---------------------
|
||||
Having achieved "proof of life" from our Ethernet module in _part14-spi-ethernet_, you're doubtless wondering how to go from there to serving web pages, posting tweets on Twitter or perhaps even just simply responding to a ping!
|
||||
|
||||
This is where you'll need a fully-fledged TCP/IP stack that goes way beyond handcrafted ARPs, implementing many more protocols to achieve efficient bi-directional communication.
|
||||
|
||||
In this part we make use of some code from Guido Socher of [tuxgraphics.org](http://tuxgraphics.org/), designed to be a lightweight TCP/IP stack for embedded devices. I chose this because it was super simple to get working (or "port"), but you might want to look at [LwIP](https://en.wikipedia.org/wiki/LwIP) if you need something more advanced.
|
||||
|
||||
The code
|
||||
--------
|
||||
Most of the new code is in the _tcpip/_ subdirectory. I actually came across it in [this Github repository](https://github.com/ussserrr/maglev-ti-rtos) and, again, made only a very few cosmetic changes (`diff` is your friend!).
|
||||
|
||||
It did require me to expose the `strlen()` function we implemented in _lib/fb.c_, so that's added to _include/fb.h_. Similarly, we expose the `memcpy()` function we implemented in _kernel/kernel.c_, so that's added to _kernel/kernel.h_.
|
||||
|
||||
I also needed a single function that tells the ENC to send a packet. Nothing new here, just different packaging:
|
||||
|
||||
```c
|
||||
void enc28j60PacketSend(unsigned short buflen, void *buffer) {
|
||||
if (ENC_RestoreTXBuffer(&handle, buflen) == 0) {
|
||||
ENC_WriteBuffer((unsigned char *) buffer, buflen);
|
||||
handle.transmitLength = buflen;
|
||||
ENC_Transmit(&handle);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This was also added to _kernel/kernel.h_. Finally, _kernel/kernel.c_ now calls a function called `net_test()` instead of our original `arp_test()`.
|
||||
|
||||
The changes to _arp.c_
|
||||
----------------------
|
||||
We initialise the network card in exactly the same way but, when we're done, we call this function in Guido's code:
|
||||
|
||||
```c
|
||||
init_udp_or_www_server(myMAC, deviceIP);
|
||||
```
|
||||
|
||||
This tells the TCP/IP library who we are, so we're all on the same page!
|
||||
|
||||
Finally, and aside from a little cleanup, the major change is the new `net_test()` function:
|
||||
|
||||
```c
|
||||
void net_test(void)
|
||||
{
|
||||
while (1) {
|
||||
while (!ENC_GetReceivedFrame(&handle));
|
||||
|
||||
uint16_t len = handle.RxFrameInfos.length;
|
||||
uint8_t *buffer = (uint8_t *)handle.RxFrameInfos.buffer;
|
||||
packetloop_arp_icmp_tcp(buffer, len);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is an infinite loop which waits for an incoming packet and then simply passes it to Guido's `packetloop_arp_icmp_tcp()` function. This function implements some useful things, like responding to pings. I modified the routine to print a message to the screen when it sends a "pong" (look from line 1381), so we can see when it's in action!
|
||||
|
||||
_Imagine my excitement when I built, ran and could ping my RPi4 at 192.168.0.66 and get a response to both my laptop and my iPhone!_
|
||||
|
||||
I recommend reading [this page](http://tuxgraphics.org/electronics/200905/embedded-tcp-ip-stack.shtml) to give you some ideas about what else you might achieve with Guido's library...
|
||||
|
||||
![Pinging from my iPhone](images/15-tcpip-pinging.jpg)
|
BIN
part15-tcpip/images/15-tcpip-pinging.jpg
Executable file
BIN
part15-tcpip/images/15-tcpip-pinging.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
|
@ -15,7 +15,6 @@
|
|||
* packet. The client "web browser" as implemented here can also receive
|
||||
* large pages.
|
||||
*
|
||||
* Chip type : ATMEGA88/168/328/644 with ENC28J60
|
||||
*********************************************/
|
||||
|
||||
#include "ip_config.h"
|
||||
|
@ -27,7 +26,7 @@
|
|||
//
|
||||
static uint8_t macaddr[6];
|
||||
static uint8_t ipaddr[4]={0,0,0,0};
|
||||
static uint8_t seqnum=0xa; // my initial tcp sequence number
|
||||
//static uint8_t seqnum=0xa; // my initial tcp sequence number
|
||||
static void (*icmp_callback)(uint8_t *ip);
|
||||
|
||||
//
|
||||
|
@ -1319,7 +1318,7 @@ uint8_t packetloop_icmp_checkreply(uint8_t *buf,uint8_t *ip_monitoredhost)
|
|||
// of the tcp data if there is tcp data part
|
||||
uint16_t packetloop_arp_icmp_tcp(uint8_t *buf,uint16_t plen)
|
||||
{
|
||||
uint16_t len;
|
||||
// uint16_t len;
|
||||
#if defined (TCP_client)
|
||||
uint8_t send_fin=0;
|
||||
uint16_t tcpstart;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*
|
||||
* IP/ARP/UDP/TCP functions
|
||||
*
|
||||
* Chip type : ATMEGA88/168/328/644 with ENC28J60
|
||||
*********************************************/
|
||||
//@{
|
||||
#ifndef IP_ARP_UDP_TCP_H
|
||||
|
|
|
@ -130,3 +130,4 @@
|
|||
//
|
||||
#endif
|
||||
//@}
|
||||
|
||||
|
|
Loading…
Reference in a new issue