Linux I2C例程应用层读写

Linux应用——I2C通信例程

背景需求

两块板子通过I2C连接,其中一块为Master角色,一块为Slave角色,可以实现双方的相互通信,包括传输文件。

本文描述Master角色的编码。

需求:

  • 可以指定Slave地址
  • 可以指定传输文件块大小
  • 可以指定传输每个数据块间隔
  • 可以指定I2C的端口名称

实现设计

  • 读取命令行参数
  • 初始化参数后,依照参数向I2C设备写入数据,并尝试读取一段定长的数据

文件组织

文件名 文件描述 备注
main.c 判断传入参数,并实现调用I2C读写接口
i2c.c I2C初始化、读写接口实现
util.c 其他接口
typedef.h 数据类型定义
log.h 日志接口头文件

代码

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

#include "i2c.h"
#include "util.h"

static void usage(const char *program)
{
   
    if (NULL == program) {
   
        return;
    }

	printf("Usage: %s [OPTION]\n"
            "\n"
			"  -h, --help\n"
			"  -f, --file        file to send\n"
			"  -a, --address     i2c slave address (0x%02X by default)\n"
			"  -b, --block       transfer block size (%dB by default)\n"
			"  -d, --delay       transfer delay us (%dus by default)\n"
			"  -p, --port        i2c port name (%s by default)\n",
            program, DFT_I2C_SLAVE_ADDR, MAX_DFU_PKT, DFT_I2C_INTERVAL, DFT_I2C_PORT);
}

static bool read_dfu_file(char *optarg, DFU *dfu)
{
   
    if (NULL == optarg || NULL == dfu) {
   
        return false;
    }

    dfu->file = fopen(optarg, "rb");
    if (NULL == dfu->file) {
   
        print("fail to open %s", optarg);
        return false;
    }

    if (fseek(dfu->file, 0L, SEEK_END)) {
   
        goto error;
    }

    dfu->total = dfu->toload = ftell(dfu->file);
    if (fseek(dfu->file, 0L, SEEK_SET)) {
   
        goto error;
    }

    return true;

error:
    fclose(dfu->file);
    return false;
}

static void check_param(I2C_CTX *i2c, DFU *dfu)
{
   
    if (NULL == i2c || NULL == dfu) {
   
        return;
    }

    if (NULL == dfu->file) {
   
        print("No file to transfer...");
        exit(EXIT_FAILURE);
    }

    if (dfu->blk_size < 1 || dfu->blk_size > MAX_DFU_PKT) {
   
        dfu->blk_size = MAX_DFU_PKT;
    }

    if (dfu->delay_us < 1 || dfu->delay_us > (DFT_I2C_INTERVAL << 2)) {
   
        dfu->delay_us = DFT_I2C_INTERVAL;
    }

    if (i2c->port[0] == '\0') {
   
        strncpy(i2c->port, DFT_I2C_PORT, FILE_SIZE);
    }

    if (i2c->slave_addr == 0x00) {
   
        i2c->slave_addr = DFT_I2C_SLAVE_ADDR;
    }

    /* master ----> slave, address right shift */
    i2c->slave_addr >>= 1;

    i2c->fd = i2c_dev_init(i2c);
    if (i2c->fd <= 0) {
   
        print("fail to init i2c device:%s", i2c->port);
        exit(EXIT_FAILURE);
    }

    print("\n\nI2C port:%s\nslave address:0x%02X\nblock size:%d B\ninterval:%d us\n",
            i2c->port, i2c->slave_addr, dfu->blk_size, dfu->delay_us);
}

static void init(int argc, char *argv[], I2C_CTX *i2c, DFU *dfu)
{
   
    int opt = 0;
    int opt_idx = 0;
    const char *short_opts = "ha:p:f:b:d:";
    const struct option long_opts[] = {
   
        {
   "help", no_argument, 0, 'h'},
        {
   "address", required_argument, 0, 'a'},
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值