für Kernel Profis, hardware register lesen/schreibe
-
Hallo
ich habe folgendes Problem,
ich soll von einem am335x Register auslesen und beschreiben
und zwar 3 so genannte Scratch Register aus dem RTCSSich verwende die selbe Adresse und offset zum lesen und schreiben,
einmal im user space via mmap
und einmal als kernel modul, wo ich die Adresse via ioremap einbindebeide schreiben und lesen, scheinen zu funktionieren
nur nicht das selbe,
was ich mit dem Kernel modul lese und schreibe ist nicht das selbe wie die mmap variante
daher ist mindestens eine Variante falsch, und ich denke es ist mein Treiber
da ich für die mmap Variante diesen Code verwende
https://github.com/viralsachde/devicedbgwenn ioremap, welches ich mit der 0x44E3E000 und gröesse 4096UL
(lt spruh73g.pdf, AM335x docu)
nicht funktioniert,
wie komm ich dann an die Register Werte?und wenn ich nicht in die Scratch register schreibe, wohin schreib ich dann?
danke für die Hilfe
-
niemand?
vielleicht und hoffentlich hilft etwas Code,warum lesen die beiden nicht den selben Speicher
ist der Treiber falsch, das Kontroll Programm, oder beides?mmap code
/* * spruh73g.pdf * page 153, memory map * RTCSS 0x44E3_E000 - 0x44E3_EFFF 4KB RTC Registers * * page 3615, 20.3.5 RTC Registers * 60h RTC_SCRATCH0_REG Scratch 0 Register * 64h RTC_SCRATCH1_REG Scratch 1 Register * 68h RTC_SCRATCH2_REG Scratch 2 Register * */ #define MAP_SIZE 4096UL #define RTCSSMEM 0x44E3E000 typedef struct scratchreg { int value [ 3 ]; } scratchreg; int read_scratchreg( scratchreg* sr ) { int fd = 0; void* memmap; void* scratch_addr; int offset = 0x60 ; fd = open("/dev/mem", O_RDWR | O_SYNC) ; if(fd == -1) { return -1; } memmap = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, RTCSSMEM ); if(memmap == (void *) -1) { close(fd); return -1; } scratch_addr = (unsigned int*)memmap + (offset ); memcpy( &sr->value[0], scratch_addr, sizeof(sr->value)); munmap(memmap, MAP_SIZE) ; close(fd); return 0; }
Kernel Code
#define RTCSSMEM 0x44E3E000 #define SCRATCHREG_OFFSET 0x60 #define SCRATCHREG_SIZE 12 // in inti this happes .. //request_mem_region( RTCSSMEM + SCRATCHREG_OFFSET, SCRATCHREG_SIZE, "scratchdev" ) ; //scratchreg = ioremap_nocache( RTCSSMEM + SCRATCHREG_OFFSET, SCRATCHREG_SIZE) ; static ssize_t scratchdev_read(struct file *f, char __user *buf, size_t len, loff_t *off) { int i; u8 byte; if (*off >= SCRATCHREG_SIZE) { return 0 ; } if (*off + len > SCRATCHREG_SIZE) { len = SCRATCHREG_SIZE - *off; } for (i = 0; i < len; i++) { byte = ioread8((u8 *)scratchreg + i); if (copy_to_user(buf + i, &byte, 1)) { return -EFAULT; } } *off += len; return len; }
-
erledigt,
in der mmap Versionscratch_addr = (unsigned int*)memmap + (offset );
muss
scratch_addr = memmap + (offset );
was aber ein warning gibt, bei -pedantic
und ich glaub ich wechsel dann rüber ins C Forum und frag dort warum und wie ich das trotzt -Wall -Wextra -pedantic ohne Wanrung kompilieren kann.
-
Wenn du "Zeiger plus Integer" (Offset = x) rechnest, wird der Zeiger nicht (zwingend) um x Bytes verschoben, sondern um x Einheiten des Types vom Zeiger. Bei einem 32bit Integer also um 4x Bytes.
Das Problem hier: void ist kein echter Typ der eine Größe hat. Deshalb warnt pedantic.
Wenn Offset in Bytes ist, sollte der Zeiger am Besten ein char sein.
-
danke,
habs, auch auf Empfehlungen im C Forum, noch mal nach gelesen