Accesso diretto al framebuffer di Linux - copyarea
-
06-07-2019 - |
Domanda
Voglio spostare molto rapidamente un rettangolo su un framebuffer in un'applicazione Linux incorporata. Ho scoperto che la funzione cfb_copyarea
può essere utile. Ma non riesco a trovare alcun ioctl sul dispositivo / dev / fb per chiamare la funzione. O questa funzione può essere chiamata direttamente?
Soluzione 3
Per quanto ne so dopo alcuni giorni di ricerche, non esiste alcun ioctl per invocare questa funzione. Devo scrivere la mia chiamata di sistema preferibilmente in un modulo del kernel. Oppure copia l'algoritmo dal sorgente del kernel e usalo nello spazio utente tramite memoria nmaped.
Altri suggerimenti
Ecco un codice per avviare e chiudere FrameBuffer
class CFrameBuffer
{
void* m_FrameBuffer;
struct fb_fix_screeninfo m_FixInfo;
struct fb_var_screeninfo m_VarInfo;
int m_FBFD;
int InitFB()
{
int iFrameBufferSize;
/* Open the framebuffer device in read write */
m_FBFD = open(FB_NAME, O_RDWR);
if (m_FBFD < 0) {
printf("Unable to open %s.\n", FB_NAME);
return 1;
}
/* Do Ioctl. Retrieve fixed screen info. */
if (ioctl(m_FBFD, FBIOGET_FSCREENINFO, &m_FixInfo) < 0) {
printf("get fixed screen info failed: %s\n",
strerror(errno));
close(m_FBFD);
return 1;
}
/* Do Ioctl. Get the variable screen info. */
if (ioctl(m_FBFD, FBIOGET_VSCREENINFO, &m_VarInfo) < 0) {
printf("Unable to retrieve variable screen info: %s\n",
strerror(errno));
close(m_FBFD);
return 1;
}
/* Calculate the size to mmap */
iFrameBufferSize = m_FixInfo.line_length * m_VarInfo.yres;
printf("Line length %d\n", m_FixInfo.line_length);
/* Now mmap the framebuffer. */
m_FrameBuffer = mmap(NULL, iFrameBufferSize, PROT_READ | PROT_WRITE,
MAP_SHARED, m_FBFD,0);
if (m_FrameBuffer == NULL) {
printf("mmap failed:\n");
close(m_FBFD);
return 1;
}
return 0;
}
void CloseFB()
{
munmap(m_FrameBuffer,0);
close(m_FBFD);
}
};
Nota che questo codice non è del tutto corretto, anche se funzionerà su molti dispositivi Linux, su alcuni non lo farà. Per calcolare la dimensione del framebuffer, non procedere come segue:
iFrameBufferSize = m_FixInfo.line_length * m_VarInfo.yres;
Invece, fai questo:
iFrameBufferSize = m_FixInfo.smem_len;
E il tuo codice sarà più portabile.