|
|
  |
FreeRTOS + LPC2378 |
|
|
|
Feb 1 2007, 19:27
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergik_vrn @ Feb 1 2007, 15:57)  Цитата(3.14 @ Feb 1 2007, 16:55)  Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.
а, ну это разумеется, да. что, кстати, неудобно - приходится инициализацию делать уже в многозадачном режиме, то есть через задницу Конец инициализации "всей системы" определяете лично Вы вызовом vTaskStartScheduler( ) причем уж точно в main() и после инициализации всякого своего железа. Медленно инициализирующееся железо подвешивается вместо IdleTask (в оригинальной реализации Hook предусмотрен) и в конце цепочки Hook снимается. Единствено, что для IdleTask задержку свою писать надо, обо системная естественно не работает. Может стоит докуменацию на FreeRTOS почитать а?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 1 2007, 19:39
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(3.14 @ Feb 1 2007, 15:55)  Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею 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 семафором, который не даст с ним работать пока инициализация не закончилась. А инициализацию в задачу запихайте.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 1 2007, 20:15
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Прямо из живого 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(); }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 2 2007, 11:10
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Спасибо, хочу теперь прикрутить стек 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 этот массив объявляется внешним, в чем тут криминал?
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Feb 2 2007, 12:59
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
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), тогда линковщик ругается на дублирование ...
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Feb 2 2007, 13:18
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(zltigo @ Feb 1 2007, 19:27)  Цитата(sergik_vrn @ Feb 1 2007, 15:57)  Цитата(3.14 @ Feb 1 2007, 16:55)  Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.
а, ну это разумеется, да. что, кстати, неудобно - приходится инициализацию делать уже в многозадачном режиме, то есть через задницу Конец инициализации "всей системы" определяете лично Вы вызовом vTaskStartScheduler( ) причем уж точно в main() и после инициализации всякого своего железа. Медленно инициализирующееся железо подвешивается вместо IdleTask (в оригинальной реализации Hook предусмотрен) и в конце цепочки Hook снимается. Единствено, что для IdleTask задержку свою писать надо, обо системная естественно не работает. Может стоит докуменацию на FreeRTOS почитать а? Вы меня немного не так поняли. я имел в виду ситуацию, когда мне уже надо пользоваться прерываниями, но не запускать многозадачный режим - скажем, инициализировать внешние объекты, используя рабочие библиотеки. режим поллинга тут в принципе подходит, но для этого надо писать отдельный код Цитата ...А инициализацию в задачу запихайте. вот это я и имел в виду, когда писал про "задницу". получается не очень красиво. а когда еще желательно это делать не в любой момент, притом стопить другие задачи, притом тоже не как попало... Цитата(3.14 @ Feb 2 2007, 12:59)  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, а объявление не константное. может, в этом дело? на месте линкера я бы обиделся
|
|
|
|
|
Feb 2 2007, 14:51
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergik_vrn @ Feb 2 2007, 12:18)  Вы меня немного не так поняли. я имел в виду ситуацию, когда мне уже надо пользоваться прерываниями, но не запускать многозадачный режим - скажем, инициализировать внешние объекты, используя рабочие библиотеки. режим поллинга тут в принципе подходит, но для этого надо писать отдельный код Пользуйтесь на здроровье! Система пользуется одним единственным таймерным прерыванием и источник этого прерывания инициализируется при старте шедулера. Глобально прерывания (и естественно конкретные источники) могут быть разрешены и использоваться и до старта шедулера. Я в приведенном куске так не делаю по одной причине - когда запущена система уже работает консоль и инициализацию наблюдать гороаздо приятнее  . Только с этой целью висит Hook.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 2 2007, 15:07
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(zltigo @ Feb 2 2007, 14:51)  Пользуйтесь на здроровье! Система пользуется одним единственным таймерным прерыванием и источник этого прерывания инициализируется при старте шедулера. Глобально прерывания (и естественно конкретные источники) могут быть разрешены и использоваться и до старта шедулера. Я в приведенном куске так не делаю по одной причине - когда запущена система уже работает консоль и инициализацию наблюдать гороаздо приятнее  . Только с этой целью висит Hook. да, действительно. свое замечание снимаю. у меня зато есть другой вопрос  почему же все-таки при использовании 71x_init.s проект с FreeRTOS у меня виснет? может это быть связано с установкой пользовательского режима, и если да - то как?
Сообщение отредактировал sergik_vrn - Feb 2 2007, 15:09
|
|
|
|
|
Jun 29 2008, 11:22
|

Местный
  
Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021

|
Пытаюсь завести FreeRTOS на этом же камне и RealView компиллере, почему-то при старте первой же задачи на строчке: Код STMDB R13!,{R4,R14} Проц вылетает в Undef_Handler  . Чего-то даже не пойму, а куда копать? И еще, в последнем realview исчез атрибут __task, не совсем понятно, он теперь просто не нужен или как?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|