Skip to content

Commit

Permalink
samples: Add sample 'application_development/out_of_tree_driver'
Browse files Browse the repository at this point in the history
Add a sample that demonstrates (and tests) that custom drivers can be
maintained outside of Zephyr.

The sample is fairly minimal with few dependencies and should
therefore be very portable. It also includes a sample.yaml that should
ensure that it does not regress.

Signed-off-by: Sebastian Bøe <[email protected]>
  • Loading branch information
SebastianBoe authored and nashif committed Jan 22, 2020
1 parent 56f6e35 commit 011da8c
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 0 deletions.
21 changes: 21 additions & 0 deletions samples/application_development/out_of_tree_driver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: Apache-2.0

# For the sake of demonstration, we add the driver directory as a zephyr module
# by hand. If your driver is a project that's managed by west, you can remove this line.
list(APPEND ZEPHYR_EXTRA_MODULES
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_module
)

cmake_minimum_required(VERSION 3.13.1)

# Add an absolute directory path to the CMake variable
# SYSCALL_INCLUDE_DIRS. This ensures that the syscall machinery will
# be able to find the module's syscalls.
list(APPEND SYSCALL_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/hello_world_module/zephyr)

include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)

target_sources(app PRIVATE
src/main.c
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: Apache-2.0

if(CONFIG_HELLO_WORLD_DRIVER)
# Add hello_world_driver.h to the set of global include paths.
zephyr_include_directories(.)

zephyr_library()
zephyr_library_sources(
hello_world_driver.c
)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) 2019 Nordic Semiconductor
# SPDX-License-Identifier: Apache-2.0

config HELLO_WORLD_DRIVER
bool "Enable support for the demonstration out of tree driver"
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "hello_world_driver.h"
#include <zephyr/types.h>

/**
* This is a minimal example of an out-of-tree driver
* implementation. See the header file of the same name for details.
*/

static struct hello_world_dev_data {
u32_t foo;
} data;

static int init(struct device *dev)
{
data.foo = 5;

return 0;
}

static void print_impl(struct device *dev)
{
printk("Hello World from the kernel: %d\n", data.foo);

__ASSERT(data.foo == 5, "Device was not initialized!");
}

DEVICE_AND_API_INIT(hello_world, "CUSTOM_DRIVER",
init, &data, NULL,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&((struct hello_world_driver_api){ .print = print_impl }));
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2019 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __HELLO_WORLD_DRIVER_H__
#define __HELLO_WORLD_DRIVER_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <device.h>

/*
* This 'Hello World' driver has a 'print' syscall that prints the
* famous 'Hello World!' string.
*
* The string is formatted with some internal driver data to
* demonstrate that drivers are initialized during the boot process.
*
* The driver exists to demonstrate (and test) custom drivers that are
* maintained outside of Zephyr.
*/

struct hello_world_driver_api {
/* This struct has a member called 'print'. 'print' is function
* pointer to a function that takes 'struct device *dev' as an
* argument and returns 'void'.
*/
void (*print)(struct device *dev);
};

__syscall void hello_world_print(struct device *dev);
static inline void z_impl_hello_world_print(struct device *dev)
{
const struct hello_world_driver_api *api = dev->driver_api;

__ASSERT(api->print, "Callback pointer should not be NULL");

api->print(dev);
}

#ifdef __cplusplus
}
#endif

#include <syscalls/hello_world_driver.h>

#endif /* __HELLO_WORLD_DRIVER_H__ */
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2019 Nordic Semiconductor

build:
cmake: zephyr
kconfig: zephyr/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_HELLO_WORLD_DRIVER=y
13 changes: 13 additions & 0 deletions samples/application_development/out_of_tree_driver/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
sample:
description: Sample that uses an out-of-tree driver
name: Out-of-tree driver
tests:
drivers.out_of_tree:
tags: out_of_tree
harness: console
harness_config:
type: multi_line
regex:
- "Hello World from the app!"
- "device is (.*), name is CUSTOM_DRIVER"
- "Hello World from the kernel: 5"
22 changes: 22 additions & 0 deletions samples/application_development/out_of_tree_driver/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2019 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "hello_world_driver.h"
#include <stdio.h>
#include <zephyr.h>

void main(void)
{
printk("Hello World from the app!\n");

struct device *dev = device_get_binding("CUSTOM_DRIVER");

__ASSERT(dev, "Failed to get device binding");

printk("device is %p, name is %s\n", dev, dev->config->name);

hello_world_print(dev);
}

0 comments on commit 011da8c

Please sign in to comment.