Skip to content

Commit 45df440

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 61eefb3 commit 45df440

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
@@ -48,14 +48,33 @@ may be helpful.
4848

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

5354
## Getting started without hardware
5455

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

60+
## Application config
61+
62+
`Circuits.I2C` supports the following application environment keys:
63+
64+
| Key | Description |
65+
| --- | ----------- |
66+
| `:include_i2c_dev` | Set to `true` or `false` to indicate whether or not to include the `Circuits.I2C.I2CDev` backend. |
67+
| `: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. |
68+
69+
`Circuits.I2C` uses a heuristic for the default values of both
70+
`:include_i2c_dev`. For example, if the `:default_backend` is set to
71+
`Circuits.I2C.I2CDev`, then `:include_i2c_dev` has to be `true`. If
72+
`:default_backend` is set to something else, then `:include_i2c_dev` defaults to
73+
`false`. If neither is set, then `Circuits.I2C.I2CDev` is built. On non-Linux
74+
platforms, the `Circuits.I2C.I2CDev` NIF will be compiled in test mode which
75+
minimally supports unit testing. Mocking is generally a better option for most
76+
users, though.
77+
5978
## I2C background
6079

6180
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
@@ -28,7 +28,7 @@ SPDX-FileCopyrightText = "2014 Frank Hunleth"
2828
SPDX-License-Identifier = "CC-BY-4.0"
2929

3030
[[annotations]]
31-
path = ["c_src/linux/i2c-dev.h"]
31+
path = ["i2c_dev/c_src/linux/i2c-dev.h"]
3232
precedence = "aggregate"
3333
SPDX-FileCopyrightText = "None"
3434
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)