[ECOS] Not working lan91cxx_sc drv

ariga masahiro ariga@link-lab.co.jp
Tue Oct 2 01:18:00 GMT 2007


Hi,

I am in a complete predicament.
You are the only hope.
Please give me any hints whatsoever.

I realized I should check Configuration conflicts.

When building "net" template,appeares 2 Resolve Conflicts windows.
I donnot know how much level auto-amendment system guarantees,
but I relied auto-amendment completely.

All-items tracking down is impossible because I consumed time enough.
If any one hits you as most suspecting,please let me know.

[First Resolve Conflicts window]
Resolve conflicts
CYGPKG_DEVS_FLASH_SH_inserter       Requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
CYGPKG_HAL_SH_SH77X9_inserter        Requires CYGHWR_HAL_SH_IRQ_USE_IRQLVL
CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires CYGPRI_HAL_SH_SH77X9_SUPERIO

Proposed Solutions:
CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled

[Second Resolve Conflicts window]
CYGPKG_POSIX_CLOCKS                   Requires 
CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER == 
"<cyg/fileio/fnmatch.h>"

Proposed Solutions:
CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>

Please help me.

Mashiro Ariga

-- my previous mail.
> As I said,
> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
> As ethernet interrupt,uses IRQ3 line.
> I build "net" template,eCos source is updated by CVS checkout.
>
> As I inserted LAN91C111's mask routine in the ISR,
> I succeeded to entered into DSR.
> (This interrupt was caused not by eCos-proper code, but by my tampered
> routine.I will later explain.)
> But although RCV-INT is assserted,delivering-packet routine never called,
> so I entered repetedly ISR and DSR.
> Then I discovered LAN91C111 driver's receive routine was never called.
>
> Please forgive me long mail,but I try to
> inform you as correctly as possible.
> First I relate current problem,and later describe what I have tampered 
> with.
>
> I register SMSC interrupt ruoitne
> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
> like this,
> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>    // Initialize environment, setup interrupt handler
>    cyg_drv_interrupt_create(cpd->interrupt,
>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>                             (cyg_addrword_t)sc, //  Data item passed to 
> interrupt handler
>                             (cyg_ISR_t *)lan91cxx_isr,
>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
> driver DSR
>                             &lan91cxx_interrupt_handle,
>                             &lan91cxx_interrupt);
>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>    cyg_drv_interrupt_unmask(cpd->interrupt);
>
> And register LAN91C111 driver in my target's 
> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
> I think this is important so I put on all content.
> #include <pkgconf/system.h>
> #include <pkgconf/devs_eth_sh_inserter.h>
> #include <cyg/hal/hal_intr.h>
>
> // MAC address is stored as a Redboot config option
> #ifdef CYGPKG_REDBOOT
> #include <pkgconf/redboot.h>
> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
> #include <redboot.h>
> #include <flash_config.h>
>
> #define LAN91CXX_IS_LAN91C111
>
> RedBoot_config_option("Network hardware address [MAC]",
>                      inserter_esa,
>                      ALWAYS_ENABLED, true,
>                      CONFIG_ESA, 0
>    );
> #endif
> #endif
>
> // ESA address fetch function
> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
> {
>    // Fetch hardware address from RedBoot config
> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
> #if defined(CYGPKG_REDBOOT) && \
>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
> #else
> #error "No RedBoot flash configuration to store ESA"
> #endif
> #else
>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>    memcpy(cpd->enaddr, static_esa, 6);
> #endif
> }
>
> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>    config_enaddr : inserter_get_ESA,
> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>    hardwired_esa : true,
> #else
>    hardwired_esa : false,
> #endif
>
> #if 0
>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>   interrupt : SA1110_IRQ_GPIO_ETH
> #else
>   base : (unsigned short *) 0xa8000000,
>   interrupt : 9,
> #endif
> };
>
> ETH_DRV_SC(lan91cxx_sc,
>           &lan91cxx_eth0_priv_data,          // Driver specific data
>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>           lan91cxx_start,
>           lan91cxx_stop,
>           lan91cxx_control,
>           lan91cxx_can_send,
>           lan91cxx_send,
>           lan91cxx_recv,
>           lan91cxx_deliver,
>           lan91cxx_poll,
>           lan91cxx_int_vector
> );
>
> NETDEVTAB_ENTRY(lan91cxx_netdev,
>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>                smsc_lan91cxx_init,
>                &lan91cxx_sc);
>
> //EOF devs_eth_inserter.inl
>
> I found ETH_DRV_SC definition as below.
> \packages\io\eth\current\include\eth_drv.h
> #define 
> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
> \
> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
> flags); \
> static void stop(struct eth_drv_sc *sc); \
> static int  control(struct eth_drv_sc *sc, unsigned long key, void *data, 
> int data_length); \
> static int  can_send(struct eth_drv_sc *sc); \
> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
> sg_len, int total, unsigned long key); \
> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
> sg_len); \
> static void deliver(struct eth_drv_sc *sc); \
> static void poll(struct eth_drv_sc *sc); \
> static int  int_vector(struct eth_drv_sc *sc); \
> static struct eth_hwr_funs sc##_funs = {        \
>    start,                                      \
>    stop,                                       \
>    control,                                    \
>    can_send,                                   \
>    send,                                       \
>    recv,                                       \
>    deliver,                                    \
>    poll,                                       \
>    int_vector,                                 \
>    &eth_drv_funs,                              \
>    (struct eth_drv_funs *)0 };                 \
> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>
> I assume this is developed like below,
> #define 
> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
> \
> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char 
> *enaddr, int flags); \
> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned long 
> key, void *data, int data_length); \
> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
> eth_drv_sg *sg_list, int sg_len); \
> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>    lan91cxx_start,                                      \
>    lan91cxx_stop,                                       \
>    lan91cxx_control,                                    \
>    lan91cxx_can_send,                                   \
>    lan91cxx_send,                                       \
>    lan91cxx_recv,                                       \
>    lan91cxx_deliver,                                    \
>    lan91cxx_poll,                                       \
>    lan91cxx_int_vector,                                 \
>    &eth_drv_funs,                              \
>    (struct eth_drv_funs *)0 };                 \
> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>
> I assume lan91cxx_recv must be called to operate on packets,
> but it was never called.
>
> I traced DSR routine
> DSR is this
> \packages\io\eth\current\src\net\eth_drv.c
> void
> eth_drv_dsr(cyg_vector_t vector,
>            cyg_ucount32 count,
>            cyg_addrword_t data)
> {
>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>
> #ifdef CYGDBG_USE_ASSERTS
>    // then check that this really is a "sc"
>    {
>        cyg_netdevtab_entry_t *t;
>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>                break; // found it
>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find 
> sc in NETDEVTAB" );
>    }
> #endif // Checking code
>
>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>
>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for this 
> dev
> }
>
> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
> void ecos_synch_eth_drv_dsr(void)
> {
>    cyg_flag_setbits( &alarm_flag, 2 );
> }
>
> And in \packages\kernel\current\src\common\kapi.cxx
> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
> {
>    ((Cyg_Flag *)flag)->setbits( value );
> }
>
> And in \packages\kernel\current\src\sync\flag.cxx
> void
> Cyg_Flag::setbits( Cyg_FlagValue arg )
> {
>    CYG_REPORT_FUNCTION();
>    CYG_ASSERTCLASS( this, "Bad this pointer");
>
>    // Prevent preemption
>    Cyg_Scheduler::lock();
>
>    // OR in the argument to get a new flag value.
>    value |= arg;
>
>    // anyone waiting?
>    if ( !(queue.empty()) ) {
>        FlagWaitInfo   *p;
>        Cyg_Thread     *thread;
>        Cyg_ThreadQueue holding;
>
>        do {
>            thread = queue.dequeue();
>            p = (FlagWaitInfo *)(thread->get_wait_info());
>
>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>                        "Both masks set" );
>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>
>            if ( ((p->allmask != 0) && (p->allmask & value) == p->allmask) 
> ||
>                 ((p->anymask & value) != 0 ) ) {
>                // success!  awaken the thread
>                thread->set_wake_reason( Cyg_Thread::DONE );
>                thread->wake();
>                // return the successful value to it
>                p->value_out = value;
>                // do we clear the value; is this the end?
>                if ( p->do_clear ) {
>                    // we can break here but need to preserve ordering
>                    value = 0;
>                    // so let it cycle the whole queue regardless
>                }
>            }
>            else {
>                // preserve the entry on the holding queue
>                holding.enqueue( thread );
>            }
>        } while ( !(queue.empty()) );
>
>        // Now re-queue the unaffected threads back into the flag queue
>        while ( !(holding.empty()) ) {
>            queue.enqueue( holding.dequeue() );
>        }
>    }
>    // Unlock scheduler and allow other threads to run
>    Cyg_Scheduler::unlock();
>    CYG_REPORT_RETURN();
> }
>
> Truely,I cannot fathom this coding and
> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
> called.
>
> Now I describe what I have tampered with in detail,please forgive me 
> lengthy details.
> The beginning of the matter is when I ran eCos as it is,I couldn't make 
> LAN91C111 into LINK State,
> LINK LED didn't light.So I inserted my own routine in order to operate 
> LAN91C111 into LINK State in top of
> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
> below.
> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
> {
>    // this is my tampered coding
>    cyg_netdevtab_entry_t *t;
>
>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> #ifdef CYGPKG_NET_FREEBSD_STACK
>    int unit;
>    char *np, *xp;
> #endif
>
>    // this is my tampered coding
>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>        log(LOG_INIT, "Init device '%s'\n", t->name);
>        if (smsc_91c111_init(t)) {             // this is my concocted 
> routine
>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>        } else {
>            // What to do if device init fails?
>            t->status = 0;  // Device not [currently] available
>        }
>    }
>
> and in order making LAN91C111 into LINK State it was necessary to use 
> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
> Above-mentioned interrupt was caused by my tampered code.At 
> LINK-established time interrupt happened.
>
> On second thought, I realized my tampering was wrong.
> So I quitted my tampering routine, I returned to eCos original source and 
> checked why couldn't make LINK LED lighed.
> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC routines).
>
> Below is RedBoot output messages log.
> I breaked lan91cxx_start() but never entered it.
> I made DEBUG_FUNCTION() available.
> -- RedBoot output messages log
> My Flash ID is 4:22f9:0:19
> eth_drv_init:enaddr=0x8c0005c4
> Ethernet eth0: MAC address 00:40:31:08:01:00
> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
> Default server: 172.16.1.1
>
> RedBoot(tm) bootstrap and debug environment [ROM]
> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>
> Platform: inserter (SH 7709S)
> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>
> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
> == Executing boot script in 3.000 seconds - enter ^C to abort
> RedBoot> fis load -b 0x8c010000 nc_slave
> RedBoot> channel 1
> RedBoot> go 0x8c010000
> Network stack using 69632 bytes for misc space
>                    69632 bytes for mbufs
>                    139264 bytes for mbuf clusters
> [cyg_net_init] Init: mbinit(0x00000000)
> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
> Init device 'lan91cxx_eth0'
> smsc_lan91cxx_init
> LAN91CXX - supposed BankReg @ a800000e = 3302
> LAN91CXX - type: 9, rev: 1
> LAN91CXX - status: 0069
> LAN91CXX - static ESA: 00:40:31:08:01:00
> [cyg_net_init] Init: loopattach(0x00000000)
> [cyg_net_init] Init: ifinit(0x00000000)
> [cyg_net_init] Init: domaininit(0x00000000)
> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
> New domain internet at 0x00000000
> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
> New domain route at 0x00000000
> [cyg_net_init] Init: call_route_init(0x00000000)
> [cyg_net_init] Done
> Start Network Characterization - SLAVE
> No load = 58470
> Set background load = 20%
> Set background load = 0%
> High Load[20] = 37131 => 37%
> Set background load = 20%
> Set background load = 0%
> Load[10] = 47736 => 19%
> Set background load = 20%
> Set background load = 0%
> Final load[10] = 47853 => 19%
> Start test for eth0
> -- end of RedBoot output messages log
>
> All matters considered,I deduce that ETH_DRV_SC-table-reference-functions 
> are not working.
> I cannot understand where and how they are called.
> Please teach me how to correctly call these functions.
>


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list