Skip to content

Commit

Permalink
build: generate mnfb at build time rather than runtime
Browse files Browse the repository at this point in the history
This change adds cfriedt/manifesto as a submodule of
greybus-for-zephyr at the path scripts/manifesto/.

It removes a lot of unecessary code that was used for
assembling the manifest at runtime.

Rather than using C code and consuming microcontroller RAM
and resources at runtime, we can now link in the Greybus
Manifest into ROM as a static const unsigned char[].

Fixes #30

Signed-off-by: Christopher Friedt <[email protected]>
  • Loading branch information
cfriedt committed Dec 15, 2020
1 parent 5fa1b5a commit 656b87d
Show file tree
Hide file tree
Showing 33 changed files with 388 additions and 1,077 deletions.
1 change: 1 addition & 0 deletions .github/workflows/module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
path: greybus
- name: Setup Environment
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "scripts/manifesto"]
path = scripts/manifesto
url = https://github.com/cfriedt/manifesto.git
59 changes: 59 additions & 0 deletions cmake/greybus.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# Copyright (c) 2020 Friedt Professional Engineering Services, Inc
#
# SPDX-License-Identifier: Apache-2.0

set(G4Z_DIR ${CMAKE_CURRENT_LIST_DIR}/..)

function(devicetree_unfixed_h_to_mnfs
source_file # The source file to be converted
generated_file # The generated file
)
add_custom_command(
OUTPUT ${generated_file}
COMMAND
${PYTHON_EXECUTABLE}
${G4Z_DIR}/scripts/gbutil.py
${ARGN} # Extra arguments are passed to gbutil.py
${source_file}
${generated_file}
DEPENDS ${source_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endfunction()

function(mnfs_to_mnfb
source_file # The source file to be converted
generated_file # The generated file
)
add_custom_command(
OUTPUT ${generated_file}
COMMAND
${PYTHON_EXECUTABLE}
${G4Z_DIR}/scripts/manifesto/manifesto
-I mnfs
-O mnfb
-o ${generated_file}
${source_file}
DEPENDS ${source_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endfunction()

function(mnfb_to_mnfs
source_file # The source file to be converted to hex
generated_file # The generated file
)
add_custom_command(
OUTPUT ${generated_file}
COMMAND
${PYTHON_EXECUTABLE}
${G4Z_DIR}/scripts/manifesto/manifesto
-I mnfb
-O mnfs
-o ${generated_file}
${source_file}
DEPENDS ${source_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endfunction()
18 changes: 0 additions & 18 deletions include/greybus/manifecto/_cdefs.h

This file was deleted.

57 changes: 0 additions & 57 deletions include/greybus/manifecto/manifest.h

This file was deleted.

15 changes: 0 additions & 15 deletions include/greybus/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
#ifndef ZEPHYR_INCLUDE_GREYBUS_PLATFORM_H_
#define ZEPHYR_INCLUDE_GREYBUS_PLATFORM_H_

#include <greybus/manifecto/manifest.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -55,19 +53,6 @@ int gb_device_to_cport(struct device *dev);
*/
struct device *gb_cport_to_device(unsigned int cport);

struct gb_transport_backend;
struct greybus_platform_api {
int (*add_interface)(struct device *bus, uint16_t vendor_string_id,
uint16_t product_string_id);
int (*add_string)(struct device *bus, uint8_t id, const char *string_);
int (*add_bundle)(struct device *bus, uint8_t id, BundleClass class_);
int (*add_cport)(struct device *bus, uint8_t id, BundleClass class_, CPortProtocol protocol);
int (*get_cports)(struct device *bus, unsigned int **cports, size_t *num_cports);
int (*gen_mnfb)(struct device *bus, uint8_t **mnfb, size_t *mnfb_size);
struct gb_transport_backend *(*get_transport)(struct device *bus);
void (*fini)(struct device *bus);
};

struct gb_spi_master_config_response;
struct gb_spi_device_config_response;
struct spi_cs_control;
Expand Down
4 changes: 4 additions & 0 deletions samples/subsys/greybus/net/boards/native_posix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) 2020 Friedt Professional Engineering Services, Inc
# SPDX-License-Identifier: Apache-2.0

CONFIG_GPIO_EMUL=y
90 changes: 90 additions & 0 deletions samples/subsys/greybus/net/boards/native_posix.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <dt-bindings/greybus/greybus.h>

/ {
greybus0: greybus0 {
compatible = "zephyr,greybus";
label = "GREYBUS_0";
greybus;
};
};

&gpio0 {
status = "okay";
ngpios = <2>;
};

&greybus0 {
status = "okay";
/* defaults in effect, so this isn't necessary */
version-major = <GREYBUS_VERSION_MAJOR>;
version-minor = <GREYBUS_VERSION_MINOR>;

gbstring1: gbstring1 {
status = "okay";
compatible = "zephyr,greybus-string";
id = <1>;
greybus-string = "Zephyr Project RTOS";
};

gbstring2: gbstring2 {
status = "okay";
compatible = "zephyr,greybus-string";
id = <2>;
greybus-string = "Greybus Service Sample Application";
};

gbinterface0 {
status = "okay";
compatible = "zephyr,greybus-interface";
vendor-string-id = <&gbstring1>;
product-string-id = <&gbstring2>;
greybus-interface;
};

gbbundle0 {
status = "okay";
compatible = "zephyr,greybus-bundle";
greybus-bundle;
/* Control Bundle 0
* Note: control bundle 0 and control cport 0 are optional
* Since instance numbers automatically begin at 0, the id
* is a mandatory field for bundles and cports.
*/
id = <CONTROL_BUNDLE_ID>;
bundle-class = <BUNDLE_CLASS_CONTROL>;

gbcontrol0 {
status = "okay";
compatible = "zephyr,greybus-control";
greybus-controller;
/* Control CPort 0
* Note: control bundle 0 and control cport 0 are optional
* Since instance numbers automatically begin at 0, the id
* is a mandatory field for bundles and cports.
*/
id = <CONTROL_CPORT_ID>;
cport-protocol = <CPORT_PROTOCOL_CONTROL>;
};
};

gbbundle1 {
status = "okay";
compatible = "zephyr,greybus-bundle";
greybus-bundle;
id = <1>;
bundle-class = <BUNDLE_CLASS_BRIDGED_PHY>;

gbgpio0 {
status = "okay";
compatible = "zephyr,greybus-gpio-controller";
greybus-gpio-controller = <&gpio0>;
id = <1>;
cport-protocol = <CPORT_PROTOCOL_GPIO>;
};
};
};
4 changes: 4 additions & 0 deletions samples/subsys/greybus/net/boards/native_posix_64.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) 2020 Friedt Professional Engineering Services, Inc
# SPDX-License-Identifier: Apache-2.0

CONFIG_GPIO_EMUL=y
1 change: 1 addition & 0 deletions samples/subsys/greybus/net/boards/native_posix_64.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "native_posix.overlay"
106 changes: 106 additions & 0 deletions scripts/gbutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env python3

import os
import sys
from manifesto import *


def get_string_descriptors(defines, iface):
sd = {}
for key in defines:
val = defines[key]
if key.endswith('_P_compatible_IDX_0') and val == '"zephyr,greybus-string"':
node = key[:-len('_P_compatible_IDX_0')]
id_ = int(defines[node + '_P_id'])
string = defines[node + '_P_greybus_string']
sd[id_] = StringDescriptor(id_, string, None)
if id_ == iface.vsid or id_ == iface.psid:
sd[id_].parent = iface
return sd


def get_interface_descriptor(defines):
iface = None
for key in defines:
val = defines[key]
if key.endswith('_P_compatible_IDX_0') and val == '"zephyr,greybus-interface"':
node = key[:-len('_P_compatible_IDX_0')]
vph = defines[node + '_P_vendor_string_id_IDX_0_PH']
pph = defines[node + '_P_product_string_id_IDX_0_PH']
vsid = int(defines[vph + '_P_id'])
psid = int(defines[pph + '_P_id'])
iface = InterfaceDescriptor(vsid, psid, None)
break
return iface


def get_bundle_descriptors(defines):
bd = {}
for key in defines:
val = defines[key]
if key.endswith('_P_compatible_IDX_0') and val == '"zephyr,greybus-bundle"':
node = key[:-len('_P_compatible_IDX_0')]
id_ = int(defines[node + '_P_id'])
class_ = int(defines[node + '_P_bundle_class'])
bd[id_] = BundleDescriptor(id_, class_, None)
return bd


def get_cport_descriptors(defines):
# add keys as necessary
cport_keys = ['"zephyr,greybus-control"', '"zephyr,greybus-gpio-controller"',
'"zephyr,greybus-i2c-controller"', '"zephyr,greybus-spi-controller"']
cd = {}
for key in defines:
val = defines[key]
if key.endswith('_P_compatible_IDX_0') and val in cport_keys:
node = key[:-len('_P_compatible_IDX_0')]
id_ = int(defines[node + '_P_id'])
bid = int(defines[defines[node + '_PARENT'] + '_P_id'])
proto = int(defines[node + '_P_cport_protocol'])
cd[id_] = CPortDescriptor(id_, bid, proto, None)
return cd


def dt2mnfs(fn):

# extract defines
defines = {}
with open(fn) as f:
for line in f:
line = line.strip()
if line.startswith('#define '):
line = line[len('#define '):]
subs = line.split()
key = subs[0]
val = line[len(key + ' '):]
val = val.strip()
defines[key] = val

interface_desc = get_interface_descriptor(defines)
string_descs = get_string_descriptors(defines, interface_desc)
bundle_descs = get_bundle_descriptors(defines)
cport_descs = get_cport_descriptors(defines)

m = Manifest()
m.add_header(ManifestHeader(0, 1))

for d in string_descs:
m.add_string_desc(string_descs[d])
m.add_interface_desc(interface_desc)
for d in bundle_descs:
m.add_bundle_desc(bundle_descs[d])
for d in cport_descs:
m.add_cport_desc(cport_descs[d])

return m


if __name__ == '__main__':
if len(sys.argv) != 3:
print('usage: {} <input> <output>'.format(sys.argv[0]))
sys.exit(1)
mnfs = dt2mnfs(sys.argv[1])
with open(sys.argv[2], 'w') as f:
f.write(str(mnfs))
sys.exit(0)
1 change: 1 addition & 0 deletions scripts/manifesto
Submodule manifesto added at cf605a
1 change: 1 addition & 0 deletions scripts/manifesto.py
Loading

0 comments on commit 656b87d

Please sign in to comment.