Перейти к содержанию
    

Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.

а, ну это разумеется, да. что, кстати, неудобно - приходится инициализацию делать уже в многозадачном режиме, то есть через задницу

 

Конец инициализации "всей системы" определяете лично Вы вызовом vTaskStartScheduler( ) причем уж точно в main() и после инициализации всякого своего железа. Медленно инициализирующееся железо

подвешивается вместо IdleTask (в оригинальной реализации Hook предусмотрен) и в конце цепочки Hook снимается. Единствено, что для IdleTask задержку свою писать надо, обо системная естественно не работает.

 

Может стоит докуменацию на FreeRTOS почитать а?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.
Прерывания не будут вызываться, пока они не разрешены глобально (не сброшен I_Bit в CPSR). Это происходит после старта ОС, в момент восстановления контекста первого процесса. Не пользуюсь я FreeRTOS, но специально для вас слазил в исходники:

    /* The last thing onto the stack is the status register, which is set for
    system mode, with interrupts enabled. */
    *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;

    #ifdef KEIL_THUMB_INTERWORK
    {        
        /* We want the task to start in thumb mode. */
        *pxTopOfStack |= portTHUMB_MODE_BIT;
    }
    #endif

Вот тут готовится значение CPSR которое разрешит прерывания при старте задачи. До этого прерывания глобально запрещены, если вы их нигде случайно не разрешили.

 

 

Отправил и "въехал" - ну так или делайте инициализацию не прерываниями а поллингом или обкладывайте ваш LCD семафором, который не даст с ним работать пока инициализация не закончилась. А инициализацию в задачу запихайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прямо из живого FreeRTOS проекта инициализацию выдрал:

//---------------------------------------------------------------------------
// Starts all the other tasks, then starts the scheduler.
//---------------------------------------------------------------------------
void main( void )
{
    // Setup the processor.
    init_cpu();
    init_delay_timer();    
    // Start Console and Console Task.
    init_console( COM_TEST_BAUD_RATE, CONSOLE_PRIORITY );
    // Hello World :-)
    boutchar( XON );
    hellomessage();
    
    xIdleTaskCreate( 200 );
extern ulong RAMEND;
extern ulong RAMSTART;
#pragma segment="HEAP_RTOS"
    bprintf( "\tRAM use:%u Heap:%8X Size:%i",
                                 (ulong)(__segment_begin( "HEAP_RTOS" ))-(ulong)&RAMSTART,
                                 __segment_begin( "HEAP_RTOS" ),
                                (ulong)&RAMEND - (ulong)(__segment_begin( "HEAP_RTOS" )) + 1 );
    if( copyprotect() )
        status_word |= STW_PROTECT;    
                    
    if( WDMOD_bit.WDTOF )
        printline( "\tWatchdog Reset Granted!");

    init_SLIC_data();
    
    init_AXE();

    vSetIdleHook( init_system );
    
    // Start the scheduler.
    vTaskStartScheduler( 0 );             // 0 - intertal timer 1 - external timer
}


//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
void init_system()
{
    init_delay_timer();
ulong ii;
    bprintf( "\tCheck CPU -LPC%i %s", iap_getid(), (status_word & STW_PROTECT) ? "" : "Evolution" );

    boutchar( XON );
    cf_addhandler( "MAIN", main_cfg );

    bprintf(     "\tInit I2C  -%s", init_i2c() ? "Fail":"Done" );
    // Read 1st - Configuration
    bprintf_str(  "\t  Config  -" );
    ii = cf_parser( FALSE );
    if( ii )
        bprintf( ii == 1 ? "Empty" : "Failed" );
    else
        bprintf(  "Ok" );
    
    if( config_flags & DEVICE_OWIRE )
      {    print_str(  "\tCheck OW  -" );
        init_ow();
    }
    bprintf(     "\tInit SPI0 -%s", init_SPI0() ? "Fail":"Done" );
    bprintf(     "\tInit CPLD -%s", init_cpld()    ? "Fail":"Ok" );
    
    bprintf(     "\tInit SPI1 -%s", init_SPI1() ? "Fail":"Done" );
    
    bprintf_str( "\tLoad FPGA -" ); load_fpga( 0x20000, TRUE );

    bprintf(     "\tInit ACSL -%s", init_armsl() ? "Fail":"Ok" );

    init_dsl_post();

    init_eth_post();

    toggle_red_LED();

    // Check Maintenance Console Request
    for( ii=0; ii< 50; ii++ )
    {   if( IO0PIN_bit.P0_14 == 0 )
        {    status_word |= STW_MAINTENANCE;
            bprintf( "\nMaintenance Console Mode" );
            goto skip_application;
        }
               vDummyDelay_ms( 2 );
    }
    //----- Switch System to external 2ms Ticks -----------------------------
    bprintf_str( "\tExt Sync  -" );
    ENTER_CRITICAL();
    {
    // Set edle-sensetive Mode
    // Bug :-(
    // The steps involved in the configuration of the EXTMODE and/or EXTPOLAR would be as follow:-
    // 1. Write 0x00 to VPBDIV
    // 2. Write the desired value to EXTMODE or EXTPOLAR register
    // 3. Write the same value to VPBDIV
    // 3a. Write 0x00 to VPBDIV (additional step for INT0 )
    // 4. Restore the VPBDIV to the previously saved value or simply write to the register again
    //    with the desired value.
    VPBDIV = 0;                 // 1.
    ii = EXTMODE & ( EXTMODE_EXTMODE0|EXTMODE_EXTMODE1|EXTMODE_EXTMODE2|EXTMODE_EXTMODE3);  // Get Curent Value
    ii |= EXTMODE_EXTMODE1;
    EXTMODE = ii;             // 2.
    VPBDIV  = ii;             // 3.
    VPBDIV  = 0;              // 3a
    VPBDIV  = configBUS_CLK; // 4.

    // Select IRQ Pin 'IRQ_2MS'
    PINSEL0_bit.P_IRQ_2MS = 0x2;            // Pin to EINT1 mode

    // IRQ Handler to Temporary MS2_ISR_handler()
    VICIntSelect &= ~(1 << VIC_EINT1);         // Classifies as IRQ.
      VICVectAddr9 = (ulong)MS2_ISR_handler;     // Connect to Slot9
      VICVectCntl9 = 0x20 | VIC_EINT1;          // Enable vector interrupt for EINT1.
    VICIntEnable =  (1 << VIC_EINT1);       // Enable EINT1 2ms interrupt.

    }

    LEAVE_CRITICAL();

    // Enable 2ms in FPGA
    work_spi_reset_clr( CSPI_WR | CSPI_RES_FPGA );
    ms_check_timer = 0;
    vDummyDelay_ms( (16+1)*2 );
    if( ms_check_timer >= 16 )
    {    // Ok 2ms Present.
        ENTER_CRITICAL();
        {
        // Disable INT Generate timer 0 compare match.
        TxMCR &= (~0x01);
        // Set New Handler
//        VICIntSelect &= ~(1 << VIC_EINT1);         // Classifies as IRQ.
          VICVectAddr0 = (ulong)vPortPreemptiveTickEntry_Ext;;     // Connect to Slot9
          VICVectCntl0 = 0x20 | VIC_EINT1;          // Enable vector interrupt for EINT1.
//        VICIntEnable =  (1 << VIC_EINT1);       // Enable EINT1 2ms interrupt.
        }
        LEAVE_CRITICAL();
        bprintf( "Ok (%i)", ms_check_timer );
        // For future....
//!!        sys_reg |= (SYS_2MS_IRQ | SYS_PKT_ENABLE);
    }
    else
    {    // 2ms Failed
          VICIntEnClear = (1<< VIC_EINT1);          // Disable vector interrupt for EINT1.
        work_spi_reset( CSPI_WR | CSPI_RES_FPGA );
        bprintf( "Failed (%i)", ms_check_timer );
        goto skip_application;
    }


    //-----------------------------------------------------------------------
    
    bprintf(     "\tInit SWH  -%s", init_switch() ? "Fail":"Done" );

    printline( "Ready" );

    sys_pkt( sys_reg );


skip_application:
    xTaskCreate( CheckerProcess, "Checker", configMINIMAL_STACK_SIZE*2, NULL, CHECK_TASK_PRIORITY, NULL );

    vSetIdleHook( idle_system );
    off_red_LED();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, хочу теперь прикрутить стек uIP.

Добавил в проект исходники стека (пока кастрировал драйверную часть), откомпилировались нормально, но вот во время линковки получаю:

*** ERROR L102: EXTERNAL ATTRIBUTE MISMATCH

SYMBOL: uip_arp_draddr

MODULE: .\obj\uip_arp.obj (uip_arp)

DEFINED: .\obj\uip.obj (uip)

Чего-то я не врубаюсь в смысл ошибки. В uip_arp объявлен массив uip_arp_draddr, а в uip_arp этот массив объявляется внешним, в чем тут криминал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чего-то я не врубаюсь в смысл ошибки. В uip_arp объявлен массив uip_arp_draddr, а в uip_arp этот массив объявляется внешним, в чем тут криминал?
Ну так приведите код этих объявлений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

uip.c (UIP_FIXEDADDR=1):

#if UIP_FIXEDADDR > 0
const u16_t uip_hostaddr[2] =
  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
const u16_t uip_arp_draddr[2] =
  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
const u16_t uip_arp_netmask[2] =
  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
#else
u16_t uip_hostaddr[2];       
u16_t uip_arp_draddr[2], uip_arp_netmask[2];
#endif /* UIP_FIXEDADDR */

uip_arp.h:

...
/**
* \internal Internal variables that are set using the macros
* uip_setdraddr and uip_setnetmask.
*/
extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
//u16_t uip_arp_draddr[2], uip_arp_netmask[2];
#endif /* __UIP_ARP_H__ */

если в uip_arp просто объявить этот массив (убрал extern), тогда линковщик ругается на дублирование ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.

а, ну это разумеется, да. что, кстати, неудобно - приходится инициализацию делать уже в многозадачном режиме, то есть через задницу

 

Конец инициализации "всей системы" определяете лично Вы вызовом vTaskStartScheduler( ) причем уж точно в main() и после инициализации всякого своего железа. Медленно инициализирующееся железо

подвешивается вместо IdleTask (в оригинальной реализации Hook предусмотрен) и в конце цепочки Hook снимается. Единствено, что для IdleTask задержку свою писать надо, обо системная естественно не работает.

 

Может стоит докуменацию на FreeRTOS почитать а?

 

Вы меня немного не так поняли. я имел в виду ситуацию, когда мне уже надо пользоваться прерываниями, но не запускать многозадачный режим - скажем, инициализировать внешние объекты, используя рабочие библиотеки. режим поллинга тут в принципе подходит, но для этого надо писать отдельный код

 

 

...А инициализацию в задачу запихайте.

вот это я и имел в виду, когда писал про "задницу". получается не очень красиво. а когда еще желательно это делать не в любой момент, притом стопить другие задачи, притом тоже не как попало...

 

uip.c (UIP_FIXEDADDR=1):
#if UIP_FIXEDADDR > 0
const u16_t uip_hostaddr[2] =
  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
const u16_t uip_arp_draddr[2] =
  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
const u16_t uip_arp_netmask[2] =
  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
#else
u16_t uip_hostaddr[2];       
u16_t uip_arp_draddr[2], uip_arp_netmask[2];
#endif /* UIP_FIXEDADDR */

uip_arp.h:

...
/**
* \internal Internal variables that are set using the macros
* uip_setdraddr and uip_setnetmask.
*/
extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
//u16_t uip_arp_draddr[2], uip_arp_netmask[2];
#endif /* __UIP_ARP_H__ */

если в uip_arp просто объявить этот массив (убрал extern), тогда линковщик ругается на дублирование ...

 

ну так он у Вас описан как const, а объявление не константное. может, в этом дело? на месте линкера я бы обиделся

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А это случайно не проблема со сменой контроллера прерываний в 2300 серии? Переносить старые исходники обработчика прерываний непрямую нельзя.

Yes, the LPC23xx and LPC24xx use the PL192 VIC while all the older chips use

the PL190 VIC. Go to www.arm.com and search for PL190 and PL192.

 

Another important difference is the address of the register where you read

the current handler address -- VICAddress instead of VICVectAddr. You now

need a "ldr pc, [pc, #-0x0120]" at address 0x18 instead of a "ldr pc, [pc,

#-0x0FF0]".

 

Karl Olsen

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обработчик, в итоге, остался старый, а вто его объявление пришлось заменить. Особой разницы в VIC-ах я не заметил, векторов стало 32 (отсюда и новое смещение) и дефаултовый вектор теперь отсутствует.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы меня немного не так поняли. я имел в виду ситуацию, когда мне уже надо пользоваться прерываниями, но не запускать многозадачный режим - скажем, инициализировать внешние объекты, используя рабочие библиотеки. режим поллинга тут в принципе подходит, но для этого надо писать отдельный код

Пользуйтесь на здроровье! Система пользуется одним единственным таймерным прерыванием и источник этого прерывания инициализируется при старте шедулера. Глобально прерывания (и естественно конкретные источники) могут быть разрешены и использоваться и до старта шедулера.

Я в приведенном куске так не делаю по одной причине - когда запущена система уже работает консоль и инициализацию наблюдать гороаздо приятнее :). Только с этой целью висит Hook.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пользуйтесь на здроровье! Система пользуется одним единственным таймерным прерыванием и источник этого прерывания инициализируется при старте шедулера. Глобально прерывания (и естественно конкретные источники) могут быть разрешены и использоваться и до старта шедулера.

Я в приведенном куске так не делаю по одной причине - когда запущена система уже работает консоль и инициализацию наблюдать гороаздо приятнее :). Только с этой целью висит Hook.

да, действительно. свое замечание снимаю. у меня зато есть другой вопрос :) почему же все-таки при использовании 71x_init.s проект с FreeRTOS у меня виснет? может это быть связано с установкой пользовательского режима, и если да - то как?

Изменено пользователем sergik_vrn

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пытаюсь завести FreeRTOS на этом же камне и RealView компиллере, почему-то при старте первой же задачи на строчке:

 

STMDB     R13!,{R4,R14}

 

Проц вылетает в Undef_Handler :05: .

 

Чего-то даже не пойму, а куда копать? :07:

 

И еще, в последнем realview исчез атрибут __task, не совсем понятно, он теперь просто не нужен или как? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё, вроде теперь со всем разобрался, теперь всё работает как надо :)

Портом не поделишься? :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...