#include <stdio.h> #include <stdlib.h> #define rGPFCON (*(volatile unsigned *)0x56000050) //Port F control #define rGPFDAT (*(volatile unsigned *)0x56000054) //Port F data int main() { volatile unsigned *ptr_control=(volatile unsigned *)rGPFCON; volatile unsigned *ptr_data=(volatile unsigned *)rGPFDAT; int ex=1; unsigned char led_state=0; *ptr_control=0; *ptr_data=0; while(ex!=0) { *ptr_control=(*ptr_control)|(1<<14); printf("turn led on or off? ON(1),OFF(0)\n"); scanf("%c",&led_state); *ptr_data=(*ptr_data)|(led_state<<7); printf("exit?yes(0),no(1)"); scanf("%d",&ex); } return 0; } im getting Segmentation fault on the mini2440 when i run it. on my notebook i compiled it with arm-linux-gcc then i used file command: arkady_ilan_rozbaum@ubuntu:~/led1$ file led2 led2: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, not stripped as you can see it is for ARM,as i said once i copy it to the mini using diskonkey (i copy it to the mini i don't run it throw the diskonkey) i get the segmentation fault. also im just a beginner and my code may not be the best but as you can see it basically is supposed to turn one led on or off.
Segmentation fault?
Try running a simple Hello program first to check your build system, then move on to the more serious stuff.
Did you try to run your program on the Mini2440 from within Linux? If yes, search in the web how to handle "memory protection" on an operation system like Linux. Other keywords are "virtual address space", "MMU (Memory Managamenet Unit)" and the "mmap()" system call.
yes davef i did run the hello world. also updated the code to this: #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #define rGPFCON (*(volatile unsigned *)0x56000050) //Port F control #define rGPFDAT (*(volatile unsigned *)0x56000054) //Port F data #define rGPFUP (*(volatile unsigned *)0x56000058) //Pull-up control F int main() { printf("%d,zero on sucess\n",mprotect((unsigned *)0x56000050,12,PROT_WRITE|PROT_READ)); printf("printf0\n"); fflush(stdout); rGPFCON=0x55aa;//all outputs printf("printf1\n"); fflush(stdout); rGPFDAT=0x56ae;//no pull up rGPFDAT=0xf0;//all leds are on printf("printf2\n"); fflush(stdout); int ex=1; unsigned char led_state=0; while(ex!=0) { printf("turn led on or off? ON(1),OFF(0)\n"); scanf("%c",&led_state); rGPFDAT|=(led_state<<7); printf("exit?yes(0),no(1)"); scanf("%d",&ex); } return 0; } but mprotect returns -1 so it doesnt succed,any ideas?
You can't access the hardware in the way you try it. The operating system prevents you from doing so. You need to be root and to re-map the IO address space into the virtual address space of your process to get access to it. You should read first some basic concepts, how current operating systems are working and how they do their memory management and protection.
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; char* mem_ptr; fd=open("/dev/leds",O_RDWR); if(fd==-1)//open returns -1 if fails,else open returns handle of open file { printf("cant open the file\n "); return 0; } mem_ptr=mmap(0,10,PROT_READ|PROT_WRITE,MAP_FILE | MAP_SHARED,fd,10); printf("mem_ptr points to 0x%lX.\n",(unsigned long) mem_ptr); close(fd); return 0; } ive read that i should first make the os let me use the addresses i want to,can you tell me why i get: mem_ptr points to 0xFFFFFFFF. this makes no sense to me since i know that: #define rGPFCON (*(volatile unsigned *)0x56000050) //Port F control #define rGPFDAT (*(volatile unsigned *)0x56000054) //Port F data shouldnt it be like: mem_ptr points to 0x56000050 ? is /dev/leds the right file? ------------------------------------------------ 1.how can i make sure im the root on the mini2440 console? it doesnt have sudo su command like in ubuntu. 2.would i be right saying the adresses i need to remap are: 0x56000050 to 0x56000060 (if including pull up)?
> can you tell me why i get: mem_ptr points to 0xFFFFFFFF $ man mmap > 1.how can i make sure im the root on the mini2440 console? You should google how Linux manages users. > 2.would i be right saying the adresses i need to remap are 0x56000050 to 0x56000060 You should try with '/dev/mem' and this address-space instead. On the other hand: why do you want to access the hardware in this way? It's the job of kernel drivers, not a userland program.
directly accessing addresses seems most natural to me. im trying it this way cuz i want to know how to do it this way,ill probably learn the way you would do it afterwards,im just a beginner and im also an electronics engineer my knowledge of programing,os and so on isnt from college and its as you can see really poor atm im trying,but its hard for me to know what is related and what isnt. could you by any chance give me an example of how to do what i want so i can see it working and then find the right read about it,knowing what im looking for,you may say this way i wont learn it but i think i would and spend the gained time on learning something new.
1. rule: never use the physical address anymore 2. rule: always map the physical address to the virtual first 3. rule: do all accesses only via the virtual address 4. rule: better let the operating handle the details 5. rule: do not do hardware access from userland And here an example how to do hardware access from userland. Never do it in this way in real life ;) #include <sys/mman.h> #define PHYSICAL_ADDRESS 0x56000000 #define PHYSICAL_ADDRESS_SIZE 0x00001000 volatile uint32_t *reg; int fd; fd = open("/dev/mem", O_RDWR); reg = mmap(NULL, PHYSICAL_ADDRESS_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, PHYSICAL_ADDRESS); printf("Content of 0x56000060 is %x\n", *(reg + 0x18)); /* change the 0x56000050 register content */ *(reg + 0x14) = 0xaa551122; munmap(reg, PHYSICAL_ADDRESS_SIZE);
Hi everybody. Like nemka, I need to access physical memory. I connect a IC to the external bus interface and want to monitor and access its registers. All the way you say end with segmentation fault!
Juergen Beisert thank you. i had my finals so i wasnt able to do anything else including this. it works great id be happy to know what is the right way to do this. MSH if you could give more details about your issue id help you.
Hello, I realized that running code to modify registers and compiling it from within linux creates problems, so I used an IDE (CodeBlocks) and built it. It is pretty similar to nemka's code, and I included all the required libraries and source files describing the various registers. But on compiling it, it is again giving a segmentation fault while running on the mini2440. I had thought that working with an IDE would remove the memory protection problems. I don't know exactly how to go about mapping physical addresses : do you run a code which does this for you? Could someone give me some idea of what to do further?
> I had thought that working with an IDE would remove the > memory protection problems. Funny. What let you think so? Memory protection is an OS security feature.