Բարի օր Մենք նախագծում ենք
Qt-ը միջպլատֆորմային շրջանակ է, որը ներառում է ոչ միայն գրաֆիկական բաղադրիչներ, այլ նաև այնպիսի բաներ, ինչպիսիք են QtNetwork-ը, տվյալների բազաների հետ աշխատելու համար նախատեսված դասերի հավաքածու, Qt ավտոմատացման համար (ներառյալ IoT ներդրման համար) և շատ ավելին: Qt թիմը ակտիվ է եղել Qt-ն ներկառուցված համակարգերում օգտագործելու հարցում, ուստի գրադարանները բավականին կարգավորելի են: Այնուամենայնիվ, մինչև վերջերս քչերն էին մտածում Qt-ը միկրոկարգավորիչներ տեղափոխելու մասին, հավանաբար այն պատճառով, որ նման առաջադրանքը դժվար է թվում. Qt-ը մեծ է, MCU-ները փոքր են:
Մյուս կողմից, այս պահին կան միկրոկոնտրոլերներ, որոնք նախատեսված են մուլտիմեդիայի հետ աշխատելու համար և գերազանցում են առաջին Pentium-ներին: Մոտ մեկ տարի առաջ հայտնվեց Qt բլոգը
Qt 4.8-ը երկար ժամանակ տեղափոխված է Embox-ում, ուստի մենք որոշեցինք փորձել այն դրա վրա: Մենք ընտրեցինք moveblocks հավելվածը՝ զսպանակավոր անիմացիայի օրինակ։
Qt-ը շարժվում է QEMU-ում
Սկզբից մենք կարգավորում ենք Qt-ը, հնարավորության դեպքում, անիմացիան աջակցելու համար անհրաժեշտ բաղադրիչների նվազագույն փաթեթով: Դրա համար կա «-qconfig նվազագույն, փոքր, միջին...» տարբերակ: Այն միացնում է Qt-ից կազմաձևման ֆայլը բազմաթիվ մակրոների հետ՝ ինչ միացնել/ինչ անջատել: Այս տարբերակից հետո մենք այլ դրոշակներ ենք ավելացնում կոնֆիգուրացիայի մեջ, եթե ցանկանում ենք այլ բան անջատել: Ահա մեր օրինակը
Որպեսզի Qt-ն աշխատի, դուք պետք է ավելացնեք ՕՀ-ի համատեղելիության շերտ: Ճանապարհներից մեկը QPA-ի (Qt Platform Abstraction) ներդրումն է: Մենք հիմք ենք ընդունել Qt-ում ներառված պատրաստի fb_base փլագինը, որի հիման վրա աշխատում է QPA-ն Linux-ի համար։ Արդյունքը փոքր փլագին է, որը կոչվում է emboxfb, որը Qt-ին տրամադրում է Embox-ի շրջանակային բուֆեր, այնուհետև այն նկարում է այնտեղ՝ առանց որևէ արտաքին օգնության:
Ահա թե ինչ տեսք ունի plugin ստեղծելը
QEmboxFbIntegration::QEmboxFbIntegration()
: fontDb(new QGenericUnixFontDatabase())
{
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
const char *fbPath = "/dev/fb0";
fbFd = open(fbPath, O_RDWR);
if (fbPath < 0) {
qFatal("QEmboxFbIntegration: Error open framebuffer %s", fbPath);
}
if (ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo) == -1) {
qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
}
if (ioctl(fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
}
fbWidth = vinfo.xres;
fbHeight = vinfo.yres;
fbBytesPerLine = finfo.line_length;
fbSize = fbBytesPerLine * fbHeight;
fbFormat = vinfo.fmt;
fbData = (uint8_t *)mmap(0, fbSize, PROT_READ | PROT_WRITE,
MAP_SHARED, fbFd, 0);
if (fbData == MAP_FAILED) {
qFatal("QEmboxFbIntegration: Error mmap framebuffer %s", fbPath);
}
if (!fbData || !fbSize) {
qFatal("QEmboxFbIntegration: Wrong framebuffer: base = %p,"
"size=%d", fbData, fbSize);
}
mPrimaryScreen = new QEmboxFbScreen(fbData, fbWidth,
fbHeight, fbBytesPerLine,
emboxFbFormatToQImageFormat(fbFormat));
mPrimaryScreen->setPhysicalSize(QSize(fbWidth, fbHeight));
mScreens.append(mPrimaryScreen);
this->printFbInfo();
}
Եվ ահա թե ինչ տեսք կունենա վերագծագրումը
QRegion QEmboxFbScreen::doRedraw()
{
QVector<QRect> rects;
QRegion touched = QFbScreen::doRedraw();
DPRINTF("QEmboxFbScreen::doRedrawn");
if (!compositePainter) {
compositePainter = new QPainter(mFbScreenImage);
}
rects = touched.rects();
for (int i = 0; i < rects.size(); i++) {
compositePainter->drawImage(rects[i], *mScreenImage, rects[i]);
}
return touched;
}
Արդյունքում, երբ միացված է հիշողության չափի համար կոմպիլյատորների օպտիմալացում -Os, գրադարանի պատկերը ստացվեց 3.5 ՄԲ, ինչը, իհարկե, չի տեղավորվում STM32F746-ի հիմնական հիշողության մեջ: Ինչպես արդեն գրել ենք OpenCV-ի մասին մեր մյուս հոդվածում, այս տախտակն ունի.
- 1 ՄԲ ROM
- 320 KB RAM
- 8 ՄԲ SDRAM
- 16 ՄԲ QSPI
Քանի որ QSPI-ից կոդի կատարման աջակցությունն արդեն ավելացվել է OpenCV-ին, մենք որոշեցինք սկսել՝ բեռնելով ողջ Embox c Qt պատկերը QSPI-ում: Եվ արագ, ամեն ինչ սկսվեց գրեթե անմիջապես QSPI-ից: Բայց ինչպես OpenCV-ի դեպքում, այնպես էլ պարզվեց, որ այն չափազանց դանդաղ է աշխատում։
Հետևաբար, մենք որոշեցինք դա անել այսպես. նախ պատճենում ենք պատկերը QSPI-ում, այնուհետև բեռնում ենք այն SDRAM-ում և կատարում այնտեղից: SDRAM-ից այն դարձավ մի փոքր ավելի արագ, բայց դեռ հեռու է QEMU-ից:
Այնուհետև միտք եղավ ներառել լողացող կետ. ի վերջո, Qt-ն անում է անիմացիայի մեջ քառակուսիների կոորդինատների որոշ հաշվարկներ: Փորձեցինք, բայց այստեղ տեսանելի արագացում չստացանք, թեև ներս
Ամենաարդյունավետ գաղափարը Framebuffer-ը SDRAM-ից ներքին հիշողություն տեղափոխելն էր: Դա անելու համար մենք էկրանի չափերը դարձրեցինք ոչ թե 480x272, այլ 272x272: Մենք նաև իջեցրեցինք գույնի խորությունը A8R8G8B8-ից մինչև R5G6B5՝ այդպիսով մեկ պիքսելի չափը 4-ից նվազեցնելով 2 բայթի: Ստացված շրջանակի բուֆերի չափը 272 * 272 * 2 = 147968 բայթ է: Սա զգալի արագացում տվեց, թերևս առավել նկատելի էր, որ անիմացիան գրեթե հարթ դարձավ:
Վերջին օպտիմիզացումը եղել է Embox կոդը RAM-ից, իսկ Qt կոդը SDRAM-ից գործարկելը: Դա անելու համար մենք նախ, ինչպես միշտ, ստատիկ կերպով կապում ենք Embox-ը Qt-ի հետ, բայց գրադարանի տեքստը, rodata-ն, տվյալները և bss հատվածները տեղադրում ենք QSPI-ում, որպեսզի այն պատճենենք այն SDRAM-ում:
section (qt_text, SDRAM, QSPI)
phdr (qt_text, PT_LOAD, FLAGS(5))
section (qt_rodata, SDRAM, QSPI)
phdr (qt_rodata, PT_LOAD, FLAGS(5))
section (qt_data, SDRAM, QSPI)
phdr (qt_data, PT_LOAD, FLAGS(6))
section (qt_bss, SDRAM, QSPI)
phdr (qt_bss, PT_LOAD, FLAGS(6))
ROM-ից Embox կոդը գործարկելով՝ մենք նաև նկատելի արագացում ստացանք։ Արդյունքում անիմացիան բավականին հարթ ստացվեց.
Հենց վերջում, հոդվածը պատրաստելիս և Embox-ի տարբեր կոնֆիգուրացիաներ փորձելիս, պարզվեց, որ Qt moveblocks-ը հիանալի է աշխատում QSPI-ից՝ SDRAM-ի շրջանակային բուֆերով, և շեղը հենց շրջանակի չափն էր: Ըստ երևույթին, նախնական «սլայդշոուն» հաղթահարելու համար բավարար էր 2 անգամ արագացումը՝ շրջանակային բուֆերի չափի սովորական նվազման պատճառով: Բայց միայն Embox կոդը տարբեր արագ հիշողություններ փոխանցելով (արագացումը ոչ թե 2, այլ մոտ 1.5 անգամ էր) հնարավոր չէր հասնել նման արդյունքի։
Ինչպես փորձել ինքներդ
Եթե դուք ունեք STM32F7-Discovery, կարող եք ինքներդ գործարկել Qt-ը Embox-ի տակ: Դուք կարող եք կարդալ, թե ինչպես է դա արվում մեր կայքում
Ամփոփում
Արդյունքում մեզ հաջողվեց գործարկել Qt! Առաջադրանքի բարդությունը, մեր կարծիքով, որոշ չափով չափազանցված է։ Բնականաբար, դուք պետք է հաշվի առնեք միկրոկոնտրոլերների առանձնահատկությունները և ընդհանուր առմամբ հասկանաք համակարգչային համակարգերի ճարտարապետությունը: Օպտիմալացման արդյունքները մատնանշում են այն հայտնի փաստը, որ հաշվողական համակարգի խոչընդոտը ոչ թե պրոցեսորն է, այլ հիշողությունը:
Այս տարի մենք մասնակցելու ենք փառատոնին
Source: www.habr.com