Monthly Archives: April 2011 - Page 2

GPIO/LEDアクセスプログラム

Pandaboard 向けのソフトをまだ何も書いていなかったので、とりあえず GPIO/LED 等にアクセスするプログラムを作ってみた。

Source code

main.c

・int ReadGPIO(int gpioNum)
  GPIO の gpioNum 番の値を戻す。
・int ReadBoardRevision(void)
  3bit の BoardRevision を ReadGPIO() で読み、Revision 番号を戻す。

・int PrintBoardRevision(void)
  Revision 番号から、Revision 文字列に変換して表示。
・int PrintRegulatorItem(int index, const char* name)
  電源 Regulator の単一プロパティを表示。
・int PrintRegulator(void)
  電源 Regulator の name, microvolts プロパティを表示。

・int CopyLED1to2(void)
  デフォルトでハートビートのように点滅している LED1 の値を LED2 にコピー。
  無限ループを止めるのは ctrl-c。
・int CleanupLED2(void)
  無限ループから抜けた後のお掃除。
・int CopyLED(void)
  LED1 の値を LED2 にコピーする一連の動作を行う。
  CopyLED1to2 を呼ぶのは 30msec 毎。
・void SigHandler(int sigNum)
  ctrl-c のハンドラ。
・コンパイルは:
  gcc -Wall -o PandaTest main.c

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
 
#define	GPIO_NUM_BOARD_ID2	(171)
#define	GPIO_NUM_BOARD_ID1	(101)
#define	GPIO_NUM_BOARD_ID0	(182)
 
static volatile sig_atomic_t exit_flag = 0;
 
int ReadGPIO(int gpioNum)
{
	const char* fmt = "/sys/class/gpio/gpio%d/value";
	char str[64];
	char buf;
	int num_read;
	int rtn = -1;
	int fd;
 
	sprintf(str, fmt, gpioNum);
	fd = open(str, O_RDONLY);
	if(fd)
	{
		num_read = read(fd, &buf, sizeof(char));
		rtn = (num_read != 1) ? num_read:(buf-'0');
		close(fd);
	}
	return rtn;
}
 
int ReadBoardRevision(void)
{
	int boardRev = 0;
	const int gpio_num_tbl[] = {	GPIO_NUM_BOARD_ID2
				,	GPIO_NUM_BOARD_ID1
				,	GPIO_NUM_BOARD_ID0	};
	size_t i;
 
	for(i=0; i<sizeof(gpio_num_tbl)/sizeof(gpio_num_tbl[0]); ++i)
	{
		boardRev *= 2;
		boardRev += ReadGPIO(gpio_num_tbl[i]);
	}
	return boardRev;
}
 
int PrintBoardRevision(void)
{
	int rtn = 0;
	const char* board_rev_tbl[] = {	"(obsolete)"
				,	"EA1"
				,	"(reserved)"
				,	"A1"
				,	"(reserved)"	};
	size_t board_rev_tbl_size = sizeof(board_rev_tbl)/sizeof(board_rev_tbl[0]);
 
	int boardRev = ReadBoardRevision();
	if(board_rev_tbl_size <= boardRev)
	{
		boardRev = board_rev_tbl_size - 1;
		rtn = -1;
	}
	printf(" - Pandaboard Revision: %s\n", board_rev_tbl[boardRev]);
	return rtn;
}
 
int PrintRegulatorItem(int index, const char* name)
{
	const char* fmt = "/sys/class/regulator/regulator.%d/%s";
	char str[64];
	char buf[16];
	int num_read;
	int fd;
 
	if(7 < index)	return -1;
 
	sprintf(str, fmt, index, name);
	fd = open(str, O_RDONLY);
	if(fd)
	{
		num_read = read(fd, buf, sizeof(buf));
		buf[num_read] = 0;
		printf("     %s: %s", name, buf);
		close(fd);
	}
	return 0;
}
 
int PrintRegulator(void)
{
	int i;
 
	printf(" - Pandaboard Regulator\n");
	for(i=0; i<8; ++i)
	{
		printf("    #%d:\n", i);
		PrintRegulatorItem(i, "name");
		PrintRegulatorItem(i, "microvolts");
	}
	return 0;
}
 
int CopyLED1to2(void)
{
	const char* str_src = "/sys/class/leds/pandaboard::status1/brightness";
	const char* str_dst = "/sys/class/leds/pandaboard::status2/brightness";
	char buf[16];
	int num_read, num_write;
	int fd_src, fd_dst;
 
	fd_src = open(str_src, O_RDONLY);
	fd_dst = open(str_dst, O_WRONLY);
 
	if(fd_src && fd_dst)
	{
		num_read = read(fd_src, buf, sizeof(buf));
		buf[num_read] = 0;
		num_write = write(fd_dst, buf, num_read);
	}
	if(fd_dst)	close(fd_dst);
	if(fd_src)	close(fd_src);
	return 0;
}
 
int CleanupLED2(void)
{
	const char* str_dst = "/sys/class/leds/pandaboard::status2/brightness";
	const char* buf = "0";
	int fd_dst;
	int num_write;
 
	fd_dst = open(str_dst, O_WRONLY);
	if(fd_dst)
	{
		num_write = write(fd_dst, buf, 1);
		close(fd_dst);
	}
	return 0;
}
 
int CopyLED(void)
{
	printf(" - Copy Status LED1 to LED2 (press ctrl-c to exit)\n");
	system("sudo chmod 666 /sys/class/leds/pandaboard::status2/brightness");
	while(!exit_flag)
	{
		CopyLED1to2();
		usleep(30*1000);
	}
	CleanupLED2();
	system("sudo chmod 644 /sys/class/leds/pandaboard::status2/brightness");
	printf("\n");
	return 0;
}
 
void SigHandler(int sigNum)
{
	exit_flag = 1;
}
 
int main(int argc, char* argv[])
{
	signal(SIGINT, SigHandler);
 
	PrintBoardRevision();
	PrintRegulator();
	CopyLED();
 
	return 0;
}

Results of execution

・Copy Status LED1 to LED2 表示時に sudo のパスワードを聞かれたら、入力する。
・その後 LED2 が LED1 と同期して点滅を開始する。
・止めるのは ctrl-c。

$ ./PandaTest 
 - Pandaboard Revision: A1
 - Pandaboard Regulator
    #0:
     name: VMMC
     microvolts: 3000000
    #1:
     name: VPP
     microvolts: 1900000
    #2:
     name: VANA
     microvolts: 2100000
    #3:
     name: VCXIO
     microvolts: 1800000
    #4:
     name: VDAC
     microvolts: 1800000
    #5:
     name: VUSB
     microvolts: 3300000
    #6:
     name: VAUX2_6030
     microvolts: 1800000
    #7:
     name: VAUX3_6030
     microvolts: 1200000
 - Copy Status LED1 to LED2 (press ctrl-c to exit)
^C
$