Skip to content

Commit 597d64f

Browse files
committed
Support builds that completely exclude I2CDev support
This removes both the Elixir module and the NIF. There's no longer any unintended NIF builds or loads or anything extra. To enable this, either set the `:default_backend` application environment key or force it by setting `:include_i2c_dev`. Most users probably want: ```elixir config :circuits_i2c, default_backend: MyI2CBackend ```
1 parent 869c576 commit 597d64f

File tree

11 files changed

+102
-36
lines changed

11 files changed

+102
-36
lines changed

.formatter.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Used by "mix format"
22
[
3-
inputs: ["{mix,.formatter,.credo}.exs", "{config,lib,test}/**/*.{ex,exs}"]
3+
inputs: ["{mix,.formatter,.credo}.exs", "{config,i2c_dev,lib,test}/**/*.{ex,exs}"]
44
]

Makefile

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# Variables to override:
1515
#
1616
# MIX_APP_PATH path to the build directory
17-
# CIRCUITS_I2C_I2CDEV Backend to build - `"normal"`, `"test"`, or `"disabled"` will build a NIF
17+
# CIRCUITS_I2C_I2CDEV Backend to build - `"normal"` or `"test"`
1818
#
1919
# CC C compiler
2020
# CROSSCOMPILE crosscompiler prefix, if any
@@ -30,7 +30,7 @@ BUILD = $(MIX_APP_PATH)/obj
3030

3131
NIF = $(PREFIX)/i2c_nif.so
3232

33-
SRC = c_src/i2c_nif.c
33+
SRC = i2c_dev/c_src/i2c_nif.c
3434
CFLAGS ?= -O2 -Wall -Wextra -Wno-unused-parameter -pedantic
3535

3636
# Check that we're on a supported build platform
@@ -40,7 +40,7 @@ ifeq ($(shell uname -s),Linux)
4040
CFLAGS += -fPIC
4141
LDFLAGS += -fPIC -shared
4242
else
43-
CFLAGS += -Ic_src/compat
43+
CFLAGS += -Ii2c_dev/c_src/compat
4444
LDFLAGS += -undefined dynamic_lookup -dynamiclib
4545
ifeq ($(CIRCUITS_I2C_I2CDEV),normal)
4646
$(error Circuits.I2C Linux I2CDev backend is not supported on non-Linux platforms. Review circuits_i2c backend configuration or report an issue if improperly detected.)
@@ -59,17 +59,16 @@ ifeq ($(CIRCUITS_I2C_I2CDEV),test)
5959
# Stub out ioctls and send back test data
6060
CFLAGS += -DTEST_BACKEND
6161
else
62-
# Don't build NIF
63-
NIF =
62+
$(error Invalid CIRCUITS_I2C_I2CDEV value: $(CIRCUITS_I2C_I2CDEV))
6463
endif
6564
endif
6665

6766
# Set Erlang-specific compile and linker flags
6867
ERL_CFLAGS ?= -I"$(ERL_EI_INCLUDE_DIR)"
6968
ERL_LDFLAGS ?= -L"$(ERL_EI_LIBDIR)" -lei
7069

71-
HEADERS =$(wildcard c_src/*.h)
72-
OBJ = $(SRC:c_src/%.c=$(BUILD)/%.o)
70+
HEADERS =$(wildcard i2c_dev/c_src/*.h)
71+
OBJ = $(SRC:i2c_dev/c_src/%.c=$(BUILD)/%.o)
7372

7473
calling_from_make:
7574
mix compile
@@ -80,7 +79,7 @@ install: $(PREFIX) $(BUILD) $(NIF)
8079

8180
$(OBJ): $(HEADERS) Makefile
8281

83-
$(BUILD)/%.o: c_src/%.c
82+
$(BUILD)/%.o: i2c_dev/c_src/%.c
8483
@echo " CC $(notdir $@)"
8584
$(CC) -c $(ERL_CFLAGS) $(CFLAGS) -o $@ $<
8685

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,33 @@ may be helpful.
5353

5454
Internally, it uses the [Linux "i2c-dev"
5555
interface](https://elixir.bootlin.com/linux/latest/source/Documentation/i2c/dev-interface)
56-
so that it does not require board-dependent code.
56+
so that it does not require board-dependent code. See the application
57+
configuration for disabling all things Linux/Nerves specific.
5758

5859
## Getting started without hardware
5960

6061
If you don't have any real I2C devices, it's possible to work with simulated
6162
devices. See the [CircuitsSim](https://github.com/elixir-circuits/circuits_sim)
6263
project for details.
6364

65+
## Application config
66+
67+
`Circuits.I2C` supports the following application environment keys:
68+
69+
| Key | Description |
70+
| --- | ----------- |
71+
| `:include_i2c_dev` | Set to `true` or `false` to indicate whether or not to include the `Circuits.I2C.I2CDev` backend. |
72+
| `:default_backend` | Default I2C backend to use when unspecified in API calls. The format is either a module name or a `{module_name, options}` tuple. |
73+
74+
`Circuits.I2C` uses a heuristic for the default values of both
75+
`:include_i2c_dev`. For example, if the `:default_backend` is set to
76+
`Circuits.I2C.I2CDev`, then `:include_i2c_dev` has to be `true`. If
77+
`:default_backend` is set to something else, then `:include_i2c_dev` defaults to
78+
`false`. If neither is set, then `Circuits.I2C.I2CDev` is built. On non-Linux
79+
platforms, the `Circuits.I2C.I2CDev` NIF will be compiled in test mode which
80+
minimally supports unit testing. Mocking is generally a better option for most
81+
users, though.
82+
6483
## I2C background
6584

6685
An [Inter-Integrated Circuit](https://en.wikipedia.org/wiki/I%C2%B2C) (I2C) bus

REUSE.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ SPDX-FileCopyrightText = "None"
1717
SPDX-License-Identifier = "CC0-1.0"
1818

1919
[[annotations]]
20-
path = ["c_src/linux/i2c-dev.h"]
20+
path = ["i2c_dev/c_src/linux/i2c-dev.h"]
2121
precedence = "aggregate"
2222
SPDX-FileCopyrightText = "None"
2323
SPDX-License-Identifier = "GPL-2.0-or-later WITH Linux-syscall-note"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

lib/i2c/nil_backend.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ defmodule Circuits.I2C.NilBackend do
99
@behaviour Circuits.I2C.Backend
1010

1111
alias Circuits.I2C.Backend
12+
alias Circuits.I2C.Bus
13+
14+
defstruct []
1215

1316
@doc """
1417
Return the I2C bus names on this system
@@ -35,4 +38,27 @@ defmodule Circuits.I2C.NilBackend do
3538
def info() do
3639
%{name: __MODULE__}
3740
end
41+
42+
defimpl Bus do
43+
@impl Bus
44+
def flags(%Circuits.I2C.NilBackend{}), do: []
45+
46+
@impl Bus
47+
def read(%Circuits.I2C.NilBackend{}, _address, _count, _options) do
48+
{:error, :unimplemented}
49+
end
50+
51+
@impl Bus
52+
def write(%Circuits.I2C.NilBackend{}, _address, _data, _options) do
53+
{:error, :unimplemented}
54+
end
55+
56+
@impl Bus
57+
def write_read(%Circuits.I2C.NilBackend{}, _address, _write_data, _read_count, _options) do
58+
{:error, :unimplemented}
59+
end
60+
61+
@impl Bus
62+
def close(%Circuits.I2C.NilBackend{}), do: :ok
63+
end
3864
end

0 commit comments

Comments
 (0)