[ECOS] Not working lan91cxx_sc drv
ariga masahiro
ariga@link-lab.co.jp
Tue Oct 2 04:46:00 GMT 2007
Hi,
In order to work ETH_DRV_SC-table-reference-functions,
should I add anything in CDL ?
If there is,
I would appreciate if you show me sample CDL.
Please help me.
Masahiro Ariga
-- my previous mail
> 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, \
>> ð_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, \
>> ð_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
>
>
--
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