⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nutinit.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -