Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:pixel-light

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2014:pixel-light [2015/01/16 22:26]
Pavel Kostelník
2014:pixel-light [2015/01/19 01:44] (aktuální)
Pavel Kostelník
Řádek 65: Řádek 65:
 __task void init (void) ​ __task void init (void) ​
 { {
- // create tasks: +   // create tasks: 
- t_blink = os_tsk_create(blink,​ 0); +      t_blink = os_tsk_create(blink,​ 0); 
- t_uart_tx = os_tsk_create(uart_tx,​ 0);  +      t_uart_tx = os_tsk_create(uart_tx,​ 0);  
- t_interpreter = os_tsk_create(interpreter,​ 0); +      t_interpreter = os_tsk_create(interpreter,​ 0); 
- t_spi247 = os_tsk_create(spi247,​ 0); +      t_spi247 = os_tsk_create(spi247,​ 0); 
- t_spi787 = os_tsk_create(spi787,​ 0); +      t_spi787 = os_tsk_create(spi787,​ 0); 
- t_dc247 = os_tsk_create(dc247,​ 0); +      t_dc247 = os_tsk_create(dc247,​ 0);
  
- // init semaphores:​ +   // init semaphores:​ 
- os_sem_init (&​Semspi247,​ 0); +      os_sem_init (&​Semspi247,​ 0); 
- os_sem_init (&​Semspi787,​ 0); +      os_sem_init (&​Semspi787,​ 0); 
- os_sem_init (&​Semdc247,​ 0);+      os_sem_init (&​Semdc247,​ 0);
   
- // init mutexes +   // init mutexes 
- os_mut_init(&​Mutspi247);​ +      os_mut_init(&​Mutspi247);​ 
- os_mut_init(&​Mutspi787);​ +      os_mut_init(&​Mutspi787);​ 
- os_mut_init(&​Mutuart_tx);​+      os_mut_init(&​Mutuart_tx);​
   
- //delete itself: +   // delete itself: 
- os_tsk_delete_self ();+      os_tsk_delete_self ();
 } }
 //​------------------------- TASK: init -- (End) ---------------------------------- //​------------------------- TASK: init -- (End) ----------------------------------
 </​code>​ </​code>​
 +
  
 === TASK: blink === === TASK: blink ===
Řádek 94: Řádek 95:
 //​-------------------------- TASK: blink -- (Begin) --------------------------------- //​-------------------------- TASK: blink -- (Begin) ---------------------------------
 // Blinking with LED D5  // Blinking with LED D5
- __task void blink (void)+__task void blink (void)
 { {
- while(1) +   while(1) 
- +   ​
- LED_off(5);​ //​ turn off LED5 +      LED_off(5);​ //​ turn off LED5 
- os_dly_wait (500); ​             // wait for 500 ms +      os_dly_wait (500); ​             // wait for 500 ms 
- LED_on(5);​ //​ turn on LED5 +      LED_on(5);​ //​ turn on LED5 
- os_dly_wait (500); ​             // wait for 500 ms +      os_dly_wait (500); ​             // wait for 500 ms 
- }+   ​}
 } }
 //​-------------------------- TASK: blink -- (End) ---------------------------------- //​-------------------------- TASK: blink -- (End) ----------------------------------
 </​code>​ </​code>​
 +
  
 === TASK: interpreter,​ spi787, spi247, dc247 === === TASK: interpreter,​ spi787, spi247, dc247 ===
Řádek 111: Řádek 113:
  
 === TASK: wb, dz, bl === === TASK: wb, dz, bl ===
-Dále software obsahuje tři dočasné tasky, které se vytváří a mažou dynamicky v případě, že je daný efekt potřeba. Například pokud přijde z počítače povel pro efekt Dark Zone, task interpreter vytvoří nový task dz, který se už sám stará o odesílání příslušných dat do SPI periferie. Task s efektem se maže opět příkazem z počítače. V jednu chvíli je možné mít spuštěných i více kopií stejného tasku, které obsluhují různé obvody integrovaného budiče.+Dále software obsahuje tři dočasné tasky, které se vytváří a mažou dynamicky v případě, že je daný efekt potřeba. Konkrétně jsou implementovány funkce Wiping Blinker, Dark Zone a Bending Light. Například pokud přijde z počítače povel pro efekt Dark Zone, task interpreter vytvoří nový task dz, který se už sám stará o odesílání příslušných dat do SPI periferie. Task s efektem se maže opět příkazem z počítače. V jednu chvíli je možné mít spuštěných i více kopií stejného tasku, které obsluhují různé obvody integrovaného budiče.
 Ukázka jednoho tasku je uvedena zde: Ukázka jednoho tasku je uvedena zde:
 <code c> <code c>
Řádek 118: Řádek 120:
 __task void wb (void) __task void wb (void)
 { {
- uint8_t target = newtarget;​ //​ target device +   uint8_t target = newtarget;​ //​ target device 
- float wb_dt = 0; // time difference+   ​float wb_dt = 0; // time difference
   
- while(1) +   while(1) 
- +   ​
- wb_dt = (float)(wb_stop[target] - wb_start[target])/​12.0;​ +      wb_dt = (float)(wb_stop[target] - wb_start[target])/​12.0;​
   
- if (wb_counter[target] >= wb_per[target]) //​ counter overflow +      ​if (wb_counter[target] >= wb_per[target]) //​ counter overflow 
- wb_counter[target] = 0; +         ​wb_counter[target] = 0; 
- else +      else 
- wb_counter[target]++;​ // increment counter+         ​wb_counter[target]++;​ // increment counter
   
   
- if (wb_counter[target] < wb_start[target]) //​ all LEDs OFF +      ​if (wb_counter[target] < wb_start[target]) //​ all LEDs OFF 
- +      
- for (i=0; i<12; i++) +         ​for (i=0; i<12; i++) 
- +         ​
- DCs[i] = 1023; +            DCs[i] = 1023; 
- +         ​
- j=0; +         ​j=0; 
- +      
- else if (wb_counter[target] < wb_stop[target]) //​all LEDs dimmed +      else if (wb_counter[target] < wb_stop[target]) //​all LEDs dimmed 
- {  +      {  
- for (i=0; i<12; i++) +         ​for (i=0; i<12; i++) 
- +         ​
- if (wb_counter[target] < (wb_start[target] + i*wb_dt)) +            if (wb_counter[target] < (wb_start[target] + i*wb_dt)) 
- DCs[i] = 1023; +               ​DCs[i] = 1023; 
- else if (wb_counter[target] < (wb_start[target] + (i+1)*wb_dt)) +            else if (wb_counter[target] < (wb_start[target] + (i+1)*wb_dt)) 
- DCs[i] = (wb_start[target] + (i+1)*wb_dt - wb_counter[target])/​wb_dt*1023;​ +               ​DCs[i] = (wb_start[target] + (i+1)*wb_dt - wb_counter[target])/​wb_dt*1023;​ 
- else  +            else  
- DCs[i] = 0; +               ​DCs[i] = 0; 
- }  +         ​}  
- +      
- else // all LEDs ON +      else // all LEDs ON 
- +      
- for (i=0; i<12; i++) +         ​for (i=0; i<12; i++) 
- +         ​
- DCs[i] = 0; +            DCs[i] = 0; 
- +         ​
- }+      }
   
- dimming(DCs,​ LEDcount, ON, OFF, TR, lastLevel[target]);​ //​ ON, OFF, TR values computation using Dimming algorithm+      ​dimming(DCs,​ LEDcount, ON, OFF, TR, lastLevel[target]);​ //​ ON, OFF, TR values computation using Dimming algorithm
   
- os_mut_wait(&​Mutspi247,​ 0xFFFF);​ //​ wait for mutex+      ​os_mut_wait(&​Mutspi247,​ 0xFFFF);​ //​ wait for mutex
   
- SPI_SendFrame(target + 3, 1, 0xCF, 0, 0, 0); // send SPI frame to pixel light+      ​SPI_SendFrame(target + 3, 1, 0xCF, 0, 0, 0); // send SPI frame to pixel light
   
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received  +      ​while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received  
- SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data +      SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data 
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received  +      while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received  
- SPI_RcvData += LPC_SSP2->​DR;​ // sum received data +      SPI_RcvData += LPC_SSP2->​DR;​ // sum received data
   
- SPI_SendFrame(target + 3, 1, 0xCC, ((SPI_RcvData)&​(0xFB)),​ (SPI_RcvData>>​8)&​0xFF,​ (SPI_RcvData>>​16)&​0xFF);​  +      ​SPI_SendFrame(target + 3, 1, 0xCC, ((SPI_RcvData)&​(0xFB)),​ (SPI_RcvData>>​8)&​0xFF,​ (SPI_RcvData>>​16)&​0xFF);​  
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +      while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data +      SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data 
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +      while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData += LPC_SSP2->​DR;​ // sum received data +      SPI_RcvData += LPC_SSP2->​DR;​ // sum received data
   
- for(i=0; i<12; i++) // send ON, OFF and TR values to pixel light +      ​for(i=0; i<12; i++) // send ON, OFF and TR values to pixel light 
- +      
- SPI_SendFrame(target + 3, 1, i + 0xC0, ((OFF[i]<<​4)+TR[i])&​0xFF,​ ((ON[i]<<​6)+(OFF[i]>>​4))&​0xFF,​ (ON[i]>>​2)&​0xFF); ​  +         ​SPI_SendFrame(target + 3, 1, i + 0xC0, ((OFF[i]<<​4)+TR[i])&​0xFF,​ ((ON[i]<<​6)+(OFF[i]>>​4))&​0xFF,​ (ON[i]>>​2)&​0xFF); ​  
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +         ​while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data +         ​SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data 
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +         ​while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData += LPC_SSP2->​DR;​ // sum received data  +         ​SPI_RcvData += LPC_SSP2->​DR;​ // sum received data  
- }+      }
   
- SPI_SendFrame(target + 3, 1, 0xCC, ((SPI_RcvData)&​0xFF)|(1<<​2),​ (SPI_RcvData>>​8)&​0xFF,​ (SPI_RcvData>>​16)&​0xFF);​ //​set MAPENA bit +      ​SPI_SendFrame(target + 3, 1, 0xCC, ((SPI_RcvData)&​0xFF)|(1<<​2),​ (SPI_RcvData>>​8)&​0xFF,​ (SPI_RcvData>>​16)&​0xFF);​ //​set MAPENA bit 
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +      while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data +      SPI_RcvData = (LPC_SSP2->​DR)<<​16;​ // shift received data 
- while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received +      while ((LPC_SSP2->​SR & 0x4)== 0x0){} // wait until frame is received 
- SPI_RcvData += LPC_SSP2->​DR;​ // sum received data +      SPI_RcvData += LPC_SSP2->​DR;​ // sum received data
   
- os_mut_release(&​Mutspi247);​ // release mutex+      ​os_mut_release(&​Mutspi247);​ // release mutex
   
- os_dly_wait(20);​+      ​os_dly_wait(20);​
   
- } // end while(1)+   } // end while(1)
 } }
 //​--------------------------- TASK: wb -- (End) ----------------------------------- //​--------------------------- TASK: wb -- (End) -----------------------------------
Řádek 201: Řádek 203:
  
  
-==== Zhodnocení výsledků a návrh na úpravy ==== 
-Naprogramovaný software je plně funkční, což je možné vidět i na ukázkovém videu níže. Nastavené časové údaje u ukázkových funkcí odpovídají skutečnosti,​ a proto je možné tvrdit, že časování v RTOS funguje podle požadavků. V softwaru je navíc implementovaná kontrola přetečení zásobníků jednotlivých tasků. Při testování softwaru bylo ověřeno, že aktuálně nastavená hodnota velikosti zásobníků 512 B je dostatečná. ​ 
  
 +
 +==== Návrh na úpravy ====
 Operační systém reálného času RTX je komplexní a velmi rozsáhlý nástroj, proto bez větších zkušeností je velký problém využít všechny jeho možnosti a vytvořit dobře optimalizovaný program. Taky proto byl kladen důraz na jednoduchost a využití pouze základních možností RTX, aby nedošlo k zamotání do různých funkcí a možností. Mezi další možnosti, které systém RTX podporuje, jsou mailboxy, signály a události, tak by jistě stálo za zvážení, zda by programu pomohly. Operační systém reálného času RTX je komplexní a velmi rozsáhlý nástroj, proto bez větších zkušeností je velký problém využít všechny jeho možnosti a vytvořit dobře optimalizovaný program. Taky proto byl kladen důraz na jednoduchost a využití pouze základních možností RTX, aby nedošlo k zamotání do různých funkcí a možností. Mezi další možnosti, které systém RTX podporuje, jsou mailboxy, signály a události, tak by jistě stálo za zvážení, zda by programu pomohly.
  
-==== Ukázka funkce ====+===== Ukázka funkce ​=====
    
 +{{youtube>​keJ7lECmeH4?​medium}}
  
 +===== Zdrojové soubory =====
 +Zdrojová data nejsou z důvodu ochrany duševního vlastnictví společnosti ON Semiconductor zcela zveřejněna. V rámci zdrojových souborů je možné najít nastavení RTX souborem RTX_Conf_CM.c. Dále jsou ve zdrojovém souboru main.c zveřejněny všechny tasky a jejich provázání,​ pouze pár menších částí bylo vyjmuto, které ale nemají vliv na fungování RTOS. Dále je v přiloženém balíku zveřejněno schéma desky s mikrokontrolérem. {{:​2014:​pixel-light:​mpoa_pixellight.zip|}}
 +
 +    ​
 +===== Závěr =====
 +Naprogramovaný software je plně funkční, což je možné vidět i na ukázkovém videu níže. Nastavené časové údaje u ukázkových funkcí odpovídají skutečnosti,​ a proto je možné tvrdit, že časování v RTOS funguje podle požadavků. V softwaru je navíc implementovaná kontrola přetečení zásobníků jednotlivých tasků. Při testování softwaru bylo ověřeno, že aktuálně nastavená hodnota velikosti zásobníků 512 B je dostatečná. ​
2014/pixel-light.1421443598.txt.gz · Poslední úprava: 2015/01/16 22:26 (upraveno mimo DokuWiki)