Supporting observation that newly created Kconfig causes the above multiple undefined symbols errors, when I set aside the Kconfig in project directory blink-plus-uart the error count goes to one. Only the symbol I referenced for the new sensor driver is undefined. Truthfully I do not yet know where to define this symbol, and I could locate through recursive pattern matching where any of the other undefined symbols above are defined in ncs 1.6.1 or the Zephyr release tag within ncs 1.6.1.

Build messages here for same project as throughout this post, but Kconfig along side src/main.c and the newly added drivers directory and subdirs moved aside and not visible to cmake:

ted@localhost:~/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart$ west build -b sparkfun_thing_plus_nrf9160 -p
-- west build: making build dir /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/build pristine
-- west build: generating a build system
Including boilerplate (Zephyr base): /home/ted/projects/embedded/ncs/zephyr/cmake/app/boilerplate.cmake
-- Application: /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart
-- Zephyr version: 2.6.0-rc1 (/home/ted/projects/embedded/ncs/zephyr), build: v2.6.0-rc1-ncs1
-- Found Python3: /usr/bin/python3.8 (found suitable exact version "3.8.10") found components: Interpreter 
-- Found west (found suitable version "0.11.0", minimum required is "0.7.1")
-- Board: sparkfun_thing_plus_nrf9160
-- Cache files will be written to: /home/ted/.cache/zephyr
-- Using toolchain: zephyr 0.12.4 (/opt/zephyr-sdk-0.12.4)
-- Found dtc: /opt/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /home/ted/projects/embedded/ncs/zephyr/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160.dts
-- Found devicetree overlay: /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/app.overlay
sparkfun_thing_plus_nrf9160.dts.pre.tmp:59.42-71.3: Warning (unique_unit_address_if_enabled): /soc/peripheral@50000000/flash-controller@39000: duplicate unit-address (also used in node /soc/peripheral@50000000/kmu@39000)
sparkfun_thing_plus_nrf9160.dts.pre.tmp:311.19-317.3: Warning (unique_unit_address_if_enabled): /soc/peripheral@50000000/clock@5000: duplicate unit-address (also used in node /soc/peripheral@50000000/power@5000)
-- Generated zephyr.dts: /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/build/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/build/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: /home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/build/zephyr/include/generated/device_extern.h
Parsing /home/ted/projects/embedded/ncs/zephyr/Kconfig
Loaded configuration '/home/ted/projects/embedded/ncs/zephyr/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_defconfig'
Merged configuration '/home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/prj.conf'

/home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/prj.conf:7: warning: attempt to assign the value 'y' to the undefined symbol KX132_1211

error: Aborting due to Kconfig warnings

CMake Error at /home/ted/projects/embedded/ncs/zephyr/cmake/kconfig.cmake:264 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  /home/ted/projects/embedded/ncs/zephyr/cmake/app/boilerplate.cmake:555 (include)
  /home/ted/projects/embedded/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:24 (include)
  /home/ted/projects/embedded/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:35 (include_boilerplate)
  CMakeLists.txt:4 (find_package)


-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart/build -S/home/ted/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart -GNinja -DBOARD=sparkfun_thing_plus_nrf9160
ted@localhost:~/projects/embedded/ncs/zephyr/samples/sandbox-de-ted/blink-plus-uart$

    tedhavelka66 In other words, is it really hard to put my driver files in progress in /home/ted/projects/embedded/ncs/zephyr/drivers/sensor?

    Not necessarily, but I would recommend you build a separate module so you don’t accidentally wipe away all your work in an update/git reset.

    tedhavelka66 Please correct me on this thought if I am mistaken. If it is reasonable to develop a new driver in Zephyr’s standard drivers location, then is it also fair to say I can create a local branch of Zephyr project, and track my development changes in git that way?

    Yup you can. You can also put it in whatever module you’re using for your custom project as well. All up to you and how you want to structure things.

    tedhavelka66 Build messages here for same project as throughout this post, but Kconfig along side src/main.c and the newly added drivers directory and subdirs moved aside and not visible to cmake:

    It can’t find the Kconfig file with the config KX132_1211 definition. Are you sure you’re including it properly? You’ll need a line in the driver Kconfig file which points the Kconfig in your driver subfolder:

    rsource "path/to/kx132_1211/Kconfig"

    As of 2021-08-18, I have the Kionix driver files under development at github:

    https://github.com/tedhavelka/nRF9160-work

    As for the Kconfig file with the config KX132_1211 definition, I thought that the following file is that one. I’ll label this “path one”:

    https://github.com/tedhavelka/nRF9160-work/blob/main/blink-plus-uart/drivers/kionix/kx132-1211/Kconfig

    Each of the Kconfig files above the final directory in path one points to a child directory Kconfig below it. Does this recursive referencing not provide to cmake knowledge of the configuration file at the end of path one?

    Thank you also for mentioning Zephyr modules again. I am reading up on them now, at https://docs.zephyrproject.org/latest/guides/modules.html to understand the whichever technical and conventional differences there are between Zephyr modules and Zephyr drivers.

      tedhavelka66 you’re getting there but you’ll need to include your drivers outside of your application. This is because they need to be compiled before compiling your application itself. (Case in point, your application can’t find the CONFIG variable for your device.

      Also you’ll need a zephyr in that root directory with a module.yml in place along with a root Kconfig and CMakeLists.txt. The format should match the ones in the links I’ve sent previously and my article from a while back.

      You can also reference the drivers folders in nrf or even zephyr to see how they did it.

      Hi Jared. This may be a very basic question: where is, or how do I determine, the outside-of-app file to change so drivers needed by the app are built first?

      At this point now I’ve spent a good ten plus hours searching, reading, and experimenting with various suggested example changes to correctly “inform” my project of the larger Nordic SDK in which it lives. This has only become an issue as I implement a local driver.

      I’ve reviewed each of your replies, again much appreciated, and I’ve looked pretty extensively over the pyrinas project you have on github. When I add a Kconfig.kx132 in the top dir of my example app, a file analogous to Kconfig.pyrinas, this causes all of the blinky driver enable flags to become undefined. Without this app top-level Kconfig file, only my newly drafted driver flag CONFIG_KX132_1211 is not found by cmake and reported as undefined.

      Where exactly should a variable such as CONFIG_PCF85063A be defined? I find many references to Zephyr’s official driver CONFIG_ flags, but no place in the Zephyr 2.6.0 cloned repository, nor the ncs 1.6.1 repository where any of these flags are pound defined.

      As for knowing the context of my example app, I know that I am using for my SDK, ncs v1.6.1. I know which directory is the root dir of this SDK where I ran west init. I know the path from this SDK root to the basic\blinky example, and likewise to my modified version of that example app. But if to “include my driver outside my app” requires a “within app” change, it is unclear to me which file and which stanzas to change.

      You state I “must include my drivers outside of my application”. How does one include one’s drivers outside of their application? Must modify a file outside my app in the larger SDK, or a file within my app?

      Looking at the original Nordic ncs 1.6.1 / Zephyr basic/blinky app, I see there is a CMakeLists.txt file but no Kconfig file. The CMakeLists.txt file contains:

       # SPDX-License-Identifier: Apache-2.0
        2
        3 cmake_minimum_required(VERSION 3.13.1)
        4 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
        5 project(blinky)
        6
        7 target_sources(app PRIVATE src/main.c)

      If I follow your blog post tutorial verbatim, I would overwrite this file with something like the following pyrinas, app-top-level-directory CMakeLists.txt file:

      #
      # Copyright (c) 2020 Circuit Dojo
      #
      # SPDX-License-Identifier: Apache-2.0
      #
      
      # Point to Pyrinas root directory.
      set(PYRINAS_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Pyrinas root directory")
      
      zephyr_include_directories(include)
      
      add_subdirectory(lib)
      add_subdirectory(ext)
      add_subdirectory(drivers)

      In adding this file to my project I would substitute my project name for ‘pyrinas’, but I’m concerned to delete the find_package() and target_sources() stanzas that are present in my pre-existing CMakeLists.txt file. This file pre-exists because my app is copied from basic/blinky. At this time I also do not have an ext nor lib subdirectly in my example app project.

      I’m willing to put in the hours to learn this new material, but as I’m building on an existing example and not from scratch, I need to know which parts of the example are ok to overwrite versus those which must stay in place. This so if I am to follow the blog instructions as close as possible and make them work.

      Here’s the file structure from the Air Quality Wing drivers repository. The most critical files are module.yml and top level CMakeLists.txt and Kconfig.

      |____dts
      | |____bindings
      | | |____sensirion,shtc3.yaml
      | | |____sensirion,sgp40.yaml
      |____CMakeLists.txt
      |____drivers
      | |____CMakeLists.txt
      | |____Kconfig
      | |____shtc3
      | | |____shtc3.c
      | | |____CMakeLists.txt
      | | |____Kconfig
      | | |____shtc3.h
      | |____sgp40
      | | |____sgp40.h
      | | |____CMakeLists.txt
      | | |____Kconfig
      | | |____sgp40.c
      |____include
      | |____aqw.h
      |____Kconfig
      |____README.md
      |____lib
      | |____CMakeLists.txt
      | |____Kconfig
      | |____aqw.c
      |____zephyr
      | |____module.yml

      If you were, per-se, going to add an application, I would create a folder within this root and call it app (or whatever you like) and put your application Kconfig CMakeLists.txt src/main.c etc.

      -rw-r--r--  1 user  staff  342 Aug 19 19:34 CMakeLists.txt
      -rw-r--r--  1 user  staff  124 Aug 19 19:34 Kconfig
      -rw-r--r--  1 user  staff   34 Aug 19 19:34 README.md
      drwxr-xr-x  6 user  staff  192 Aug 19 19:34 drivers
      drwxr-xr-x  3 user  staff   96 Aug 19 19:34 dts
      drwxr-xr-x  3 user  staff   96 Aug 19 19:34 include
      drwxr-xr-x  5 user  staff  160 Aug 19 19:34 lib
      drwxr-xr-x  3 user  staff   96 Aug 19 19:34 zephyr
      drwxr-xr-x  3 user  staff   96 Aug 19 19:34 app

      It’s important to understand how the Kconfig and Cmakelists.txt trickle down and work during compilation. If you have zephyr/module.yml configured properly ./CMakeLists.txt should be processed first before your application. This is critical for loading drivers correctly.

      I can’t stress enough looking at some of these repos to see how they’re formatted. It takes a bit of noodling but once you get it you’ll be on your way. 😀

      Alternatively, like I have done, you can put your drivers in a completely separate repository and your application in another. That’s what I did with the AQW sample. Most crucially, you need to create your top level west.yml manifest and define what are the dependencies. Here’s mine:

      manifest:
        remotes:
          - name: nrfconnect
            url-base: https://github.com/nrfconnect
        projects:
          - name: nrf
            repo-path: sdk-nrf
            remote: nrfconnect
            revision: v1.6.1
            import: true
          # Drivers repository
          - name: air-quality-wing-drivers
            path: aqw
            revision: main
            url: git@github.com:circuitdojo/air-quality-wing-zephyr-drivers.git
        self:
          # This repository should be cloned to 
          path: demo

      You can see I’m pulling in the AQW drivers repo mentioned above this way. In my case the demo code lives in a directory called demo and demo is located in a higher level air-quality-wing-sample directory. You can initialize west locally using west init -l demo which will reference west.yml in demo. west update then pulls all the dependencies like nrf zephyr and so on.

      So if your drivers are going to live beyond this project, I would likely put them in a separate repository eventually. To understand all these concepts though, I would likely integrate them into one.

      Good evening Jared,
      Only last night Satuday 8-21 did I notice your edits to your most recent messages to this longer post. Thank you for the directory structures, reiterated points of import and further guidance. I’m working through these highlighted app and driver pieces now. Hopefully will have a driver which compiles soon!
      I may come back to a point I see in the AQW driver top level CMakeLists.txt file. It is not clear to me how to choose what is line 6 in air quality wing CMakeLists.txt:

      #
      # Copyright (c) 2021 Circuit Dojo LLC
      #
      
      # Point to this project's root directory.
      set(AQW_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Air Quality Wing root directory")
      
      # Subdirectories
      add_subdirectory(drivers)
      add_subdirectory_ifdef(CONFIG_AQW lib)
      
      # Include headers
      zephyr_include_directories(include)
      zephyr_include_directories(drivers)

      Variable AQW_DIR looks custom, like a name chosen entirely by the developer. I’m searching for where else this is referenced. Is there a naming convention here for this variable? In general terms is this “the given driver root directory”?

        tedhavelka66 that’s just a simple way to refer the root of the module. For instance if you want to refer to a specific file within a module you can use the XXX_DIR variable rather than providing the absolute/relative address. With that being said, you are correct i’m currently not using this variable anywhere.

        Ah ok, and to be clear by “absolute/relative address” do you mean this in the sense of absolute path or relative path to file?

        One other question, your AQW driver has a lib directory containing a source file. In AQW driver this catches my eye thanks to line 10 of the top-level CMakeLists.txt file. If I have only a drivers directory at the root of my out-of-tree driver, is that a workable layout? (I must think a little longer why a lib directory is helpful among closely related specific sensor drivers.)

          tedhavelka66 (I must think a little longer why a lib directory is helpful among closely related specific sensor drivers.)

          You are correct!

          tedhavelka66 If I have only a drivers directory at the root of my out-of-tree driver, is that a workable layout?

          Yup!

          Terms and Conditions | Privacy Policy