Merge pull request #2146 from oliverschmidt/slip

Add SLIP support to retro platforms.
This commit is contained in:
Oliver Schmidt 2017-03-18 15:56:06 +01:00 committed by GitHub
commit 356814fe9c
27 changed files with 615 additions and 272 deletions

View file

@ -68,7 +68,6 @@ typedef unsigned short uip_stats_t;
#define UIP_ARCH_ADD32 1
#define UIP_ARCH_CHKSUM 1
#define UIP_CONF_LLH_LEN 14
#define RESOLV_CONF_SUPPORTS_MDNS 0
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
@ -80,6 +79,12 @@ void logscr(const void *msg, unsigned len);
#define logscr(msg, len) write(STDERR_FILENO, msg, len)
#endif
#if WITH_SLIP
#define UIP_CONF_LLH_LEN 0
#else /* WITH_SLIP */
#define UIP_CONF_LLH_LEN 14
#endif /* WITH_SLIP */
#if MTU_SIZE
#define UIP_CONF_BUFFER_SIZE (UIP_LLH_LEN + MTU_SIZE)
#else /* MTU_SIZE */

View file

@ -31,6 +31,10 @@
# Author: Oliver Schmidt <ol.sc@web.de>
#
ifdef SLIP
DEFINES += WITH_SLIP
endif
.SUFFIXES:
CONTIKI_TARGET_DIRS = . lib sys
@ -39,7 +43,7 @@ CONTIKI_CPU_DIRS = . lib sys ctk net
CONTIKI_TARGET_SOURCEFILES += contiki-main.c
CONTIKI_CPU_SOURCEFILES += log.c error.c unload.c config.c ctk-mouse.c \
clock.c mtarch.c mtarch-asm.S lc-asm.S \
uip_arch.c ethernet-drv.c ethernet.c
uip_arch.c slip_arch.c ethernet-drv.c ethernet.c
ETHERNET_SOURCEFILES = cs8900a.S lan91c96.S w5100.S

View file

@ -6,7 +6,7 @@ cc65 compiler [http://cc65.github.io/cc65/](http://cc65.github.io/cc65/).
The Contiki network configuration for 6502-based targets is loaded from a
binary configuration file (by default named contiki.cfg). It has the following
format:
format for Ethernet:
- Bytes 1 - 4: IP Address (HiByte first)
- Bytes 5 - 8: Subnet Mask (HiByte first)
@ -15,10 +15,13 @@ format:
- Bytes 17 - 18: Ethernet card I/O address (LoByte first !)
- Bytes 19 - xx: Ethernet card driver name (ASCII / PETSCII)
An online Contiki configuration file generator is available at two sites:
It has the following format for SLIP (based on RS232 driver coming with cc65):
- [http://www.a2retrosystems.com/contiki.html](http://www.a2retrosystems.com/contiki.html)
- [http://contiki.cbm8bit.com](http://contiki.cbm8bit.com)
- Bytes 1 - 4: IP Address (HiByte first)
- Bytes 5 - 8: Subnet Mask (HiByte first)
- Bytes 9 - 12: Default Router (HiByte first)
- Bytes 13 - 16: DNS Server (HiByte first)
- Bytes 17 - 21: struct ser_params (see cc65 serial.h)
The build for 6502-based machines includes the 'disk' make goal which creates a
bootable floppy disk image containing the project binary, a sample
@ -32,6 +35,11 @@ make goal. The values of the high-level configuration macros are not tracked by
the build so a manual rebuild is necessary on any change. The following
high-level configuration macros may be set:
- WITH_SLIP
- Default: 0
- Purpose: Use SLIP (based on RS232 driver coming with cc65) instead of
Ethernet.
- MTU_SIZE
- Default: 1500
- Purpose: Set the Maximum Transfer Unit size.
@ -78,6 +86,10 @@ high-level configuration macros may be set:
- Default: 0
- Purpose: Enable CTK mouse support and load a mouse driver.
- STATIC_MOUSE
- Default: N/A
- Purpose: Link mouse driver statically instead of loading it dynamically.
- WITH_ARGS
- Default: 0
- Purpose: Enable support for contiki_argc / contiki_argv.

View file

@ -49,6 +49,15 @@ static uint8_t okay;
void
ctk_mouse_init(void)
{
#ifdef STATIC_MOUSE
okay = mouse_install(&mouse_def_callbacks, &STATIC_MOUSE) == MOUSE_ERR_OK;
if(okay) {
atexit((void (*)(void))mouse_uninstall);
}
#else /* STATIC_MOUSE */
struct mod_ctrl module_control = {cfs_read};
module_control.callerdata = cfs_open("contiki.mou", CFS_READ);
@ -65,6 +74,8 @@ ctk_mouse_init(void)
}
cfs_close(module_control.callerdata);
}
#endif /* STATIC_MOUSE */
}
/*-----------------------------------------------------------------------------------*/
unsigned short

View file

@ -42,6 +42,7 @@ choose(uint8_t max)
exit(0);
}
putchar('\n');
return val - '0';
}
/*-----------------------------------------------------------------------------------*/
@ -65,13 +66,13 @@ main(void)
d = choose(d) - 1;
#ifdef __APPLE2__
printf("\nSlot (1-7)\n");
printf("Slot (1-7)\n");
drivers[d].address += choose(7) * 0x10;
#endif
f = cfs_open("contiki.cfg", CFS_WRITE);
if(f == -1) {
printf("\nSaving Config - Error\n");
printf("Saving Config - Error\n");
return;
}
cfs_write(f, ipcfg, sizeof(ipcfg));
@ -79,6 +80,6 @@ main(void)
cfs_write(f, drivers[d].driver, strlen(drivers[d].driver));
cfs_close(f);
printf("\nSaving Config - Done\n");
printf("Saving Config - Done\n");
}
/*-----------------------------------------------------------------------------------*/

View file

@ -39,7 +39,24 @@
#include "cfs/cfs.h"
#include "sys/log.h"
#include "lib/error.h"
#include "net/ethernet-drv.h"
#include "lib/config.h"
struct {
uip_ipaddr_t hostaddr;
uip_ipaddr_t netmask;
uip_ipaddr_t draddr;
uip_ipaddr_t resolvaddr;
union {
struct {
uint16_t addr;
#ifndef STATIC_DRIVER
char name[12+1];
#endif /* !STATIC_DRIVER */
} ethernet;
uint8_t slip[5];
};
} config;
/*-----------------------------------------------------------------------------------*/
#if LOG_CONF_ENABLED
@ -59,16 +76,9 @@ ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer)
}
#endif /* LOG_CONF_ENABLED */
/*-----------------------------------------------------------------------------------*/
struct ethernet_config *
void
config_read(char *filename)
{
static struct {
uip_ipaddr_t hostaddr;
uip_ipaddr_t netmask;
uip_ipaddr_t draddr;
uip_ipaddr_t resolvaddr;
struct ethernet_config ethernetcfg;
} config;
int file;
file = cfs_open(filename, CFS_READ);
@ -77,29 +87,35 @@ config_read(char *filename)
error_exit();
}
if(cfs_read(file, &config, sizeof(config)) < sizeof(config)
- sizeof(config.ethernetcfg.name)) {
if(cfs_read(file, &config, sizeof(config)) < sizeof(uip_ipaddr_t) * 4
+ sizeof(uint16_t)) {
log_message(filename, ": No config file");
error_exit();
}
cfs_close(file);
log_message("IP Address: ", ipaddrtoa(&config.hostaddr, uip_buf));
log_message("Subnet Mask: ", ipaddrtoa(&config.netmask, uip_buf));
log_message("Def. Router: ", ipaddrtoa(&config.draddr, uip_buf));
log_message("DNS Server: ", ipaddrtoa(&config.resolvaddr, uip_buf));
log_message("IP Address: ", ipaddrtoa(&config.hostaddr, uip_buf));
log_message("Subnet Mask: ", ipaddrtoa(&config.netmask, uip_buf));
log_message("Def. Router: ", ipaddrtoa(&config.draddr, uip_buf));
log_message("DNS Server: ", ipaddrtoa(&config.resolvaddr, uip_buf));
#ifndef STATIC_DRIVER
log_message("Eth. Driver: ", config.ethernetcfg.name);
#else /* !STATIC_DRIVER */
#ifdef STATIC_DRIVER
#define _stringize(arg) #arg
#define stringize(arg) _stringize(arg)
log_message("Eth. Driver: ", stringize(ETHERNET));
#if WITH_SLIP
log_message("SLIP Driver: ", stringize(STATIC_DRIVER));
#else /* WITH_SLIP */
log_message("Eth. Driver: ", stringize(STATIC_DRIVER));
#endif /* WITH_SLIP */
#undef _stringize
#undef stringize
#endif /* !STATIC_DRIVER */
log_message("Driver Port: $", utoa(config.ethernetcfg.addr, uip_buf, 16));
#else /* STATIC_DRIVER */
log_message("Eth. Driver: ", config.ethernet.name);
#endif /* STATIC_DRIVER */
#if !WITH_SLIP
log_message("Driver Port: $", utoa(config.ethernet.addr, uip_buf, 16));
#endif /* !WITH_SLIP */
uip_sethostaddr(&config.hostaddr);
uip_setnetmask(&config.netmask);
@ -107,7 +123,5 @@ config_read(char *filename)
#if WITH_DNS
uip_nameserver_update(&config.resolvaddr, UIP_NAMESERVER_INFINITE_LIFETIME);
#endif /* WITH_DNS */
return &config.ethernetcfg;
}
/*-----------------------------------------------------------------------------------*/

View file

@ -35,6 +35,22 @@
#ifndef CONFIG_H_
#define CONFIG_H_
struct ethernet_config * config_read(char *filename);
extern struct {
uip_ipaddr_t hostaddr;
uip_ipaddr_t netmask;
uip_ipaddr_t draddr;
uip_ipaddr_t resolvaddr;
union {
struct {
uint16_t addr;
#ifndef STATIC_DRIVER
char name[12+1];
#endif /* !STATIC_DRIVER */
} ethernet;
uint8_t slip[5];
};
} config;
void config_read(char *filename);
#endif /* CONFIG_H_ */

View file

@ -92,7 +92,7 @@ PROCESS_THREAD(ethernet_process, ev, data)
PROCESS_BEGIN();
ethernet_init((struct ethernet_config *)data);
ethernet_init();
tcpip_set_outputfunc(ethernet_output);

View file

@ -35,11 +35,6 @@
#include "contiki.h"
struct ethernet_config {
uint16_t addr;
char name[12+1];
};
PROCESS_NAME(ethernet_process);
#if NETSTACK_CONF_WITH_IPV6

View file

@ -38,7 +38,7 @@
#include "cfs/cfs.h"
#include "sys/log.h"
#include "lib/error.h"
#include "net/ethernet-drv.h"
#include "lib/config.h"
#include "net/ethernet.h"
@ -59,25 +59,42 @@ struct {
/*---------------------------------------------------------------------------*/
void
ethernet_init(struct ethernet_config *config)
ethernet_init(void)
{
static const char signature[4] = {0x65, 0x74, 0x68, 0x01};
#ifndef STATIC_DRIVER
#ifdef STATIC_DRIVER
extern void STATIC_DRIVER;
module = &STATIC_DRIVER;
module->buffer = uip_buf;
module->buffer_size = UIP_BUFSIZE;
if(module->init(config.ethernet.addr)) {
#define _stringize(arg) #arg
#define stringize(arg) _stringize(arg)
log_message(stringize(STATIC_DRIVER), ": No hardware");
#undef _stringize
#undef stringize
error_exit();
}
#else /* STATIC_DRIVER */
struct mod_ctrl module_control = {cfs_read};
uint8_t byte;
module_control.callerdata = cfs_open(config->name, CFS_READ);
module_control.callerdata = cfs_open(config.ethernet.name, CFS_READ);
if(module_control.callerdata < 0) {
log_message(config->name, ": File not found");
log_message(config.ethernet.name, ": File not found");
error_exit();
}
byte = mod_load(&module_control);
if(byte != MLOAD_OK) {
log_message(config->name, byte == MLOAD_ERR_MEM? ": Out of memory":
": No module");
log_message(config.ethernet.name, byte == MLOAD_ERR_MEM? ": Out of memory":
": No module");
error_exit();
}
@ -86,26 +103,20 @@ ethernet_init(struct ethernet_config *config)
for(byte = 0; byte < 4; ++byte) {
if(module->signature[byte] != signature[byte]) {
log_message(config->name, ": No ETH driver");
log_message(config.ethernet.name, ": No ETH driver");
error_exit();
}
}
#else /* !STATIC_DRIVER */
extern void STATIC_DRIVER;
module = &STATIC_DRIVER;
#endif /* !STATIC_DRIVER */
module->buffer = uip_buf;
module->buffer_size = UIP_BUFSIZE;
if(module->init(config->addr)) {
log_message(config->name, ": No hardware");
if(module->init(config.ethernet.addr)) {
log_message(config.ethernet.name, ": No hardware");
error_exit();
}
#endif /* STATIC_DRIVER */
uip_setethaddr(module->ethernet_address);
}
/*---------------------------------------------------------------------------*/

View file

@ -35,7 +35,7 @@
#ifndef ETHERNET_H_
#define ETHERNET_H_
void ethernet_init(struct ethernet_config *config);
void ethernet_init(void);
uint16_t ethernet_poll(void);
void ethernet_send(void);
void ethernet_exit(void);

84
cpu/6502/net/slip_arch.c Normal file
View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2017, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Oliver Schmidt <ol.sc@web.de>
*
*/
#include <serial.h>
#include <stdlib.h>
#include "contiki-net.h"
#include "sys/log.h"
#include "lib/error.h"
#include "lib/config.h"
#include "dev/slip.h"
#if WITH_SLIP
/*---------------------------------------------------------------------------*/
void
slip_arch_init(unsigned long ubr)
{
unsigned err;
err = ser_install(STATIC_DRIVER);
if(err == SER_ERR_OK) {
err = ser_open((struct ser_params *)config.slip);
if(err == SER_ERR_OK)
atexit((void (*)(void))ser_close);
}
if(err != SER_ERR_OK) {
err += '0';
/* High byte of err serves as string termination. */
log_message("Serial init error code: ", (char *)&err);
error_exit();
}
tcpip_set_outputfunc(slip_send);
}
/*---------------------------------------------------------------------------*/
void
slip_arch_writeb(unsigned char c)
{
while(ser_put(c) == SER_ERR_OVERFLOW)
;
}
/*---------------------------------------------------------------------------*/
void
slip_arch_poll(void)
{
static unsigned char c;
while(ser_get(&c) != SER_ERR_NO_DATA)
slip_input_byte(c);
}
/*---------------------------------------------------------------------------*/
#endif /* WITH_SLIP */

View file

@ -0,0 +1,6 @@
CONTIKI_PROJECT = serconfig
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
CONTIKI_WITH_IPV4 = 1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1 @@
DEFINES = WITH_PFS

View file

@ -0,0 +1 @@
DEFINES = WITH_PFS

View file

@ -0,0 +1,105 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <serial.h>
#include "cfs/cfs.h"
static struct {
char *screen;
uint8_t value;
} baud[] = {
{" 300 baud", SER_BAUD_300},
{" 600 baud", SER_BAUD_600},
{" 1200 baud", SER_BAUD_1200},
{" 2400 baud", SER_BAUD_2400},
{" 4800 baud", SER_BAUD_4800},
{" 9600 baud", SER_BAUD_9600},
{"19200 baud", SER_BAUD_19200}
};
static struct {
char *screen;
uint8_t value;
} stop[] = {
{"1 stop bit", SER_STOP_1},
{"2 stop bits", SER_STOP_2}
};
static struct {
char *screen;
uint8_t value;
} parity[] = {
{" No parity", SER_PAR_NONE},
{" Odd parity", SER_PAR_ODD},
{"Even parity", SER_PAR_EVEN}
};
uint8_t ipcfg[16];
struct ser_params params;
/*-----------------------------------------------------------------------------------*/
uint8_t
choose(uint8_t max)
{
char val;
do {
printf("\n?");
val = getchar();
} while(val < '0' || val > max + '0');
putchar('\n');
if(val == '0') {
exit(0);
}
putchar('\n');
return val - '0';
}
/*-----------------------------------------------------------------------------------*/
void
main(void)
{
int f;
uint8_t c;
f = cfs_open("contiki.cfg", CFS_READ);
if(f == -1) {
printf("Loading Config - Error\n");
return;
}
cfs_read(f, ipcfg, sizeof(ipcfg));
cfs_close(f);
for(c = 0; c < sizeof(baud) / sizeof(baud[0]); ++c) {
printf("%d: %s\n", c + 1, baud[c].screen);
}
params.baudrate = baud[choose(c) - 1].value;
params.databits = SER_BITS_8;
for(c = 0; c < sizeof(stop) / sizeof(stop[0]); ++c) {
printf("%d: %s\n", c + 1, stop[c].screen);
}
params.stopbits = stop[choose(c) - 1].value;
for(c = 0; c < sizeof(parity) / sizeof(parity[0]); ++c) {
printf("%d: %s\n", c + 1, parity[c].screen);
}
params.parity = parity[choose(c) - 1].value;
params.handshake = SER_HS_HW;
f = cfs_open("contiki.cfg", CFS_WRITE);
if(f == -1) {
printf("\nSaving Config - Error\n");
return;
}
cfs_write(f, ipcfg, sizeof(ipcfg));
cfs_write(f, &params, sizeof(params));
cfs_close(f);
printf("Saving Config - Done\n");
}
/*-----------------------------------------------------------------------------------*/