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 RTCSS

    ich 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 einbinde

    beide 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/devicedbg

    wenn 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 Version

    scratch_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


Log in to reply