mmap liefert anderes Ergebnis als unter C

Antworten
Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

mmap liefert anderes Ergebnis als unter C

Beitrag von Socke »

Hallo zusammen,

ich versuche die GPIO-Pins des Raspberry Pis per direktem Speicherzugriff zu ändern. Ein entsprechendes Beispiel in C findet man unter http://elinux.org/RPi_Low-level_peripherals#C_2 Dieses funktioniert auch an sich (Software läuft, nicht getestet, ob die Pins wirklich geschaltet werden).
Mein Port auf Pascal kann dabei nicht die Datei /dev/mem per fpmmap in den Speicher mappen. Das Ergebnis ist immer $FFFFFFFF (MAP_FAILED) und als ErrNo erhalte ich 22 (Invalid Argument). Die Datei /dev/mem kann geöffnet werden, als Dateihandle erhalte ich z.B. 5 zurück.

Ich habe auch schon die anderen Konstanten überprüft. Das C-Programm kommt auf die gleichen Werte wie mein Pascal-Programm. Daher die Fragen: Was mache ich falsch? Selbst der Aufruf von mmap() aus der libc ändert Nichts am Ergebnis.

Ausschnitt des Originals

Code: Alles auswählen

#define BCM2708_PERI_BASE        0x20000000
#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
 
void setup_io()
{
   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      exit(-1);
   }
 
   /* mmap GPIO */
   gpio_map = mmap(
      NULL,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
   );
 
   close(mem_fd); //No need to keep mem_fd open after mmap
 
   if (gpio_map == MAP_FAILED) {
      printf("mmap error %d\n", (int)gpio_map);//errno also set!
      exit(-1);
   }
 
   // Always use volatile pointer!
   gpio = (volatile unsigned *)gpio_map;
} // setup_io


Ausschnitt der Pascal-Portierung

Code: Alles auswählen

const
  BCM2708_PERI_BASE = $20000000;
  GPIO_BASE         = (BCM2708_PERI_BASE + $200000); // GPIO controller
  PAGE_SIZE         = (4*1024);
  BLOCK_SIZE        = (4*1024);
 
var
  mem_fd: cint = 0;
  gpio_map: Pointer = nil;
  gpio: PPtrUInt = nil;     
 
procedure setup_io();
begin
  // open /dev/mem
  mem_fd := FpOpen('/dev/mem', O_RDWR OR O_SYNC);
  if (mem_fd < 0) then
    raise EFOpenError.CreateFmt(SFOpenError, ['/dev/mem']);
  try
    // mmap GPIO
    gpio_map := Fpmmap(
      nil,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ OR PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
    );
 
    if (gpio_map = MAP_FAILED) then
       raise EOSError.CreateFmt('mmap error %d.', [fpgeterrno]);//errno also set!
  finally
    FpClose(mem_fd); //No need to keep mem_fd open after mmap
  end;
  gpio := gpio_map;
end; // setup_io   
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten