Selamat siang Kami berada dalam proyek ini
Qt adalah kerangka kerja lintas platform yang tidak hanya mencakup komponen grafis, tetapi juga hal-hal seperti QtNetwork, sekumpulan kelas untuk bekerja dengan database, Qt untuk Otomatisasi (termasuk untuk implementasi IoT) dan banyak lagi. Tim Qt telah proaktif dalam menggunakan Qt dalam sistem tertanam, sehingga perpustakaannya cukup dapat dikonfigurasi. Namun, hingga saat ini, hanya sedikit orang yang berpikir untuk mem-porting Qt ke mikrokontroler, mungkin karena tugas seperti itu tampaknya sulit - Qt besar, MCU kecil.
Di sisi lain, saat ini terdapat mikrokontroler yang dirancang untuk bekerja dengan multimedia dan lebih unggul dari Pentium pertama. Sekitar setahun yang lalu, blog Qt muncul
Qt 4.8 telah lama di-porting ke Embox, jadi kami memutuskan untuk mencobanya. Kami memilih aplikasi moveblocks - contoh animasi kenyal.
Qt memindahkan blok di QEMU
Untuk memulainya, kami mengonfigurasi Qt, jika memungkinkan, dengan kumpulan komponen minimum yang diperlukan untuk mendukung animasi. Untuk ini ada opsi β-qconfig minimal,small,mediumβ¦β. Ini menghubungkan file konfigurasi dari Qt dengan banyak makro - apa yang diaktifkan / apa yang dinonaktifkan. Setelah opsi ini, kami menambahkan tanda lain ke konfigurasi jika kami ingin menonaktifkan yang lain. Ini adalah contoh kami
Agar Qt berfungsi, Anda perlu menambahkan lapisan kompatibilitas OS. Salah satu caranya adalah dengan menerapkan QPA (Qt Platform Abstraksi). Kami mengambil sebagai dasar plugin fb_base siap pakai yang disertakan dalam Qt, yang menjadi dasar kerja QPA untuk Linux. Hasilnya adalah sebuah plugin kecil bernama emboxfb, yang menyediakan Qt dengan framebuffer Embox, dan kemudian menariknya ke sana tanpa bantuan dari luar.
Seperti inilah tampilan pembuatan 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();
}
Dan seperti inilah gambaran ulangnya
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;
}
Hasilnya, ketika optimasi kompiler untuk ukuran memori -Os diaktifkan, gambar perpustakaan menjadi 3.5 MB, yang tentu saja tidak sesuai dengan memori utama STM32F746. Seperti yang sudah kami tulis di artikel kami yang lain tentang OpenCV, board ini memiliki:
- ROM 1 MB
- RAM 320KB
- 8MB SDRAM
- 16MB QSPI
Karena dukungan untuk mengeksekusi kode dari QSPI telah ditambahkan ke OpenCV, kami memutuskan untuk memulai dengan memuat seluruh gambar Embox c Qt ke QSPI. Dan hore, semuanya dimulai segera dari QSPI! Namun seperti halnya OpenCV, ternyata kerjanya terlalu lambat.
Oleh karena itu, kami memutuskan untuk melakukannya dengan cara ini - pertama kami menyalin gambar ke QSPI, lalu memuatnya ke SDRAM dan menjalankannya dari sana. Dari SDRAM menjadi sedikit lebih cepat, namun masih jauh dari QEMU.
Selanjutnya, ada ide untuk memasukkan floating point - lagipula, Qt melakukan beberapa perhitungan koordinat kotak dalam animasi. Kami mencobanya, tetapi di sini kami tidak mendapatkan akselerasi yang terlihat, meskipun masuk
Ide paling efektif adalah memindahkan framebuffer dari SDRAM ke memori internal. Untuk melakukan ini, kami membuat dimensi layar bukan 480x272, tetapi 272x272. Kami juga menurunkan kedalaman warna dari A8R8G8B8 ke R5G6B5, sehingga mengurangi ukuran satu piksel dari 4 menjadi 2 byte. Ukuran framebuffer yang dihasilkan adalah 272*272*2 = 147968 bytes. Hal ini memberikan akselerasi yang signifikan, mungkin yang paling terasa, animasinya menjadi hampir mulus.
Optimasi terbaru adalah menjalankan kode Embox dari RAM dan kode Qt dari SDRAM. Untuk melakukan ini, pertama-tama kita, seperti biasa, menghubungkan Embox secara statis dengan Qt, tetapi kita menempatkan segmen teks, rodata, data dan bss dari perpustakaan di QSPI untuk kemudian menyalinnya ke 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))
Dengan menjalankan kode Embox dari ROM, kami juga menerima akselerasi yang nyata. Hasilnya, animasinya menjadi cukup mulus:
Pada akhirnya, saat menyiapkan artikel dan mencoba konfigurasi Embox yang berbeda, ternyata moveblock Qt berfungsi dengan baik dari QSPI dengan framebuffer di SDRAM, dan hambatannya justru pada ukuran framebuffer! Rupanya, untuk mengatasi "slideshow" awal, akselerasi 2 kali lipat sudah cukup karena pengurangan ukuran framebuffer. Namun hasil seperti itu tidak dapat dicapai hanya dengan mentransfer kode Embox ke berbagai memori cepat (percepatannya bukan 2, tetapi sekitar 1.5 kali).
Cara mencobanya sendiri
Jika Anda memiliki STM32F7-Discovery, Anda dapat menjalankan sendiri Qt di bawah Embox. Anda dapat membaca bagaimana hal ini dilakukan di kami
Kesimpulan
Hasilnya, kami berhasil meluncurkan Qt! Kompleksitas tugas ini, menurut kami, agak dilebih-lebihkan. Tentu saja, Anda perlu mempertimbangkan spesifikasi mikrokontroler dan secara umum memahami arsitektur sistem komputer. Hasil optimasi menunjukkan fakta yang diketahui bahwa hambatan dalam sistem komputasi bukanlah prosesor, tetapi memori.
Tahun ini kami akan berpartisipasi dalam festival tersebut
Sumber: www.habr.com