abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 20:22 | Nová verze

    Byla vydána (𝕏) květnová aktualizace aneb nová verze 1.101 editoru zdrojových kódů Visual Studio Code (Wikipedie). Přehled novinek i s náhledy a videi v poznámkách k vydání. Ve verzi 1.101 vyjde také VSCodium, tj. komunitní sestavení Visual Studia Code bez telemetrie a licenčních podmínek Microsoftu.

    Ladislav Hagara | Komentářů: 0
    dnes 10:00 | Komunita

    V Brně na FIT VUT probíhá třídenní open source komunitní konference DevConf.CZ 2025. Vstup je zdarma, nutná je ale registrace. Na programu je celá řada zajímavých přednášek, lightning talků, meetupů a workshopů. Přednášky lze sledovat i online na YouTube kanálu konference. Aktuální dění lze sledovat na Matrixu, 𝕏 nebo Mastodonu.

    Ladislav Hagara | Komentářů: 0
    dnes 09:44 | IT novinky

    Vyloučení technologií, které by mohly představovat bezpečnostní riziko pro stát, má umožnit zákon o kybernetické bezpečnosti, který včera Senát schválil spolu s novelami navazujících právních předpisů. Norma, kterou nyní dostane k podpisu prezident, počítá rovněž s prověřováním dodavatelů technologií pro stát. Normy mají nabýt účinnosti od třetího měsíce po jejich vyhlášení ve Sbírce zákonů.

    Ladislav Hagara | Komentářů: 8
    dnes 01:11 | Nová verze

    Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána v nové verzi 2025.6.

    Ladislav Hagara | Komentářů: 0
    dnes 00:55 | Nová verze

    Po Red Hat Enterprise Linuxu a AlmaLinuxu byl v nové stabilní verzi 10.0 vydán také Rocky Linux. Přehled novinek v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    včera 22:55 | Nová verze

    Bylo vydáno Eclipse IDE 2025-06 aneb Eclipse 4.36. Představení novinek tohoto integrovaného vývojového prostředí také na YouTube.

    Ladislav Hagara | Komentářů: 0
    včera 22:33 | IT novinky

    Americká filmová studia Walt Disney a Universal Pictures podala žalobu na provozovatele populárního generátoru obrázků pomocí umělé inteligence (AI) Midjourney. Zdůvodňují to údajným porušováním autorských práv. V žalobě podané u federálního soudu v Los Angeles označují firmu za „bezednou jámu plagiátorství“, neboť podle nich bez povolení bezostyšně kopíruje a šíří postavy z filmů jako Star Wars, Ledové království nebo Já, padouch, aniž by do nich investovala jediný cent.

    Ladislav Hagara | Komentářů: 1
    včera 18:33 | IT novinky

    Ultra Ethernet Consortium (UEC), jehož cílem je optimalizace a další vývoj Ethernetu s důrazem na rostoucí síťové požadavky AI a HPC, vydalo specifikaci Ultra Ethernet 1.0 (pdf, YouTube).

    Ladislav Hagara | Komentářů: 0
    včera 13:00 | IT novinky

    Francouzský prezident Emmanuel Macron chce zakázat přístup na sociální sítě pro děti do 15 let. Francie podle něj tento krok udělá sama do několika měsíců, i pokud se na něm neshodnou další státy Evropské unie. Reaguje tak na úterní vraždu vychovatelky, kterou ve východofrancouzském městě Nogent pobodal 14letý mladík. Jednotlivé sociální sítě podle něj mají možnost věk ověřit a vymáhat zákaz pomocí systémů na rozpoznávání tváří.

    Ladislav Hagara | Komentářů: 12
    včera 05:11 | IT novinky

    Byl aktualizován seznam 500 nejvýkonnějších superpočítačů na světě TOP500. Nejvýkonnějším superpočítačem zůstává El Capitan od HPE (Cray) s výkonem 1,742 exaFLOPS. Druhý Frontier má výkon 1,353 exaFLOPS. Třetí Aurora má výkon 1,012 exaFLOPS. Nejvýkonnější český počítač C24 klesl na 165 místo. Karolina, GPU partition klesla na 195. místo a Karolina, CPU partition na 421. místo. Další přehledy a statistiky na stránkách projektu.

    Ladislav Hagara | Komentářů: 0
    Jaký je váš oblíbený skriptovací jazyk?
     (55%)
     (31%)
     (7%)
     (2%)
     (0%)
     (1%)
     (3%)
    Celkem 255 hlasů
     Komentářů: 16, poslední 8.6. 21:05
    Rozcestník

    Linux a MCU Stellaris ARM Cortex-M3

    26. 1. 2012 | Martin Kučera | Hardware | 5014×

    Tento článek by měl seznámit čtenáře s vývojovými nástroji a jednoduchou aplikací pro evaluation kit LM3S-8962 od Texas Instruments, která bude komunikovat s počítačem přes sériový port.

    Obsah

    Seznámení se s kitem LM3S-8962

    link

    Desku pohání 32bitový proceosor s jádrem ARM Cortex M3. Deska je osazena procesorem LM3S8962, disponuje OLED displejem s 128x96 pixely, síťovým rozhraním, pěti tlačítky, slotem pro microSD kartu... Více informací o desce najdete na ti.com. Na následujících obrázcích je blokové schéma procesoru řady 8000 a fotka desky.

    Linux a MCU Stellaris ARM Cortex-M3 Linux a MCU Stellaris ARM Cortex-M3

    Uživatelská příručka ke kitu je ke zhlédnutí také na ti.com. K dispozici jsem měl verzi kitu s vývojovým prostředím Code Composer Studio pro Windows. Jednoho dne mi však vývojové prostředí založené na Eclipsu nechtělo naběhnout, tak jsem začal řešit problém, jak uchodit potřebné vývojové nástroje pro Linux. Veškeré popisované kroky byly vyzkoušeny na starším notebooku Thinkpad T61 (CPU T7300 a 2GB RAM) s nainstalovaným Linuxem Mint verze Isadora s pracovním prostředím GNOME.

    Před připojením desky budeme nejspíš potřebovat doinstalovat knihovnu libftdi1 (nachází se v repozitáři). Po připojení desky USB kabelem se v systému identifikuje následovně:

    mk@t61 ~ $ lsusb 
    Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 005 Device 002: ID 0403:bcd9 Future Technology Devices International, Ltd Stellaris Evaluation Board
    Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 004 Device 002: ID 1ea7:0002  
    Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 003 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
    Bus 003 Device 002: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
    Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    Vývojové nástroje

    link

    Při vývoji aplikace byl použit překladč od Code Sourcery a jejich produkt Sourcery G++ Lite. Verze překladače pro MCU Stellaris je třeba arm-none-eabi. Já jsem instaloval verzi z května 2011, instalační binárka pro linux spolu s příručkou pro instalaci je k dispozici zde.

    Pro nahrání programu do desky je třeba použít program OpenOCD – Open On-Chip Debugger (nachází se normálně v repozitářích). Konfigurační soubor pro naší desku a postup pro nahrávání najde zde.

    Ladění kódu lze provádět např. prográmkem arm-none-eabi-gdbtui, který je součástí balíku Sourcery G++ Lite. Postup debugování lze dohledat zde.

    Při vývoji byla dále použita knihovna Stellarisware, ta obsahuje ovladače pro periferie MCU a ukázkové kódy pro různé desky s procesory ARM Cortex. Knihovna se nachází na přiložetém CD k development kitu.

    Seznámení se s aplikací

    link

    Jedná se o jednoduchou aplikaci, kterou budeme mít možnost ovládat běžící přehrávač na počítači. Já jsem si zvolil konzolový hudební přehrávač moc player, který používám k poslechu hudby. Program si může každý upravit pro svůj oblíbený přehrávač, stačí pouze pokud přehrávač disponuje konzolovým rozhraním, můžeme mu pomocí jednoduchého příkazu zadat, ať např. přehraje následující písničku. Pro přehrávač mocp to představuje spustit příkaz mocp -f, pro přehrávač exaile by to byl příkaz exaile -n atd.

    Uvededné přehrávače neumějí samy o sobě komunikovat s deskou, proto budeme potřebovat jednoduchý prográmek, který bude zachycovat vysílané příkazy od desky a podle přijatého příkazu bude spouštět příslušné příkazy pro danný přehrávač. Tento prográmek si napíšeme v jazyce C++ za využití knihovny Qt a qextserialport.

    Nyní si shrneme požadavky na aplikaci:

    • možnost přeskakovat písničky v playlistu (další / předchozí)
    • pauza
    • ovládání hlasitosti
    • výpis informací o přehrávané písničce na LCD displeji desky (skladba, autor a deska)

    Prográmek pro desku

    link

    Nyní se podíváme na jednotlivé části souboru control.c, který obsahuje program pro desku. Na začátku souboru najdeme vložené knihovny, které potřebujeme pro práci s MCU a periferiemi desky. Zdrojové kódy pro oba programy jsou k dispozici ke stažení zde.

        #include "inc/hw_ints.h"
        #include "inc/hw_memmap.h"
        #include "inc/hw_types.h"
        #include "driverlib/debug.h"
        #include "driverlib/gpio.h"
        #include "driverlib/interrupt.h"
        #include "driverlib/sysctl.h"
        #include "driverlib/uart.h"
        #include "drivers/rit128x96x4.h"
        #include "utils/ustdlib.h"
        #include <string.h>
        #include "driverlib/timer.h"
        
    Nyní se seznámíme s jednotlivými metodami.

    void initHw() se stará o inicialiaci částí MCU, které budeme používat. Jedná se postupně o nastavení

    • hodin procesoru
    • inicializaci LED displeje
    • zpřístupnění UARTu a jeho nastavení
    • zpřístupnění portů E a F na který jsou připojena jednotlivá tlačítka (nastevení pinů jako vstupní)
    • inicializace jednoho časovače (chceme, aby se každých 5 sekund zjišťovalo info o přehrávané skladbě)
    • povolení přerušení pro jednotlivé použité periferie

    O to, jak se ošetří určité přerušení se stará soubor startup_gcc.c, kde se definují externí metody přerušení a příslušným vektorům se pak předá ukazatel na tyto funkce.

        void initHw(){
            //
            // Set the clocking to run directly from the crystal.
            //
            SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
    
            //
            // Initialize the OLED display and write status.
            //
            RIT128x96x4Init(3000000);
    
            //
            // Enable the peripherals used by this example.
            //
            SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
            //butons
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
            //timer
            SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
            //
            // Enable processor interrupts.
            //
            IntMasterEnable();
    
            //
            // Set GPIO A0 and A1 as UART pins.
            //
            GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
            //
            // Configure the UART for 115,200, 8-N-1 operation.
            //
            UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                    UART_CONFIG_PAR_NONE));
    
            //
            // Configure the GPIOs used to read the state of the on-board push buttons.
            //
            GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
            GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    
            GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_1);
            GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    
            //
            // Enable the UART interrupt.
            //
            IntEnable(INT_UART0);
            UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    
    
            // Configure GPIO Block E Pin 2 and 3 to detect a falling edge
            //   (i.e. when the LEFT or RIGHT button is pressed).
            GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_FALLING_EDGE);
            GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_FALLING_EDGE);
    
            // Enable GPIO Port E, Pin 0 - 3 to generate an interrupt
            GPIOPinIntEnable(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
            GPIOPinIntEnable(GPIO_PORTF_BASE, GPIO_PIN_1);
    
    
            // Enable the Interrupt for GPIO block E and F in the NVIC
            IntEnable(INT_GPIOE);
            IntEnable(INT_GPIOF);
    
            //
            // Configure the two 32-bit periodic timers.
            //
            TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
            TimerLoadSet(TIMER0_BASE, TIMER_A, 5 * SysCtlClockGet());
    
            //
            // Setup the interrupts for the timer timeouts.
            //
            IntEnable(INT_TIMER0A);
            TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
            //
            // Enable the timers.
            //
            TimerEnable(TIMER0_BASE, TIMER_A);
    
        }
        

    void printInfo(void) Tato metoda se stará o vypsání informací o přehrávané skladbě na displeji.

        void printInfo(void) {
    
            RIT128x96x4Clear();
            RIT128x96x4StringDraw(song, 2, 10, 13);
            RIT128x96x4StringDraw(artist, 2, 25, 10);
            RIT128x96x4StringDraw(album, 2, 40, 7);
            RIT128x96x4StringDraw(menuStr, 2, 80, 10);
    
        }
        
    void Timer0IntHandler(void) Přerušení od časovače, pošle na PC žádost o zaslání informací o přehrávané skladbě.
        void Timer0IntHandler(void) {
    
            TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
            char message[5];
            strcpy(message, "INFO");
            UARTSend(message, strlen(message));
    
        }    
        

    void ButtonIntHandler(void) Stará se o obsluhu tlačítek. Mění menu na displeji desky, po zmáčknutí příslušného tlačítka se případně odešle příkaz do počítače, že chceme vykonat určitý příkaz. Příkazy se odesílají jako řetězce např. „NEXT_SONG“, „VOLUME_UP“ atd.

        void ButtonIntHandler(void) {
            // Variable for pin status (LEFT or RIGHT)
            long pinStatus;
    
            // Delay for debouncing
            volatile unsigned long delay;
    
            char message[16];
    
            // Wait a bit
            for (delay = 0; delay < 100000; delay++) {
            }
    
            // Read the state again
            pinStatus = (GPIOPinRead(GPIO_PORTE_BASE, (GPIO_PIN_0 | GPIO_PIN_1 |
                    GPIO_PIN_2 | GPIO_PIN_3)) |
                    (GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1) << 3));
    
            // Clear the GPIO interrupt.
            GPIOPinIntClear(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
            GPIOPinIntClear(GPIO_PORTF_BASE, GPIO_PIN_1);
    
    
            switch (pinStatus) {
                case KEY_DOWN_VALUE:
                    strcpy(message, "VOLUME_DOWN");
                    UARTSend(message, strlen(message));
                    break;
    
                case KEY_ENTER_VALUE:
                    //tady se rozhodne, co se odešle
                    switch (menuInt) {
                        case 0:
                            strcpy(message, "NEXT_SONG");
                            UARTSend(message, strlen(message));
                            break;
                        case 1:
                            strcpy(message, "PREVIOUS_SONG");
                            UARTSend(message, strlen(message));
                            break;
                        case 2:
                            strcpy(message, "PAUSE");
                            UARTSend(message, strlen(message));
                            break;
                        case 3:
                            strcpy(message, "PLAY");
                            UARTSend(message, strlen(message));
                            break;
                        default:
                            break;
                    }
                    break;
                case KEY_LEFT_VALUE:
                case KEY_RIGHT_VALUE:
    
                    //pohyb v menu
                    if (pinStatus == KEY_LEFT_VALUE) {
                        menuInt = menuInt - 1;
                        if (menuInt < 0) menuInt = 3;
                    } else {
                        menuInt = menuInt + 1;
                        //MAX položek v menu
                        if (menuInt > 3) menuInt = 0;
                    }
    
                    //vypis polozky
                    switch (menuInt) {
                        case 0:
                            strcpy(menuStr, "Next song");
                            break;
                        case 1:
                            strcpy(menuStr, "Previous song");
                            break;
                        case 2:
                            strcpy(menuStr, "Pause");
                            break;
                        case 3:
                            strcpy(menuStr, "Play");
                            break;
                        default:
                            menuInt = 0;
                            strcpy(menuStr, "Next song");
                            break;
                    }
                    printInfo();
    
    
                    break;
                case KEY_UP_VALUE:
                    strcpy(message, "VOLUME_UP");
                    UARTSend(message, strlen(message));
                    break;
                default:
                    //strcpy(message, "ERROR");
                    break;
            }
        }
        

    void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount) Odeslání bufferu po sériové lince.

        void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount) {
    
            while (ulCount--) {
                UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
            }
        }
        

    void UARTIntHandler(void) Obsluha přerušení od UARTu. Jedná se o přijetí informací o přehrávané skladbě. Informace jsou zasílané jako textový řetězec, kde řídící znaky 0xF3, 0xF6 a 0xF9 odělují informace o skladbě, autorovi a desce.

        void UARTIntHandler(void) {
            unsigned long ulStatus;
    
            char c;
    
            ulStatus = UARTIntStatus(UART0_BASE, true);
    
            UARTIntClear(UART0_BASE, ulStatus);
    
    
            while (UARTCharsAvail(UART0_BASE)) {
    
                c = UARTCharGetNonBlocking(UART0_BASE);
                buf[lenght] = c;
                lenght++;
    
                if (c == 0xF3) {
                    buf[lenght - 1] = '\0';
                    strcpy(song, buf);
                    lenght = 0;
                }
                if (c == 0xF6) {
                    buf[lenght - 1] = '\0';
                    strcpy(artist, buf);
                    lenght = 0;
                }
                if (c == 0xF9) {
                    buf[lenght - 1] = '\0';
                    strcpy(album, buf);
                    lenght = 0;
                    printInfo();
                }
            }
        }
        

    int main(void) Hlavní metoda programu, volá inicializaci zařízení a obsahuje nekonečnou smyčku pro běh programu, jednotlivé události jsou pak obsluhovány v přerušení.

        int main(void) {
    
            initHw();
    
            strcpy(artist, "artist");
            strcpy(song, "song");
            strcpy(album, "album");
    
            printInfo();
            RIT128x96x4StringDraw("Next song", 2, 80, 10);
    
            while (1) {
    
            }
        }
        

    Obslužný prográmek na PC

    link

    Nejedná se o nic zázračného, jde o jednoduché okénko (odděděné od QMainWindow) s pár widgety (QLabel, QComboBox, QPushButton, ...), kde si vybereme příslušný sériový port a připojíme se k němu. Prográmek pak odebírá od desky příkazy a pomocí forku spouští jednotlivé příkazy pro přehrávač. Můžete si stáhnout celý projekt.

    Konstruktor MainWindow(QWidget *parent)

      MainWindow::MainWindow(QWidget *parent) :
          QMainWindow(parent),
          ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
    
          cnt = 0;
          cnt2 = 0;
    
          //info o portech
          slotRefresh();
    
          connect(ui->pushButtonConnect, SIGNAL(clicked()), this, SLOT(nastavVysilac()));
          connect(ui->pushButtonDisconnect, SIGNAL(clicked()), this, SLOT(slotDisconnect()));
          connect(ui->pushButtonRefresh, SIGNAL(clicked()), this, SLOT(slotRefresh()));
      }  
      

    Nastavení sériového portu slotNastavVysilac(). Nastavení příslušné baudové rychlosti, počtu datových a stop bitů a nastavení slotu pro událost readyRead().

      void MainWindow::slotNastavVysilac(){
    
          vysilac = new QextSerialPort(ui->comboBoxVysilac->currentText(), QextSerialPort::EventDriven);
          vysilac->setBaudRate(BAUD115200);
          vysilac->setFlowControl(FLOW_OFF);//FLOW_OFF
          vysilac->setParity(PAR_NONE);
          vysilac->setDataBits(DATA_8);
          vysilac->setStopBits(STOP_1);
    
          int state = vysilac->open(QIODevice::ReadWrite);
          qDebug("vysilac->open() = %d", state);
          if(!vysilac->isOpen()) qDebug("nejde nastavit vysilac");;
    
          connect(vysilac, SIGNAL(readyRead()), this, SLOT(signalizaceDat()));
          connect(vysilac, SIGNAL(readChannelFinished()), this, SLOT(konec()));
    
          ui->pushButtonConnect->setEnabled(false);
          ui->pushButtonRefresh->setEnabled(false);
          ui->pushButtonDisconnect->setEnabled(true);
    
      }
      

    Pokud přichází data přes sériovou linku, je zavolána metoda slotSignalizaceDat() a jsou přečteny do buffru data. Z přečtené zprávy se určí o jaký jde příkaz a do proměnné argum uloží příslušný parametr příkazu mocp, který se bude volat pro přijatý příkaz a zavoláme metodu void provedPrikaz(int cmd, char * cCmd, char * argum), která provede fork a v potomkovi provede příslušný příkaz pro přehrávač.

      void MainWindow::slotSignalizaceDat(){
    
          QByteArray bytes;
          int a = vysilac->bytesAvailable();
    
    
          if(a > 0){
            bytes.resize(a);
            vysilac->read(bytes.data(), bytes.size());
            ui->statusBar->showMessage(bytes.data(), 2000);
          }
    
    
          int cmd = 0;
    
          if(QString::compare(bytes.data(), "VOLUME_DOWN", Qt::CaseSensitive) == 0) cmd = CMD_VOLUME_DOWN;
          else if(QString::compare(bytes.data(), "VOLUME_UP", Qt::CaseSensitive) == 0) cmd = CMD_VOLUME_UP;
          else if(QString::compare(bytes.data(), "NEXT_SONG", Qt::CaseSensitive) == 0) cmd = CMD_NEXT_SONG;
          else if(QString::compare(bytes.data(), "PREVIOUS_SONG", Qt::CaseSensitive) == 0) cmd = CMD_PREVIOUS_SONG;
          else if(QString::compare(bytes.data(), "PAUSE", Qt::CaseSensitive) == 0) cmd = CMD_PAUSE;
          else if(QString::compare(bytes.data(), "PLAY", Qt::CaseSensitive) == 0) cmd = CMD_PLAY;
          else if(QString::compare(bytes.data(), "INFO", Qt::CaseSensitive) == 0) cmd = CMD_INFO;
          else cmd = CMD_NOCMD;
    
          char cCmd[] = "mocp";
          char argum[5];
    
          //argum = "-f";
          switch(cmd){
    
              case CMD_NEXT_SONG:
                                        strcpy(argum, "-f");
                                        break;
    
              case CMD_PREVIOUS_SONG:
                                        strcpy(argum, "-r");
                                        break;
              case CMD_VOLUME_DOWN:
                                        strcpy(argum, "-v-2");
                                        break;
              case CMD_VOLUME_UP:
                                        strcpy(argum, "-v+2");
                                        break;
              case CMD_PLAY:
                                        strcpy(argum, "-U");
                                        break;
              case CMD_PAUSE:
                                        strcpy(argum, "-P");
                                        break;
              case CMD_INFO:
                                        strcpy(argum, "-i");
                                        break;
    
              default:
                                      break;
          }
    
          provedPrikaz(cmd, cCmd, argum);
    
      }
      

    provedPrikaz(int cmd, char * cCmd, char * argum) vytvoření potomka procesu a v něm spustíme příslušný příkaz pro přehrávač. Pokud jde o příkaz, jako je přeskočení skladby nebo zvýšení hlasitosti, zavoláme pouze execlp s příslušnými parametry. Jestli ale zjišťujeme informace o přehrávané skladbě, vytvoříme si soubor vystup.txt, do kterého se nám uloží informace o skladbě. Tento soubor následně otevřeme a na příslušných řádkách vyhledáma informace o skladbě, autorovi a desce. Na řádce se nenachází pouze např. název skladby, ale i text artist:, ten pomocí metody QString::mid(int pos, int len) ořízneme a ponecháme případně 21 znaků. (na displej se jich více nevejde). Informace o skladbě pak odešleme přes sériový port desce, která je zobrazí.

      void MainWindow::provedPrikaz(int cmd, char * cCmd, char * argum){
    
          int soubor;
    
          if(cmd == CMD_INFO) soubor = open("vystup.txt",   O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    
          int status;
          int pid = fork();
          if (pid == -1)
          {  qDebug("Fork selhal !\n");
             exit(-1);
          }
          if (pid == 0)
          {
              // potomek
              if(cmd == CMD_INFO){
                  //přesměrování do souboru
                  //dup2(soubor,1);
    
                  // Redirect standard output
                  if (soubor >= 0) {
                   //close(STDOUT_FILENO);
                   dup2(soubor, STDOUT_FILENO);
                  }
              }
    
              int ret = execlp(cCmd, cCmd, argum, NULL);
              qDebug("ret = %d\n", ret);
    
          }
          else
          {  // rodic
             qDebug("Rodic: Cekam na syna\n");
             int spid = wait(&status);
             if (spid != pid) qDebug("Rodic: To neni muj syn !");
    
             qDebug("Rodic: Uz koncim");
          }
    
    
          if(cmd == CMD_INFO) {
              QFile fileQt("vystup.txt");
              if (!fileQt.open(QIODevice::ReadOnly | QIODevice::Text))
              {
                  ;
              }
    
              QByteArray artist, song, album;
              int radek = 1;
              while (!fileQt.atEnd()) {
                  QByteArray line = fileQt.readLine();
    
                  if(radek == 4) {
                      artist.append(line);
                      artist = artist.mid(8, 21);
                  }
                  if(radek == 5){
                      song.append(line);
                      song = song.mid(11, 21);
                  }
                  if(radek == 6){
                      album.append(line);
                      album = album.mid(7, 21);
                  }
    
                  radek++;
              }
    
              fileQt.close();
    
              QByteArray msg;
              msg.append(song);
              msg.append(0xF3);
              msg.append(artist);
              msg.append(0xF6);
              msg.append(album);
              msg.append(0xF9);
    
              vysilac->write(msg.data(), msg.length());
    
          }
      }
      

    Na posledním obrázku je fotka z nasazení, v terminálu běží OpenOCD server, připojení k OpenOCD servru přes telnet a program pro zachytávání příkazů od desky.

    Linux a MCU Stellaris ARM Cortex-M3

           

    Hodnocení: 100 %

            špatnédobré        

    Nástroje: Tisk bez diskuse

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    26.1.2012 08:33 avzgag
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    nejde nainstalit linux pro arm primo na tu desku? nevim jestli linux jede na cortex-3.
    26.1.2012 09:11 Mark
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Jsou jiste pokusy o portaci Linuxu na Cortex-M[3,4], ale procesory s timto jadrem jsou primarne urcene jako "velke a rychle" MCU == jednocipy s integrovanou SRAM i Flash, proste moderni evoluce Intel 8051. Vetsinou nemaji radice DDR[1,2,3] SDRAM a celkove jsou prilis "male" bez sirokych externich sbernic.
    26.1.2012 09:38 avzgag
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    dik za info, ja ty rozdily mezi cortex-3 a napr. cortex-7 neznam. cortex-7 je myslim na linux pripraven, nebo cortex-9, ne?
    26.1.2012 11:17 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Miešate jedno cez druhé. Jadro Cortex je nové jadro od ARM, konkrétne ho ARM označuje ako verzia č. 7 svojho jadra. Toto jadro má 3 "edície": M, R a A, každá edícia má vlastný set jadrových periférií, čím vznikajú jadrá Cortex-M0 až M4, Cortex-A5 až A15, Cortex R (neviem presne, dá sa dohľadať). Každá edícia je primárne určená na iný trh: M- microcontroller, A- multimedia application, R- signal processing. Jadrá Cortex Mx nemajú MMU a preto nemožno linux na ne nasadiť, jedine uClinux.
    26.1.2012 23:59 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Hmm podle TI @50MHz, to by možná zvládlo přehrát mptrojku samo :-D.

    BTW obrázek desky (vedle blokovýho) nejde.
    vlastikroot avatar 27.1.2012 08:26 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Proc, kdyz se k tomu da pripojit HW dekoder ...
    We will destroys the Christian's legion ... and the cross, will be inverted
    28.1.2012 00:46 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Já jen poukazuju na to, jak jsou dneska uC výkonný.
    29.1.2012 22:25 JZD | skóre: 15 | blog: Na_dvorku
    Rozbalit Rozbalit vše Re: Linux a MCU Stellaris ARM Cortex-M3
    Druhý obrázek nejde otevřít. Chyba Error 500.
    Víra znamená vyznávat to, o čem člověk dobře ví, že to není pravda. Mlčeti platina, mluviti v gajzu, býti v hajzlu.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.