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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.