Auf feste Adresse im embedded Linux Schreiben

OP #3646335
Lesenswert?

Hallo,

Ich versuche in einen embedded Linux auf einen ARROW SoCkit auf eine 
feste Adresse (0x00010080) zu schreiben. Um eine virtuelle Adresse mit 
der gewünschten Adresse zu erstellen nutze ich mmap. Leider habe ich im 
bereich speicher zugriff unter Linux nicht viel erfahrungen...

Schreibe im mit folgenden Code auf die Adresse?
1
#include "hwlib.h"
2
#include "socal/socal.h"
3
#include "socal/hps.h"
4
#include "socal/alt_gpio.h"
5
#include "system.h"
6

7

8
int main(){
9
  void *virtual_base;
10
  void *adresse = 0x00010080;
11
  unsigned int fd;
12
  unsigned int in = 0xFFFF9FFF;
13
  unsigned int out;
14
  if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) {
15
    printf( "ERROR: could not open \"/dev/mem\"...\n" );
16
    return( 1 );
17
  }
18

19
  virtual_base = mmap( adresse, 32, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd , 0 );
20

21
  if( virtual_base == MAP_FAILED ) {
22
    printf( "ERROR: mmap() failed...\n" );
23
    close( fd );
24
    return( 1 );
25
  }
26

27
  alt_write_word( virtual_base, in );
28

29
  out = alt_read_word(virtual_base);
30
  printf("%i wurde zurueckgegeben!!",out);
31
  return 0;
32
}
Gast #3646389
Lesenswert?

Damit ein mmap Erfolg hat, muss etwas zum 'mmap'en da sein.
Z.B. durch ein malloc.
1
  // Allocate MAP block
2
  if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
3
    printf("allocation error \n");
4
    exit (-1);
5
  }
6

7
  // Make sure pointer is on 4K boundary
8
  if ((unsigned long)gpio_mem % PAGE_SIZE)
9
    gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
10

11
  // Now map it
12
  gpio_map = (unsigned char *)mmap(
13
    (caddr_t)gpio_mem,
14
    BLOCK_SIZE,
15
    PROT_READ|PROT_WRITE,
16
    MAP_SHARED|MAP_FIXED,
17
    mem_fd,
18
    GPIO_BASE
19
    );
20

21
  if ((long)gpio_map < 0) {
22
    printf("mmap error %d\n", (int)gpio_map);
23
    exit (-1);
24
  }
OP #3646408
Lesenswert?

Ok jetzt habe ich mmap ein bisschen mehr verstanden.
ich habe die zeile mit mmap() auf

virtual_base = mmap( NULL , 32, ( PROT_READ | PROT_WRITE ), MAP_SHARED, 
fd , 0x00010080 );

geändert. Jetzt gibt mit mmap den Fehler zurück :(
Der speicherbereich müsste durch den ersten Übergabewert, der jetzt NULL 
ist, den Speicherberich reservieren.
#3646538
Lesenswert?

1. Der Speicher wird immer ein Vielfaches einer Kachelgröße gemappt.
D.h. du wirst nicht irgendeine physikalische an irgendeine beliebige 
Adresse mappen können, sondern nur seitenweise.
Also erst überlegen, in welcher Seite die gesuchte Adresse ist, dann 
mappen.
2. Du musst entsprechend vorher für die gemappte Seite Speicher 
allokieren.
3. Siehe man mmap
OP #3646642
Lesenswert?

Es Funktioniert jetzt :)
Der Code sieht jetzt so aus:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <unistd.h>
4
#include <fcntl.h>
5
#include <sys/mman.h>
6
#include <errno.h>
7
#include <string.h>
8
#include "hwlib.h"
9
#include "socal/socal.h"
10
#include "socal/hps.h"
11
#include "socal/alt_gpio.h"
12
#include "system.h"
13

14

15

16
int main(){
17
  void *virtual_base;
18
  unsigned int offset = 0x00010080;
19

20
  unsigned int fd;
21
  unsigned int in = 0xFFFFFFFF;
22
  unsigned int out;
23
  unsigned int i = 0;
24
  off_t base = 0xff200000;
25

26

27

28
  if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) {
29
    printf( "ERROR: could not open \"/dev/mem\"...\n" );
30
    return( 1 );
31
  }
32

33
  virtual_base = mmap( NULL , 2000000, PROT_WRITE , MAP_SHARED, fd , base );
34

35
  if( virtual_base == MAP_FAILED ) {
36
    printf( "ERROR: mmap() failed...\n" );
37
    close( fd );
38
    printf("%s\n", strerror(errno));
39
    return( 1 );
40
  }
41

42
  alt_write_word( virtual_base + offset, in );
43

44
  for(i = 0;i<=1000;i++){
45
    i--;
46
    i++;
47
  }
48
  out = alt_read_word(virtual_base);
49
  printf("%i wurde zurueckgegeben!!",out);
50
  return 0;
51
}
OP #3646709
Lesenswert?

So (Florian H.) habe ich es in den beschreibungen für malloc auch 
verstanden. Gibt man als ersten Übergabewert eine NULL an, wird ein 
freier Speicherbereich der angegeben Größe alloziiert.
Im Anhang befindet sich der Adressaufbau des Mikrocontrollers und ich 
kann mit meinen Programm mit den Lightweight FPGA Slaves kommunizieren 
(3 LEDs an der FPGA Peripherie einschalten).
Angehängte Dateien:
Gast #3646759
Lesenswert?

> Unsinn. Im Gegenteil verwenden einige Betriebssysteme mmap um Speicher
> für malloc zu alloziieren.

mmap hat ja auch deutlich mehr als nur 1 Parameter.

Mein Schnipsel weiter oben funktionierte jedenfalls von Anfang an...
Du darfst das aber gerne weiter als Unsinn qualifizieren...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren