lunes, 9 de julio de 2012

Servidor WEB desde cero. (II)

Voy a seguir con esta pequeña aventura que he empezado y que por ahora parece que va viento en popa. En la entrada Servidor WEB desde cero. (I), fue donde os puse todos los materiales que había comprado para fabricar mi propio servidor, en esta entrada vamos a empezar crear el firmware que irá dentro del micro con el que vamos a hacer que nuestro servidor funcione. Os dije que quería utilizar un PIC18LF4685, pues ese es el que voy a utilizar y ahora os voy a comentar los cambios que hay que hacer en el firmware.
Como dije en la entrada anterior, vamos a partir del la aplicación Demo App que se instala junto a las Microchip aplication libraries que podéis descargar de aquí. El primer archivo que vamos a modificar para hacerlo funcionar en el PIC18f4685 es el Hardware Profile, que en el proyecto se llama HWP PIC18EX_ENC28.h. 
#ifndef HARDWARE_PROFILE_H
#define HARDWARE_PROFILE_H
 
#include "Compiler.h"
 
// Define a macro describing this hardware set up (used in other files)
#define PIC18_EXPLORER
 
// Set configuration fuses (but only in MainDemo.c where THIS_IS_STACK_APPLICATION is defined)
#if defined(THIS_IS_STACK_APPLICATION)
 
//CONFIGURACIÓN PARA PIC18F4685
        #pragma config OSC = HSPLL, FCMEN = OFF, IESO = OFF, WDT=OFF, LVP=OFF
 
    // Automatically set Extended Instruction Set fuse based on compiler setting
    #if defined(__EXTENDED18__)
        #pragma config XINST=ON
    #else
        #pragma config XINST=OFF
    #endif
#endif
 
 
// Clock frequency values
#define GetSystemClock()    (40000000ul)
 
#define GetInstructionClock()    (GetSystemClock()/4)    // Should be GetSystemClock()/4 for PIC18
#define GetPeripheralClock()    (GetSystemClock()/4)    // Should be GetSystemClock()/4 for PIC18
 
 
// Hardware I/O pin mappings
 
// LEDs
#define LED0_TRIS            (TRISDbits.TRISD0)    // Ref D1
#define LED0_IO                (LATDbits.LATD0)
#define LED1_TRIS            (TRISDbits.TRISD1)    // Ref D2
#define LED1_IO                (LATDbits.LATD1)
#define LED2_TRIS            (TRISDbits.TRISD2)    // Ref D3
#define LED2_IO                (LATDbits.LATD2)
#define LED3_TRIS            (TRISDbits.TRISD3)    // Ref D4
#define LED3_IO                (LATDbits.LATD3)
#define LED4_TRIS            (TRISDbits.TRISD4)    // Ref D5
#define LED4_IO                (LATDbits.LATD4)
#define LED5_TRIS            (TRISDbits.TRISD5)    // Ref D6
#define LED5_IO                (LATDbits.LATD5)
#define LED6_TRIS            (TRISDbits.TRISD6)    // Ref D7
#define LED6_IO                (LATDbits.LATD6)
#define LED7_TRIS            (TRISDbits.TRISD7)    // Ref D8
#define LED7_IO                (LATDbits.LATD7)
#define LED_GET()            (LATD)
#define LED_PUT(a)            (LATD = (a))
 
// Momentary push buttons
#define BUTTON0_TRIS        (TRISAbits.TRISA5)
#define    BUTTON0_IO            (PORTAbits.RA5)
#define BUTTON1_TRIS        (TRISBbits.TRISB0)
#define    BUTTON1_IO            (PORTBbits.RB0)
#define BUTTON2_TRIS        (TRISBbits.TRISB0)    // No Button2 on this board
#define    BUTTON2_IO            (1u)
#define BUTTON3_TRIS        (TRISBbits.TRISB0)    // No Button3 on this board
#define    BUTTON3_IO            (1u)
 
// ENC28J60 I/O pins
#define ENC_RST_TRIS        (TRISBbits.TRISB5)
#define ENC_RST_IO            (LATBbits.LATB5)
#define ENC_CS_TRIS            (TRISBbits.TRISB3)
#define ENC_CS_IO            (LATBbits.LATB3)
#define ENC_SCK_TRIS        (TRISCbits.TRISC3)
#define ENC_SDI_TRIS        (TRISCbits.TRISC4)
#define ENC_SDO_TRIS        (TRISCbits.TRISC5)
#define ENC_SPI_IF            (PIR1bits.SSPIF)
#define ENC_SSPBUF            (SSPBUF)
#define ENC_SPISTAT            (SSPSTAT)
#define ENC_SPISTATbits        (SSPSTATbits)
#define ENC_SPICON1            (SSPCON1)
#define ENC_SPICON1bits        (SSPCON1bits)
#define ENC_SPICON2            (SSPCON2)
 
// LCD I/O pins
// TODO: Need to add support for LCD behind MCP23S17 I/O expander.  This 
// requires code that isn't in the TCP/IP stack, not just a hardware 
// profile change.
 
// UART mapping functions for consistent API names across 8-bit and 16 or 
// 32 bit compilers.  For simplicity, everything will use "UART" instead 
// of USART/EUSART/etc.
#define BusyUART()            BusyUSART()
#define CloseUART()            CloseUSART()
#define ConfigIntUART(a)    ConfigIntUSART(a)
#define DataRdyUART()        DataRdyUSART()
#define OpenUART(a,b,c)        OpenUSART(a,b,c)
#define ReadUART()            ReadUSART()
#define WriteUART(a)        WriteUSART(a)
#define getsUART(a,b,c)        getsUSART(b,a)
#define putsUART(a)            putsUSART(a)
#define getcUART()            ReadUSART()
#define putcUART(a)            WriteUSART(a)
#define putrsUART(a)        putrsUSART((far rom char*)a)
 
#endif // #ifndef HARDWARE_PROFILE_H
Lo principal que hemos modificado en este archivo son las configuraciones del micro, utilizando los pragma configs correspondientes para cada PIC. A partir de como lo hayamos configurado, debemos también cambiar el #define GetSystemClock() por la frecuencia a la que va a funciona nuestro micro, en mi caso, utilizo un cristal de 10Mz, y he configurado el PLL para que multiplique por 4 esta frecuencia por lo que tengo una frecuencia de 40MHz. Otra cosa que debéis modificar según el micro que utilicéis es la posición de los pines de comunicación SPI que son SCK, SDI y SDO. Los pines CS y RST los podéis configurar en el pin que queráis.
El siguiente archivo que vamos a modificar es el MainDemo.c. Este es el programa principal, y básicamente lo que he hecho ha sido eliminar todo lo que no voy a utilizar como memoria, wifi, uart o lcd y me ha quedado así.

#define THIS_IS_STACK_APPLICATION
 
// Include all headers for any enabled TCPIP Stack functions
#include "TCPIP Stack/TCPIP.h"
 
#if defined(STACK_USE_ZEROCONF_LINK_LOCAL)
#include "TCPIP Stack/ZeroconfLinkLocal.h"
#endif
#if defined(STACK_USE_ZEROCONF_MDNS_SD)
#include "TCPIP Stack/ZeroconfMulticastDNS.h"
#endif
 
#include "MainDemo.h"
 
// Declare AppConfig structure and some other supporting stack variables
APP_CONFIG AppConfig;
static unsigned short wOriginalAppConfigChecksum;    // Checksum of the ROM defaults for AppConfig
 
static void InitAppConfig(void);
static void InitializeBoard(void);
static void ProcessIO(void);
 
    #pragma interruptlow LowISR    // Interrupciones de baja prioridad
    void LowISR(void)
    {
        TickUpdate();
    }
    
 
    #pragma interruptlow HighISR // Interrupciones de alta prioridad
    void HighISR(void)
    {
 
    }
 
 
    #pragma code lowVector=0x18
    void LowVector(void){_asm goto LowISR _endasm}
    #pragma code highVector=0x8
    void HighVector(void){_asm goto HighISR _endasm}
    #pragma code // Return to default code section
 
//
// Main application entry point.
//
 
void main(void)
{
    static DWORD t = 0;
    static DWORD dwLastIP = 0;
 
    // Inicializamos la placa
    InitializeBoard();
 
    //Inicializamos la rutina que hace que parpadee el led.
    //Utiliza el TMR1, por lo que este queda inutilizado. (tick.c)
    TickInit();
    
    // Inicializamos los archivos del STACK.
    MPFSInit();
    InitAppConfig();
    StackInit();
 
    
    while(1)
    {
        // Invierte la señal del led cada segundo
        if(TickGet() - t >= TICK_SECOND/2ul)
        {
            t = TickGet();
            LED0_IO ^= 1;
        }
        
        // Tareas delk STACK
        StackTask();
        StackApplications();
        
        PingDemo(); //esta aplicación permite al STACK responder a PINGs
 
        ProcessIO();
 
        // Comprobamos si la dirección IP ha cambiado, si es así mostramos la nueva direccion IP.
        if(dwLastIP != AppConfig.MyIPAddr.Val)
        {
            dwLastIP = AppConfig.MyIPAddr.Val;
            
            DisplayIPValue(AppConfig.MyIPAddr);
 
        }
    }
}
 
// Mostramos la direccion IP en el LCD
void DisplayIPValue(IP_ADDR IPVal)
{
    //#####################################################
    // Lo dejamos en blanco de momento,luego crearemos un #
    //programa que haga que la placa muestre la IP en un  #
    // LCD de 16x2 ########################################
    //#####################################################
}
 
static void ProcessIO(void)
{    
    //#####################################################
    // AQUÍ VA NUESTRO CÓDIGO #############################
    //#####################################################
}
 
/****************************************************************
    Función: InitializeBoard(void)
Esta función se encarga de inicializar la placa se´gun el hardware 
que tengamos conectado, lo utilizaremos tambien más tarde para 
incializar el LCD, o la comunicación UART si la implementamos
*****************************************************************/
static void InitializeBoard(void)
{    
    // LEDs
    LED0_TRIS = 0;
    LED1_TRIS = 0;
    LED2_TRIS = 0;
    LED3_TRIS = 0;
    LED4_TRIS = 0;
    LED5_TRIS = 0;
    LED6_TRIS = 0;
    LED7_TRIS = 0;
    LED_PUT(0x00);
 
    // Enable internal PORTB pull-ups
    INTCON2bits.RBPU = 0;
 
    // Enable Interrupts
    RCONbits.IPEN = 1;        // Enable interrupt priorities
    INTCONbits.GIEH = 1;
    INTCONbits.GIEL = 1;
 
    //INICIALIZACION DEL PIN CHIP SELECT DEL ENC
    ENC_CS_IO = 1;
    ENC_CS_TRIS = 0;
 
    
}
 
/****************************************************************
    Función: InitAppCondig(void)
Esta función inicializa variables del stack, hemos eliminado 
toda la inicialización referente a memorias y WIFI.
*****************************************************************/
 
static ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6};
 
 
static void InitAppConfig(void)
{
    while(1)
    {
        // Start out zeroing all AppConfig bytes to ensure all fields are 
        // deterministic for checksum generation
        memset((void*)&AppConfig, 0x00, sizeof(AppConfig));
        
        AppConfig.Flags.bIsDHCPEnabled = TRUE;
        AppConfig.Flags.bInConfigMode = TRUE;
        memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
//        {
//            _prog_addressT MACAddressAddress;
//            MACAddressAddress.next = 0x157F8;
//            _memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr));
//        }
        AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
        AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
        AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
        AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
        AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
        AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul  | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul  | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
        AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul  | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul  | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;
    
    
        // Load the default NetBIOS Host Name
        memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
        FormatNetBIOSName(AppConfig.NetBIOSName);
    
        // Compute the checksum of the AppConfig defaults as loaded from ROM
        wOriginalAppConfigChecksum = CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig));
 
        break;
    }
}
 
He dejado el archivo main muy reducido de forma que se entienda todo lo que hay en el. Hay funciones que no he implementado todavía como DisplayIp(IPAddres), ya que en un principio dije que no iba a poner LCD pero he estado revisando los pines y quizás tenga suficientes, así que lo dejo preparado por si luego quisiera. La otra función que está vacía es ProcessIO(), ya que en la aplicación que he preparado, no ha hecho falta poner nada aquí, pero si nuestra aplicación debe hacer cosas a parte de su función como servidor, irá aquí.
Por último el archivo que debemos modificar es el TCPIPConfig.h, en este, como ya comenté le decimos al STACK que funciones vamos a utilizar y que funciones no, a parte de la dirección IP por defecto, o el nombre del HOST. Queda así.

#ifndef __TCPIPCONFIG_H
#define __TCPIPCONFIG_H
 
#include "GenericTypeDefs.h"
#include "Compiler.h"
#define GENERATED_BY_TCPIPCONFIG "Version 1.0.4168.28618"
 
// =======================================================================
//   Application Options
// =======================================================================
 
/* Application Level Module Selection
 *   Uncomment or comment the following lines to enable or
 *   disabled the following high-level application modules.
 */
//#define STACK_USE_UART                    // Application demo using UART for IP address display and stack configuration
//#define STACK_USE_UART2TCP_BRIDGE        // UART to TCP Bridge application example
//#define STACK_USE_IP_GLEANING
#define STACK_USE_ICMP_SERVER            // Ping query and response capability
#define STACK_USE_ICMP_CLIENT            // Ping transmission capability
#define STACK_USE_HTTP2_SERVER            // New HTTP server with POST, Cookies, Authentication, etc.
//#define STACK_USE_SSL_SERVER            // SSL server socket support (Requires SW300052)
//#define STACK_USE_SSL_CLIENT            // SSL client socket support (Requires SW300052)
//#define STACK_USE_AUTO_IP               // Dynamic link-layer IP address automatic configuration protocol
//#define STACK_USE_DHCP_CLIENT            // Dynamic Host Configuration Protocol client for obtaining IP address and other parameters
//#define STACK_USE_DHCP_SERVER            // Single host DHCP server
//#define STACK_USE_FTP_SERVER            // File Transfer Protocol (old)
//#define STACK_USE_SMTP_CLIENT            // Simple Mail Transfer Protocol for sending email
//#define STACK_USE_SNMP_SERVER            // Simple Network Management Protocol v2C Community Agent
//#define STACK_USE_SNMPV3_SERVER            // Simple Network Management Protocol v3 Agent
//#define STACK_USE_TFTP_CLIENT            // Trivial File Transfer Protocol client
//#define STACK_USE_GENERIC_TCP_CLIENT_EXAMPLE    // HTTP Client example in GenericTCPClient.c
//#define STACK_USE_GENERIC_TCP_SERVER_EXAMPLE    // ToUpper server example in GenericTCPServer.c
//#define STACK_USE_TELNET_SERVER            // Telnet server
#define STACK_USE_ANNOUNCE                // Microchip Embedded Ethernet Device Discoverer server/client
#define STACK_USE_DNS                    // Domain Name Service Client for resolving hostname strings to IP addresses
//#define STACK_USE_DNS_SERVER            // Domain Name Service Server for redirection to the local device
#define STACK_USE_NBNS                    // NetBIOS Name Service Server for repsonding to NBNS hostname broadcast queries
#define STACK_USE_REBOOT_SERVER            // Module for resetting this PIC remotely.  Primarily useful for a Bootloader.
#define STACK_USE_SNTP_CLIENT            // Simple Network Time Protocol for obtaining current date/time from Internet
//#define STACK_USE_UDP_PERFORMANCE_TEST    // Module for testing UDP TX performance characteristics.  NOTE: Enabling this will cause a huge amount of UDP broadcast packets to flood your network on the discard port.  Use care when enabling this on production networks, especially with VPNs (could tunnel broadcast traffic across a limited bandwidth connection).
//#define STACK_USE_TCP_PERFORMANCE_TEST    // Module for testing TCP TX performance characteristics
//#define STACK_USE_DYNAMICDNS_CLIENT        // Dynamic DNS client updater module
//#define STACK_USE_BERKELEY_API            // Berekely Sockets APIs are available
//#define STACK_USE_ZEROCONF_LINK_LOCAL    // Zeroconf IPv4 Link-Local Addressing
//#define STACK_USE_ZEROCONF_MDNS_SD        // Zeroconf mDNS and mDNS service discovery
 
 
// =======================================================================
//   Data Storage Options
// =======================================================================
 
/* MPFS Configuration
 *   MPFS is automatically included when required for other
 *   applications.  If your custom application requires it
 *   otherwise, uncomment the appropriate selection.
 */
#define STACK_USE_MPFS2
 
/* MPFS Storage Location
 *   If html pages are stored in internal program memory,
 *   comment both MPFS_USE_EEPROM and MPFS_USE_SPI_FLASH, then
 *   include an MPFS image (.c or .s file) in the project.
 *   If html pages are stored in external memory, uncomment the
 *   appropriate definition.
 *
 *   Supported serial flash parts include the SST25VFxxxB series.
 */
//#define MPFS_USE_EEPROM
//#define MPFS_USE_SPI_FLASH
 
/* EEPROM Addressing Selection
 *   If using the 1Mbit EEPROM, uncomment this line
 */
//#define USE_EEPROM_25LC1024
 
/* EEPROM Reserved Area
 *   Number of EEPROM bytes to be reserved before MPFS storage starts.
 *   These bytes host application configurations such as IP Address,
 *   MAC Address, and any other required variables.
 *
 *   For MPFS Classic, this setting must match the Reserved setting
 *     on the Advanced Settings page of the MPFS2 Utility.
 */
#define MPFS_RESERVE_BLOCK                (137ul)
 
/* MPFS File Handles
 *   Maximum number of simultaneously open MPFS2 files.
 *   For MPFS Classic, this has no effect.
 */
#define MAX_MPFS_HANDLES                (7ul)
 
 
// =======================================================================
//   Network Addressing Options
// =======================================================================
 
/* Default Network Configuration
 *   These settings are only used if data is not found in EEPROM.
 *   To clear EEPROM, hold BUTTON0, reset the board, and continue
 *   holding until the LEDs flash.  Release, and reset again.
 */
//#define MY_DEFAULT_HOST_NAME            "MCHPBOARD"
#define MY_DEFAULT_HOST_NAME            "MIPSBOARD"
 
#define MY_DEFAULT_MAC_BYTE1            (0x00)    // Use the default of 00-04-A3-00-00-00
#define MY_DEFAULT_MAC_BYTE2            (0x04)    // if using an ENCX24J600, MRF24WB0M, or
#define MY_DEFAULT_MAC_BYTE3            (0xA3)    // PIC32MX6XX/7XX internal Ethernet 
#define MY_DEFAULT_MAC_BYTE4            (0x00)    // controller and wish to use the 
#define MY_DEFAULT_MAC_BYTE5            (0x00)    // internal factory programmed MAC
#define MY_DEFAULT_MAC_BYTE6            (0x00)    // address instead.
 
#define MY_DEFAULT_IP_ADDR_BYTE1        (169ul)
#define MY_DEFAULT_IP_ADDR_BYTE2        (254ul)
#define MY_DEFAULT_IP_ADDR_BYTE3        (1ul)
#define MY_DEFAULT_IP_ADDR_BYTE4        (1ul)
 
#define MY_DEFAULT_MASK_BYTE1           (255ul)
#define MY_DEFAULT_MASK_BYTE2           (255ul)
#define MY_DEFAULT_MASK_BYTE3           (0ul)
#define MY_DEFAULT_MASK_BYTE4           (0ul)
 
#define MY_DEFAULT_GATE_BYTE1           (169ul)
#define MY_DEFAULT_GATE_BYTE2           (254ul)
#define MY_DEFAULT_GATE_BYTE3           (1ul)
#define MY_DEFAULT_GATE_BYTE4           (1ul)
 
#define MY_DEFAULT_PRIMARY_DNS_BYTE1    (169ul)
#define MY_DEFAULT_PRIMARY_DNS_BYTE2    (254ul)
#define MY_DEFAULT_PRIMARY_DNS_BYTE3    (1ul)
#define MY_DEFAULT_PRIMARY_DNS_BYTE4    (1ul)
 
#define MY_DEFAULT_SECONDARY_DNS_BYTE1    (0ul)
#define MY_DEFAULT_SECONDARY_DNS_BYTE2    (0ul)
#define MY_DEFAULT_SECONDARY_DNS_BYTE3    (0ul)
#define MY_DEFAULT_SECONDARY_DNS_BYTE4    (0ul)
 
// =======================================================================
//   PIC32MX7XX/6XX MAC Layer Options
//   If not using a PIC32MX7XX/6XX device, ignore this section.
// =======================================================================
#define    ETH_CFG_LINK            0        // set to 1 if you need to config the link to specific following parameters
                                        // otherwise the default connection will be attempted
                                        // depending on the selected PHY
    #define    ETH_CFG_AUTO        1        // use auto negotiation
    #define    ETH_CFG_10            1        // use/advertise 10 Mbps capability
    #define    ETH_CFG_100            1        // use/advertise 100 Mbps capability
    #define    ETH_CFG_HDUPLEX        1        // use/advertise half duplex capability
    #define    ETH_CFG_FDUPLEX        1        // use/advertise full duplex capability
    #define    ETH_CFG_AUTO_MDIX    1        // use/advertise auto MDIX capability
    #define    ETH_CFG_SWAP_MDIX    1        // use swapped MDIX. else normal MDIX
 
#define EMAC_TX_DESCRIPTORS        2        // number of the TX descriptors to be created
#define EMAC_RX_DESCRIPTORS        8        // number of the RX descriptors and RX buffers to be created
 
#define    EMAC_RX_BUFF_SIZE        1536    // size of a RX buffer. should be multiple of 16
                                        // this is the size of all receive buffers processed by the ETHC
                                        // The size should be enough to accomodate any network received packet
                                        // If the packets are larger, they will have to take multiple RX buffers
                                        // The current implementation does not handle this situation right now and the packet is discarded.
 
 
// =======================================================================
//   Transport Layer Options
// =======================================================================
 
/* Transport Layer Configuration
 *   The following low level modules are automatically enabled
 *   based on module selections above.  If your custom module
 *   requires them otherwise, enable them here.
 */
//#define STACK_USE_TCP
//#define STACK_USE_UDP
 
/* Client Mode Configuration
 *   Uncomment following line if this stack will be used in CLIENT
 *   mode.  In CLIENT mode, some functions specific to client operation
 *   are enabled.
 */
#define STACK_CLIENT_MODE
 
/* TCP Socket Memory Allocation
 *   TCP needs memory to buffer incoming and outgoing data.  The
 *   amount and medium of storage can be allocated on a per-socket
 *   basis using the example below as a guide.
 */
    // Allocate how much total RAM (in bytes) you want to allocate
    // for use by your TCP TCBs, RX FIFOs, and TX FIFOs.
    #define TCP_ETH_RAM_SIZE                    (1238ul)
    #define TCP_PIC_RAM_SIZE                    (0ul)
    #define TCP_SPI_RAM_SIZE                    (0ul)
    #define TCP_SPI_RAM_BASE_ADDRESS            (0x00)
 
    // Define names of socket types
    #define TCP_SOCKET_TYPES
        #define TCP_PURPOSE_GENERIC_TCP_CLIENT 0
        #define TCP_PURPOSE_GENERIC_TCP_SERVER 1
        #define TCP_PURPOSE_TELNET 2
        #define TCP_PURPOSE_FTP_COMMAND 3
        #define TCP_PURPOSE_FTP_DATA 4
        #define TCP_PURPOSE_TCP_PERFORMANCE_TX 5
        #define TCP_PURPOSE_TCP_PERFORMANCE_RX 6
        #define TCP_PURPOSE_UART_2_TCP_BRIDGE 7
        #define TCP_PURPOSE_HTTP_SERVER 8
        #define TCP_PURPOSE_DEFAULT 9
        #define TCP_PURPOSE_BERKELEY_SERVER 10
        #define TCP_PURPOSE_BERKELEY_CLIENT 11
    #define END_OF_TCP_SOCKET_TYPES
 
    #if defined(__TCP_C)
        // Define what types of sockets are needed, how many of
        // each to include, where their TCB, TX FIFO, and RX FIFO
        // should be stored, and how big the RX and TX FIFOs should
        // be.  Making this initializer bigger or smaller defines
        // how many total TCP sockets are available.
        //
        // Each socket requires up to 56 bytes of PIC RAM and
        // 48+(TX FIFO size)+(RX FIFO size) bytes of TCP_*_RAM each.
        //
        // Note: The RX FIFO must be at least 1 byte in order to
        // receive SYN and FIN messages required by TCP.  The TX
        // FIFO can be zero if desired.
        #define TCP_CONFIGURATION
        ROM struct
        {
            BYTE vSocketPurpose;
            BYTE vMemoryMedium;
            WORD wTXBufferSize;
            WORD wRXBufferSize;
        } TCPSocketInitializer[] = 
        {
            //{TCP_PURPOSE_GENERIC_TCP_CLIENT, TCP_ETH_RAM, 125, 100},
            //{TCP_PURPOSE_GENERIC_TCP_SERVER, TCP_ETH_RAM, 20, 20},
            //{TCP_PURPOSE_TELNET, TCP_ETH_RAM, 200, 150},
            //{TCP_PURPOSE_TELNET, TCP_ETH_RAM, 200, 150},
            //{TCP_PURPOSE_TELNET, TCP_ETH_RAM, 200, 150},
            //{TCP_PURPOSE_FTP_COMMAND, TCP_ETH_RAM, 100, 40},
            //{TCP_PURPOSE_FTP_DATA, TCP_ETH_RAM, 0, 128},
            {TCP_PURPOSE_TCP_PERFORMANCE_TX, TCP_ETH_RAM, 200, 1},
            //{TCP_PURPOSE_TCP_PERFORMANCE_RX, TCP_ETH_RAM, 40, 1500},
            //{TCP_PURPOSE_UART_2_TCP_BRIDGE, TCP_ETH_RAM, 256, 256},
            {TCP_PURPOSE_HTTP_SERVER, TCP_ETH_RAM, 200, 200},
            {TCP_PURPOSE_HTTP_SERVER, TCP_ETH_RAM, 200, 200},
            //{TCP_PURPOSE_DEFAULT, TCP_ETH_RAM, 200, 200},
            {TCP_PURPOSE_BERKELEY_SERVER, TCP_ETH_RAM, 25, 20},
            //{TCP_PURPOSE_BERKELEY_SERVER, TCP_ETH_RAM, 25, 20},
            //{TCP_PURPOSE_BERKELEY_SERVER, TCP_ETH_RAM, 25, 20},
            //{TCP_PURPOSE_BERKELEY_CLIENT, TCP_ETH_RAM, 125, 100},
        };
        #define END_OF_TCP_CONFIGURATION
    #endif
 
/* UDP Socket Configuration
 *   Define the maximum number of available UDP Sockets, and whether
 *   or not to include a checksum on packets being transmitted.
 */
#define MAX_UDP_SOCKETS     (8u)
#define UDP_USE_TX_CHECKSUM        // This slows UDP TX performance by nearly 50%, except when using the ENCX24J600 or PIC32MX6XX/7XX, which have a super fast DMA and incurs virtually no speed pentalty.
 
 
/* Berkeley API Sockets Configuration
 *   Note that each Berkeley socket internally uses one TCP or UDP socket
 *   defined by MAX_UDP_SOCKETS and the TCPSocketInitializer[] array.
 *   Therefore, this number MUST be less than or equal to MAX_UDP_SOCKETS + the
 *   number of TCP sockets defined by the TCPSocketInitializer[] array
 *   (i.e. sizeof(TCPSocketInitializer)/sizeof(TCPSocketInitializer[0])).
 *   This define has no effect if STACK_USE_BERKELEY_API is not defined and
 *   Berkeley Sockets are disabled.  Set this value as low as your application
 *   requires to avoid waisting RAM.
 */
#define BSD_SOCKET_COUNT (5u)
 
 
// =======================================================================
//   Application-Specific Options
// =======================================================================
 
// -- HTTP2 Server options -----------------------------------------------
 
    // Maximum numbers of simultaneous HTTP connections allowed.
    // Each connection consumes 2 bytes of RAM and a TCP socket
    #define MAX_HTTP_CONNECTIONS    (2u)
 
    // Optional setting to use PIC RAM instead of Ethernet/Wi-Fi RAM for
    // storing HTTP Connection Context variables (HTTP_CONN structure for each 
    // HTTP connection).  Undefining this macro results in the Ethernet/Wi-Fi 
    // RAM being used (minimum PIC RAM usage, lower performance).  Defining 
    // this macro results in PIC RAM getting used (higher performance, but uses 
    // PIC RAM).  This option should not be enabled on PIC18 devices.  The 
    // performance increase of having this option defined is only apparent when 
    // the HTTP server is servicing multiple connections simultaneously.
    //#define HTTP_SAVE_CONTEXT_IN_PIC_RAM
 
    // Indicate what file to serve when no specific one is requested
    #define HTTP_DEFAULT_FILE        "index.htm"
    #define HTTPS_DEFAULT_FILE        "index.htm"
    #define HTTP_DEFAULT_LEN        (10u)        // For buffer overrun protection.
                                                // Set to longest length of above two strings.
 
    // Configure MPFS over HTTP updating
    // Comment this line to disable updating via HTTP
    #define HTTP_MPFS_UPLOAD        "mpfsupload"
    //#define HTTP_MPFS_UPLOAD_REQUIRES_AUTH    // Require password for MPFS uploads
        // Certain firewall and router combinations cause the MPFS2 Utility to fail
        // when uploading.  If this happens, comment out this definition.
 
    // Define which HTTP modules to use
    // If not using a specific module, comment it to save resources
    #define HTTP_USE_POST                    // Enable POST support
    #define HTTP_USE_COOKIES                // Enable cookie support
//    #define HTTP_USE_AUTHENTICATION            // Enable basic authentication support
 
    //#define HTTP_NO_AUTH_WITHOUT_SSL        // Uncomment to require SSL before requesting a password
 
    // Define the listening port for the HTTP server
      #define HTTP_PORT               (80u)
    
    // Define the listening port for the HTTPS server (if STACK_USE_SSL_SERVER is enabled)
    #define HTTPS_PORT                (443u)
    
    // Define the maximum data length for reading cookie and GET/POST arguments (bytes)
    #define HTTP_MAX_DATA_LEN        (100u)
    
    // Define the minimum number of bytes free in the TX FIFO before executing callbacks
    #define HTTP_MIN_CALLBACK_FREE    (16u)
 
    #define STACK_USE_HTTP_APP_RECONFIG        // Use the AppConfig web page in the Demo App (~2.5kb ROM, ~0b RAM)
    //#define STACK_USE_HTTP_MD5_DEMO            // Use the MD5 Demo web page (~5kb ROM, ~160b RAM)
    //#define STACK_USE_HTTP_EMAIL_DEMO        // Use the e-mail demo web page
 
// -- SSL Options --------------------------------------------------------
 
    #define MAX_SSL_CONNECTIONS        (2ul)    // Maximum connections via SSL
    #define MAX_SSL_SESSIONS        (2ul)    // Max # of cached SSL sessions
    #define MAX_SSL_BUFFERS            (4ul)    // Max # of SSL buffers (2 per socket)
    #define MAX_SSL_HASHES            (5ul)    // Max # of SSL hashes  (2 per, plus 1 to avoid deadlock)
 
    // Bits in SSL RSA key.  This parameter is used for SSL sever
    // connections only.  The only valid value is 512 bits (768 and 1024
    // bits do not work at this time).  Note, however, that SSL client
    // operations do currently work up to 1024 bit RSA key length.
    #define SSL_RSA_KEY_SIZE        (512ul)
 
 
// -- Telnet Options -----------------------------------------------------
 
    // Number of simultaneously allowed Telnet sessions.  Note that you
    // must have an equal number of TCP_PURPOSE_TELNET type TCP sockets
    // declared in the TCPSocketInitializer[] array above for multiple
    // connections to work.  If fewer sockets are available than this
    // definition, then the the lesser of the two quantities will be the
    // actual limit.
    #define MAX_TELNET_CONNECTIONS    (1u)
 
    // Default local listening port for the Telnet server.  Port 23 is the
    // protocol default.
    #define TELNET_PORT                (23u)
 
    // Default local listening port for the Telnet server when SSL secured.
    // Port 992 is the telnets protocol default.
    #define TELNETS_PORT            (992u)
 
    // Force all connecting clients to be SSL secured and connected via
    // TELNETS_PORT.  Connections on port TELNET_PORT will be ignored.  If
    // STACK_USE_SSL_SERVER is undefined, this entire setting is ignored
    // (server will accept unsecured connections on TELNET_PORT and won't even
    // listen on TELNETS_PORT).
    //#define TELNET_REJECT_UNSECURED
 
    // Default username and password required to login to the Telnet server.
    #define TELNET_USERNAME            "admin"
    #define TELNET_PASSWORD            "microchip"
 
 
// -- SNMP Options -------------------------------------------------------
 
    // Comment following line if SNMP TRAP support is needed
    //#define SNMP_TRAP_DISABLED
 
    //#define SNMP_STACK_USE_V2_TRAP
    #if defined(STACK_USE_SNMPV3_SERVER)
        #define SNMP_V1_V2_TRAP_WITH_SNMPV3
    #endif
 
    // This is the maximum length for community string.
    // Application must ensure that this length is observed.
    // SNMP module adds one byte extra after SNMP_COMMUNITY_MAX_LEN
    // for adding '\0' NULL character.
    #define SNMP_COMMUNITY_MAX_LEN      (8u)
    #define SNMP_MAX_COMMUNITY_SUPPORT    (3u)
    #define NOTIFY_COMMUNITY_LEN        (SNMP_COMMUNITY_MAX_LEN)
 
    // Default SNMPv2C community names.  These can be overridden at run time if
    // alternate strings are present in external EEPROM or Flash (actual
    // strings are stored in AppConfig.readCommunity[] and
    // AppConfig.writeCommunity[] arrays).  These strings are case sensitive.
    // An empty string means disabled (not matchable).
    // For application security, these default community names should not be
    // used, but should all be disabled to force the end user to select unique
    // community names.  These defaults are provided only to make it easier to
    // start development.  Specifying more strings than
    // SNMP_MAX_COMMUNITY_SUPPORT will result in the later strings being
    // ignored (but still wasting program memory).  Specifying fewer strings is
    // legal, as long as at least one is present.  A string larger than
    // SNMP_COMMUNITY_MAX_LEN bytes will be ignored.
    #define SNMP_READ_COMMUNITIES        {"public", "read", ""}
    #define END_OF_SNMP_READ_COMMUNITIES
    #define SNMP_WRITE_COMMUNITIES        {"private", "write", "public"}
    #define END_OF_SNMP_WRITE_COMMUNITIES
#endif
 
 
//#define MPFS_USE_FAT        
 
#define MDD_ROOT_DIR_PATH        "\\"
De este archivo no he eliminado nada ya que luego puede que me sea útil, además que la mayoría de las modificaciones no las realizo yo, sino la aplicación que os mostré en la entrada anterior. He cambiado el nombre de la placa a MIPSBOARD/ de forma que poniendo esto en el navegador, no es necesario saber la dirección IP que se le ha asignado.
Una vez tenemos configurado todo el firmware del micro, debemos crear una página web, para ello debemos crear un directorio en el que pongamos todos los archivos de la página web, y llamar al archivo principal index.htm, o si no queremos llamarlo así debemos cambiarlo en el TCPIPConfig.h. Podemos crear una página web sencilla para probar. Una vez creada la página y todos los archivos que la componen vamos a utilizar otra de las aplicaciones que se instalan junto con las Microchip Aplication Libraries, que es la aplicación MPFS2.

image
Microchip utiliza un formato especial para introducir las páginas web en el microcontrolador, ese formato es el MPFS. Esta aplicación convierte una página web completa, imágenes, textos, enlaces… a un archivo cuyo formato dependerá de lo que nosotros queramos. En la parte superior de la ventana debemos seleccionar la carpeta donde se encuentra la página web, y es en el punto 2 donde le decimos que formato queremos. Como no utilizamos memoria exterior, debemos crear un archivo .c y agregarlo al proyecto, por lo que escogeremos la opción C18/C32 Image. Una vez hecho esto, seleccionamos un nombre para la imagen y le damos a Generate. La imagen se crea en el directorio del proyecto que le hemos dicho en el espacio Project Directory. Luego solo queda agregar el archivo de imagen al proyecto y volver a compilarlo y ya estamos listos para arrancar nuestro servidor web.
Como esta entrada ha quedado bastante larga, dejo para la próxima todo lo referente a monitorización y control de la página. En las próximas entradas también os podré todos los archivos para que los veáis y un vídeo demostrativo.

63 comentarios:

  1. Gracias amigo ahora si tengo la punta de la madeja para comenzar con mis estudios. Con cuál programa se hace la pagina web? puedes mostrar en otra entrada cómo la haces?.
    Saludos.

    ResponderEliminar
  2. pues realmente puedes hacerla en el bloc de notas, pero yo por ejemplo he utilizado Kompozer que es gratuito. También existen editores html online, por ejemplo http://ckeditor.com/demo/ , que te genera ella misma el código html y tu solo vas haciendo la página web conforme quieres que se vea. Respecto a lo que me comentaste de GSM, por supuesto que me interesaría, puedes mandármelo si quieres a palo_tru@ono.com. Gracias!

    ResponderEliminar
  3. Hola estoy intentando mandarle por mail la información pero me devuelven los mail por error de dirección de mail.

    ResponderEliminar
  4. ai perdon, pablo_tru@ono.com, es esta ;)

    ResponderEliminar
  5. hola excelente tu trabajo en especial adaptando el hardware profile a unn pic mas cerca de lo que lamayoria puede manipular.
    estube tratando compilar con las instrucciones que dejas aca en tu blog pero me da el siguiente error
    MPLINK 4.42, Linker
    Device Database Version 1.7
    Copyright (c) 1998-2011 Microchip Technology Inc.
    Error - section '.code_ENC28J60.o' can not fit the section. Section '.code_ENC28J60.o' length=0x000011d8
    Errors : 1

    Link step failed.

    hay que tener alguna consideracion con el linker o es algun error mio
    desde ya muuchas gracias.

    ResponderEliminar
  6. Lo que te está diciendo es que el código no cabe en el micro que has elegido. Que micro utilizas? el stack entero no cabe en el PIC18F4685, de hecho si te fijas en el TCPIPConfig la mayoría de los servicios están deshabilitados dejando un servidor web pelao y mondao. Además la página web que introduzcas también tiene que ser de tamaño reducido, aunque te cabe una web completa sin problemas. Intenta reducir el numero de servicios, y si has intentado compilar mi código, quizás el problema esté en la página web que estas intentando cargar. En la próxima entrada que hable del servidor web intentaré poner el proyecto que yo he creado donde estarán todos los códigos que utilizo para el 18F4685.
    Un saludo

    ResponderEliminar
  7. Muchas gracias por tu respuesta PTrujillo voy a seguir mirando los pasos y las caracteristicas del proyecto y te cuento cuando lo logre compilar

    por ahora estoy "entretenido" con trabajo del puro y duro (el que me da de commer jajja).
    tambien te pasare para compartir en el blog loq ue he logrado hasta ahora con el stack 3.75.6(el modificado por Jorge Amodio).
    Saludos desde Argentina.

    ResponderEliminar
  8. Hola,
    para el pic 18F4550 con un crystal de 20MHz, la frecuencia de reloj cuanto hay que poner? Donde se modifica el PLL?
    Muchas gracias

    ResponderEliminar
    Respuestas
    1. hola amigo
      de casualidad
      tienes configurado el hardware profile del pic 18f4550 que me ayudes,...
      te lo agradezco

      Eliminar
  9. Hola Roberto! pues a ver, en principio yo creo que podrias hacer funcionar tu proyecto sin necesidad de aumentar la frecuencia, es decir, con el cristal de 20 MHz debería funcionar perfectamente, lo unico que deberias cambiar seria el tipo de oscilador que sería HS y cambiar el #define getsystemclock por tu frecuencia. En el caso de que quieras hacerlo a 40MHz te voy a explicar porqué no es posible, ya que el PLL del 4550 es diferente del 4685. Para que el PLL funcione no has de tener a la entrada de esta más de 4MHz, por lo que deberias dividir la frecuencia de entrada entre 5 añadiendo a los pragma esto : PLLDIV = 5. Una vez tienes 4 MHz a la entrada del PLL, este saca 96MHz siempre, no es configurable, y luego estos 96 los puedes dividir entre 2, 3, 4, 6 mediante el pragma CPUDIV = n, y obtendrías varias frecuencias. En el caso de que quieras 48, lo divides entre dos y luego cambias la frecuencia en el #define. El 4685 el PLL multiplica x4 cualquier frecuencia de entrada que le metas, sabiendo que no puedes superar 40MHz a la salida, por eso yo utilizo un cristal de 10 MHz. Espero haber solucionado tu duda.
    Un saludo.

    ResponderEliminar
  10. hola
    AMIGO QUIEN ME PUEDE AYUDAR PARA LA CONFIGURACION DEL TCPIPCONFIG.H PARA EL PIC 18F4550


    AGRADEZCO TODOS SUS BUENOS GESTOS

    ResponderEliminar
    Respuestas
    1. Hola!, la configuración del TCPIPConfig.h es la misma para cualquier pic, en lo unico que influye el micro utilizado es en la cantidad de servicios que puedes habilitar. En el ejemplo que yo pongo, está habilitado el número minimo de servicios para realizar un servidor web así que utilizando ese mismo debería valer.
      UN saludo

      Eliminar
    2. GRACIAS AMIGO...
      PERO OTRA INQUIETUD

      NECESITO HACER PING CON EL 18F4550.. PERO NO SE AL MODIFICAR EL MAIN
      ME SALE ERRO Y NO SE POR QUE

      AYUDAME

      Eliminar
    3. pero que has modificado? que error te sale? quizas hayas coemntado alguna linea en el hardware_profile que no debias... si no me das mas datos no te puedo ayudar...

      Eliminar
  11. BUENAS TARDES
    SOY NUEVO EN ESTE TEMA....TENGO LAS BASES PARA PROGRAMAR PIC ..PERO
    HE TRATADO DE LEER ESTE PROYCTO Y ALGO ENTIENDO.. PERO EL PIC QUE SOLO TENGO DISPONIBLE ES EL PIC18F4550...QUIEN ME PUEDE GUIAR DE COMO EMPEZAR PARA HACER LA COMUNICACION DEL ENC28J60 CON EL PIC 18F4550...YO TENGO EL MODULO DE ARDUINO DEL ENEC28J60


    AGRADEZCO SU VALIOSA COLABORACION

    ResponderEliminar
  12. hola!, el codigo para el 4550 es muy parecido al que yo pongo, las diferencias vendrán a la hora de configurar el pll y el oscilador. También tienes que tener en cuenta que el espacio en memoria que tiene el 4550 es menor al 4685, por lo que deberás casi deshabilitar la mayoria de los módulos, dejando unicamente el servidor web. En una de las ultimas entradas colgué el codigo completo para que lo podais descargas.
    Un saludo.

    ResponderEliminar
    Respuestas
    1. ah ok..pero amigo..
      el pll de 4550 como tiene que quedar pues tngo un cristal de 20HMhz.
      y LO MAS IMPORTANTE... como dejo el servidor de pic par la cuenstion de poca memorria, en que archivo es... y necesito hacer ping desde DOS

      ya descarge el codigo..lo mirare

      te agradezco tu colaborcion

      Eliminar
    2. te copio lo que le dije a otro lector que utiliza el mismo micro que tu con la misma frecuencia:
      pues a ver, en principio yo creo que podrias hacer funcionar tu proyecto sin necesidad de aumentar la frecuencia, es decir, con el cristal de 20 MHz debería funcionar perfectamente, lo unico que deberias cambiar seria el tipo de oscilador que sería HS y cambiar el #define getsystemclock por tu frecuencia. En el caso de que quieras hacerlo a 40MHz te voy a explicar porqué no es posible, ya que el PLL del 4550 es diferente del 4685. Para que el PLL funcione no has de tener a la entrada de esta más de 4MHz, por lo que deberias dividir la frecuencia de entrada entre 5 añadiendo a los pragma esto : PLLDIV = 5. Una vez tienes 4 MHz a la entrada del PLL, este saca 96MHz siempre, no es configurable, y luego estos 96 los puedes dividir entre 2, 3, 4, 6 mediante el pragma CPUDIV = n, y obtendrías varias frecuencias. En el caso de que quieras 48, lo divides entre dos y luego cambias la frecuencia en el #define. El 4685 el PLL multiplica x4 cualquier frecuencia de entrada que le metas, sabiendo que no puedes superar 40MHz a la salida, por eso yo utilizo un cristal de 10 MHz. Espero haber solucionado tu duda.

      Un saludo.

      Eliminar
    3. OK ENTIENDO..PERO COMO HAGO CON EL ACASO DE LA POCA MEMORIA

      EN QUE ARCHIVO DESABILITO LA MAYOIA DE LOS MODULO..YOSOLO QUIERO HACER ALGO COMO EL TUYO Y ADEMAS DE PODER HACER PING

      TE AGRADEZCO TU AYUDA

      Eliminar
    4. en el codigo que yo he compartido está activado lo minimo, que es el servidor web, y la posibilidad de hacer ping. ESto lo modificas en el archivo TCPIPConfig.h, donde al principio comentas los servicios que no quieres utilizar, tal y como se ve en esta misma entrada, donde en el codigo que aparece hay un puñado de lineas comentadas que contienen #defines.
      Un saludo.

      Eliminar
    5. amigo yo estoy modificando el archivo tcp ip config con el programa de configuraion wizard q u hay me dice los servicios que voy a utilizar... estoy en lo correcto??

      per o almimento de utilizar MPSF me sale error y no se por que
      ayudame porfavor

      Eliminar
    6. pero que error te sale¿? te refieres al programa que te genera el codigo c de tu página web?

      Eliminar
    7. si ese mismo me sle un error....

      pero sabes... por curiosidad coji el proyecto que subiste y pues lo estaba analizando y no modifique nada y por curiosidad compile y me sale 3 errores.. que sera

      Eliminar
    8. te sigo diciendo lo mismo de antes, si no me dices los errores que te está dando no puedo ayudarte. Puede ser que no quepa en el pic que estás utilizando, si lo estas intentando compilar para un 18f4550 no va a compilar ya que las configuraciones son diferentes. Esta noche cuando llegue a casa lo compilo. También puede ser un problema de librerías, que haya algunas que no las encuentre...
      Un saludo.

      Eliminar
    9. HOLA , ANTE TODO TE AGRADEZCO LA PACIENCIA NO SOY BUENO EN EL TEMA DE ENC28J60 SE ME HA HECHO MUY DIFIL PODER HACER EL SERVIDOR WEB Y EL PING CON EL PIC 18F4550 YA QUE CON ESTE ES EL UNICO QUE TENGO POR AHORA.... YO ABRRI TU PROYECTO, LO COMPLIE SIN MODIFICAR NADA PARA VER COMO SALIA EL TUYO... NO MIDFIQUE NADA Y ME SALEN 3 ERRORES
      C:\Users\BJ\Desktop\tcp\ejemplo de la pagina\Microchip Solutions v2012-04-03\TCPIP\Demo App\CustomHTTPApp.c:131:Warning [2066] type qualifier mismatch in assignment
      C:\Users\BJ\Desktop\tcp\ejemplo de la pagina\Microchip Solutions v2012-04-03\TCPIP\Demo App\CustomHTTPApp.c:136:Warning [2066] type qualifier mismatch in assignment
      C:\Users\BJ\Desktop\tcp\ejemplo de la pagina\Microchip Solutions v2012-04-03\TCPIP\Demo App\CustomHTTPApp.c:141:Warning [2066] type qualifier mismatch in assignment

      Y PUES ME INTERSA HACER ESTE PROYECTO

      AGRADEZCO TU PACIENCIA Y LA AYUDA QUE ME HAS DADO

      Eliminar
    10. Eso no son errores, son warnings. Esos warnings son debidos a que en ese archivo (CustomHTTPApp.c), se realiza una conversión de datos, en esta linea
      TCPPutROMString(sktHTTP, (LED2_IO?"ON":"OFF"));
      ya que por ethernet solo se pueden mandar strings. Verás que al final de esas lineas, te pone BUILD SUCCEDED, y te genera el archivo .hex del pic y todo. Un placer poder ayudarte, y si entre los dos podemos hacerlo funcionar será genial.

      Un saludo.

      Eliminar
    11. Error: File "C:\Users\Pablo\Desktop\TCPIP 4685 FUNCIONANDO\Microchip Solutions v2012-04-03\Microchip\TCPIP Stack\DNS.c" not found.
      Executing: "C:\Program Files (x86)\Microchip\mplabc18\v3.40\bin\mcc18.exe" -p=18F4685 /i"." -I"..\Microchip\Include" -I"..\..\Microchip\Include" "PingDemo.c" -fo="Obj-C18-PIC18EX_ENC28\PingDemo.o" -D__DEBUG -k -sco -DCFG_INCLUDE_PIC18EX_ENC28 -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
      Error: File "C:\Users\Pablo\Desktop\TCPIP 4685 FUNCIONANDO\Microchip Solutions v2012-04-03\Microchip\TCPIP Stack\UDP.c" not found.
      Error: File "C:\Users\Pablo\Desktop\TCPIP 4685 FUNCIONANDO\Microchip Solutions v2012-04-03\Microchip\TCPIP Stack\SPIEEPROM.c" not found.
      Executing: "C:\Program Files (x86)\Microchip\mplabc18\v3.40\bin\mcc18.exe" -p=18F4685 /i"." -I"..\Microchip\Include" -I"..\..\Microchip\Include" "MPFSImg2.c" -fo="Obj-C18-PIC18EX_ENC28\MPFSImg2.o" -D__DEBUG -k -sco -DCFG_INCLUDE_PIC18EX_ENC28 -mL -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
      Skipping link step. Not all sources built successfully.


      eso son los errores
      pero....
      tu colocaste en el programa alguna ruta fija??
      o tu proycto hay que colocarlos en una carpeta especifica por que mira que al compliar , me sale una ruta que no es mia

      Eliminar
    12. a ver, las rutas que te están saliendo son las mias. Lo que pasa es que no te encuentra los códigos que le hacen falta. Todos los codigos están en el archivo que yo puse para descargar, pero tienes que decirle a tu MPLAB donde están en tu ordenador. Eso lo haces desde Project > Build Options > project. Ahí tienes que decirle seleccionas Includes en el desplpegable, y le dices donde están los codigos en tu PC.

      Eliminar
    13. hize como explicas, me fui a projetc, build option, project y en el inckude agrage la ruta donde estan mis archivos en ese caso la tengo en el escritorio
      pero me sale al compliar
      C:\Users\BJ\Desktop\tcp\ejemplo de la pagina\Microchip Solutions v2012-04-03\TCPIP\Demo App\Configs\TCPIP ENC28.h:53:Error [1027] unable to locate 'Compiler.h'
      C:\Users\BJ\Desktop\tcp\ejemplo de la pagina\Microchip Solutions v2012-04-03\Microchip\TCPIP Stack\Announce.c:65:Error [1027] unable to locate 'TCPIP Stack/TCPIP.h'



      Eliminar
    14. esos archivos están en el .rar que has descargado. Puedes localizarlos manualmente de la siguiente manera. LO primero es ver los directorios de tu proyecto, para ello le das a view -> project, (lo normal es que ya tengas sacada la ventana), y ahi buscas los archivos, si son .h estarán en la carpeta includes, y los que no encuentre, te pondrá (missing file). Pulsando boton derecho sobre estos te da la opción de buscarlos manualmente. El compiler.h está en Microchip Solutions.../Microchip/Include, y el TCPIP.h está en Microchip Solutions.../Microchip/Include/TCPIP. Puede ser que esas carpetas no las hayas añadido a tu proyecto... Un saludo.

      Eliminar
    15. bueno .me puse a verificar y estos dos archivos Compiler.h y TCPIP.h ya estaban incluido en el proyecto y trate de incluirlo nuevamente por si las dudas estaba equivocado yo, pero no me deja por que ya esos archivos estan incluidos. volvi a compliar y me salen los mismo errores...
      no tengo maneras de enviarte una imagen para que verificaras o comprobaras lo que digo

      SALUDOS

      Eliminar
    16. Sera que me estara faltadando alguna configuracion en mplab????
      por mas que le doy no encuentro el error

      Eliminar
    17. configure nuevamente la parte de configure search path,library search path,liker script search pat

      pero sige saliendo los mismos dos errorres al momento de compliar

      Eliminar
    18. has puesto los directorios también en el include search path?

      Eliminar
    19. pues te comento que nada, ya puse todos los dicrectorios como son hasta me guie de un tutorial pero nada... pensaba que es algun error al instalar mplab c18 pero abri el el mismo proyecto del stack que baje de internet y este si me compila. Por mas que le intento no encuentro el error... revisare nuevamente

      Eliminar
  13. BUENAS...AMIGO ESTOY EN LA COMPRA DE UN PIC 16F8645....EL PROYECTO QUE PUBLICASTE .. ESTA COMPLETO PARA VE SI LO PUEDO UTILIZAR... ADEMAS TENGO UN PLACA DE ENC28J60 D SURE ELECTRONIC COMPATIBLE CON ARDUINO... ESA ME SIRVE???

    AGRADEZCO SU COMENTARIO


    ResponderEliminar
  14. Hola!, bueno pues por parte de la placa con el enc28j60 no tendrás ningun problema, ya que lo unico que necesitas es que tenga accesibles los puertos del enc, y si es una placa para arduino seguro que los tiene. En cuantoa utilizar un PIC16, tienes que tener en cuenta que mi codigo está hecho para el compilador C18, por lo que no es compatible con el micro que quieres utilizar tu... si te haces con un PIC18, no tendrás problemas en hacerlo funcionar.

    Un saludo.

    ResponderEliminar
  15. Hola mi querido amigo. Sos un tenaz al poner este tema y sacarlo adelante.
    Te cuento que cuando build all me sale {C:\Microchip Solutions v2012-04-03\TCPIP\Demo App\HardwareProfile.h:190:Error [1099] "No extended HWP .h included. Add the appropriate compiler macro to the MPLAB project."}
    Sabes que debo configurar alli.



    Gracias de antemano

    ResponderEliminar
    Respuestas
    1. Hola! estas utilizando el proyecto mio? lo que creo que te está diciendo es que no encuentra el archivo al que hace referencia HWP.h. No controlo muy bien este tema, pero te explico. Con el MPLAB, tu puedes crearte llamar a archivos "genericos", que luego serán diferentes, por ejemplo, imagina que tienes proyecto que debe funcionar en diferentes microcontroladores, por tanto tendras aisgnaciones diferentes paracada pic. Cada vez que quisieras cambiar de microcontrolador, deberias buscar en cada archivo (.c y .h) que llamara a tu configuración hardware y cambiarlo. Con las macros lo que haces es, en el codigo llamar siempre al archivo HardwareProfile.h, y en realidad tienes los archivos HWP_4550.h, HWP_4685.h. Entonces si quieres cambiar de micro, te vas a la configuración de las macros y escoges a que archivo hace referencia HardwareProfile.h, de forma que no tocas nada en el codigo. Puede que tu error venga por ahi, bien que no encuentra el archivo al que se hace referencia, o bien que no existe esa referencia. Siento no poder dejartelo más claro, pero como he dicho, no he trabajado nunca con macros.
      Un saludo.

      Eliminar
  16. Hola. Gracias x tu respuesta. Estoy utilizando tu proyecto. Para eso abri el workspace que ya venia configurado alli. Estoy haciendo las cosas muy normales, nada cosas nuevas pues tambien estoy aprendiendo. Aun no encuentro la solucion, podrias decirme q version de MPLAB utilizaste.


    Cordialmente

    ResponderEliminar
    Respuestas
    1. pues el proyecto esta hecho en la 8.7, pero deberia funcionar en principio con cualquier versión del MPLAB 8. La verdad es que no se a que se debe el error que tienes...

      Eliminar
  17. Amigo gracias por tus respuestas. Seria mucho pedirte el codigo fuente que compila correctamente con la ultima version del MPLAB. Y asi descartar cualquier otro problema en el camino.


    Muchas gracias de antemano.

    xgp.latino@gmail.com

    ResponderEliminar
  18. la ultima versión de mplab te refieres a la 8.8 o a la X?, en la 8.8 funciona perfectamente, y en la X, una vez exportes el proyecto, si no hay problemas con los directorios de las librerías, debería funcionar correctamente.
    Un saludo.

    ResponderEliminar
  19. hola !!
    si funciona !!!
    pero ahora quiero por ejemplo utilizar al funcion reboot();
    ya la puse en httprint
    tambien esta declara en custom

    pero al momento de correrla me dice que no la encuentra en 18CPIC....HTTP2.o??

    ResponderEliminar
    Respuestas
    1. Hola!, me alegro de que te funcione! no conozco esa función... has comprobado que existe en el archivo HTTP2.h?
      Un saludo!!

      Eliminar
  20. Hola Pablo, solo aquí leyendo el post, ya que estoy realizando un trabajo de escuela y ya he checado tu programa pero al momento de querer editarlo como proyecto de MPLAB no lo encuentro como tal, no se si podrías ayudarme con esto, de antemano gracias, un saludo!!

    ResponderEliminar
    Respuestas
    1. Hola, mi proyecto completo lo puedes encontrar en esta entrada http://www.mipsandchips.com.es/search/label/Servidor%20WEB. lo que si que deberás cambiar serán las carpetas de los include, ya que en ese proyecto están puestas las mías. De todas formas, si te descargas las Microchip Application Libraries de la página de Microchip tienes el proyecto actualizado para cualquier microcontrolador de esa marca.
      Un saludo.

      Eliminar
  21. hola que tal espero que no te moleste ni robe mucho de tu tiempo, ya descargue tu proyecto y lo cheque, gracias, y ya descargue el que me sugeriste, pero trabaja con un 18F8722 y una memoria externa y aunque intento quitarla del main principal la utiliza en varios lados, quiero cambiarlo a otro micro para no tener la necesidad de utilizarla, podrías darme un tip para cambiarlo????
    Bueno muchas gracias por tu tiempo, Saludos.

    ResponderEliminar
    Respuestas
    1. Hola! con que PIC vas a trabajar?, para hacer funcionar el STACK necesitas bastante memoria.
      Un saludo.

      Eliminar
  22. Según yo el stack puede funcionar con micro con memoria de 32k siempre y cuando reduzcas la pagina que quieras guardar, en mi caso quiero utilizar un pic18f45j50 que cuneta con spi i2c y serial , y los suficientes pines para trabajar, yo supongo que este puede servir muy bien para ciertos fines que deseo tener a largo plazo, ahora estoy trabajando en tu ejemplo con el pic18f4685 y estoy haciendo lo que me recomendaste de cambiara carpetas y archivos de lugar y estoy por compilar, pero aun así no se si me puedas asesorar un poco mas para cambiar de micro y bueno esperando no quitarte tanto tu tiempo. Gracias.

    ResponderEliminar
    Respuestas
    1. Hola!, en ese microcontrolador no te va a caber, con esa memoria no tienes suficiente. Desde microchip recomiendan el que utilicé yo, el PIC18f4685 que tiene 96k. Yo lo intenté con el 4550 y no pude, incluso deshabilitando todos los módulos y con una página web que era solo un texto. Cambiate al que yo utilizo si puedes, o busca otro con un mínimo de 96k.
      Un saludo.

      Eliminar
  23. ok, muchas gracias, pues buscare entonces otro y estaba pensando si podría simular el servidor en ISIS para no estarle perdiendo con los micros

    ResponderEliminar
    Respuestas
    1. Si que se puede simular en ISIS, pero yo nunca lo he hecho. He hablado con algunos usuarios que si que lo han probado y les ha funcionado correctamente. Lo que pasa es que, que funcione en Proteus Isis, no significa que luego funcione cuando lo montes, aunque es un gran paso.
      En absoluto me haces perder el tiempo, estamos aquí para eso ;).
      Un saludo!!

      Eliminar
  24. Pues seguiré chendolo, y muchas gracias, una pregunta mas no logro conseguir cambiarlo de micro aunque configure los puertos I/O y el SPI, podrias decirme unos tips!!

    ResponderEliminar
    Respuestas
    1. a que micro quieres cambiarte? al 45k50? toda la configuración de los pines y periféricos se hace desde el archivo HWP PIC18EX_ENC28.h. Desde ahi cambias el puerto y el pin al que quieres asignar cada señal.
      Un saludo!!

      Eliminar
  25. En dado caso quisiera cambiarme al 18F46J60 que tiene 64k, yo creo que si cabria pues no quiero la gran cosas, con un simple Led para hacer pruebas, bueno eso es lo que creo, espero puedas darme tu consejo.Gracias por tu tiempo, un saludo!!

    ResponderEliminar
    Respuestas
    1. digo al 18F46j50 que tiene 64k jeje

      Eliminar
    2. No es cuestion de que tu programa no quepa, sino que el mismo stack no pueda funcionar correctamente. Con 64k puede que si te llegue a funcionar. Si lo haces funcionar me gustaría que lo publicaras aquí para que los demás visitantes puedan ver que hay más opciones para utilizar el stack.
      Deberás revisar bien que archivo que te dije en mi anterior comentario, para asignar correctamente los pines.
      Un saludo!

      Eliminar
  26. Saludos! Muy interesante este blog. Hace semanas estoy con una iniciativa de crear un control por medio de Ethernet para mi casa que se divide en varios subproyectos. El primero de ellos es crear un servidor web como punto intermedio para controlar otras interfaces, que iré haciendo, usando el smartphone. En fin, primero descubrí el ENC28J60 y según yo iba a escribir todo el código desde cero para manejar el ENC28J60 guiandome con el DataSheet del mismo pero fue mision imposible, era muy complicado. Luego descubrí el Stack de Microchip y en esas búsquedas llegué a este Blog y para mi sorpresa me encuentro con estas series de entradas donde se describe algo muy muy similar a lo que pretendo hacer.

    En estos últimos días me puse a seguir las instrucciones que detallas sobre modificar el Stack para un PIC diferente. Estoy planeando usar el PIC18F26K20 que tiene 64k de memoria que creo que es suficiente para lo que ocupo, y talvez usar una memoia FLASH externa para guardar la página pero eso de la memoria lo decidiré luego. El problema que tengo ahora es que una vez realizadas todas las modificaciones necesarias com los bits de configuracion, oscilador, frecuencia de trabajo, pines, registros de control, etc, etc, etc me da un error de compilación y no se como solucionarlo. El error es sobre el LINKER y es el que dice de que no puede encontrar la definicion XXXXXXX en el archivo YYYYY.o. Así que ni idea... Primero intenté modificando el mismo proyecto que venía en el Stack, y luego traté creando un proyecto desde cero e ir agregando los archivos necesarios y siempre tenía ese resultado dle error del LINKER.

    Te lo comento para ver si me das una ayuda pero justo ahora que estoy escribiendo esto se me ocurrió bajar los archivos tuyos que ya estan modificados para otro PIC, ver si lo puedo compilar y luego ver si lo puedo adaptar para este otro PIC que planeo usar. Si eso no me funciona pues creo que agotaré mis ideas de intentar hacer funcionar el Stack, o hasta que se me ocurran otras alternativas.

    Seguro esta semana seguiré con este proyecto ahora basandome en los archivos tuyos y comentaré si lo logré o si no. Por lo demás, de nuevo felicitarte por el blog que esta muy bueno y completo. Tambien me fijé en las tiendas online, principalmente en la de Asia Engineer y los precios son demasiado bajos, el problema es que yo soy de Costa Rica y tendré que pagar envío de USA a Costa Rica, pero de China a USA es gratis!. Planeo comprar LEDs de varios colores, diodos 4007 y transistores 2N2222 que son componentes que uno suele usar para cosas generales y así me evito comprar por muuuuuucho tiempo.

    Bueno, me resultó algo largo este "pequeño" comentario.

    ResponderEliminar
    Respuestas
    1. Hola Diego! me alegro de que te guste el blog. Ese tipo de errores en linkado suele ser porque no existe alguna definición que utilizas, es decir, te falta algún #define. Busca el símbolo que te da el error y luego busca donde debería estar.
      En cuanto a las tiendas, eso es lo que yo hago, lo ultimo que compré son 50 condensadres electrolíticos por 3 euros, no es que necesites 50, pero es algo que siempre vas a acabar utilizando.
      Un saludo y muchas gracias por pasarte!

      Eliminar
  27. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  28. Que tal, saludos!. Quisiera saber si se puede hacer mediante un PIC18F4620, tal cual está el código, o que modificaciones debería de hacer. Saludos

    ResponderEliminar
  29. Que tal, saludos!. Quisiera saber si se puede hacer mediante un PIC18F4620, tal cual está el código, o que modificaciones debería de hacer. Saludos

    ResponderEliminar