1. /dev/mem - это устр-во или device
2. Вы на пол пути к истине, а именно вы сказали:
который отображаеться
Вам нужно пробросить адреса которые отображаются в устро-ве в вашу программу тобишь в user space. тобишь в пространство пользователя, при помощи mmap.
Ведь что такое Адрес регистра
$FFFFF800 правильно адрес в линейной памяти проца АРМ. в устр-ве /dev/mem они отображены также линейно. А вы работаете (ну не вы а ваша программа) со страничной памятью.. итого вам для адреса регистра нужно для программы построить страницы (отобразить из устр-ва в программу) через которую можно писать уже в регистр.. писать я думаю вы уже поняли через указатель и смещение от-но него

Замечание: - проброс в большинстве случаев нужно делать от адреса кратным странице Linux-а а это 4 Кбайта. Тобишь вы не сможете сделать mmap скажем с адреса $FFFFF803.. нужно будет отобразить кратный адрес, получить указатель на него и сместиться и бла бла бла...
Короче долго это писать вот код, он делает проброс GPIO - а если быть точным всего устр-ва GPIO для проца AM37xx от TI. (omap3) ну и в цикле дергает ногой
Код на Си, но я думаю все прозрачно:- Код: Выделить всё
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#define OMAP24XX_BASE_ADDRES_PER_CM 0x48005000
// omap2+ PER_CM Register Summary
#define CM_FCLKEN_PER 0x0000
#define CM_ICLKEN_PER 0x0010
#define CM_IDLEST_PER 0x0020
#define CM_AUTOIDLE_PER 0x0030
#define CM_CLKSEL_PER 0x0040
#define CM_SLEEPDEP_PER 0x0044
#define CM_CLKSTCTRL_PER 0x0048
#define CM_CLKSTST_PER 0x004C
#define OMAP24XX_BASE_ADDRES_GPIO1 0x48310000
#define OMAP24XX_BASE_ADDRES_GPIO2 0x49050000
#define OMAP24XX_BASE_ADDRES_GPIO3 0x49052000
#define OMAP24XX_BASE_ADDRES_GPIO4 0x49054000
#define OMAP24XX_BASE_ADDRES_GPIO5 0x49056000
#define OMAP24XX_BASE_ADDRES_GPIO6 0x49058000
// omap2+ specific GPIO registers
#define OMAP24XX_GPIO_REVISION 0x0000
#define OMAP24XX_GPIO_SYSCONFIG 0x0010
#define OMAP24XX_GPIO_SYSSTATUS 0x0014
#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
#define OMAP24XX_GPIO_IRQENABLE2 0x002c
#define OMAP24XX_GPIO_IRQENABLE1 0x001c
#define OMAP24XX_GPIO_WAKE_EN 0x0020
#define OMAP24XX_GPIO_CTRL 0x0030
#define OMAP24XX_GPIO_OE 0x0034
#define OMAP24XX_GPIO_DATAIN 0x0038
#define OMAP24XX_GPIO_DATAOUT 0x003c
#define OMAP24XX_GPIO_LEVELDETECT0 0x0040
#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
#define OMAP24XX_GPIO_RISINGDETECT 0x0048
#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050
#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054
#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
#define OMAP24XX_GPIO_SETWKUENA 0x0084
#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
#define GPIO_MAP_SIZE 4096
#define PIN_MASK ( (1<<16) | (1<<17) )
struct OMAP3_GPIO{
/// Register Name Type Offset
unsigned int Revision; // R 0x000
unsigned char Reserv0[12]; // R 0x004
unsigned int SysConfig; // RW 0x010
unsigned int SysStatus; // R 0x014
unsigned int IrqStatus1; // RW 0x018
unsigned int IrqEnable1; // RW 0x01C
unsigned int WakeUpEnable; // RW 0x020
unsigned char Reserv1[4]; // R 0x024
unsigned int IrqStatus2; // RW 0x028
unsigned int IrqEnable2; // RW 0x02C
unsigned int Ctrl; // RW 0x030
unsigned int OE; // RW 0x034
unsigned int DataIN; // R 0x038
unsigned int DataOUT; // RW 0x03C
unsigned int LevelDetect0; // RW 0x040
unsigned int LevelDetect1; // RW 0x044
unsigned int RisingDetect; // RW 0x048
unsigned int FallingDetect; // RW 0x04C
unsigned int DebouncEnable; // RW 0x050
unsigned int DebouncingTime; // RW 0x054
unsigned char Reserv2[8]; // R 0x058
unsigned int ClearIrqEnable1; // RW 0x060
unsigned int SetIrqEnable1; // RW 0x064
unsigned char Reserv3[8]; // R 0x068
unsigned int ClearIrqEnable2; // RW 0x070
unsigned int SetIrqEnable2; // RW 0x074
unsigned char Reserv4[8]; // R 0x078
unsigned int ClearWKUENA; // RW 0x080
unsigned int SetWKUENA; // RW 0x084
unsigned char Reserv5[8]; // R 0x088
unsigned int ClearDataOUT; // RW 0x090
unsigned int SetDataOUT; // RW 0x094
};
int Enable_Clk_GPIO3(void)
{
int fd;
void *mapped_base;
fd = open("/dev/mem", O_RDWR);
if( fd < 0 )
{
printf("Cannot open /dev/mem.\n");
exit(EXIT_FAILURE);
}
printf("/dev/mem opened.\n");
mapped_base = mmap(0, GPIO_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, OMAP24XX_BASE_ADDRES_PER_CM);
if (mapped_base == MAP_FAILED)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}
printf("Memory block mapped at address %p.\n", mapped_base);
unsigned int old_val = *(int *)(mapped_base + CM_FCLKEN_PER);
printf("CM_FCLKEN_PER = 0x%x \n", old_val);
*(int *)(mapped_base + CM_FCLKEN_PER) = old_val | (1 << 14);
old_val = *(int *)(mapped_base + CM_ICLKEN_PER);
*(int *)(mapped_base + CM_ICLKEN_PER) = old_val | (1 << 14);
printf("CM_ICLKEN_PER = 0x%x \n", *(int *)(mapped_base + CM_ICLKEN_PER));
close(fd);
}
int main(void)
{
int fd;
struct OMAP3_GPIO *GPIO3_Reg;
fd = open("/dev/mem", O_RDWR);
if( fd < 0 )
{
printf("Cannot open /dev/mem.\n");
exit(EXIT_FAILURE);
}
printf("/dev/mem opened.\n");
GPIO3_Reg = mmap(0, sizeof(struct OMAP3_GPIO), PROT_READ | PROT_WRITE, MAP_SHARED, fd, OMAP24XX_BASE_ADDRES_GPIO3);
if (GPIO3_Reg == MAP_FAILED)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}
printf("Memory block mapped at address %p.\n", GPIO3_Reg);
printf("OMAP24XX_GPIO_OE = 0x%x \n", GPIO3_Reg->OE);
unsigned int old_val = GPIO3_Reg->OE;
GPIO3_Reg->OE = ( old_val & ~(1<< 17) ) ;
printf("SYSCONFIG = 0x%x \n", GPIO3_Reg->SysConfig);
printf("SYSSTATUS = 0x%x \n", GPIO3_Reg->SysStatus);
printf("OMAP24XX_GPIO_WAKE_EN = 0x%x \n", GPIO3_Reg->WakeUpEnable);
printf("OMAP24XX_GPIO_IRQENABLE1 = 0x%x \n", GPIO3_Reg->IrqEnable1);
printf("OMAP24XX_GPIO_IRQENABLE2 = 0x%x \n", GPIO3_Reg->IrqEnable2);
int val=0;
while (1)
{
val = !val;
if (val)
{
GPIO3_Reg->SetDataOUT = (1 << 17); // PIN_MASK;
printf("Set \n");
}
else
{
GPIO3_Reg->ClearDataOUT = (1 << 17);//PIN_MASK;
printf("Clear \n");
}
printf("DATAOUT = 0x%x \n", GPIO3_Reg->DataOUT);
sleep (1);
}
return 0;
}