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