在友善之臂的EEPROM的示例程序中看到有一些不一样的地方,使用了__LINE__这样的预编译宏。而且其用法也是比较好,使得主程序简洁明了。所以就学习了一下。
-
#include <stdio.h>
-
#include <fcntl.h>
-
#include <getopt.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <errno.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include "24cXX.h"
-
-
#define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);//__LINE__编译后输出所在行,使用宏定义好处:编译器会确定所在行
-
void do_usage_if(int b, int line)
-
{
-
const static char *eeprog_usage =
-
"I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n"
-
"FriendlyARM Computer Tech. 2009\n"
-
"Usage: -r/-w\n";
-
if(!b)
-
return;
-
fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);
-
exit(1);
-
}
-
-
-
#define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);//退出信息输出,同样使用了__LINE__信息
-
void do_die_if(int b, char* msg, int line)
-
{
-
if(!b)
-
return;
-
fprintf(stderr, "Error at line %d: %s\n", line, msg);
-
fprintf(stderr, " sysmsg: %s\n", strerror(errno));
-
exit(1);
-
}
-
-
-
static int read_from_eeprom(struct eeprom *e, int addr, int size)
-
{
-
int ch, i;
-
for(i = 0; i < size; ++i, ++addr)
-
{
-
die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");
-
if( (i % 16) == 0 )
-
printf("\n %.4x| ", addr);
-
else if( (i % 8) == 0 )
-
printf(" ");
-
printf("%.2x ", ch);
-
fflush(stdout);
-
}
-
fprintf(stderr, "\n\n");
-
return 0;
-
}
-
-
static int write_to_eeprom(struct eeprom *e, int addr)
-
{
-
int i;
-
for(i=0, addr=0; i<256; i++, addr++)
-
{
-
if( (i % 16) == 0 )
-
printf("\n %.4x| ", addr);
-
else if( (i % 8) == 0 )
-
printf(" ");
-
printf("%.2x ", i);
-
fflush(stdout);
-
die_if(eeprom_write_byte(e, addr, i), "write error");
-
}
-
fprintf(stderr, "\n\n");
-
return 0;
-
}
-
-
int main(int argc, char** argv)
-
{
-
struct eeprom e;
-
int op;
-
-
op = 0;
-
-
usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0');
-
op = argv[1][1];
-
-
fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");
-
die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0, //若打开错误
-
"unable to open eeprom device file "
-
"(check that the file exists and that it's readable)");
-
switch(op)
-
{
-
case 'r':
-
fprintf(stderr, " Reading 256 bytes from 0x0\n");
-
read_from_eeprom(&e, 0, 256);
-
break;
-
case 'w':
-
fprintf(stderr, " Writing 0x00-0xff into 24C08 \n");
-
write_to_eeprom(&e, 0);
-
break;
-
default:
-
usage_if(1);
-
exit(1);
-
}
-
eeprom_close(&e);
-
-
return 0;
-
}
主要是集中在两个函数上
void do_usage_if(int b, int line)
void do_die_if(int b, char* msg, int line)
并且使用了宏定义,使得___LINE__对应使用的地方替换成对应所在行号
扩展学习
ANSI标准说明了C中的五个预定义的宏名。它们是:
__FILE__ 包含当前程序文件名的字符串
__LINE__ 表示当前行号的整数
__DATE__ 包含当前日期的字符串
__STDC__ 如果编译器遵循ANSI C标准,它就是个非零值
__TIME__ 包含当前时间的字符串
注意,是双下划线,而不是单下划线 。
如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
阅读(1038) | 评论(0) | 转发(0) |