⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio_test.c

📁 利用开发板上的/dev/mem设备,进行内存映射,驱动cpu的GPIO口,点亮和熄灭led灯.附makefile文件
💻 C
字号:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <unistd.h>

void  *mapDirectIoRegister(unsigned long addr, size_t length);
int    iounmap(volatile void *start, size_t length);
void   sysLedSet(unsigned char value);

#define MAP_SIZE                        4096UL
#define MAP_MASK                        (MAP_SIZE - 1)	//4095
#define HCU3_LED_REGISTER               0xEF600700

volatile unsigned long *ledRegister;
#define __PPC4xx__
#ifdef __PPC4xx__
inline void out_32(volatile unsigned long *addr, unsigned val)
{
        __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" 
(val));
}
/* etc., cf asm/io.h */
#else
extern inline void out_32(volatile unsigned long *addr, unsigned val)
{ * which shows you how to use PPC assembler code to ensure correct IO 
ordering.

        *addr = val & 0xff;
}
#endif

void  *mapDirectIoRegister(unsigned long addr, size_t length)
{
	void *map_base, * virtAddr;
	off_t target = ((unsigned int) addr) & ~MAP_MASK;	//off_t就是int类型; MAP_MASK=4095UL=> ~MAP_MASK=0xFFFFF000UL
	int fd;
        
	if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)	//打开内存文件(驱动)
	{
		printf("/dev/mem could not be opened.\n");
		exit(1);
	}
        
	// Map one page
	map_base = mmap((void *)target, length, PROT_READ | PROT_WRITE, MAP_SHARED,fd, target);
	if(map_base == (void *) -1)
	{
		printf("Memory map failed for address 0x%lx\n", addr);
		return map_base;
	}
        
	virtAddr = (void *) ((unsigned long)map_base + ( (unsigned long)addr & MAP_MASK));	//基地址+偏移量
	printf("Memory map 0x%lx -> %p offset 0x%lx virtual %p\n", addr, map_base,addr & MAP_MASK, virtAddr);
	//输出:Memory map 0xef600700 -> 0x30001000 offset 0x700 virtual 0x30001700
	return virtAddr;
}

int iounmap(volatile void *start, size_t length)
{
	unsigned long ofs_addr;
	ofs_addr = (unsigned long)start & (getpagesize()-1);
        
	 /* do some cleanup when you're done with it */
	return munmap((void*)start-ofs_addr, length+ofs_addr);
}

void sysLedSet(unsigned char value)
{
	/* For obscure HW reasons, we have to negated it and shift the value 23 bits to the left  */
	*ledRegister = (( unsigned long ) ~value <<23) ;
	out_32(ledRegister, ( unsigned long ) ~value <<23 );
}

int main (int argc, char *argv[])
{
	unsigned char j;
	printf("%s: %s %s\n", __FUNCTION__, __DATE__, __TIME__ );	//输出main: Feb  9 2007 18:13:55 
        
	/* HW initialisation */
	ledRegister = (unsigned long *)mapDirectIoRegister(HCU3_LED_REGISTER, MAP_SIZE);	//MAP_SIZE=4096UL
	//上面一行输出:Memory map 0xef600700 -> 0x30001000 offset 0x700 virtual 0x30001700
	/* next we set the correct control mask in the GPIO_TCR */
	
	//ledRegister[1]  = 0x7ffe0000; /* Three State Control */
  
	/* Now scroll our leds and pause a little bit between */
	/*for (j=0; j < 8; j++)
	{
		sleep(1);
		printf(".");
		fflush(stdout);
		sysLedSet(1 << j);
	}*/

	*ledRegister  =  0x7fffffff;
	//out_32(ledRegister, 0x7fffffff );

	sleep(1);

	*ledRegister  = 0x0;
	//out_32(ledRegister, 0x0 );

	iounmap((volatile void *)HCU3_LED_REGISTER, MAP_SIZE);
	printf("\n%s:done\n", __FUNCTION__);	//输出:main:done
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -