📄 nutinit.c
字号:
static void FakeNicEeprom(void) __attribute__ ((naked, section(".init1"), used));void FakeNicEeprom(void){ /* * Prepare the EEPROM emulation port bits. Configure the EEDO * and the EEMU lines as outputs and set both lines to high. */#ifdef RTL_EEMU_BIT sbi(RTL_EEMU_PORT, RTL_EEMU_BIT); sbi(RTL_EEMU_DDR, RTL_EEMU_BIT);#endif sbi(RTL_EEDO_PORT, RTL_EEDO_BIT); sbi(RTL_EEDO_DDR, RTL_EEDO_BIT); /* Force the chip to re-read the EEPROM contents. */ NIC_CR = 0xE1; NIC_EE = 0x40; /* No external memory access beyond this point. */#ifdef RTL_EE_MEMBUS cbi(MCUCR, SRE);#endif /* * Loop until the chip stops toggling our EESK input. We do it in * assembly language to make sure, that no external RAM is used * for the counter variable. */ __asm__ __volatile__("\n" /* */ "EmuLoop: " "\n" /* */ " ldi r24, 0 " "\n" /* Clear counter. */ " ldi r25, 0 " "\n" /* */ " sbis %0, %1 " "\n" /* Check if EESK set. */ " rjmp EmuClkClr " "\n" /* */ "EmuClkSet: " "\n" /* */ " adiw r24, 1 " "\n" /* Count loops with EESK set. */ " breq EmuDone " "\n" /* Exit loop on counter overflow. */ " sbis %0, %1 " "\n" /* Test if EESK is still set. */ " rjmp EmuLoop " "\n" /* EESK changed, do another loop. */ " rjmp EmuClkSet " "\n" /* Continue waiting. */ "EmuClkClr: " "\n" /* */ " adiw r24, 1 " "\n" /* Count loops with EESK clear. */ " breq EmuDone " "\n" /* Exit loop on counter overflow. */ " sbic %0, %1 " "\n" /* Test if EESK is still clear. */ " rjmp EmuLoop " "\n" /* EESK changed, do another loop. */ " rjmp EmuClkClr " "\n" /* Continue waiting. */ "EmuDone: \n\t" /* */ : /* No outputs. */ :"I"(_SFR_IO_ADDR(RTL_EESK_PIN)), /* Emulation port. */ "I"(RTL_EESK_BIT) /* EESK bit. */ :"r24", "r25"); /* Enable memory interface. */#ifdef RTL_EE_MEMBUS sbi(MCUCR, SRE);#endif /* Reset port outputs to default. */#ifdef RTL_EEMU_BIT cbi(RTL_EEMU_PORT, RTL_EEMU_BIT); cbi(RTL_EEMU_DDR, RTL_EEMU_BIT);#endif cbi(RTL_EEDO_PORT, RTL_EEDO_BIT); cbi(RTL_EEDO_DDR, RTL_EEDO_BIT);}#endif /* RTL_EESK_BIT && __GNUC__ && NUTXMEM_SIZE *//*! \fn NutThreadSetSleepMode(u_char mode) * \brief Sets the sleep mode to enter in Idle thread * * If the idle thread is running, no other thread is active * so we can safely put the mcu to sleep. * * \param mode one of the sleep modes defined in avr/sleep.h or * sleep_mode_none (don't enter sleep mode) */#if defined(__GNUC__) && defined(__AVR_ENHANCED__)void NutThreadSetSleepMode(u_char mode){ idle_sleep_mode = mode;}#endif/*! * \brief AVR Idle thread. * * Running at priority 254 in an endless loop. */THREAD(NutIdle, arg){#if defined(__GNUC__) && defined(__AVR_ENHANCED__) u_char sleep_mode;#endif /* Initialize system timers. */ NutTimerInit(); /* Create the main application thread. */ NutThreadCreate("main", main, 0, NUT_THREAD_MAINSTACK); /* * Run in an idle loop at the lowest priority. We can still * do something useful here, like killing terminated threads * or putting the CPU into sleep mode. */ NutThreadSetPriority(254); for (;;) { NutThreadYield(); NutThreadDestroy();#if defined(__GNUC__) && defined(__AVR_ENHANCED__) if (idle_sleep_mode != SLEEP_MODE_NONE) { sleep_mode = AVR_SLEEP_CTRL_REG & _SLEEP_MODE_MASK; set_sleep_mode(idle_sleep_mode); /* Note: avr-libc has a sleep_mode() function, but it's broken for AT90CAN128 with avr-libc version earlier than 1.2 */ AVR_SLEEP_CTRL_REG |= _BV(SE); __asm__ __volatile__ ("sleep" "\n\t" :: ); AVR_SLEEP_CTRL_REG &= ~_BV(SE); set_sleep_mode(sleep_mode); }#endif }}#if defined(__GNUC__)static void NutInitSP(void) __attribute__ ((naked, section (".init5"), used));void NutInitSP(void){#if defined (__AVR_AT90CAN128__) /* Stack must remain in internal RAM where avr-libc's runtime lib init placed it */#else /* Initialize stack pointer to end of external RAM while starting up the system * to avoid overwriting .data and .bss section. */ SP = (u_short)(NUTMEM_END);#endif}#endif#if defined(__GNUC__)static void NutInitHeap(void) __attribute__ ((naked, section (".init5"), used));#endifvoid NutInitHeap(){#if defined (NUTMEM_STACKHEAP) /* Stack resides in internal memory */ NutStackAdd((void *) NUTMEM_START, NUTMEM_STACKHEAP);#endif /* Then add the remaining RAM to heap. * * 20.Aug.2004 haraldkipp: This had been messed up somehow. It's nice to have * one continuous heap area, but we lost the ability to have systems with * a gap between internal and external RAM. */ if ((u_short)NUTMEM_END - (u_short) (&__heap_start) > 384) { NutHeapAdd(&__heap_start, (u_short) NUTMEM_END - 256 - (u_short) (&__heap_start)); }}#if defined(__GNUC__)static void NutCustomInit(void) __attribute__ ((naked, section (".init1"), used));#endif/*! * NutCustomInit is a container function for hardware specific init code. * * The hardware is selected with a PLATFORM macro definition. * * Typically this function configures CPLDs, enables chips, * overwrites NutInitXRAM's default wait state settings, sets the default * baudrate for NUDEBUG as they depend on the crystal frequency used, etc. */void NutCustomInit(void)/** MMnet02 CPLD initialization.*/#if defined(MMNET02){ volatile u_char *breg = (u_char *)((size_t)-1 & ~0xFF); *(breg + 1) = 0x01; // Memory Mode 1, Banked Memory /* Assume 14.745600 MHz crystal, set to 115200bps */ outp(7, UBRR); outp(7, UBRR1L);}/* * Arthernet CPLD initialization. */#elif defined(ARTHERNET1){ /* Arthernet1 memory setup - mt - TODO: check this Note: This overwrites the default settings of NutInitXRAM()! 0x1100-0x14FF CLPD area -> use 3 Waitstates for 0x1100-0x1FFF (no Limit at 0x1500 available) 0x1500-0xFFFF Heap/Stack -> use 1 Waitstate for 0x2000-0xFFFF */ MCUCR = _BV(SRE); /* enable xmem-Interface */ XMCRA |= _BV(SRL0) | _BV(SRW01) | _BV(SRW00); /* sep. at 0x2000, 3WS for lower Sector */ XMCRB = 0; *((volatile u_char *)(ARTHERCPLDSTART)) = 0x10; // arthernet cpld init - Bank *((volatile u_char *)(ARTHERCPLDSPI)) = 0xFF; // arthernet cpld init - SPI /* Assume standard Arthernet1 with 16 MHz crystal, set to 38400 bps */ outp(25, UBRR); outp(25, UBRR1L);}/** XNUT board initialization*/#elif defined(XNUT_100) || defined(XNUT_105){ PORTB = 0b11110101; DDRB = 0b00111111; PORTD = 0b01101100; DDRD = 0b10110000; PORTE = 0b11011111; DDRE = 0b00000010; PORTF = 0b11110000; DDRF = 0b00001111; PORTG = 0b00011111; DDRG = 0b00000111; ACSR |= _BV(ACD); /* Switch off analog comparator to reduce power consumption */ /* Init I2C bus w/ 100 kHz */ TWSR = 0; TWBR = (NUT_CPU_FREQ / 100000UL - 16) / 2; /* 100 kHz I2C */ /* Set default baudrate */#if NUT_CPU_FREQ == 14745600 UBRR0L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1; UBRR1L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1;#else sbi(UCSR0A, U2X0); sbi(UCSR1A, U2X1); UBRR0L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1; UBRR1L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1;#endif}/* * Rest of the world and standard ETHERNUT 1/2 */#else{ /* Assume standard Ethernut with 14.745600 MHz crystal, set to 115200bps */ outp(7, UBRR);#ifdef __AVR_ENHANCED__ outp(7, UBRR1L);#endif}#endif/*! * \brief Nut/OS Initialization. * * Initializes the memory management and the thread system and starts * an idle thread, which in turn initializes the timer management. * Finally the application's main() function is called. * * Depending on the compiler, different methods are used to execute this * function before main() is called. * * For ICCAVR the default crtatmega.o startup file is replaced by * crtnut.o, which calls NutInit instead of main(). This is done * by adding the following compiler options in the project: * \code -ucrtnut.o nutinit.o \endcode * * crtnut.o should be replaced by crtnutram.o, if the application's * variable space exceeds 4kB. For boards with RTL8019AS and EEPROM * emulation (like Ethernut 1.3 Rev-G) use crtenut.o or crtenutram.o. * * For AVRGCC this function is located in section .init8, which is * called immediately before jumping to main(). NutInit is defined * as: * \code * void NutInit(void) __attribute__ ((naked)) __attribute__ ((section (".init8"))); * \endcode * * \todo Make heap threshold configurable, currently hardcoded at 384. * * \todo Make wait states for external memory access configuratble. * * \todo Make early UART initialization for kernel debugging configurable. */void NutInit(void){ /* * We can't use local variables in naked functions. */#ifdef NUTDEBUG /* Note: The platform's default baudrate will be set in NutCustomInit() */ outp(BV(RXEN) | BV(TXEN), UCR);#endif#ifndef __GNUC__ NutCustomInit(); /* Initialize stack pointer to end of external RAM while starting up the system * to avoid overwriting .data and .bss section. */ SP = (u_short)(NUTMEM_END); /* Initialize the heap memory */ NutInitHeap();#endif /* __GNUC__ */ /* * Read eeprom configuration. */ if (NutLoadConfig()) { strcpy(confos.hostname, "ethernut"); NutSaveConfig(); } /* Create idle thread */ NutThreadCreate("idle", NutIdle, 0, NUT_THREAD_IDLESTACK);}/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -