URL
https://opencores.org/ocsvn/plasma/plasma/trunk
Subversion Repositories plasma
Compare Revisions
- This comparison shows the changes necessary to convert path
/plasma/trunk
- from Rev 415 to Rev 416
- ↔ Reverse comparison
Rev 415 → Rev 416
/kernel/os_stubs.c
1,79 → 1,100
/*-------------------------------------------------------------------- |
* TITLE: OS stubs |
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
* DATE CREATED: 2/18/08 |
* FILENAME: os_stubs.c |
* PROJECT: Plasma CPU core |
* COPYRIGHT: Software placed into the public domain by the author. |
* Software 'as is' without warranty. Author liable for nothing. |
* DESCRIPTION: |
*--------------------------------------------------------------------*/ |
#include <stdlib.h> |
#include "plasma.h" |
#include "rtos.h" |
|
unsigned char *flash; |
int beenInit; |
|
|
void FlashRead(uint16 *dst, uint32 byteOffset, int bytes) |
{ |
if(beenInit == 0) |
{ |
beenInit = 1; |
flash = (unsigned char*)malloc(1024*1024*16); |
memset(flash, 0xff, sizeof(flash)); |
} |
memcpy(dst, flash+byteOffset, bytes); |
} |
|
|
void FlashWrite(uint16 *src, uint32 byteOffset, int bytes) |
{ |
memcpy(flash+byteOffset, src, bytes); |
} |
|
|
void FlashErase(uint32 byteOffset) |
{ |
memset(flash+byteOffset, 0xff, 1024*128); |
} |
|
|
//Stub out RTOS functions |
#undef malloc |
#undef free |
/*-------------------------------------------------------------------- |
* TITLE: OS stubs |
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
* DATE CREATED: 2/18/08 |
* FILENAME: os_stubs.c |
* PROJECT: Plasma CPU core |
* COPYRIGHT: Software placed into the public domain by the author. |
* Software 'as is' without warranty. Author liable for nothing. |
* DESCRIPTION: |
*--------------------------------------------------------------------*/ |
#include <stdlib.h> |
#include "plasma.h" |
#include "rtos.h" |
|
static unsigned char *flash; |
|
void FlashLock(void) {} |
void FlashUnlock(void) {} |
|
void FlashRead(uint16 *dst, uint32 byteOffset, int bytes) |
{ |
if(flash == NULL) |
{ |
flash = (unsigned char*)malloc(1024*1024*16); |
memset(flash, 0xff, 1024*1024*16); |
} |
memcpy(dst, flash+byteOffset, bytes); |
} |
|
|
void FlashWrite(uint16 *src, uint32 byteOffset, int bytes) |
{ |
memcpy(flash+byteOffset, src, bytes); |
} |
|
|
void FlashErase(uint32 byteOffset) |
{ |
memset(flash+byteOffset, 0xff, 1024*128); |
} |
|
|
//Stub out RTOS functions |
#undef malloc |
#undef free |
#undef printf |
static void *infoValue; |
void *OS_HeapMalloc(OS_Heap_t *heap, int bytes) {(void)heap; return malloc(bytes);} |
void OS_HeapFree(void *block) {free(block);} |
void UartPrintfCritical(const char *format, ...) {(void)format;} |
uint32 OS_AsmInterruptEnable(uint32 state) {(void)state; return 0;} |
void OS_Assert(void) {} |
OS_Thread_t *OS_ThreadSelf(void) {return NULL;} |
void OS_ThreadSleep(int ticks) {(void)ticks;} |
uint32 OS_ThreadTime(void) {return 0;} |
OS_Mutex_t *OS_MutexCreate(const char *name) {(void)name; return NULL; } |
void OS_MutexDelete(OS_Mutex_t *semaphore) {(void)semaphore;} |
void OS_MutexPend(OS_Mutex_t *semaphore) {(void)semaphore;} |
void OS_MutexPost(OS_Mutex_t *semaphore) {(void)semaphore;} |
#if OS_CPU_COUNT > 1 |
uint32 OS_SpinLock(void) {return 0;} |
void OS_SpinUnlock(uint32 state) {(void)state;} |
#endif |
|
OS_MQueue_t *OS_MQueueCreate(const char *name, |
int messageCount, |
int messageBytes) |
{(void)name;(void)messageCount;(void)messageBytes; return NULL;} |
|
void OS_MQueueDelete(OS_MQueue_t *mQueue) {(void)mQueue;} |
|
int OS_MQueueSend(OS_MQueue_t *mQueue, void *message) |
{(void)mQueue;(void)message; return 0;} |
|
int OS_MQueueGet(OS_MQueue_t *mQueue, void *message, int ticks) |
{(void)mQueue;(void)message;(void)ticks; return 0;} |
|
void OS_Job(JobFunc_t funcPtr, void *arg0, void *arg1, void *arg2) |
{funcPtr(arg0, arg1, arg2);} |
|
|
void UartPrintfCritical(const char *format, |
int a, int b, int c, int d, int e, int f, int g, int h) |
{printf(format,a,b,c,d,e,f,g,h);} |
uint32 OS_AsmInterruptEnable(uint32 state) {(void)state; return 0;} |
void OS_Assert(void) |
{} |
OS_Thread_t *OS_ThreadCreate(const char *name, |
OS_FuncPtr_t funcPtr, |
void *arg, |
uint32 priority, |
uint32 stackSize) |
{(void)name;(void)funcPtr;(void)arg;(void)priority;(void)stackSize;return NULL;} |
void OS_ThreadExit(void) {} |
OS_Thread_t *OS_ThreadSelf(void) {return NULL;} |
void OS_ThreadSleep(int ticks) {(void)ticks;} |
uint32 OS_ThreadTime(void) {return 0;} |
void *OS_ThreadInfoGet(OS_Thread_t *thread, uint32 index) |
{(void)thread;(void)index;return infoValue;} |
void OS_ThreadInfoSet(OS_Thread_t *thread, uint32 index, void *info) |
{(void)thread;(void)index;infoValue=info;} |
|
OS_Semaphore_t *OS_SemaphoreCreate(const char *name, uint32 count) |
{(void)name;(void)count;return NULL;} |
void OS_SemaphoreDelete(OS_Semaphore_t *semaphore) {(void)semaphore;} |
int OS_SemaphorePend(OS_Semaphore_t *semaphore, int ticks) |
{(void)semaphore; (void)ticks; return 0;} |
void OS_SemaphorePost(OS_Semaphore_t *semaphore) {(void)semaphore;} |
|
OS_Mutex_t *OS_MutexCreate(const char *name) {(void)name; return NULL;} |
void OS_MutexDelete(OS_Mutex_t *semaphore) {(void)semaphore;} |
void OS_MutexPend(OS_Mutex_t *semaphore) {(void)semaphore;} |
void OS_MutexPost(OS_Mutex_t *semaphore) {(void)semaphore;} |
#if OS_CPU_COUNT > 1 |
uint32 OS_SpinLock(void) {return 0;} |
void OS_SpinUnlock(uint32 state) {(void)state;} |
#endif |
|
OS_MQueue_t *OS_MQueueCreate(const char *name, |
int messageCount, |
int messageBytes) |
{(void)name;(void)messageCount;(void)messageBytes; return NULL;} |
void OS_MQueueDelete(OS_MQueue_t *mQueue) {(void)mQueue;} |
int OS_MQueueSend(OS_MQueue_t *mQueue, void *message) |
{(void)mQueue;(void)message; return 0;} |
int OS_MQueueGet(OS_MQueue_t *mQueue, void *message, int ticks) |
{(void)mQueue;(void)message;(void)ticks; return 0;} |
|
void OS_Job(JobFunc_t funcPtr, void *arg0, void *arg1, void *arg2) |
{funcPtr(arg0, arg1, arg2);} |
|
|
/kernel/libc.c
183,10 → 183,10
|
|
static uint32 Rand1=0x1f2bcda3; |
int rand(void) |
unsigned int rand(void) |
{ |
Rand1 = 1664525 * Rand1 + 1013904223; //from D.E. Knuth and H.W. Lewis |
return Rand1; |
return Rand1 << 16 | Rand1 >> 16; |
} |
|
|
/kernel/uart.c
8,15 → 8,12
* Software 'as is' without warranty. Author liable for nothing. |
* DESCRIPTION: |
* Plasma Uart Driver |
* UART_PACKETS permits "Ethernet" packets to be sent and received. |
*--------------------------------------------------------------------*/ |
#define NO_ELLIPSIS2 |
#include "plasma.h" |
#include "rtos.h" |
|
#ifndef NO_PACKETS |
#define SUPPORT_DATA_PACKETS |
#endif |
|
#define BUFFER_WRITE_SIZE 128 |
#define BUFFER_READ_SIZE 128 |
#define BUFFER_PRINTF_SIZE 1024 |
38,7 → 35,7
static OS_Semaphore_t *SemaphoreUart; |
static char PrintfString[BUFFER_PRINTF_SIZE]; //Used in UartPrintf |
|
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
//For packet processing [0xff lengthMSB lengthLSB checksum data] |
static PacketGetFunc_t UartPacketGet; |
static uint8 *PacketCurrent; |
48,8 → 45,8
static uint32 PacketBytes, PacketLength; |
static uint32 UartPacketOutLength, UartPacketOutByte; |
int CountOk, CountError; |
#endif |
static uint8 *UartPacketOut; |
#endif //UART_PACKETS |
|
|
/******************************************/ |
124,7 → 121,7
|
|
/******************************************/ |
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
static void UartPacketRead(uint32 value) |
{ |
uint32 message[4]; |
232,7 → 229,7
} |
return value; |
} |
#endif |
#endif //UART_PACKETS |
|
|
static void UartInterrupt(void *arg) |
244,7 → 241,7
while(status & IRQ_UART_READ_AVAILABLE) |
{ |
value = MemoryRead(UART_READ); |
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
if(UartPacketGet && (value == 0xff || PacketBytes)) |
UartPacketRead(value); |
else |
256,7 → 253,7
} |
while(status & IRQ_UART_WRITE_AVAILABLE) |
{ |
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
if(UartPacketOut) |
{ |
value = UartPacketWrite(); |
352,7 → 349,7
{ |
if(*ptr == '\n') |
UartWrite('\r'); |
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
if(*ptr == 0xff) |
*ptr = '@'; |
#endif |
362,6 → 359,7
} |
|
|
#if 0 |
void UartPrintfPoll(const char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
389,6 → 387,7
if(SemaphoreUart) |
OS_SemaphorePost(SemaphoreUart); |
} |
#endif |
|
|
void UartPrintfCritical(const char *format, |
395,19 → 394,20
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
{ |
char buffer[128]; |
uint8 *ptr; |
uint32 state; |
|
state = OS_CriticalBegin(); |
sprintf(PrintfString, format, arg0, arg1, arg2, arg3, |
sprintf(buffer, format, arg0, arg1, arg2, arg3, |
arg4, arg5, arg6, arg7); |
ptr = (uint8*)PrintfString; |
ptr = (uint8*)buffer; |
while(*ptr) |
{ |
while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0) |
; |
MemoryWrite(UART_WRITE, *ptr++); |
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
if(UartPacketOut && UartPacketOutByte - 4 < UartPacketOutLength) |
{ |
++UartPacketOutByte; |
415,16 → 415,10
} |
#endif |
} |
memset(PrintfString, 0, sizeof(PrintfString)); |
OS_CriticalEnd(state); |
} |
|
|
void UartPrintfNull(void) |
{ |
} |
|
|
void UartScanf(const char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
458,7 → 452,7
} |
|
|
#ifdef SUPPORT_DATA_PACKETS |
#ifdef UART_PACKETS |
void UartPacketConfig(PacketGetFunc_t PacketGetFunc, |
int PacketSize, |
OS_MQueue_t *mQueue) |
476,7 → 470,7
UartPacketOut = data; |
OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE); |
} |
#else |
#else //UART_PACKETS |
void UartPacketConfig(PacketGetFunc_t PacketGetFunc, |
int PacketSize, |
OS_MQueue_t *mQueue) |
/kernel/dlltest.c
1,38 → 1,19
// dlltest.c |
// Compile this program with "make dlltest". |
// Then ftp test.bin to /flash/bin/dlltest. |
// Then ftp dlltest.axf to /flash/bin/dlltest. |
// Then from a telnet prompt type "dlltest". |
#include "dll.h" |
|
int a, b=7; |
|
void SocketReceive(IPSocket *socket) |
int main(int argc, char *argv[]) |
{ |
int i=40; |
printf("Hello from dlltest! a=%d b=%d\n", a, b); |
if(argc > 1) |
printf("arg=%s\n", argv[1]); |
printf("Enter a number\n"); |
scanf("%d", &i); |
printf("i=%d\n", i); |
return 0; |
} |
|
|
void MyThread(void *sock) |
{ |
char buf[80]; |
int i, bytes; |
IPSocket *socket = sock; |
|
for(i = 0; i < 10; ++i) |
{ |
bytes = IPRead(socket, buf, sizeof(buf)-1); |
buf[bytes] = 0; |
IPPrintf(socket, "%d %s\n", i, buf); |
OS_ThreadSleep(100); |
} |
socket->funcPtr = socket->userFunc; //restore socket receive function |
} |
|
|
// Function shouldn't block |
void Start(IPSocket *socket, char *argv[]) |
{ |
IPPrintf(socket, "Hello from dlltest\n"); |
socket->userFunc = socket->funcPtr; //remember prev socket receive func |
socket->funcPtr = SocketReceive; //new socket receive function |
OS_ThreadCreate("MyThread", MyThread, socket, 100, 0); |
} |
|
/kernel/ethernet.c
1,428 → 1,363
/*-------------------------------------------------------------------- |
* TITLE: Plasma Ethernet MAC |
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
* DATE CREATED: 1/12/08 |
* FILENAME: ethernet.c |
* PROJECT: Plasma CPU core |
* COPYRIGHT: Software placed into the public domain by the author. |
* Software 'as is' without warranty. Author liable for nothing. |
* DESCRIPTION: |
* Ethernet MAC implementation. |
* Data is received from the Ethernet PHY four bits at a time. |
* After 32-bits are received they are written to 0x13ff0000 + N. |
* The data is received LSB first for each byte which requires the |
* nibbles to be swapped. |
* Transmit data is read from 0x13fe0000. Write length/4+1 to |
* ETHERNET_REG to start transfer. |
*--------------------------------------------------------------------*/ |
#include "plasma.h" |
#include "rtos.h" |
#include "tcpip.h" |
|
#define POLYNOMIAL 0x04C11DB7 //CRC bit 33 is truncated |
#define TOPBIT (1<<31) |
#define BYTE_EMPTY 0xde //Data copied into receive buffer |
#define COUNT_EMPTY 16 //Count to decide there isn't data |
#define INDEX_MASK 0xffff //Size of receive buffer |
|
//void dump(const unsigned char *data, int length); |
|
static unsigned char gDestMac[]={0x5d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
static unsigned int CrcTable[256]; |
static unsigned char reflect[256]; |
static unsigned char reflectNibble[256]; |
static OS_Semaphore_t *SemEthernet, *SemEthTransmit; |
static int gIndex; //byte index into 0x13ff0000 receive buffer |
static int gCheckedBefore; |
static int gEmptyBefore; |
|
|
//Read received data from 0x13ff0000. Data starts with 0x5d+MACaddress. |
//Data is being received while processing the data. Therefore, |
//all errors require waiting and then re-processing the data |
//to see if the error is fixed by receiving the rest of the packet. |
int EthernetReceive(unsigned char *buffer, int length) |
{ |
int count; |
int start, i, j, shift, offset; |
int byte, byteNext; |
unsigned long crc; |
int byteCrc; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE; |
int countEmpty, countEmptyGoal, countOk, needWait; |
int packetExpected; |
|
//Find the start of a frame |
countEmpty = 0; |
countOk = 0; |
needWait = 0; |
countEmptyGoal = COUNT_EMPTY; |
packetExpected = MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_RECEIVE; |
if(packetExpected && buf[gIndex] == BYTE_EMPTY && gEmptyBefore) |
{ |
//printf("Check "); |
countEmptyGoal = 1500; |
} |
MemoryRead(ETHERNET_REG); //clear receive interrupt |
for(i = 0; i < INDEX_MASK; ++i) |
{ |
//Check if partial packet possibly received |
if(needWait && gCheckedBefore == 0 && countOk != i && countEmpty != i) |
{ |
gCheckedBefore = 1; |
//printf("W(%d,%d,%d)", i, countOk, countEmpty); |
return 0; //Wait for more data |
} |
|
//Detect start of frame |
byte = buf[(gIndex + i) & INDEX_MASK]; |
if(byte == gDestMac[countOk] || (countOk && byte == 0xff)) |
{ |
if(++countOk == sizeof(gDestMac)) |
{ |
//Set bytes before 0x5d to BYTE_EMPTY |
offset = i - (int)sizeof(gDestMac); |
//if(offset > 3) |
// printf("es%d ", offset); |
for(j = 0; j <= offset; ++j) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
break; |
} |
} |
else |
{ |
//if(countOk) |
// printf("N%d ", countOk); |
if(countOk == 3 && byte == BYTE_EMPTY) |
needWait = 1; |
if(byte == 0x5d) |
countOk = 1; |
else |
countOk = 0; |
} |
|
//Check if remainder of buffer is empty |
if(byte == BYTE_EMPTY) |
{ |
if(++countEmpty >= countEmptyGoal) |
{ |
//Set skiped bytes to BYTE_EMPTY |
//if(i - countEmpty > 3) |
//{ |
// printf("eb%d \n", i - countEmpty); |
// //dump((char*)buf+gIndex, 0x200); |
//} |
for(j = 0; j <= i - countEmpty; ++j) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
gCheckedBefore = 0; |
if(countEmpty >= i && packetExpected) |
gEmptyBefore = 1; |
return 0; |
} |
} |
else |
{ |
if(countEmpty > 2 || (countEmpty > 0 && countEmpty == i)) |
needWait = 1; |
countEmpty = 0; |
gEmptyBefore = 0; |
} |
} |
|
//Found start of frame. Now find end of frame and check CRC. |
start = gIndex; |
gIndex = (gIndex + 1) & INDEX_MASK; //skip 0x5d byte |
crc = 0xffffffff; |
for(count = 0; count < length; ) |
{ |
byte = buf[gIndex]; |
gIndex = (gIndex + 1) & INDEX_MASK; |
|
byte = ((byte << 4) & 0xf0) | (byte >> 4); //swap nibbles |
buffer[count++] = (unsigned char)byte; |
byte = reflect[byte] ^ (crc >> 24); //calculate CRC32 |
crc = CrcTable[byte] ^ (crc << 8); |
if(count >= 40) |
{ |
//Check if CRC matches to detect end of frame |
byteCrc = reflectNibble[crc >> 24]; |
byteNext = buf[gIndex]; |
if(byteCrc == byteNext) |
{ |
for(i = 1; i < 4; ++i) |
{ |
shift = 24 - (i << 3); |
byteCrc = reflectNibble[(crc >> shift) & 0xff]; |
byteNext = buf[(gIndex + i) & 0xffff]; |
if(byteCrc != byteNext) |
{ |
//printf("nope %d %d 0x%x 0x%x\n", count, i, byteCrc, byteNext); |
i = 99; |
} |
} |
if(i == 4) |
{ |
//Found end of frame -- set used bytes to BYTE_EMPTY |
//printf("Found it! %d\n", count); |
gIndex = (gIndex + 4) & INDEX_MASK; |
for(i = 0; i < count+5; ++i) |
buf[(start + i) & INDEX_MASK] = BYTE_EMPTY; |
while(gIndex & 3) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
gCheckedBefore = 0; |
return count; |
} |
} |
} |
} |
gIndex = start; |
if(gCheckedBefore) |
{ |
//printf("CRC failure\n"); |
buf[gIndex] = BYTE_EMPTY; |
} |
gCheckedBefore = 1; |
return 0; //wait for more data |
} |
|
|
//Copy transmit data to 0x13fe0000 with preamble and CRC32 |
void EthernetTransmit(unsigned char *buffer, int length) |
{ |
int i, byte, shift; |
unsigned long crc; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_TRANSMIT; |
|
OS_SemaphorePend(SemEthTransmit, OS_WAIT_FOREVER); |
|
//Wait for previous transfer to complete |
for(i = 0; i < 10000; ++i) |
{ |
if(MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_TRANSMIT) |
break; |
} |
//if(i > 100) |
// printf("wait=%d ", i); |
|
Led(2, 2); |
while(length < 60 || (length & 3) != 0) |
buffer[length++] = 0; |
|
//Start of Ethernet frame |
for(i = 0; i < 7; ++i) |
buf[i] = 0x55; |
buf[7] = 0x5d; |
|
//Calculate CRC32 |
crc = 0xffffffff; |
for(i = 0; i < length; ++i) |
{ |
byte = buffer[i]; |
buf[i + 8] = (unsigned char)((byte << 4) | (byte >> 4)); //swap nibbles |
byte = reflect[byte] ^ (crc >> 24); //calculate CRC32 |
crc = CrcTable[byte] ^ (crc << 8); |
} |
|
//Output CRC32 |
for(i = 0; i < 4; ++i) |
{ |
shift = 24 - (i << 3); |
byte = reflectNibble[(crc >> shift) & 0xff]; |
buf[length + 8 + i] = (unsigned char)byte; |
} |
|
//Start transfer |
length = (length + 12 + 4) >> 2; |
MemoryWrite(ETHERNET_REG, length); |
Led(2, 0); |
|
OS_SemaphorePost(SemEthTransmit); |
} |
|
|
void EthernetThread(void *arg) |
{ |
int length; |
/*-------------------------------------------------------------------- |
* TITLE: Plasma Ethernet MAC |
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
* DATE CREATED: 1/12/08 |
* FILENAME: ethernet.c |
* PROJECT: Plasma CPU core |
* COPYRIGHT: Software placed into the public domain by the author. |
* Software 'as is' without warranty. Author liable for nothing. |
* DESCRIPTION: |
* Ethernet MAC implementation. |
* Data is received from the Ethernet PHY four bits at a time. |
* After 32-bits are received they are written to 0x13ff0000 + N. |
* The data is received LSB first for each byte which requires the |
* nibbles to be swapped. |
* Transmit data is read from 0x13fe0000. Write length/4+1 to |
* ETHERNET_REG to start transfer. |
*--------------------------------------------------------------------*/ |
#include "plasma.h" |
#include "rtos.h" |
#include "tcpip.h" |
|
#define POLYNOMIAL 0x04C11DB7 //CRC bit 33 is truncated |
#define TOPBIT (1<<31) |
#define BYTE_EMPTY 0xde //Data copied into receive buffer |
#define COUNT_EMPTY 16 //Count to decide there isn't data |
#define INDEX_MASK 0xffff //Size of receive buffer |
|
//void dump(const unsigned char *data, int length); |
|
static unsigned char gDestMac[]={0x5d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
static unsigned int CrcTable[256]; |
static unsigned char reflect[256]; |
static unsigned char reflectNibble[256]; |
static OS_Semaphore_t *SemEthernet, *SemEthTransmit; |
static int gIndex; //byte index into 0x13ff0000 receive buffer |
static int gCheckedBefore; |
|
|
//Read received data from 0x13ff0000. Data starts with 0x5d+MACaddress. |
//Data is being received while processing the data. Therefore, |
//all errors require waiting and then re-processing the data |
//to see if the error is fixed by receiving the rest of the packet. |
int EthernetReceive(unsigned char *buffer, int length) |
{ |
int count; |
int start, i, j, shift, offset, index; |
int byte, byteNext; |
unsigned long crc; |
int byteCrc; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE; |
int packetExpected; |
|
//Find the start of a frame |
packetExpected = MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_RECEIVE; |
MemoryRead(ETHERNET_REG); //clear receive interrupt |
|
//Find dest MAC address |
for(offset = 0; offset <= INDEX_MASK; ++offset) |
{ |
index = (gIndex + offset) & INDEX_MASK; |
byte = buf[index]; |
if(byte == 0x5d) //bit pattern 01011101 |
{ |
for(i = 1; i < sizeof(gDestMac); ++i) |
{ |
j = (index + i) & INDEX_MASK; |
byte = buf[j]; |
if(byte != 0xff && byte != gDestMac[i]) |
break; |
} |
if(i == sizeof(gDestMac)) |
break; //found dest MAC |
} |
else if(byte == BYTE_EMPTY && packetExpected == 0) |
return 0; |
} |
if(offset > INDEX_MASK) |
return 0; |
while(gIndex != index) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
|
//Found start of frame. Now find end of frame and check CRC. |
start = gIndex; |
gIndex = (gIndex + 1) & INDEX_MASK; //skip 0x5d byte |
crc = 0xffffffff; |
for(count = 0; count < length; ) |
{ |
byte = buf[gIndex]; |
gIndex = (gIndex + 1) & INDEX_MASK; |
|
byte = ((byte << 4) & 0xf0) | (byte >> 4); //swap nibbles |
buffer[count++] = (unsigned char)byte; |
byte = reflect[byte] ^ (crc >> 24); //calculate CRC32 |
crc = CrcTable[byte] ^ (crc << 8); |
if(count >= 40) |
{ |
//Check if CRC matches to detect end of frame |
byteCrc = reflectNibble[crc >> 24]; |
byteNext = buf[gIndex]; |
if(byteCrc == byteNext) |
{ |
for(i = 1; i < 4; ++i) |
{ |
shift = 24 - (i << 3); |
byteCrc = reflectNibble[(crc >> shift) & 0xff]; |
byteNext = buf[(gIndex + i) & 0xffff]; |
if(byteCrc != byteNext) |
{ |
//printf("nope %d %d 0x%x 0x%x\n", count, i, byteCrc, byteNext); |
i = 99; |
} |
} |
if(i == 4) |
{ |
//Found end of frame -- set used bytes to BYTE_EMPTY |
//printf("Found it! %d\n", count); |
gIndex = (gIndex + 4) & INDEX_MASK; |
for(i = 0; i < count+5; ++i) |
buf[(start + i) & INDEX_MASK] = BYTE_EMPTY; |
while(gIndex & 3) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
gCheckedBefore = 0; |
return count; |
} |
} |
} |
} |
gIndex = start; |
if(gCheckedBefore++ > 1) |
{ |
buf[gIndex] = BYTE_EMPTY; |
gIndex = (gIndex + 1) & INDEX_MASK; |
} |
return 0; //wait for more data |
} |
|
|
//Copy transmit data to 0x13fe0000 with preamble and CRC32 |
void EthernetTransmit(unsigned char *buffer, int length) |
{ |
int i, byte, shift; |
unsigned long crc; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_TRANSMIT; |
|
OS_SemaphorePend(SemEthTransmit, OS_WAIT_FOREVER); |
|
//Wait for previous transfer to complete |
for(i = 0; i < 10000; ++i) |
{ |
if(MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_TRANSMIT) |
break; |
} |
//if(i > 100) |
// printf("wait=%d ", i); |
|
Led(2, 2); |
while(length < 60 || (length & 3) != 0) |
buffer[length++] = 0; |
|
//Start of Ethernet frame |
for(i = 0; i < 7; ++i) |
buf[i] = 0x55; |
buf[7] = 0x5d; |
|
//Calculate CRC32 |
crc = 0xffffffff; |
for(i = 0; i < length; ++i) |
{ |
byte = buffer[i]; |
buf[i + 8] = (unsigned char)((byte << 4) | (byte >> 4)); //swap nibbles |
byte = reflect[byte] ^ (crc >> 24); //calculate CRC32 |
crc = CrcTable[byte] ^ (crc << 8); |
} |
|
//Output CRC32 |
for(i = 0; i < 4; ++i) |
{ |
shift = 24 - (i << 3); |
byte = reflectNibble[(crc >> shift) & 0xff]; |
buf[length + 8 + i] = (unsigned char)byte; |
} |
|
//Start transfer |
length = (length + 12 + 4) >> 2; |
MemoryWrite(ETHERNET_REG, length); |
Led(2, 0); |
|
OS_SemaphorePost(SemEthTransmit); |
} |
|
|
void EthernetThread(void *arg) |
{ |
int length; |
int rc; |
unsigned int ticks, ticksLast=0; |
unsigned int ticks, ticksLast=0; |
int ticksWait=50; |
IPFrame *ethFrame=NULL; |
static int ethErrorCount=0; |
(void)arg; |
|
for(;;) |
(void)arg; |
|
for(;;) |
{ |
OS_InterruptMaskSet(IRQ_ETHERNET_RECEIVE); |
OS_SemaphorePend(SemEthernet, 50); //wait for interrupt |
|
//Process all received packets |
for(;;) |
{ |
if(ethFrame == NULL) |
ethFrame = IPFrameGet(FRAME_COUNT_RCV); |
OS_InterruptMaskSet(IRQ_ETHERNET_RECEIVE); //enable interrupt |
rc = OS_SemaphorePend(SemEthernet, ticksWait); //wait for interrupt |
if(rc) |
ticksWait = 50; |
else |
ticksWait = 2; |
|
//Process all received packets |
for(;;) |
{ |
if(ethFrame == NULL) |
{ |
OS_ThreadSleep(50); |
ethFrame = IPFrameGet(FRAME_COUNT_RCV); |
if(ethFrame == NULL) |
break; |
} |
length = EthernetReceive(ethFrame->packet, PACKET_SIZE); |
length = EthernetReceive(ethFrame->packet, PACKET_SIZE); |
if(length == 0) |
{ |
#if 1 //Disable this on quiet networks |
//No Ethernet packets seen for 60 seconds? |
if(++ethErrorCount >= 120) |
{ |
printf("\nEthernetInit\n"); |
ethErrorCount = 0; |
EthernetInit(NULL); //Need to re-initialize |
} |
#endif |
break; |
} |
ethErrorCount = 0; |
Led(1, 1); |
rc = IPProcessEthernetPacket(ethFrame, length); |
Led(1, 0); |
if(rc) |
ethFrame = NULL; |
} |
|
ticks = OS_ThreadTime(); |
if(ticks - ticksLast >= 50) |
{ |
IPTick(); |
ticksLast = ticks; |
} |
} |
} |
|
|
void EthernetIsr(void *arg) |
{ |
Led(1, 1); |
rc = IPProcessEthernetPacket(ethFrame, length); |
Led(1, 0); |
if(rc) |
ethFrame = NULL; |
} |
|
ticks = OS_ThreadTime(); |
if(ticks - ticksLast >= 50) |
{ |
IPTick(); |
ticksLast = ticks; |
} |
} |
} |
|
|
void EthernetIsr(void *arg) |
{ |
(void)arg; |
OS_InterruptMaskClear(IRQ_ETHERNET_TRANSMIT | IRQ_ETHERNET_RECEIVE); |
OS_InterruptMaskClear(IRQ_ETHERNET_RECEIVE); |
OS_SemaphorePost(SemEthernet); |
} |
|
|
/******************* CRC32 calculations ********************** |
* The CRC32 code is modified from Michale Barr's article in |
* Embedded Systems Programming January 2000. |
* A CRC is really modulo-2 binary division. Substraction means XOR. */ |
static unsigned int Reflect(unsigned int value, int bits) |
{ |
unsigned int num=0; |
int i; |
for(i = 0; i < bits; ++i) |
{ |
num = (num << 1) | (value & 1); |
value >>= 1; |
} |
return num; |
} |
|
|
static void CrcInit(void) |
{ |
unsigned int remainder; |
int dividend, bit, i; |
|
//Compute the remainder of each possible dividend |
for(dividend = 0; dividend < 256; ++dividend) |
{ |
//Start with the dividend followed by zeros |
remainder = dividend << 24; |
//Perform modulo-2 division, a bit at a time |
for(bit = 8; bit > 0; --bit) |
{ |
//Try to divide the current data bit |
if(remainder & TOPBIT) |
remainder = (remainder << 1) ^ POLYNOMIAL; |
else |
remainder = remainder << 1; |
} |
CrcTable[dividend] = remainder; |
} |
for(i = 0; i < 256; ++i) |
{ |
reflect[i] = (unsigned char)Reflect(i, 8); |
reflectNibble[i] = (unsigned char)((Reflect((i >> 4) ^ 0xf, 4) << 4) | |
Reflect(i ^ 0xf, 4)); |
} |
} |
|
|
static void SpinWait(int clocks) |
{ |
int value = *(volatile int*)COUNTER_REG + clocks; |
while(*(volatile int*)COUNTER_REG - value < 0) |
; |
} |
|
|
void EthernetInit(unsigned char MacAddress[6]) |
{ |
//Format of SMI data: 0101 A4:A0 R4:R0 00 D15:D0 |
unsigned long data=0x5f800100; //SMI R0 = 10Mbps full duplex |
//unsigned long data=0x5f800000; //SMI R0 = 10Mbps half duplex |
int i, value; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE; |
|
} |
|
|
/******************* CRC32 calculations ********************** |
* The CRC32 code is modified from Michale Barr's article in |
* Embedded Systems Programming January 2000. |
* A CRC is really modulo-2 binary division. Substraction means XOR. */ |
static unsigned int Reflect(unsigned int value, int bits) |
{ |
unsigned int num=0; |
int i; |
for(i = 0; i < bits; ++i) |
{ |
num = (num << 1) | (value & 1); |
value >>= 1; |
} |
return num; |
} |
|
|
static void CrcInit(void) |
{ |
unsigned int remainder; |
int dividend, bit, i; |
|
//Compute the remainder of each possible dividend |
for(dividend = 0; dividend < 256; ++dividend) |
{ |
//Start with the dividend followed by zeros |
remainder = dividend << 24; |
//Perform modulo-2 division, a bit at a time |
for(bit = 8; bit > 0; --bit) |
{ |
//Try to divide the current data bit |
if(remainder & TOPBIT) |
remainder = (remainder << 1) ^ POLYNOMIAL; |
else |
remainder = remainder << 1; |
} |
CrcTable[dividend] = remainder; |
} |
for(i = 0; i < 256; ++i) |
{ |
reflect[i] = (unsigned char)Reflect(i, 8); |
reflectNibble[i] = (unsigned char)((Reflect((i >> 4) ^ 0xf, 4) << 4) | |
Reflect(i ^ 0xf, 4)); |
} |
} |
|
|
static void SpinWait(int clocks) |
{ |
int value = *(volatile int*)COUNTER_REG + clocks; |
while(*(volatile int*)COUNTER_REG - value < 0) |
; |
} |
|
|
void EthernetInit(unsigned char MacAddress[6]) |
{ |
//Format of SMI data: 0101 A4:A0 R4:R0 00 D15:D0 |
unsigned long data=0x5f800100; //SMI R0 = 10Mbps full duplex |
//unsigned long data=0x5f800000; //SMI R0 = 10Mbps half duplex |
int i, value; |
volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE; |
|
CrcInit(); |
if(MacAddress) |
{ |
for(i = 0; i < 6; ++i) |
{ |
value = MacAddress[i]; |
gDestMac[i+1] = (unsigned char)((value >> 4) | (value << 4)); |
{ |
for(i = 0; i < 6; ++i) |
{ |
value = MacAddress[i]; |
gDestMac[i+1] = (unsigned char)((value >> 4) | (value << 4)); |
} |
} |
|
//Configure Ethernet PHY for 10Mbps full duplex via SMI interface |
MemoryWrite(GPIO0_OUT, ETHERNET_MDIO | ETHERNET_MDIO_WE | ETHERENT_MDC); |
for(i = 0; i < 34; ++i) |
{ |
MemoryWrite(GPIO0_OUT, ETHERENT_MDC); //clock high |
SpinWait(10); |
MemoryWrite(GPIO0_CLEAR, ETHERENT_MDC); //clock low |
SpinWait(10); |
} |
for(i = 31; i >= 0; --i) |
{ |
value = (data >> i) & 1; |
if(value) |
MemoryWrite(GPIO0_OUT, ETHERNET_MDIO); |
else |
MemoryWrite(GPIO0_CLEAR, ETHERNET_MDIO); |
MemoryWrite(GPIO0_OUT, ETHERENT_MDC); //clock high |
SpinWait(10); |
MemoryWrite(GPIO0_CLEAR, ETHERENT_MDC); //clock low |
SpinWait(10); |
} |
MemoryWrite(GPIO0_CLEAR, ETHERNET_MDIO_WE | ETHERNET_ENABLE); |
|
//Clear receive buffer |
for(i = 0; i <= INDEX_MASK; ++i) |
buf[i] = BYTE_EMPTY; |
|
} |
|
//Configure Ethernet PHY for 10Mbps full duplex via SMI interface |
MemoryWrite(GPIO0_OUT, ETHERNET_MDIO | ETHERNET_MDIO_WE | ETHERENT_MDC); |
for(i = 0; i < 34; ++i) |
{ |
MemoryWrite(GPIO0_OUT, ETHERENT_MDC); //clock high |
SpinWait(10); |
MemoryWrite(GPIO0_CLEAR, ETHERENT_MDC); //clock low |
SpinWait(10); |
} |
for(i = 31; i >= 0; --i) |
{ |
value = (data >> i) & 1; |
if(value) |
MemoryWrite(GPIO0_OUT, ETHERNET_MDIO); |
else |
MemoryWrite(GPIO0_CLEAR, ETHERNET_MDIO); |
MemoryWrite(GPIO0_OUT, ETHERENT_MDC); //clock high |
SpinWait(10); |
MemoryWrite(GPIO0_CLEAR, ETHERENT_MDC); //clock low |
SpinWait(10); |
} |
MemoryWrite(GPIO0_CLEAR, ETHERNET_MDIO_WE | ETHERNET_ENABLE); |
|
//Clear receive buffer |
for(i = 0; i <= INDEX_MASK; ++i) |
buf[i] = BYTE_EMPTY; |
|
if(SemEthernet == NULL) |
{ |
SemEthernet = OS_SemaphoreCreate("eth", 0); |
SemEthTransmit = OS_SemaphoreCreate("ethT", 1); |
OS_ThreadCreate("eth", EthernetThread, NULL, 240, 0); |
} |
|
//Setup interrupts for receiving data |
SemEthernet = OS_SemaphoreCreate("eth", 0); |
SemEthTransmit = OS_SemaphoreCreate("ethT", 1); |
OS_ThreadCreate("eth", EthernetThread, NULL, 240, 0); |
} |
|
//Setup interrupts for receiving data |
OS_InterruptRegister(IRQ_ETHERNET_RECEIVE, EthernetIsr); |
|
//Start receive DMA |
MemoryWrite(GPIO0_OUT, ETHERNET_ENABLE); |
} |
|
//Start receive DMA |
MemoryWrite(GPIO0_OUT, ETHERNET_ENABLE); |
} |
/kernel/http.c
97,7 → 97,7
if(strncmp((char*)buf+4, name, len) == 0) |
break; |
} |
#if defined(WIN32) || defined(INCLUDE_FILESYS) |
#ifndef EXCLUDE_FILESYS |
if(length == HTML_LENGTH_LIST_END && HtmlFiles) |
{ |
FILE *file; |
137,7 → 137,7
return; |
} |
} |
#endif |
#endif //!EXCLUDE_FILESYS |
if(length != HTML_LENGTH_LIST_END) |
{ |
if(length == HTML_LENGTH_CALLBACK) |
/kernel/tcpip.c
20,7 → 20,7
* FrameInsert() |
*--------------------------------------------------------------------*/ |
#include "rtos.h" |
#define IPPRINTF |
#define INSIDE_TCPIP |
#include "tcpip.h" |
|
//ETHER FIELD OFFSET LENGTH VALUE |
661,7 → 661,7
static int IPProcessTCPPacket(IPFrame *frameIn) |
{ |
uint32 seq, ack; |
int length, ip_length, bytes, rc=0, notify=0; |
int length, ip_length, bytes, rc=0, notify=0, window; |
IPSocket *socket, *socketNew; |
IPFrame *frameOut, *frame2, *framePrev; |
uint8 *packet, *packetOut; |
873,12 → 873,16
FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn); |
socket->ack += bytes; |
|
//Ack data |
frameOut = IPFrameGet(FRAME_COUNT_SEND); |
if(frameOut) |
window = RECEIVE_WINDOW - (socket->ack - socket->ackProcessed); |
if(window >= 536) |
{ |
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK; |
TCPSendPacket(socket, frameOut, TCP_DATA); |
//Ack data |
frameOut = IPFrameGet(FRAME_COUNT_SEND); |
if(frameOut) |
{ |
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK; |
TCPSendPacket(socket, frameOut, TCP_DATA); |
} |
} |
|
//Using frame |
1310,6 → 1314,9
void IPWriteFlush(IPSocket *socket) |
{ |
uint8 *packetOut; |
|
if(socket == NULL) |
socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
if(socket->frameSend && socket->state != IP_UDP && |
socket->state != IP_PING) |
{ |
1331,6 → 1338,9
int offset; |
OS_Thread_t *self; |
|
if(socket == NULL) |
socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
|
if(socket->state > IP_TCP) |
return 0; |
|
1337,7 → 1347,7
if(socket->timeout) |
socket->timeout = socket->timeoutReset; |
|
#ifdef INCLUDE_FILESYS |
#ifndef EXCLUDE_FILESYS |
if(socket->fileOut) //override stdout |
return fwrite((char*)buf, 1, length, socket->fileOut); |
#endif |
1420,7 → 1430,10
IPFrame *frame, *frame2; |
int count=0, bytes, offset; |
|
#ifdef INCLUDE_FILESYS |
if(socket == NULL) |
socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
|
#ifndef EXCLUDE_FILESYS |
if(socket->fileIn) //override stdin |
{ |
bytes = fread(buf, 1, 1, socket->fileIn); |
1550,27 → 1563,29
} |
|
|
void IPPrintf(IPSocket *socket, char *message, |
int arg0, int arg1, int arg2, int arg3) |
int IPPrintf(IPSocket *socket, char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
{ |
char buf[500]; |
char buffer[256], *ptr = buffer; |
int rc = 1; |
int length; |
|
if(socket == NULL) |
{ |
printf(message, arg0, arg1, arg2, arg3); |
return; |
} |
if(strcmp(message, "%s") == 0) |
IPWrite(socket, (uint8*)arg0, (int)strlen((char*)arg0)); |
socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
if(strcmp(format, "%s") == 0) |
ptr = (char*)arg0; |
else |
{ |
sprintf(buf, message, arg0, arg1, arg2, arg3, 0, 0, 0, 0); |
IPWrite(socket, (uint8*)buf, (int)strlen(buf)); |
} |
if(socket->dontFlush == 0 || strstr(message, "\n")) |
rc = sprintf(buffer, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
length = strlen(ptr); |
IPWrite(socket, (unsigned char*)ptr, length); |
if(socket->dontFlush == 0 || strstr(format, "\n")) |
IPWriteFlush(socket); |
return rc; |
} |
|
|
|
void IPTick(void) |
{ |
IPFrame *frame, *frame2; |
/kernel/dll.h
12,7 → 12,6
#ifndef __DLL_H__ |
#define __DLL_H__ |
|
#define INCLUDE_FILESYS |
#include "rtos.h" |
#include "tcpip.h" |
|
24,6 → 23,10
void *DllDummy(void) { printf("Dummy"); return NULL; } |
|
const DllFunc DllFuncList[] = { |
(DllFunc)ConsolePrintf, |
(DllFunc)ConsoleScanf, |
(DllFunc)ConsoleKbhit, |
(DllFunc)ConsoleGetch, |
(DllFunc)strcpy, |
(DllFunc)strncpy, |
(DllFunc)strcat, |
108,13 → 111,30
(DllFunc)OS_InterruptMaskSet, |
(DllFunc)OS_InterruptMaskClear, |
(DllFunc)UartPrintf, |
(DllFunc)UartPrintfPoll, |
(DllFunc)UartPrintfCritical, |
(DllFunc)UartPrintfCritical, |
(DllFunc)UartScanf, |
(DllFunc)OS_puts, |
(DllFunc)OS_getch, |
(DllFunc)OS_kbhit, |
(DllFunc)Led, |
#ifndef WIN32 |
(DllFunc)__negsf2, |
(DllFunc)__addsf3, |
(DllFunc)__subsf3, |
(DllFunc)__mulsf3, |
(DllFunc)__divsf3, |
(DllFunc)__fixsfsi, |
(DllFunc)__floatsisf, |
#else |
DllDummy, |
DllDummy, |
DllDummy, |
DllDummy, |
DllDummy, |
DllDummy, |
DllDummy, |
#endif |
(DllFunc)FP_Sqrt, |
(DllFunc)FP_Cos, |
(DllFunc)FP_Sin, |
123,7 → 143,7
(DllFunc)FP_Exp, |
(DllFunc)FP_Log, |
(DllFunc)FP_Pow, |
#ifdef INCLUDE_FILESYS |
#ifndef EXCLUDE_FILESYS |
(DllFunc)OS_fopen, |
(DllFunc)OS_fclose, |
(DllFunc)OS_fread, |
132,7 → 152,7
(DllFunc)OS_fmkdir, |
(DllFunc)OS_fdir, |
(DllFunc)OS_fdelete, |
#else //INCLUDE_FILESYS |
#else //EXCLUDE_FILESYS |
DllDummy, |
DllDummy, |
DllDummy, |
141,8 → 161,8
DllDummy, |
DllDummy, |
DllDummy, |
#endif //INCLUDE_FILESYS |
#ifndef WIN32 |
#endif //EXCLUDE_FILESYS |
#ifndef EXCLUDE_FLASH |
(DllFunc)FlashRead, |
(DllFunc)FlashWrite, |
(DllFunc)FlashErase, |
159,7 → 179,9
(DllFunc)IPPrintf, |
(DllFunc)IPResolve, |
(DllFunc)IPAddressSelf, |
(DllFunc)IPNameValue |
(DllFunc)IPNameValue, |
DllDummy, |
DllDummy |
}; |
|
#endif //DLL_SETUP |
168,6 → 190,10
#if defined(DLL_CALL) || !defined(DLL_SETUP) |
|
enum { |
ENUM_ConsolePrintf, |
ENUM_ConsoleScanf, |
ENUM_ConsoleKbhit, |
ENUM_ConsoleGetch, |
ENUM_strcpy, |
ENUM_strncpy, |
ENUM_strcat, |
243,6 → 269,13
ENUM_OS_getch, |
ENUM_OS_kbhit, |
ENUM_Led, |
ENUM_NEGSF2, |
ENUM_ADDSF3, |
ENUM_SUBSF3, |
ENUM_MULSF3, |
ENUM_DIVSF3, |
ENUM_FIXSFSI, |
ENUM_FLOATSISF, |
ENUM_FP_Sqrt, |
ENUM_FP_Cos, |
ENUM_FP_Sin, |
270,22 → 303,41
ENUM_IPPrintf, |
ENUM_IPResolve, |
ENUM_IPAddressSelf, |
ENUM_IPNameValue |
ENUM_IPNameValue, |
ENUM_USER0, |
ENUM_USER1, |
ARGV_SOCKET = -2 |
}; |
|
extern const DllFunc *DllF; |
|
#undef strcpy |
#undef strncpy |
#undef strcat |
#undef strncat |
#undef strcmp |
#undef strncmp |
#undef strlen |
#undef memcpy |
#undef memcmp |
#undef memmove |
#undef memset |
#undef abs |
#undef atoi |
#undef itoa |
#undef srand |
#undef rand |
#undef sprintf |
#undef sscanf |
#undef strstr |
#undef strtol |
#undef scanf |
#undef printf |
|
#define printf (int)DllF[ENUM_ConsolePrintf] |
#define scanf (int)DllF[ENUM_ConsoleScanf] |
#define kbhit (int)DllF[ENUM_ConsoleKbhit] |
#define getch (int)DllF[ENUM_ConsoleGetch] |
#define strcpy DllF[ENUM_strcpy] |
#define strncpy DllF[ENUM_strncpy] |
#define strcat DllF[ENUM_strcat] |
292,7 → 344,7
#define strncat DllF[ENUM_strncat] |
#define strcmp (int)DllF[ENUM_strcmp] |
#define strncmp (int)DllF[ENUM_strncmp] |
#define strstr DllF[ENUM_strstr] |
#define strstr (char*)DllF[ENUM_strstr] |
#define strlen (int)DllF[ENUM_strlen] |
#define memcpy DllF[ENUM_memcpy] |
#define memmove DllF[ENUM_memmove] |
299,13 → 351,13
#define memcmp (int)DllF[ENUM_memcmp] |
#define memset DllF[ENUM_memset] |
#define abs (int)DllF[ENUM_abs] |
#define rand (int)DllF[ENUM_rand] |
#define rand (unsigned int)DllF[ENUM_rand] |
#define srand DllF[ENUM_srand] |
#define strtol (int)DllF[ENUM_strtol] |
#define atoi (int)DllF[ENUM_atoi] |
#define itoa DllF[ENUM_itoa] |
#define sprintf DllF[ENUM_sprintf] |
#define sscanf DllF[ENUM_sscanf] |
#define sprintf (int)DllF[ENUM_sprintf] |
#define sscanf (int)DllF[ENUM_sscanf] |
#define dump DllF[ENUM_dump] |
#define qsort DllF[ENUM_qsort] |
#define bsearch DllF[ENUM_bsearch] |
324,7 → 376,7
#define OS_ThreadExit DllF[ENUM_OS_ThreadExit] |
#define OS_ThreadSelf DllF[ENUM_OS_ThreadSelf] |
#define OS_ThreadSleep DllF[ENUM_OS_ThreadSleep] |
#define OS_ThreadTime DllF[ENUM_OS_ThreadTime] |
#define OS_ThreadTime (int)DllF[ENUM_OS_ThreadTime] |
#define OS_ThreadInfoSet DllF[ENUM_OS_ThreadInfoSet] |
#define OS_ThreadInfoGet DllF[ENUM_OS_ThreadInfoGet] |
#define OS_ThreadPriorityGet (int)DllF[ENUM_OS_ThreadPriorityGet] |
372,8 → 424,8
#define OS_fopen DllF[ENUM_OS_fopen] |
#define OS_fclose DllF[ENUM_OS_fclose] |
#define OS_fread (int)DllF[ENUM_OS_fread] |
#define OS_fwrite DllF[ENUM_OS_fwrite] |
#define OS_fseek DllF[ENUM_OS_fseek] |
#define OS_fwrite (int)DllF[ENUM_OS_fwrite] |
#define OS_fseek (int)DllF[ENUM_OS_fseek] |
#define OS_fmkdir DllF[ENUM_OS_fmkdir] |
#define OS_fdir DllF[ENUM_OS_fdir] |
#define OS_fdelete DllF[ENUM_OS_fdelete] |
385,10 → 437,11
#define IPWrite (int)DllF[ENUM_IPWrite] |
#define IPRead (int)DllF[ENUM_IPRead] |
#define IPClose DllF[ENUM_IPClose] |
#define IPPrintf DllF[ENUM_IPPrintf] |
#define IPPrintf (int)DllF[ENUM_IPPrintf] |
#define IPResolve DllF[ENUM_IPResolve] |
#define IPAddressSelf (int)DllF[ENUM_IPAddressSelf] |
#define IPNameValue DllF[ENUM_IPNameValue] |
#define time(P) OS_ThreadTime() |
|
#endif //DLL_CALL |
|
402,27 → 455,46
|
// Included by DLL to initialize the DLL |
#if defined(DLL_ENTRY) && !defined(NO_DLL_ENTRY) |
const DllFunc *DllF; //array of function pointers |
extern void *__bss_start; |
extern void *_end; |
void Start(IPSocket *socket, char *argv[]); |
const DllFunc *DllF; //array of function pointers |
int main(int argc, char *argv[]); |
|
//Must be first function in file |
void *__start(DllFunc *DllFuncList) |
int __start(int argc, char *argv[]) |
{ |
int *bss; |
if(DllFuncList == NULL) |
return (void*)__start; //address where DLL should be loaded |
for(bss = (int*)&__bss_start; bss < (int*)&_end; ++bss) |
*bss = 0; |
DllF = DllFuncList; |
return (void*)Start; |
extern void *__bss_start; |
extern void *_end; |
int *bss = (int*)&__bss_start; |
|
if(bss == (int*)DllF) |
++bss; |
while(bss < (int*)&_end) |
*bss++ = 0; |
DllF = (DllFunc*)argv[-1]; |
return main(argc, argv); |
} |
|
#ifdef INCLUDE_MATH |
typedef float (*DllFloat)(float); |
typedef float (*DllFloat2)(float,float); |
typedef long (*DllFloat3)(float); |
float __negsf2(float a) {return ((DllFloat)DllF[ENUM_NEGSF2])(a);} |
float __addsf3(float a,float b) {return ((DllFloat2)DllF[ENUM_ADDSF3])(a,b);} |
float __subsf3(float a,float b) {return ((DllFloat2)DllF[ENUM_SUBSF3])(a,b);} |
float __mulsf3(float a,float b) {return ((DllFloat2)DllF[ENUM_MULSF3])(a,b);} |
float __divsf3(float a,float b) {return ((DllFloat2)DllF[ENUM_DIVSF3])(a,b);} |
long __fixsfsi(float a) {return ((DllFloat3)DllF[ENUM_FIXSFSI])(a);} |
float __floatsisf(long a) {return ((DllFloat)DllF[ENUM_FLOATSISF])(a);} |
#endif |
|
#endif //DLL_ENTRY |
|
|
#ifdef DLL_STRINGS |
const char * const DllStrings[] = { |
"printf", |
"scanf", |
"kbhit", |
"getch", |
"strcpy", |
"strncpy", |
"strcat", |
490,14 → 562,21
"OS_InterruptStatus", |
"OS_InterruptMaskSet", |
"OS_InterruptMaskClear", |
"printf", //"UartPrintf", |
"UartPrintf", |
"UartPrintfPoll", |
"UartPrintfCritical", |
"scanf", //"UartScanf", |
"UartScanf", |
"OS_puts", |
"OS_getch", |
"OS_kbhit", |
"Led", |
"FP_Neg", |
"FP_Add", |
"FP_Sub", |
"FP_Mult", |
"FP_Div", |
"FP_ToInt", |
"FP_ToLong", |
"FP_Sqrt", |
"FP_Cos", |
"FP_Sin", |
/kernel/rtos_ex.c
92,6 → 92,22
void OS_AsmInterruptInit(void) |
{ |
} |
|
void UartInit(void) {} |
uint8 UartRead(void) {return getch();} |
int OS_kbhit(void) {return kbhit();} |
void UartPrintf(const char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
{ |
char buffer[256], *ptr = buffer; |
|
sprintf(buffer, format, arg0, arg1, arg2, arg3, |
arg4, arg5, arg6, arg7); |
while(ptr[0]) |
putchar(*ptr++); |
} |
|
#endif //WIN32 |
|
|
/kernel/tcpip.h
17,9 → 17,9
#define FRAME_COUNT_SEND 10 |
#define FRAME_COUNT_RCV 5 |
#define RETRANSMIT_TIME 110 |
#define SOCKET_TIMEOUT 15 |
#define SOCKET_TIMEOUT 10 |
#define SEND_WINDOW 7000 |
#define RECEIVE_WINDOW 5120 |
#define RECEIVE_WINDOW (536*FRAME_COUNT/4) |
|
typedef enum IPMode_e { |
IP_MODE_UDP, |
81,6 → 81,7
void *userPtr2; |
uint32 userData; |
uint32 userData2; |
OS_Semaphore_t *userSemaphore; |
}; |
|
//ethernet.c |
100,10 → 101,12
uint32 IPWrite(IPSocket *socket, const uint8 *buf, uint32 length); |
uint32 IPRead(IPSocket *socket, uint8 *buf, uint32 length); |
void IPClose(IPSocket *socket); |
#ifdef IPPRINTF |
void IPPrintf(IPSocket *socket, char *message, int arg0, int arg1, int arg2, int arg3); |
#ifdef INSIDE_TCPIP |
int IPPrintf(IPSocket *socket, char *message, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7); |
#else |
void IPPrintf(IPSocket *socket, char *message, ...); |
int IPPrintf(IPSocket *socket, char *message, ...); |
#endif |
void IPResolve(char *name, IPCallbackPtr resolvedFunc, void *arg); |
uint32 IPAddressSelf(void); |
131,5 → 134,10
IPCallbackPtr callback); |
void ConsoleInit(void); |
void *IPNameValue(const char *name, void *value); |
int ConsoleGetch(void); |
#ifndef INSIDE_NETUTIL |
int ConsoleScanf(char *format, ...); |
int ConsolePrintf(char *format, ...); |
#endif |
|
#endif //__TCPIP_H__ |
/kernel/netutil.c
10,12 → 10,12
* Plasma FTP server and FTP client and TFTP server and client |
* and Telnet server. |
*--------------------------------------------------------------------*/ |
#undef INCLUDE_FILESYS |
#define INCLUDE_FILESYS |
#define INSIDE_NETUTIL |
#include "plasma.h" |
#include "rtos.h" |
#include "tcpip.h" |
|
#ifdef DLL_SETUP |
#ifndef EXCLUDE_DLL |
static void ConsoleRun(IPSocket *socket, char *argv[]); |
#endif |
|
135,7 → 135,7
info->done = 0; |
if(strstr((char*)buf, "RETR")) |
info->file = fopen((char*)buf + 5, "rb"); |
else if(info->canReceive) |
else if(info->canReceive && strcmp((char*)buf+5, "/flash/web")) |
info->file = fopen((char*)buf + 5, "wb"); |
if(info->file) |
{ |
375,7 → 375,7
IPWrite(socket, buf, 4); |
if(bytes-4 < 512) |
{ |
socket->userFunc(socket, socket->userPtr, length); |
socket->userFunc(socket, (uint8*)socket->userPtr, length); |
IPClose(socket); |
} |
} |
409,6 → 409,7
static char CommandHistory[400]; |
static char *CommandPtr[COMMAND_BUFFER_COUNT]; |
static int CommandIndex; |
static OS_Semaphore_t *semProtect; |
|
typedef void (*ConsoleFunc)(IPSocket *socket, char *argv[]); |
typedef struct { |
417,20 → 418,124
} TelnetFunc_t; |
static TelnetFunc_t *TelnetFuncList; |
|
|
static void TelnetServer(IPSocket *socket) |
static int TelnetGetLine(IPSocket *socket, uint8 *bufIn, int bytes) |
{ |
uint8 buf[COMMAND_BUFFER_SIZE+4]; |
int i, j, length; |
char *ptr, *command = (char*)socket->userPtr; |
char bufOut[32]; |
int bytes, i, j, k, length, found; |
char *ptr, *command = socket->userPtr; |
char *argv[10]; |
|
length = (int)strlen(command); |
for(j = 0; j < bytes; ++j) |
{ |
if(bufIn[j] == 255) |
break; |
if(bufIn[j] == 8 || (bufIn[j] == 27 && bufIn[j+2] == 'D')) |
{ |
if(bufIn[j] == 27) |
j += 2; |
if(length) |
{ |
// Backspace |
command[--length] = 0; |
bufOut[0] = 8; |
bufOut[1] = ' '; |
bufOut[2] = 8; |
IPWrite(socket, (uint8*)bufOut, 3); |
IPWriteFlush(socket); |
} |
} |
else if(bufIn[j] == 27) |
{ |
// Command History |
if(bufIn[j+2] == 'A') |
{ |
if(++CommandIndex > COMMAND_BUFFER_COUNT) |
CommandIndex = COMMAND_BUFFER_COUNT; |
} |
else if(bufIn[j+2] == 'B') |
{ |
if(--CommandIndex < 0) |
CommandIndex = 0; |
} |
else |
return -1; |
bufOut[0] = 8; |
bufOut[1] = ' '; |
bufOut[2] = 8; |
for(i = 0; i < length; ++i) |
IPWrite(socket, (uint8*)bufOut, 3); |
command[0] = 0; |
if(CommandIndex && CommandPtr[CommandIndex-1]) |
strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1); |
length = (int)strlen(command); |
IPWrite(socket, (uint8*)command, length); |
IPWriteFlush(socket); |
j += 2; |
} |
else |
{ |
if(bufIn[j] == 0) |
bufIn[j] = '\n'; //Linux support |
if(length < COMMAND_BUFFER_SIZE-4 || (length < |
COMMAND_BUFFER_SIZE-2 && (bufIn[j] == '\r' || bufIn[j] == '\n'))) |
{ |
IPWrite(socket, (uint8*)bufIn+j, 1); |
IPWriteFlush(socket); |
command[length] = bufIn[j]; |
command[++length] = 0; |
} |
} |
ptr = strstr(command, "\r\n"); |
if(ptr == NULL) |
ptr = strstr(command, "\n"); |
if(ptr) |
{ |
// Save command in CommandHistory |
ptr[0] = 0; |
length = (int)strlen(command); |
if(length == 0) |
{ |
IPPrintf(socket, "\n-> "); |
continue; |
} |
if(length < COMMAND_BUFFER_SIZE) |
{ |
OS_SemaphorePend(semProtect, OS_WAIT_FOREVER); |
memmove(CommandHistory + length + 1, CommandHistory, |
sizeof(CommandHistory) - length - 1); |
strcpy(CommandHistory, command); |
CommandHistory[sizeof(CommandHistory)-1] = 0; |
for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i) |
{ |
if(CommandPtr[i] == NULL || CommandPtr[i] + length + 1 >= |
CommandHistory + sizeof(CommandHistory)) |
CommandPtr[i+1] = NULL; |
else |
CommandPtr[i+1] = CommandPtr[i] + length + 1; |
} |
CommandPtr[0] = CommandHistory; |
OS_SemaphorePost(semProtect); |
} |
return 0; |
} |
} |
return -1; |
} |
|
|
static void TelnetServerCallback(IPSocket *socket) |
{ |
uint8 bufIn[COMMAND_BUFFER_SIZE+4]; |
int bytes, i, k, found, rc; |
char *ptr, *command = (char*)socket->userPtr; |
char command2[COMMAND_BUFFER_SIZE]; |
char *argvStorage[12], **argv = argvStorage+2; |
|
if(socket->state > IP_TCP) |
return; |
for(;;) |
{ |
bytes = IPRead(socket, buf, sizeof(buf)-1); |
bytes = IPRead(socket, bufIn, sizeof(bufIn)-1); |
if(command == NULL) |
{ |
socket->userPtr = command = (char*)malloc(COMMAND_BUFFER_SIZE); |
439,185 → 544,158
IPClose(socket); |
return; |
} |
socket->timeoutReset = 300; |
buf[0] = 255; //IAC |
buf[1] = 251; //WILL |
buf[2] = 3; //suppress go ahead |
buf[3] = 255; //IAC |
buf[4] = 251; //WILL |
buf[5] = 1; //echo |
strcpy((char*)buf+6, "Welcome to Plasma.\r\n-> "); |
IPWrite(socket, buf, 6+23); |
socket->timeoutReset = 60*15; |
bufIn[0] = 255; //IAC |
bufIn[1] = 251; //WILL |
bufIn[2] = 3; //suppress go ahead |
bufIn[3] = 255; //IAC |
bufIn[4] = 251; //WILL |
bufIn[5] = 1; //echo |
strcpy((char*)bufIn+6, "Welcome to Plasma.\r\n-> "); |
IPWrite(socket, bufIn, 6+23); |
IPWriteFlush(socket); |
command[0] = 0; |
OS_ThreadInfoSet(OS_ThreadSelf(), 0, (void*)socket); //for stdin and stdout |
return; |
} |
if(bytes == 0) |
return; |
socket->dontFlush = 0; |
buf[bytes] = 0; |
length = (int)strlen(command); |
for(j = 0; j < bytes; ++j) |
bufIn[bytes] = 0; |
|
//Get a complete command line |
rc = TelnetGetLine(socket, bufIn, bytes); |
if(rc) |
continue; |
strcpy(command2, command); |
command[0] = 0; |
|
//Process arguments |
for(i = 0; i < 10; ++i) |
argv[i] = ""; |
i = 0; |
argv[i++] = command2; |
for(ptr = command2; *ptr && i < 10; ++ptr) |
{ |
if(buf[j] == 255) |
return; |
if(buf[j] == 8 || (buf[j] == 27 && buf[j+2] == 'D')) |
if(*ptr == ' ') |
{ |
if(buf[j] == 27) |
j += 2; |
if(length) |
{ |
// Backspace |
command[--length] = 0; |
bufOut[0] = 8; |
bufOut[1] = ' '; |
bufOut[2] = 8; |
IPWrite(socket, (uint8*)bufOut, 3); |
} |
*ptr = 0; |
argv[i++] = ptr + 1; |
} |
else if(buf[j] == 27) |
} |
if(argv[0][0] == 0) |
{ |
IPPrintf(socket, "-> "); |
continue; |
} |
|
//Check for file in or out |
for(k = 1; k < 10; ++k) |
{ |
if(argv[k][0] == '>') //stdout to file? |
{ |
// Command History |
if(buf[j+2] == 'A') |
{ |
if(++CommandIndex > COMMAND_BUFFER_COUNT) |
CommandIndex = COMMAND_BUFFER_COUNT; |
} |
else if(buf[j+2] == 'B') |
{ |
if(--CommandIndex < 0) |
CommandIndex = 0; |
} |
else |
return; |
bufOut[0] = 8; |
bufOut[1] = ' '; |
bufOut[2] = 8; |
for(i = 0; i < length; ++i) |
IPWrite(socket, (uint8*)bufOut, 3); |
command[0] = 0; |
if(CommandIndex && CommandPtr[CommandIndex-1]) |
strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1); |
length = (int)strlen(command); |
IPWrite(socket, (uint8*)command, length); |
j += 2; |
if(argv[k][1]) |
socket->fileOut = fopen(&argv[k][1], "a"); |
else |
socket->fileOut = fopen(argv[k+1], "a"); |
argv[k] = ""; |
} |
if(argv[k][0] == '<') //stdin from file? |
{ |
if(argv[k][1]) |
socket->fileIn = fopen(&argv[k][1], "r"); |
else |
socket->fileIn = fopen(argv[k+1], "r"); |
argv[k] = ""; |
} |
} |
|
//Find command |
found = 0; |
for(i = 0; TelnetFuncList[i].name; ++i) |
{ |
if(strcmp(argv[0], TelnetFuncList[i].name) == 0 && |
TelnetFuncList[i].func) |
{ |
found = 1; |
TelnetFuncList[i].func(socket, argv); |
break; |
} |
} |
#ifndef EXCLUDE_DLL |
if(found == 0) |
{ |
FILE *file = fopen(argv[0], "r"); |
if(file) |
{ |
fclose(file); |
ConsoleRun(socket, argv); |
} |
else |
{ |
if(buf[j] == 0) |
buf[j] = '\n'; //Linux support |
if(length < COMMAND_BUFFER_SIZE-4 || (length < |
COMMAND_BUFFER_SIZE-2 && (buf[j] == '\r' || buf[j] == '\n'))) |
{ |
IPWrite(socket, buf+j, 1); |
command[length] = buf[j]; |
command[++length] = 0; |
} |
strcpy((char*)bufIn, "/flash/bin/"); |
strcat((char*)bufIn, argv[0]); |
argv[0] = (char*)bufIn; |
ConsoleRun(socket, argv); |
} |
ptr = strstr(command, "\r\n"); |
if(ptr) |
{ |
// Save command in CommandHistory |
ptr[0] = 0; |
length = (int)strlen(command); |
if(length == 0) |
{ |
IPPrintf(socket, "-> "); |
continue; |
} |
if(length < COMMAND_BUFFER_SIZE) |
{ |
memmove(CommandHistory + length + 1, CommandHistory, |
sizeof(CommandHistory) - length - 1); |
strcpy(CommandHistory, command); |
CommandHistory[sizeof(CommandHistory)-1] = 0; |
for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i) |
{ |
if(CommandPtr[i] == NULL || CommandPtr[i] + length + 1 >= |
CommandHistory + sizeof(CommandHistory)) |
CommandPtr[i+1] = NULL; |
else |
CommandPtr[i+1] = CommandPtr[i] + length + 1; |
} |
CommandPtr[0] = CommandHistory; |
} |
|
//Start command |
for(i = 0; i < 10; ++i) |
argv[i] = ""; |
i = 0; |
argv[i++] = command; |
for(ptr = command; *ptr && i < 10; ++ptr) |
{ |
if(*ptr == ' ') |
{ |
*ptr = 0; |
argv[i++] = ptr + 1; |
} |
} |
if(argv[0][0] == 0) |
{ |
IPPrintf(socket, "-> "); |
continue; |
} |
found = 0; |
for(i = 0; TelnetFuncList[i].name; ++i) |
{ |
if(strcmp(command, TelnetFuncList[i].name) == 0 && |
TelnetFuncList[i].func) |
{ |
found = 1; |
for(k = 1; k < 10; ++k) |
{ |
if(argv[k][0] == '>' && argv[k][1]) //stdout to file? |
{ |
socket->fileOut = fopen(&argv[k][1], "a"); |
argv[k] = ""; |
} |
if(argv[k][0] == '<' && argv[k][1]) //stdin from file? |
{ |
socket->fileIn = fopen(&argv[k][1], "r"); |
argv[k] = ""; |
} |
} |
TelnetFuncList[i].func(socket, argv); |
if(socket->fileOut) |
{ |
fwrite("\r\n", 1, 2, socket->fileOut); |
fclose(socket->fileOut); |
} |
socket->fileOut = NULL; |
break; |
} |
} |
#ifdef DLL_SETUP |
if(found == 0) |
{ |
strcpy((char*)buf, "/flash/bin/"); |
strcat((char*)buf, argv[0]); |
argv[0] = (char*)buf; |
ConsoleRun(socket, argv); |
} |
} |
#endif |
if(socket->state > IP_TCP) |
return; |
command[0] = 0; |
length = 0; |
CommandIndex = 0; |
if(socket->dontFlush == 0) |
IPPrintf(socket, "\r\n-> "); |
} //command entered |
} //bytes |
IPWriteFlush(socket); |
if(socket->fileOut) |
{ |
fwrite("\r\n", 1, 2, (FILE*)socket->fileOut); |
fclose((FILE*)socket->fileOut); |
socket->fileOut = NULL; |
} |
|
if(socket->state > IP_TCP) |
return; |
CommandIndex = 0; |
if(socket->dontFlush == 0) |
IPPrintf(socket, "\r\n-> "); |
} |
} |
|
|
static void TelnetThread(void *socketIn) |
{ |
IPSocket *socket = (IPSocket*)socketIn; |
|
while(socket->state <= IP_TCP) |
{ |
OS_SemaphorePend(socket->userSemaphore, OS_WAIT_FOREVER); |
TelnetServerCallback(socket); |
} |
if(socket->userPtr) |
free(socket->userPtr); |
socket->userPtr = NULL; |
OS_SemaphoreDelete(socket->userSemaphore); |
socket->userSemaphore = NULL; |
OS_ThreadExit(); |
} |
|
|
static void TelnetServer(IPSocket *socket) |
{ |
if(socket->state <= IP_TCP && socket->userSemaphore == NULL) |
{ |
socket->userSemaphore = OS_SemaphoreCreate("telnet", 0); |
OS_ThreadCreate("telnet", TelnetThread, socket, 100, 1024*8); |
} |
if(socket->userSemaphore) |
OS_SemaphorePost(socket->userSemaphore); |
} |
|
|
void TelnetInit(TelnetFunc_t *funcList) |
{ |
IPSocket *socket; |
TelnetFuncList = funcList; |
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer); |
semProtect = OS_SemaphoreCreate("telprot", 1); |
#ifndef WIN32 |
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer); //create thread |
#else |
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServerCallback); |
#endif |
} |
|
|
629,12 → 707,74
static char storageFilename[60]; |
|
|
int ConsoleScanf(char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
{ |
IPSocket *socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
char *command = (char*)socket->userPtr; |
uint8 bufIn[256]; |
int bytes; |
int rc; |
|
while(socket->state <= IP_TCP) |
{ |
bytes = IPRead(socket, (unsigned char*)bufIn, sizeof(bufIn)); |
rc = TelnetGetLine(socket, bufIn, bytes); |
if(rc == 0) |
break; |
OS_ThreadSleep(1); |
} |
|
rc = sscanf(command, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
command[0] = 0; |
return rc; |
} |
|
|
int ConsoleKbhit(void) |
{ |
IPSocket *socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0); |
|
if(socket->state > IP_TCP || socket->frameReadTail || socket->fileIn) |
return 1; |
return 0; |
} |
|
|
int ConsoleGetch(void) |
{ |
unsigned char buffer[8]; |
int rc, i; |
|
for(i = 0; i < 100*60; ++i) |
{ |
if(ConsoleKbhit()) |
break; |
OS_ThreadSleep(5); |
} |
|
rc = IPRead(NULL, buffer, 1); |
if(rc <= 0) |
return -1; |
return buffer[0]; |
} |
|
|
int ConsolePrintf(char *format, |
int arg0, int arg1, int arg2, int arg3, |
int arg4, int arg5, int arg6, int arg7) |
{ |
return IPPrintf(NULL, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
} |
|
|
static void ConsoleHelp(IPSocket *socket, char *argv[]) |
{ |
char buf[200]; |
int i; |
(void)argv; |
strcpy(buf, "Commands: "); |
strcpy(buf, "Version " __DATE__ " " __TIME__ "\nCommands: "); |
for(i = 0; TelnetFuncList[i].name; ++i) |
{ |
if(TelnetFuncList[i].func) |
650,12 → 790,80
|
static void ConsoleExit(IPSocket *socket, char *argv[]) |
{ |
free(argv[0]); |
socket->userPtr = NULL; |
IPClose(socket); |
} |
|
|
static void ConsoleMemcpyReboot(int *dst, int *src, int length) |
{ |
OS_FuncPtr_t funcPtr = (OS_FuncPtr_t)dst; |
while(length-- > 0) |
*dst++ = *src++; |
funcPtr(NULL); |
} |
|
|
static void ConsoleReboot(IPSocket *socket, char *argv[]) |
{ |
FILE *file = NULL; |
OS_FuncPtr_t funcPtr; |
unsigned char *ptr; |
int length; |
(void)socket; |
|
if(argv[1][0]) |
file = fopen(argv[1], "r"); |
#ifndef EXCLUDE_FLASH |
if(file && strcmp(argv[2], "flash") == 0) |
{ |
unsigned char buffer[64]; |
int offset; |
|
FlashErase(0); //erase 128KB sector |
offset = 0; |
for(;;) |
{ |
length = fread(buffer, 1, sizeof(buffer), file); |
if(length == 0) |
break; |
FlashWrite((uint16*)buffer, offset, length); |
offset += length; |
} |
fclose(file); |
file = NULL; |
} |
#endif |
if(file) |
{ |
//Reboot running new image |
typedef void (*RebootFunc)(int *, int *, int); |
typedef void (*MemcpyFunc)(int *dst, int *src, int length); |
union { //convert from function pointer to data pointer |
RebootFunc rebootFunc; |
MemcpyFunc memcpyFunc; |
unsigned char *ptr; |
} rfUnion; |
|
ptr=(unsigned char*)malloc(256+1024*128); |
if(ptr == NULL) |
return; |
rfUnion.memcpyFunc = ConsoleMemcpyReboot; |
memcpy(ptr, rfUnion.ptr, 256); //rfUnion.ptr==ConsoleMemcpyReboot |
rfUnion.ptr = ptr; |
ptr += 256; |
length = fread(ptr, 1, 128*1024, file) + 3; |
fclose(file); |
printf("rebooting 0x%x 0x%x %d\n", (int)rfUnion.rebootFunc, (int)ptr, length); |
OS_ThreadSleep(100); |
OS_CriticalBegin(); |
rfUnion.rebootFunc((int*)RAM_EXTERNAL_BASE, (int*)ptr, length>>2); |
} |
funcPtr = NULL; |
OS_CriticalBegin(); |
funcPtr(NULL); |
} |
|
|
static void ConsoleCat(IPSocket *socket, char *argv[]) |
{ |
FILE *file; |
683,9 → 891,19
int bytes; |
(void)socket; |
|
fileOut = fopen(argv[2], "r"); |
if(fileOut) |
{ |
IPPrintf(socket, "File already exists!\n"); |
fclose(fileOut); |
return; |
} |
fileIn = fopen(argv[1], "r"); |
if(fileIn == NULL) |
{ |
IPPrintf(socket, "Error!\n"); |
return; |
} |
fileOut = fopen(argv[2], "w"); |
if(fileOut) |
{ |
752,19 → 970,21
} |
|
|
#ifdef INCLUDE_FLASH |
#ifndef EXCLUDE_FLASH |
static void ConsoleFlashErase(IPSocket *socket, char *argv[]) |
{ |
int bytes; |
OS_FuncPtr_t funcPtr = NULL; |
(void)argv; |
IPPrintf(socket, "\r\nErasing"); |
IPPrintf(socket, "\r\nErasing\n"); |
OS_ThreadSleep(10); |
OS_CriticalBegin(); |
for(bytes = 1024*128; bytes < 1024*1024*16; bytes += 1024*128) |
{ |
IPPrintf(socket, "."); |
UartPrintfCritical("."); |
FlashErase(bytes); |
} |
IPPrintf(socket, "\r\nMust Reboot\r\n"); |
OS_ThreadSleep(OS_WAIT_FOREVER); |
funcPtr(NULL); |
} |
#endif |
|
797,7 → 1017,7
|
static void PingCallback(IPSocket *socket) |
{ |
IPSocket *socket2 = socket->userPtr; |
IPSocket *socket2 = (IPSocket*)socket->userPtr; |
IPClose(socket); |
if(socket2) |
IPPrintf(socket2, "Ping Reply"); |
914,10 → 1134,12
|
static void ConsoleUptime(IPSocket *socket, char *argv[]) |
{ |
unsigned int ticks; |
int days, hours, minutes, seconds; |
(void)argv; |
//ticks per sec = 25E6/2^18 = 95.36743 -> 10.48576 ms/tick |
seconds = OS_ThreadTime() / 95; |
ticks = OS_ThreadTime(); // 1/(1-95.3674/95) = -259 |
seconds = (ticks - ticks / 259) / 95; |
minutes = seconds / 60 % 60; |
hours = seconds / 3600 % 24; |
days = seconds / 3600 / 24; |
1006,19 → 1228,93
} |
|
|
#ifdef DLL_SETUP |
#ifndef EXCLUDE_DLL |
#ifndef WIN32 |
#define DLL_SETUP |
#include "dll.h" |
#else |
typedef void *(*DllFunc)(); |
DllFunc DllFuncList[1]; |
#define ntohl(A) (((A)>>24)|(((A)&0x00ff0000)>>8)|(((A)&0xff00)<<8)|((A)<<24)) |
#define ntohs(A) (uint16)((((A)&0xff00)>>8)|((A)<<8)) |
#endif |
|
typedef struct |
{ |
uint8 e_ident[16]; |
uint16 e_e_type; |
uint16 e_machine; |
uint32 e_version; |
uint32 e_entry; |
uint32 e_phoff; |
uint32 e_shoff; |
uint32 e_flags; |
uint16 e_ehsize; |
uint16 e_phentsize; |
uint16 e_phnum; |
uint16 e_shentsize; |
uint16 e_shnum; |
uint16 e_shstrndx; |
} ElfHeader; |
|
typedef struct |
{ |
uint32 p_type; |
uint32 p_offset; |
uint32 p_vaddr; |
uint32 p_paddr; |
uint32 p_filesz; |
uint32 p_memsz; |
uint32 p_flags; |
uint32 p_align; |
} Elf32_Phdr; |
|
|
static unsigned int ConsoleLoadElf(FILE *file, uint8 *ptr) |
{ |
int i; |
ElfHeader *elfHeader = (ElfHeader*)ptr; |
Elf32_Phdr *elfProgram; |
#ifdef WIN32 |
elfHeader->e_entry = ntohl(elfHeader->e_entry); |
elfHeader->e_phoff = ntohl(elfHeader->e_phoff); |
elfHeader->e_phentsize = ntohs(elfHeader->e_phentsize); |
elfHeader->e_phnum = ntohs(elfHeader->e_phnum); |
#endif |
//printf("Entry=0x%x ", elfHeader->e_entry); |
OS_ThreadSleep(10); |
|
for(i = 0; i < elfHeader->e_phnum; ++i) |
{ |
elfProgram = (Elf32_Phdr*)(ptr + elfHeader->e_phoff + |
elfHeader->e_phentsize * i); |
#ifdef WIN32 |
elfProgram->p_offset = ntohl(elfProgram->p_offset); |
elfProgram->p_vaddr = ntohl(elfProgram->p_vaddr); |
elfProgram->p_filesz = ntohl(elfProgram->p_filesz); |
#endif |
//printf("0x%x 0x%x 0x%x\n", elfProgram->p_vaddr, elfProgram->p_offset, elfProgram->p_filesz); |
fseek(file, elfProgram->p_offset, 0); |
#ifndef WIN32 |
fread((char*)elfProgram->p_vaddr, 1, elfProgram->p_filesz, file); |
#endif |
} |
return elfHeader->e_entry; |
} |
|
|
static void ConsoleRun(IPSocket *socket, char *argv[]) |
{ |
FILE *file; |
int bytes, i; |
uint8 code[128]; |
int bytes, i, run=0; |
uint8 code[256]; |
DllFunc funcPtr; |
char *command, *ptr; |
|
if(strcmp(argv[0], "run") == 0) |
{ |
run = 1; |
++argv; |
} |
file = fopen(argv[0], "r"); |
if(file == NULL) |
{ |
1026,47 → 1322,32
return; |
} |
|
bytes = fread(code, 1, sizeof(code), file); //load first 128 bytes |
if(code[0] >= ' ') |
memset(code, 0, sizeof(code)); |
bytes = fread(code, 1, sizeof(code), file); //load first bytes |
if(strncmp((char*)code + 1, "ELF", 3) == 0) |
{ |
socket->fileIn = file; //script file |
fseek(file, 0, 0); |
funcPtr = (DllFunc)ConsoleLoadElf(file, code); |
fclose(file); |
argv[-1] = (char*)DllFuncList; //DllF = argv[-1] |
argv[-2] = (char*)socket; |
for(i = 0; i < 10; ++i) |
{ |
if(argv[i] == 0) |
break; |
} |
#ifndef WIN32 |
funcPtr(i, argv); |
#endif |
return; |
} |
|
funcPtr = (DllFunc)code; |
ptr = funcPtr(NULL); //determine load address |
|
memcpy(ptr, code, bytes); //copy to correct address |
bytes += fread(ptr + bytes, 1, 1024*1024*8, file); |
fclose(file); |
printf("address=0x%x bytes=%d\n", (int)ptr, bytes); |
funcPtr = (DllFunc)ptr; |
funcPtr = (DllFunc)funcPtr(DllFuncList); //initialize DLL, find Start() |
|
//Register new command |
command = argv[0]; |
for(;;) |
if(run == 0) |
{ |
ptr = strstr(command, "/"); |
if(ptr == NULL) |
break; |
command = ptr + 1; |
fclose(file); |
return; |
} |
for(i = 0; TelnetFuncList[i].name; ++i) |
{ |
if(TelnetFuncList[i].name[0] == 0 || |
strcmp(TelnetFuncList[i].name, command) == 0) |
{ |
TelnetFuncList[i].name = (char*)malloc(40); |
strcpy(TelnetFuncList[i].name, command); |
TelnetFuncList[i].func = (ConsoleFunc)funcPtr; |
break; |
} |
} |
|
socket->userFunc = (IPCallbackPtr)socket->funcPtr; |
funcPtr(socket, argv); |
socket->fileIn = file; //script file |
fseek(file, 0, 0); |
} |
|
|
1073,7 → 1354,7
typedef struct NameValue_t { |
struct NameValue_t *next; |
void *value; |
char name[1]; |
char name[4]; |
} NameValue_t; |
|
//Find the value associated with the name |
1081,6 → 1362,7
{ |
static NameValue_t *head; |
NameValue_t *node; |
OS_SemaphorePend(semProtect, OS_WAIT_FOREVER); |
for(node = head; node; node = node->next) |
{ |
if(strcmp(node->name, name) == 0) |
1098,6 → 1380,7
} |
if(value) |
node->value = value; |
OS_SemaphorePost(semProtect); |
return node->value; |
} |
#endif |
1112,7 → 1395,7
{"cp", ConsoleCp}, |
{"dump", ConsoleDump}, |
{"exit", ConsoleExit}, |
#ifdef INCLUDE_FLASH |
#ifndef EXCLUDE_FLASH |
{"flashErase", ConsoleFlashErase}, |
#endif |
{"ftp", ConsoleFtp}, |
1123,26 → 1406,16
{"mkdir", ConsoleMkdir}, |
{"mkfile", ConsoleMkfile}, |
{"ping", ConsolePing}, |
{"reboot", ConsoleReboot}, |
{"rm", ConsoleRm}, |
{"tftp", ConsoleTftp}, |
{"uptime", ConsoleUptime}, |
#ifdef DLL_SETUP |
#ifndef EXCLUDE_DLL |
{"run", ConsoleRun}, |
#endif |
#ifdef EDIT_FILE |
{"edit", EditFile}, |
#endif |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{"", NULL}, |
{NULL, NULL} |
}; |
|
/kernel/rtos_test.c
108,12 → 108,15
for(k = 0; k < value; ++k) |
{ |
if(ptr[k] != value) |
{ |
printf("Error\n"); |
break; |
} |
} |
OS_HeapFree(ptrs[j]); |
} |
size[j] = (uint8)(rand() & 255); |
ptrs[j] = OS_HeapMalloc(NULL, size[j]); |
ptrs[j] = (uint8*)OS_HeapMalloc(NULL, size[j]); |
if(ptrs[j] == NULL) |
printf("malloc NULL\n"); |
else |
512,12 → 515,12
HtmlInit(1); |
#endif |
|
#ifdef INCLUDE_HTML |
#ifdef INCLUDE_UART_PACKETS |
IPInit(NULL, macAddress, "plasma"); |
HtmlInit(1); |
#endif |
|
#ifdef INCLUDE_CONSOLE |
#if !defined(EXCLUDE_CONSOLE) && (defined(INCLUDE_ETH) || defined(INCLUDE_UART_PACKETS)) |
ConsoleInit(); |
#endif |
|
/kernel/rtos.c
24,7 → 24,7
#define HEAP_COUNT 8 |
|
#define PRINTF_DEBUG(STRING, A, B) |
//#define PRINTF_DEBUG(STRING, A, B) printf(STRING, A, B) |
//#define PRINTF_DEBUG(STRING, A, B) UartPrintfCritical(STRING, A, B) |
|
/*************** Structures ***************/ |
#ifdef WIN32 |
203,8 → 203,9
} |
heap->available = prevp; |
node->next = (HeapNode_t*)heap; |
PRINTF_DEBUG("malloc(%d, %d)\n", node->size * sizeof(HeapNode_t), heap->count); |
++heap->count; |
OS_SemaphorePost(heap->semaphore); |
++heap->count; |
//UartPrintfCritical("OS_HeapMalloc(%d)=0x%x\n", bytes, (int)(node+1)); |
return (void*)(node + 1); |
} |
234,8 → 235,9
assert(heap->magic == HEAP_MAGIC); |
if(heap->magic != HEAP_MAGIC) |
return; |
OS_SemaphorePend(heap->semaphore, OS_WAIT_FOREVER); |
--heap->count; |
OS_SemaphorePend(heap->semaphore, OS_WAIT_FOREVER); |
PRINTF_DEBUG("free(%d, %d)\n", bp->size * sizeof(HeapNode_t), heap->count); |
for(node = heap->available; !(node < bp && bp < node->next); node = node->next) |
{ |
if(node >= node->next && (bp > node || bp < node->next)) |
425,12 → 427,12
assert(threadCurrent->magic[0] == THREAD_MAGIC); //check stack overflow |
if(threadCurrent->state == THREAD_RUNNING) |
OS_ThreadPriorityInsert(&ThreadHead, threadCurrent); |
PRINTF_DEBUG("Pause(%d,%s) ", OS_CpuIndex(), threadCurrent->name); |
//PRINTF_DEBUG("Pause(%d,%s) ", OS_CpuIndex(), threadCurrent->name); |
rc = setjmp(threadCurrent->env); //ANSI C call to save registers |
if(rc) |
{ |
PRINTF_DEBUG("Resume(%d,%s) ", OS_CpuIndex(), |
ThreadCurrent[OS_CpuIndex()]->name); |
//PRINTF_DEBUG("Resume(%d,%s) ", OS_CpuIndex(), |
// ThreadCurrent[OS_CpuIndex()]->name); |
return; //Returned from longjmp() |
} |
} |
730,7 → 732,7
OS_Thread_t *thread; |
int returnCode=0; |
|
PRINTF_DEBUG("SemPend(%d,%s) ", OS_CpuIndex(), semaphore->name); |
//PRINTF_DEBUG("SemPend(%d,%s) ", OS_CpuIndex(), semaphore->name); |
assert(semaphore); |
assert(InterruptInside[OS_CpuIndex()] == 0); |
state = OS_CriticalBegin(); //Disable interrupts |
773,7 → 775,7
uint32 state; |
OS_Thread_t *thread; |
|
PRINTF_DEBUG("SemPost(%d,%s) ", OS_CpuIndex(), semaphore->name); |
//PRINTF_DEBUG("SemPost(%d,%s) ", OS_CpuIndex(), semaphore->name); |
assert(semaphore); |
state = OS_CriticalBegin(); |
if(++semaphore->count <= 0) |
1324,6 → 1326,11
OS_InterruptMaskClear(0xffffffff); //Disable interrupts |
HeapArray[0] = OS_HeapCreate("Heap", heapStorage, bytes); |
HeapArray[1] = HeapArray[0]; |
#ifndef WIN32 |
HeapArray[7] = OS_HeapCreate("Alt", (uint8*)RAM_EXTERNAL_BASE + |
RAM_EXTERNAL_SIZE*2, 1024*1024*60); |
OS_HeapAlternate(HeapArray[0], HeapArray[7]); |
#endif |
SemaphoreSleep = OS_SemaphoreCreate("Sleep", 0); |
SemaphoreRelease = OS_SemaphoreCreate("Release", 1); |
SemaphoreLock = OS_SemaphoreCreate("Lock", 1); |
1375,6 → 1382,7
(void)argv; |
|
UartPrintfCritical("Starting RTOS\n"); |
MemoryWrite(IRQ_MASK, 0); |
#ifdef WIN32 |
OS_Init((uint32*)HeapSpace, sizeof(HeapSpace)); //For PC simulation |
#else |
/kernel/rtos.h
92,7 → 92,7
void *memset(void *dst, int c, unsigned long bytes); |
int abs(int n); |
int atoi(const char *s); |
int rand(void); |
unsigned int rand(void); |
void srand(unsigned int seed); |
long strtol(const char *s, char **end, int base); |
char *itoa(int num, char *dst, int base); |
102,12 → 102,13
int sscanf(const char *s, const char *format, ...); |
#endif |
|
#define printf UartPrintf |
#ifndef _LIBC |
#define assert(A) if((A)==0){OS_Assert();UartPrintfCritical("\r\nAssert %s:%d\r\n", __FILE__, __LINE__);} |
#define printf UartPrintf |
//#define printf UartPrintfPoll |
#define scanf UartScanf |
#define NULL (void*)0 |
#else |
#define UartPrintfCritical UartPrintf |
#endif //_LIBC |
|
#ifdef INCLUDE_DUMP |
338,7 → 339,7
float FP_Pow(float x, float y); |
|
/***************** Filesys ******************/ |
#ifdef INCLUDE_FILESYS |
#ifndef EXCLUDE_FILESYS |
#define FILE OS_FILE |
#define fopen OS_fopen |
#define fclose OS_fclose |
359,6 → 360,8
int OS_flength(char *entry); |
|
/***************** Flash ******************/ |
void FlashLock(void); |
void FlashUnlock(void); |
void FlashRead(uint16 *dst, uint32 byteOffset, int bytes); |
void FlashWrite(uint16 *src, uint32 byteOffset, int bytes); |
void FlashErase(uint32 byteOffset); |
/kernel/makefile
58,10 → 58,11
# Use 16 fewer registers (make reg_bank.vhd smaller) |
CFLAGS_FEW_REGS = -ffixed-t0 -ffixed-t1 -ffixed-t2 -ffixed-t3 -ffixed-t4 -ffixed-t5 -ffixed-t6 -ffixed-t7 -ffixed-s0 -ffixed-s1 -ffixed-s2 -ffixed-s3 -ffixed-s4 -ffixed-s5 -ffixed-s6 -ffixed-s7 |
|
CFLAGS = -O2 -Wall -c -s -I$(TOOLS2_DIR) -msoft-float -fno-builtin |
CFLAGS = -O2 -Wall -c -I$(TOOLS2_DIR) -msoft-float -fno-builtin |
CFLAGS += -fno-pic -mips1 -mno-abicalls |
#CFLAGS += $(CFLAGS_SW_MULT) |
#CFLAGS += $(CFLAGS_FEW_REGS) |
#CFLAGS += -Wa,-alhs -g |
|
# Build just the Plasma RTOS for Plasma CPU |
rtos: |
71,8 → 72,9
$(GCC_MIPS) uart.c |
$(GCC_MIPS) rtos_test.c |
$(GCC_MIPS) math.c $(ALIASING) |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map \ |
-s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o |
$(CONVERT_BIN) |
@sort <test.map >test2.map |
@$(DUMP_MIPS) --disassemble test.axf > test.lst |
79,20 → 81,21
|
# Build the Plasma RTOS, Plasma TCP/IP stack, and web server for the Plasma CPU |
# Use the serial port and etermip for TCP/IP packets |
rtos_tcpip: |
rtos_tcpip_uart: |
$(AS_MIPS) -o boot.o $(TOOLS_DIR)boot.asm |
$(GCC_MIPS) rtos.c |
$(GCC_MIPS) libc.c |
$(GCC_MIPS) uart.c |
$(GCC_MIPS) rtos_test.c -DINCLUDE_HTML -DINCLUDE_CONSOLE |
$(GCC_MIPS) uart.c -DUART_PACKETS |
$(GCC_MIPS) rtos_test.c -DINCLUDE_UART_PACKETS |
$(GCC_MIPS) math.c $(ALIASING) |
$(GCC_MIPS) tcpip.c -DINCLUDE_FILESYS |
$(GCC_MIPS) http.c -DINCLUDE_FILESYS -DEXAMPLE_HTML |
$(GCC_MIPS) netutil.c |
$(GCC_MIPS) filesys.c |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o tcpip.o \ |
http.o netutil.o filesys.o |
$(GCC_MIPS) tcpip.c |
$(GCC_MIPS) http.c -DEXAMPLE_HTML |
$(GCC_MIPS) netutil.c -DEXCLUDE_FLASH |
$(GCC_MIPS) filesys.c -DEXCLUDE_FLASH |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map \ |
-s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o \ |
tcpip.o http.o netutil.o filesys.o |
$(CONVERT_BIN) |
@sort <test.map >test2.map |
@$(DUMP_MIPS) --disassemble test.axf > test.lst |
102,18 → 105,19
$(AS_MIPS) -o boot.o $(TOOLS_DIR)boot.asm |
$(GCC_MIPS) rtos.c |
$(GCC_MIPS) libc.c |
$(GCC_MIPS) uart.c -DNO_PACKETS |
$(GCC_MIPS) rtos_test.c -DINCLUDE_ETH -DINCLUDE_CONSOLE |
$(GCC_MIPS) uart.c |
$(GCC_MIPS) rtos_test.c -DINCLUDE_ETH |
$(GCC_MIPS) math.c $(ALIASING) |
$(GCC_MIPS) tcpip.c -DINCLUDE_FILESYS |
$(GCC_MIPS) http.c -DINCLUDE_FILESYS -DEXAMPLE_HTML |
$(GCC_MIPS) netutil.c -DINCLUDE_FLASH -DDLL_SETUP |
$(GCC_MIPS) filesys.c -DINCLUDE_FLASH |
$(GCC_MIPS) tcpip.c |
$(GCC_MIPS) http.c -DEXAMPLE_HTML |
$(GCC_MIPS) netutil.c |
$(GCC_MIPS) filesys.c |
$(GCC_MIPS) ethernet.c |
$(GCC_MIPS) flash.c |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o tcpip.o \ |
http.o netutil.o filesys.o ethernet.o flash.o |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map \ |
-s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o \ |
tcpip.o http.o netutil.o filesys.o ethernet.o flash.o |
$(CONVERT_BIN) |
@sort <test.map >test2.map |
@$(DUMP_MIPS) --disassemble test.axf > test.lst |
123,13 → 127,13
$(AS_MIPS) -o boot.o $(TOOLS_DIR)boot.asm |
$(GCC_MIPS) rtos.c |
$(GCC_MIPS) libc.c |
$(GCC_MIPS) uart.c -DNO_PACKETS |
$(GCC_MIPS) rtos_test.c -DINCLUDE_ETH -DINCLUDE_CONSOLE |
$(GCC_MIPS) uart.c |
$(GCC_MIPS) rtos_test.c -DINCLUDE_ETH |
$(GCC_MIPS) math.c $(ALIASING) |
$(GCC_MIPS) tcpip.c -DINCLUDE_FILESYS |
$(GCC_MIPS) http.c -DINCLUDE_FILESYS |
$(GCC_MIPS) netutil.c -DINCLUDE_FLASH -DDLL_SETUP |
$(GCC_MIPS) filesys.c -DINCLUDE_FLASH |
$(GCC_MIPS) tcpip.c |
$(GCC_MIPS) http.c |
$(GCC_MIPS) netutil.c |
$(GCC_MIPS) filesys.c |
$(GCC_MIPS) ethernet.c |
$(GCC_MIPS) flash.c |
$(GCC_MIPS) -I. $(APP_DIR)html.c -DMainThread=HtmlThread |
137,40 → 141,43
$(GCC_MIPS) -I. $(APP_DIR)tictac.c |
$(GCC_MIPS) -I. $(APP_DIR)tic3d.c |
$(GCC_MIPS) -I. $(APP_DIR)connect4.c |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o tcpip.o \ |
http.o netutil.o filesys.o ethernet.o flash.o \ |
html.o image.o tictac.o tic3d.o connect4.o |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map \ |
-s -N -o test.axf \ |
boot.o rtos.o libc.o uart.o rtos_test.o math.o \ |
tcpip.o http.o netutil.o filesys.o ethernet.o \ |
flash.o html.o image.o tictac.o tic3d.o connect4.o |
$(CONVERT_BIN) |
@sort <test.map >test2.map |
@$(DUMP_MIPS) --disassemble test.axf > test.lst |
|
# Create a separate Dynamically Linked Library executable |
# ftp test.bin to /flash/web/dlltest |
# ftp test.bin to /flash/bin/dlltest |
# telnet to board and execute "dlltest" |
dlltest: |
$(GCC_MIPS) -G0 dlltest.c |
$(LD_MIPS) -Ttext 0x10100000 -s -N -o test.axf dlltest.o |
$(CONVERT_BIN) |
@$(DUMP_MIPS) --disassemble test.axf > test.lst |
$(LD_MIPS) -Ttext 0x10100000 -s -N -o dlltest.axf dlltest.o |
@echo PlasmaSend > ftp.txt |
@echo password >> ftp.txt |
@echo send dlltest.axf >> ftp.txt |
@echo quit >> ftp.txt |
ftp -s:ftp.txt plasma |
|
# Test the RTOS running on a PC |
# Test the RTOS running on a PC (requires Windows) |
testrtos: |
@$(CC_X86) $(CFLAGS_X86) rtos.c |
@$(CC_X86) $(CFLAGS_X86) rtos_ex.c |
@$(CC_X86) $(CFLAGS_X86) libc.c |
@$(CC_X86) $(CFLAGS_X86) uart.c |
@$(CC_X86) $(CFLAGS_X86) rtos_test.c |
@$(CC_X86) $(CFLAGS_X86) math.c $(ALIASING) |
@$(CC_X86) $(LFLAGS_X86) -o testrtos.exe rtos.$(OBJ) rtos_ex.$(OBJ) libc.$(OBJ) uart.$(OBJ) rtos_test.$(OBJ) math.$(OBJ) |
@$(CC_X86) $(LFLAGS_X86) -o testrtos.exe rtos.$(OBJ) rtos_ex.$(OBJ) libc.$(OBJ) rtos_test.$(OBJ) math.$(OBJ) |
$(LINUX_PWD)testrtos.exe |
|
# Test the TCP/IP protocol stack running on a PC (requires Windows) |
testip: |
testip: *.c |
@$(CC_X86) $(CFLAGS_X86) tcpip.c |
@$(CC_X86) $(CFLAGS_X86) http.c /DEXAMPLE_HTML |
@$(CC_X86) $(CFLAGS_X86) netutil.c |
@$(CC_X86) $(CFLAGS_X86) filesys.c |
@$(CC_X86) $(CFLAGS_X86) filesys.c /DEXCLUDE_FLASH |
@$(CC_X86) $(CFLAGS_X86) libc.c /I$(TOOLS_DIR) |
@$(CC_X86) $(CFLAGS_X86) /DSIMULATE_PLASMA $(TOOLS_DIR)etermip.c |
@$(CC_X86) $(CFLAGS_X86) os_stubs.c |
179,6 → 186,14
@echo Try http://plasmb/. Try telnet plasmb. Try ftp plasmb. |
$(LINUX_PWD)testip.exe |
|
install: |
@echo PlasmaSend > ftp.txt |
@echo password >> ftp.txt |
@echo send test.bin >> ftp.txt |
@echo quit >> ftp.txt |
ftp -s:ftp.txt plasma |
@echo Telnet to plasma and run 'reboot test.bin [flash]' |
|
clean: |
-$(RM) *.o *.obj *.axf *.map *.lst *.hex *.txt *.bin *.exe |
|
189,8 → 204,8
disassemble: |
-@$(TOOLS_DIR)mlite.exe test.bin BD > test.txt |
|
# Start the EtermIP terminal program to download the code to the Plasma CPU |
# and permit an Ethernet packets to be transfered. |
# Start the EtermIP terminal program to download the code to the |
# Plasma CPU and permit an Ethernet packets to be transfered. |
download: |
@echo Reset board before downloading code |
$(TOOLS_DIR)etermip.exe |