Compare commits
48 Commits
Author | SHA1 | Date |
---|---|---|
Daniel Thompson | a960916b4f | |
Daniel Thompson | a241931fff | |
Daniel Thompson | a83f1f6468 | |
Daniel Thompson | 5697f83e22 | |
Daniel Thompson | 225189221e | |
Daniel Thompson | 6dacfe36be | |
Daniel Thompson | 0a0426a20b | |
Daniel Thompson | 57c0a77a98 | |
Daniel Thompson | 1d20df0a65 | |
Paul Sokolovsky | ef0bf69d0b | |
Daniel Thompson | 3f39068a08 | |
Daniel Thompson | 00a3b12f5f | |
Daniel Thompson | fc217133ad | |
Daniel Thompson | db9f7d5266 | |
Paul Sokolovsky | a20f4f96c7 | |
Paul Sokolovsky | 4683f05240 | |
Paul Sokolovsky | 0867a52177 | |
Paul Sokolovsky | 3074d4f4e2 | |
Paul Sokolovsky | 1125d7890a | |
Paul Sokolovsky | 140152f07b | |
Paul Sokolovsky | 82c481755b | |
Paul Sokolovsky | 58c95ceff2 | |
Paul Sokolovsky | f48425b60c | |
Paul Sokolovsky | 469ad079a3 | |
Paul Sokolovsky | d5c564ae81 | |
Paul Sokolovsky | 236e749884 | |
Paul Sokolovsky | 375db1918c | |
Paul Sokolovsky | d569483d11 | |
Paul Sokolovsky | 7bbda4dbb5 | |
Paul Sokolovsky | 6d1eb1baeb | |
Paul Sokolovsky | c160813a75 | |
Paul Sokolovsky | 58d63c0c9a | |
Paul Sokolovsky | f51421f51c | |
Paul Sokolovsky | cfe6ab9aa4 | |
Paul Sokolovsky | 023364cdd6 | |
Paul Sokolovsky | c3695b3212 | |
Paul Sokolovsky | 6b1ed34336 | |
Paul Sokolovsky | 90a01bb5c6 | |
Paul Sokolovsky | f0a3ca0be1 | |
Paul Sokolovsky | 21bc7ccbaf | |
Paul Sokolovsky | e4d4c55621 | |
Paul Sokolovsky | 9af8e49885 | |
Paul Sokolovsky | 372fdb7a8c | |
Paul Sokolovsky | d3e4ba1c94 | |
Paul Sokolovsky | 069c8e7c82 | |
Paul Sokolovsky | fef0b4463e | |
Paul Sokolovsky | 42ab119d9f | |
Paul Sokolovsky | ca4ba17c68 |
|
@ -0,0 +1,3 @@
|
|||
outdir/
|
||||
qemu.pid
|
||||
z_config_proxy.mk
|
|
@ -0,0 +1,3 @@
|
|||
#subdir-ccflags-y += -I$(SOURCE_DIR)/../mylib/include
|
||||
|
||||
obj-y += src/
|
|
@ -0,0 +1,119 @@
|
|||
#
|
||||
# This is main Makefile, which uses MicroPython build system, but
|
||||
# Zephyr arch-specific toolchain (setup by Zephyr's Makefile.toolchain.*).
|
||||
# Unfortunately, it's currently not possible to get target (as in: specific
|
||||
# board to run on) specific compile-time options from Zephyr, so these must
|
||||
# be set (duplicated) in this Makefile. Currently, these configured for
|
||||
# ARM Cortex-M3. This Makefile builds MicroPython as a library, and then
|
||||
# calls recursively Makefile.zephyr to build complete application using
|
||||
# Zephyr build system.
|
||||
#
|
||||
|
||||
BOARD ?= qemu_x86
|
||||
# Zephyr 1.5.0
|
||||
#OUTDIR_PREFIX =
|
||||
# Zephyr 1.6.0
|
||||
OUTDIR_PREFIX = $(BOARD)
|
||||
|
||||
# Zephyr (generated) config files - must be defined before include below
|
||||
Z_DOTCONFIG = outdir/$(OUTDIR_PREFIX)/.config
|
||||
Z_SYSGEN_H = outdir/$(OUTDIR_PREFIX)/misc/generated/sysgen/sysgen.h
|
||||
Z_EXPORTS = outdir/$(OUTDIR_PREFIX)/Makefile.export
|
||||
DQUOTE = "
|
||||
# "
|
||||
include $(Z_EXPORTS)
|
||||
|
||||
ifdef CONFIG_MBEDTLS
|
||||
MICROPY_PY_USSL = 1
|
||||
MICROPY_SSL_MBEDTLS = 1
|
||||
MICROPY_SSL_MBEDTLS_INCLUDE = $(ZEPHYR_BASE)/ext/lib/crypto/mbedtls/include
|
||||
endif
|
||||
|
||||
FROZEN_DIR = scripts
|
||||
|
||||
include ../py/mkenv.mk
|
||||
include ../py/py.mk
|
||||
|
||||
INC += -I.
|
||||
INC += -I..
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(ZEPHYR_BASE)/net/ip
|
||||
INC += -I$(ZEPHYR_BASE)/net/ip/contiki
|
||||
INC += -I$(ZEPHYR_BASE)/net/ip/contiki/os
|
||||
|
||||
ifdef CONFIG_NETWORKING
|
||||
SRC_MOD += modsocket.c
|
||||
endif
|
||||
|
||||
SRC_C = help.c \
|
||||
main.c \
|
||||
modutime.c \
|
||||
modmachine.c \
|
||||
modpybpin.c \
|
||||
uart_core.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/printf.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/netutils/netutils.c \
|
||||
$(BUILD)/frozen.c \
|
||||
$(SRC_MOD)
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
utils/pyhelp.c \
|
||||
)
|
||||
|
||||
# List of sources for qstr extraction
|
||||
SRC_QSTR += $(SRC_C)
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
|
||||
CFLAGS = $(KBUILD_CFLAGS) $(NOSTDINC_FLAGS) $(ZEPHYRINCLUDE) \
|
||||
-std=gnu99 -DNDEBUG $(INC)
|
||||
|
||||
include ../py/mkrules.mk
|
||||
|
||||
$(Z_EXPORTS):
|
||||
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) initconfig outputexports
|
||||
|
||||
GENERIC_TARGETS = all zephyr qemu qemugdb flash debug
|
||||
KCONFIG_TARGETS = \
|
||||
initconfig config nconfig menuconfig xconfig gconfig \
|
||||
oldconfig silentoldconfig defconfig savedefconfig \
|
||||
allnoconfig allyesconfig alldefconfig randconfig \
|
||||
listnewconfig olddefconfig
|
||||
CLEAN_TARGETS = pristine mrproper
|
||||
|
||||
$(GENERIC_TARGETS) : $(LIBMICROPYTHON)
|
||||
$(CLEAN_TARGETS) : clean
|
||||
|
||||
$(GENERIC_TARGETS) $(KCONFIG_TARGETS) $(CLEAN_TARGETS):
|
||||
$(RM) -f outdir/$(OUTDIR_PREFIX)/zephyr.lnk
|
||||
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) $@
|
||||
|
||||
# Note: doesn't rebuild binary, just runs qemu against it
|
||||
qemu-net:
|
||||
$(ZEPHYR_SDK_INSTALL_DIR)/sysroots/i686-pokysdk-linux/usr/bin/qemu-system-i386 -m 32 -cpu qemu32 \
|
||||
-no-reboot -nographic -vga none -display none -net none -clock dynticks -no-acpi -balloon none \
|
||||
-L $(ZEPHYR_SDK_INSTALL_DIR)/sysroots/i686-pokysdk-linux/usr/share/qemu \
|
||||
-bios bios.bin -machine type=pc-0.14 -pidfile qemu.pid \
|
||||
-serial mon:stdio -serial none -serial unix:/tmp/slip.sock \
|
||||
-kernel outdir/$(OUTDIR_PREFIX)/zephyr.elf
|
||||
# For GDB debugging with QEMU
|
||||
#-s -S
|
||||
|
||||
$(LIBMICROPYTHON): $(Z_SYSGEN_H)
|
||||
build/genhdr/qstr.i.last: $(Z_SYSGEN_H)
|
||||
|
||||
$(Z_SYSGEN_H):
|
||||
rm -f $(LIBMICROPYTHON)
|
||||
-$(MAKE) -f Makefile.zephyr BOARD=$(BOARD)
|
||||
|
||||
CLEAN_EXTRA = z_config_proxy.mk
|
||||
|
||||
# Clean Zephyr things too
|
||||
clean : z_clean
|
||||
|
||||
z_clean :
|
||||
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) clean
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Copyright (c) 2016 Intel Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
KERNEL_TYPE = micro
|
||||
# BOARD must be passed on command line from main Makefile
|
||||
#BOARD =
|
||||
CONF_FILE = prj.conf
|
||||
MDEF_FILE = prj.mdef
|
||||
|
||||
#export SOURCE_DIR = $(ZEPHYR_BASE)/samples/static_lib/hello_world
|
||||
export LDFLAGS_zephyr += -L$(CURDIR)
|
||||
export ALL_LIBS += micropython
|
||||
|
||||
# Need to reference dir with mbedTLS config. ZEPHYRINCLUDE doesn't work
|
||||
# (gets completely overriden by Z). Using STDINCLUDE is definitely a
|
||||
# hack, but it happens not to be overriden by Z.
|
||||
#export ZEPHYRINCLUDE += -I$(CURDIR)/src
|
||||
export STDINCLUDE += -I$(CURDIR)/src
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.inc
|
|
@ -0,0 +1,22 @@
|
|||
This is initial proof of concept port of MicroPython to Zephyr RTOS
|
||||
http://zephyrproject.org. It only integrates with Zephyr's console
|
||||
subsystem so far.
|
||||
|
||||
Supported out of the box is Zephyr's armv7-m (Cortex-M3) architecture,
|
||||
with qemu_cortex_m3 being a default target. Supporting others architectures
|
||||
may require editing makefiles.
|
||||
|
||||
To build:
|
||||
|
||||
Intstall Zephyr SDK and Zephyr source from the link above. Configure
|
||||
Zephyr environment as described in its instructions. Then:
|
||||
|
||||
make
|
||||
|
||||
To run in QEMU:
|
||||
|
||||
make qemu
|
||||
|
||||
To build for a real board (see link above for supported Cortex-M boards):
|
||||
|
||||
make BOARD=frdm_k64f
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2016 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lib/utils/pyhelp.h"
|
||||
|
||||
STATIC const char *help_text =
|
||||
"Welcome to MicroPython!\n"
|
||||
"\n"
|
||||
"Control commands:\n"
|
||||
" CTRL-A -- on a blank line, enter raw REPL mode\n"
|
||||
" CTRL-B -- on a blank line, enter normal REPL mode\n"
|
||||
" CTRL-C -- interrupt a running program\n"
|
||||
" CTRL-D -- on a blank line, do a soft reset of the board\n"
|
||||
" CTRL-E -- on a blank line, enter paste mode\n"
|
||||
"\n"
|
||||
"For further help on a specific object, type help(obj)\n"
|
||||
;
|
||||
|
||||
STATIC mp_obj_t builtin_help(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// print a general help message
|
||||
printf("%s", help_text);
|
||||
|
||||
} else {
|
||||
// try to print something sensible about the given object
|
||||
pyhelp_print_obj(args[0]);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, builtin_help);
|
|
@ -0,0 +1,100 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
printf("MemoryError: lexer could not allocate memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
static char *stack_top;
|
||||
static char heap[24 * 1024];
|
||||
|
||||
int real_main(void) {
|
||||
int stack_dummy;
|
||||
stack_top = (char*)&stack_dummy;
|
||||
mp_stack_set_top(stack_top);
|
||||
// Should be set to CONFIG_MAIN_STACK_SIZE in prj.conf minus fuzz factor
|
||||
mp_stack_set_limit(3584);
|
||||
|
||||
#if MICROPY_ENABLE_GC
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
#endif
|
||||
mp_init();
|
||||
pyexec_frozen_module("main.py");
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
pyexec_event_repl_init();
|
||||
for (;;) {
|
||||
int c = mp_hal_stdin_rx_chr();
|
||||
if (pyexec_event_repl_process_char(c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
pyexec_friendly_repl();
|
||||
#endif
|
||||
//do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT);
|
||||
//do_str("for i in range(10):\r\n print(i)", MP_PARSE_FILE_INPUT);
|
||||
mp_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
// WARNING: This gc_collect implementation doesn't try to get root
|
||||
// pointers from CPU registers, and thus may function incorrectly.
|
||||
void *dummy;
|
||||
gc_collect_start();
|
||||
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
|
||||
gc_collect_end();
|
||||
gc_dump_info();
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
__fatal_error("Assertion failed");
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2015 Damien P. George
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
* Copyright (c) 2016 Linaro Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/machine_mem.h"
|
||||
#include "extmod/machine_pulse.h"
|
||||
#include "extmod/machine_i2c.h"
|
||||
#include "modpyb.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE
|
||||
|
||||
STATIC mp_obj_t machine_reset(void) {
|
||||
printf("Warning: %s is not implemented\n", __func__);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
|
||||
|
||||
STATIC mp_obj_t machine_reset_cause(void) {
|
||||
printf("Warning: %s is not implemented\n", __func__);
|
||||
return MP_OBJ_NEW_SMALL_INT(42);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause);
|
||||
|
||||
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
||||
|
||||
// reset causes
|
||||
/*{ MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) },*/
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_machine = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_MACHINE
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __MICROPY_INCLUDED_ZEPHYR_MODPYB_H__
|
||||
#define __MICROPY_INCLUDED_ZEPHYR_MODPYB_H__
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_type_t pyb_pin_type;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_info_obj);
|
||||
|
||||
typedef struct _pyb_pin_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct device *port;
|
||||
uint32_t pin;
|
||||
} pyb_pin_obj_t;
|
||||
|
||||
#endif // __MICROPY_INCLUDED_ZEPHYR_MODPYB_H__
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014, 2015 Damien P. George
|
||||
* Copyright (c) 2016 Linaro Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <gpio.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "modpyb.h"
|
||||
|
||||
const mp_obj_base_t pyb_pin_obj_template = {&pyb_pin_type};
|
||||
|
||||
STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
|
||||
// pin name
|
||||
mp_printf(print, "Pin(%p@%d)", self->port, self->pin);
|
||||
}
|
||||
|
||||
// pin.init(mode, pull=None, *, value)
|
||||
STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_mode, ARG_pull, ARG_value };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none}},
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get io mode
|
||||
uint mode = args[ARG_mode].u_int;
|
||||
|
||||
// get pull mode
|
||||
uint pull = GPIO_PUD_NORMAL;
|
||||
if (args[ARG_pull].u_obj != mp_const_none) {
|
||||
pull = mp_obj_get_int(args[ARG_pull].u_obj);
|
||||
}
|
||||
|
||||
int ret = gpio_pin_configure(self->port, self->pin, mode | pull);
|
||||
if (ret) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
|
||||
}
|
||||
|
||||
// get initial value
|
||||
int value;
|
||||
if (args[ARG_value].u_obj != MP_OBJ_NULL) {
|
||||
(void) gpio_pin_write(self->port, self->pin,
|
||||
mp_obj_is_true(args[ARG_value].u_obj));
|
||||
}
|
||||
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// constructor(drv_name, pin, ...)
|
||||
STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// get the wanted port
|
||||
const char *drv_name = mp_obj_str_get_str(args[0]);
|
||||
int wanted_pin = mp_obj_get_int(args[1]);
|
||||
struct device *wanted_port = device_get_binding(drv_name);
|
||||
if (!wanted_port) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
|
||||
}
|
||||
|
||||
pyb_pin_obj_t *pin = m_new_obj(pyb_pin_obj_t);
|
||||
pin->base = pyb_pin_obj_template;
|
||||
pin->port = wanted_port;
|
||||
pin->pin = wanted_pin;
|
||||
|
||||
if (n_args > 2 || n_kw > 0) {
|
||||
// pin mode given, so configure this GPIO
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_pin_obj_init_helper(pin, n_args - 2, args + 2, &kw_args);
|
||||
}
|
||||
|
||||
return (mp_obj_t)pin;
|
||||
}
|
||||
|
||||
// fast method for getting/setting pin value
|
||||
STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
if (n_args == 0) {
|
||||
uint32_t pin_val;
|
||||
(void) gpio_pin_read(self->port, self->pin, &pin_val);
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_val);
|
||||
} else {
|
||||
(void) gpio_pin_write(self->port, self->pin, mp_obj_is_true(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
// pin.init(mode, pull)
|
||||
STATIC mp_obj_t pyb_pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pyb_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_init_obj, 1, pyb_pin_obj_init);
|
||||
|
||||
// pin.value([value])
|
||||
STATIC mp_obj_t pyb_pin_value(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return pyb_pin_call(args[0], n_args - 1, 0, args + 1);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pin_value_obj, 1, 2, pyb_pin_value);
|
||||
|
||||
// pin.low()
|
||||
STATIC mp_obj_t pyb_pin_low(mp_obj_t self_in) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
(void) gpio_pin_write(self->port, self->pin, 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_low_obj, pyb_pin_low);
|
||||
|
||||
// pin.high()
|
||||
STATIC mp_obj_t pyb_pin_high(mp_obj_t self_in) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
(void) gpio_pin_write(self->port, self->pin, 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_high_obj, pyb_pin_high);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_pin_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pyb_pin_value_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pyb_pin_low_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pyb_pin_high_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_IN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_OUT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PUD_PULL_UP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PUD_PULL_DOWN) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_pin_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Pin,
|
||||
.print = pyb_pin_print,
|
||||
.make_new = pyb_pin_make_new,
|
||||
.call = pyb_pin_call,
|
||||
.locals_dict = (mp_obj_t)&pyb_pin_locals_dict,
|
||||
};
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if 1 // MICROPY_PY_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/stream.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
// Zephyr includes
|
||||
#include <zephyr.h>
|
||||
#include <net/net_core.h>
|
||||
#include <net/net_socket.h>
|
||||
#include <net/ip_buf.h>
|
||||
#define PACK_ALIAS_STRUCT __attribute__((__packed__,__may_alias__))
|
||||
#include <contiki/ip/uipaddr.h>
|
||||
|
||||
#if 1 // print debugging info
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(...) (void)0
|
||||
#endif
|
||||
|
||||
#define IPADDR {{192, 0, 2, 2}}
|
||||
#define MY_IPADDR {IPADDR}
|
||||
|
||||
#define WAIT_TICKS TICKS_UNLIMITED
|
||||
|
||||
// These are uIP public interface variables wich specify this host address/netmask.
|
||||
uip_ipaddr_t uip_hostaddr = IPADDR;
|
||||
uip_ipaddr_t uip_netmask = { { 255, 255, 255, 0 } };
|
||||
uip_ipaddr_t uip_draddr = {{192, 0, 2, 1}};
|
||||
|
||||
static struct net_addr my_addr = {
|
||||
.family = AF_INET,
|
||||
{ .in_addr = MY_IPADDR },
|
||||
};
|
||||
|
||||
typedef struct _socket_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct net_context *sock;
|
||||
struct net_addr peer_addr;
|
||||
struct net_buf *incoming;
|
||||
mp_uint_t recv_offset;
|
||||
|
||||
#define STATE_NEW 0
|
||||
#define STATE_CONNECTING 1
|
||||
#define STATE_CONNECTED 2
|
||||
#define STATE_PEER_CLOSED 3
|
||||
#define STATE_CLOSED 4
|
||||
byte state;
|
||||
} socket_obj_t;
|
||||
|
||||
STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
socket_obj_t *self = self_in;
|
||||
if (self->sock != NULL) {
|
||||
struct uip_conn *uip_connr = net_context_get_internal_connection(self->sock);
|
||||
mp_printf(print, "<socket %p: state=%d Zstatus=%d income=%p(@%d) uip_conn=%p",
|
||||
self->sock,
|
||||
self->state,
|
||||
net_context_get_connection_status(self->sock),
|
||||
self->incoming,
|
||||
self->recv_offset,
|
||||
uip_connr);
|
||||
|
||||
if (uip_connr != NULL) {
|
||||
mp_printf(print, " uip_flags=%x uip_oustand=%d",
|
||||
uip_connr->tcpstateflags,
|
||||
uip_outstanding(uip_connr));
|
||||
}
|
||||
mp_printf(print, ">");
|
||||
} else {
|
||||
mp_printf(print, "<socket %p: state=%d>", self->sock, self->state);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
assert(n_args == 0);
|
||||
#if 0
|
||||
// Net initialization on demand. Has been moved to main(), to let
|
||||
// the app respond to pings imemdiately after startup.
|
||||
if (net_init() < 0) {
|
||||
printf("Error in net_init()\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
#endif
|
||||
socket_obj_t *o = m_new_obj(socket_obj_t);
|
||||
o->base.type = type;
|
||||
// We don't know if this will be client or server socket, so it's
|
||||
// instantiated lazily
|
||||
o->sock = NULL;
|
||||
o->incoming = NULL;
|
||||
o->recv_offset = 0;
|
||||
o->state = STATE_NEW;
|
||||
return o;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
socket_obj_t *self = self_in;
|
||||
|
||||
// Get address
|
||||
uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE];
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
||||
DEBUG_printf("resolved: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
||||
|
||||
struct in_addr in4addr_peer = {{{ip[0], ip[1], ip[2], ip[3]}}};
|
||||
self->peer_addr.in_addr = in4addr_peer;
|
||||
self->peer_addr.family = AF_INET;
|
||||
|
||||
int proto = IPPROTO_TCP;
|
||||
self->sock = net_context_get(proto, &self->peer_addr, port, &my_addr, 0);
|
||||
|
||||
int ret = net_context_tcp_init(self->sock, /*NULL,*/ NET_TCP_TYPE_CLIENT);
|
||||
DEBUG_printf("net_context_tcp_init()=%d\n", ret);
|
||||
// Blocking wait until actually connected
|
||||
while (net_context_get_connection_status(self->sock) == -EINPROGRESS) {
|
||||
DEBUG_printf("waiting to connect: %d\n", net_context_get_connection_status(self->sock));
|
||||
task_sleep(sys_clock_ticks_per_sec / 10);
|
||||
}
|
||||
|
||||
if (net_context_get_connection_status(self->sock) == -ECONNRESET) {
|
||||
self->state = STATE_PEER_CLOSED;
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ECONNRESET)));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
||||
|
||||
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
socket_obj_t *self = self_in;
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
struct net_buf *netbuf = ip_buf_get_tx(self->sock);
|
||||
uint8_t *ptr = net_buf_add(netbuf, bufinfo.len);
|
||||
memcpy(ptr, bufinfo.buf, bufinfo.len);
|
||||
ip_buf_appdatalen(netbuf) = bufinfo.len;
|
||||
|
||||
int ret = net_send(netbuf);
|
||||
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
|
||||
|
||||
STATIC mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t len, int *errcode) {
|
||||
DEBUG_printf("socket_write(%p, %p, %d)\n", self_in, buf, len);
|
||||
socket_obj_t *self = self_in;
|
||||
struct uip_conn *uip_connr = net_context_get_internal_connection(self->sock);
|
||||
|
||||
while (uip_outstanding(uip_connr)) {
|
||||
DEBUG_printf("wait outstanding flush of %d bytes (connflags: %x)\n", uip_outstanding(uip_connr), uip_connr->tcpstateflags);
|
||||
task_sleep(sys_clock_ticks_per_sec / 10);
|
||||
}
|
||||
|
||||
struct net_buf *netbuf = ip_buf_get_tx(self->sock);
|
||||
if (len > net_buf_tailroom(netbuf)) {
|
||||
len = net_buf_tailroom(netbuf);
|
||||
}
|
||||
uint8_t *ptr = net_buf_add(netbuf, len);
|
||||
memcpy(ptr, buf, len);
|
||||
ip_buf_appdatalen(netbuf) = len;
|
||||
|
||||
int ret = net_send(netbuf);
|
||||
if (ret >= 0) {
|
||||
return len;
|
||||
}
|
||||
*errcode = ret;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_read(mp_obj_t self_in, void *buf, mp_uint_t len, int *errcode) {
|
||||
socket_obj_t *self = self_in;
|
||||
struct uip_conn *uip_connr = net_context_get_internal_connection(self->sock);
|
||||
DEBUG_printf("socket_read(%p, %p, %d) conn_flags: %x\n", self_in, buf, len, uip_connr->tcpstateflags);
|
||||
|
||||
while (self->incoming == NULL) {
|
||||
if (self->state == STATE_PEER_CLOSED /*|| uip_connr->tcpstateflags == UIP_CLOSED*/) {
|
||||
DEBUG_printf("socket_read: Returning EOF\n");
|
||||
return 0;
|
||||
}
|
||||
DEBUG_printf("socket_read: calling net_receive\n");
|
||||
self->incoming = net_receive(self->sock, WAIT_TICKS);
|
||||
if (uip_closed(self->incoming)) {
|
||||
DEBUG_printf("uip_closed() == true\n");
|
||||
self->state = STATE_PEER_CLOSED;
|
||||
}
|
||||
if (ip_buf_appdatalen(self->incoming) == 0) {
|
||||
// We may be passed 0-length packet to indicate peer closed
|
||||
// condition (or by any other reason).
|
||||
self->incoming = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mp_uint_t remaining = ip_buf_appdatalen(self->incoming) - self->recv_offset;
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
memcpy(buf, ip_buf_appdata(self->incoming) + self->recv_offset, len);
|
||||
remaining -= len;
|
||||
if (remaining == 0) {
|
||||
ip_buf_unref(self->incoming);
|
||||
self->incoming = NULL;
|
||||
self->recv_offset = 0;
|
||||
} else {
|
||||
self->recv_offset += len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
socket_obj_t *self = self_in;
|
||||
|
||||
if (self->state == STATE_PEER_CLOSED) {
|
||||
return mp_const_empty_bytes;
|
||||
}
|
||||
|
||||
struct net_buf *buf = net_receive(self->sock, WAIT_TICKS);
|
||||
mp_obj_t ret = mp_obj_new_bytes(ip_buf_appdata(buf), ip_buf_appdatalen(buf));
|
||||
if (uip_closed(buf)) {
|
||||
//printf("uip_closed() == true\n");
|
||||
self->state = STATE_PEER_CLOSED;
|
||||
}
|
||||
ip_buf_unref(buf);
|
||||
return ret;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
|
||||
|
||||
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
|
||||
socket_obj_t *self = self_in;
|
||||
net_context_put(self->sock);
|
||||
self->sock = NULL;
|
||||
self->state = STATE_CLOSED;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
|
||||
|
||||
STATIC const mp_map_elem_t socket_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t socket_stream_p = {
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t socket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_socket,
|
||||
.print = socket_print,
|
||||
.make_new = socket_make_new,
|
||||
.protocol = &socket_stream_p,
|
||||
.locals_dict = (mp_obj_t)&socket_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usocket) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_type },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_socket = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2016 Linaro Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_PY_UTIME
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <zephyr.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#define MP_CLOCKS_PER_SEC CLOCKS_PER_SEC
|
||||
#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F)
|
||||
|
||||
STATIC mp_obj_t mod_time_time(void) {
|
||||
/* the absense of f.p. support is deliberate. the zephyr port uses
|
||||
* single precision floats so the fraction component will start to
|
||||
* lose precision on devices with a long uptime.
|
||||
*/
|
||||
return mp_obj_new_int(sys_tick_get() / sys_clock_ticks_per_sec);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_time_obj, mod_time_time);
|
||||
|
||||
STATIC mp_obj_t mod_time_ticks_us(void) {
|
||||
mp_int_t us = sys_tick_get() * sys_clock_us_per_tick;
|
||||
return MP_OBJ_NEW_SMALL_INT(us & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_ticks_us_obj, mod_time_ticks_us);
|
||||
|
||||
STATIC mp_obj_t mod_time_ticks_ms(void) {
|
||||
int64_t us = sys_tick_get() * sys_clock_us_per_tick;
|
||||
mp_int_t ms = us / 1000;
|
||||
return MP_OBJ_NEW_SMALL_INT(ms & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_ticks_ms_obj, mod_time_ticks_ms);
|
||||
|
||||
STATIC mp_obj_t mod_time_ticks_cycles(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_cycle_get_32());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_ticks_cycles_obj, mod_time_ticks_cycles);
|
||||
|
||||
STATIC mp_obj_t mod_time_cycles_to_ns(mp_obj_t arg) {
|
||||
mp_int_t cycles = mp_obj_get_int(arg);
|
||||
return mp_obj_new_int(SYS_CLOCK_HW_CYCLES_TO_NS(cycles));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_cycles_to_ns_obj, mod_time_cycles_to_ns);
|
||||
|
||||
STATIC mp_obj_t mod_time_ticks_diff(mp_obj_t oldval, mp_obj_t newval) {
|
||||
mp_uint_t old = MP_OBJ_SMALL_INT_VALUE(oldval);
|
||||
mp_uint_t new = MP_OBJ_SMALL_INT_VALUE(newval);
|
||||
return MP_OBJ_NEW_SMALL_INT((new - old) & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_time_ticks_diff_obj, mod_time_ticks_diff);
|
||||
|
||||
STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
if (MP_OBJ_IS_INT(arg)) {
|
||||
#endif
|
||||
task_sleep(SECONDS(mp_obj_get_int(arg)));
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
} else {
|
||||
task_sleep(MSEC(1000 * mp_obj_get_float(arg)));
|
||||
}
|
||||
#endif
|
||||
MP_THREAD_GIL_ENTER();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_obj, mod_time_sleep);
|
||||
|
||||
STATIC mp_obj_t mod_time_sleep_ms(mp_obj_t arg) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
task_sleep(MSEC(mp_obj_get_int(arg)));
|
||||
MP_THREAD_GIL_ENTER();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_ms_obj, mod_time_sleep_ms);
|
||||
|
||||
STATIC mp_obj_t mod_time_sleep_us(mp_obj_t arg) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
task_sleep(USEC(mp_obj_get_int(arg)));
|
||||
MP_THREAD_GIL_ENTER();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_us_obj, mod_time_sleep_us);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mod_time_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mod_time_sleep_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mod_time_sleep_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mod_time_time_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mod_time_ticks_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mod_time_ticks_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_cycles), MP_ROM_PTR(&mod_time_ticks_cycles_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_cycles_to_ns), MP_ROM_PTR(&mod_time_cycles_to_ns_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mod_time_ticks_diff_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_time = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_time_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_UTIME
|
|
@ -0,0 +1,88 @@
|
|||
#include <alloca.h>
|
||||
|
||||
// Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles
|
||||
#include "autoconf.h"
|
||||
|
||||
// Saving extra crumbs to make sure binary fits in 128K
|
||||
#define MICROPY_COMP_CONST_FOLDING (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
|
||||
|
||||
#define MICROPY_DEBUG_PRINTERS (1)
|
||||
#define MICROPY_STACK_CHECK (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_REPL_AUTO_INDENT (1)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||
#define MICROPY_PY_ATTRTUPLE (0)
|
||||
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
|
||||
#define MICROPY_PY_BUILTINS_FILTER (0)
|
||||
#define MICROPY_PY_BUILTINS_MIN_MAX (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY_BUILTINS_RANGE_ATTRS (0)
|
||||
#define MICROPY_PY_BUILTINS_REVERSED (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (0)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_UTIME (1)
|
||||
/* TODO: Would really like IS_ENABLED(CONFIG_NETWORKING) here but Zephyr
|
||||
* doesn't have this yet...
|
||||
*/
|
||||
#ifdef CONFIG_NETWORKING
|
||||
#define MICROPY_PY_SOCKET (1)
|
||||
#else
|
||||
#define MICROPY_PY_SOCKET (0)
|
||||
#endif
|
||||
#define MICROPY_PY_STRUCT (1)
|
||||
#define MICROPY_PY_SYS_MODULES (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
#define MICROPY_PY_BUILTINS_COMPLEX (0)
|
||||
#define MICROPY_HW_BOARD_NAME "zephyr-generic"
|
||||
#define MICROPY_HW_MCU_NAME "unknown-cpu"
|
||||
#define MICROPY_MODULE_FROZEN_STR (1)
|
||||
|
||||
typedef int mp_int_t; // must be pointer size
|
||||
typedef unsigned mp_uint_t; // must be pointer size
|
||||
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
#define BYTES_PER_WORD (sizeof(mp_int_t))
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8];
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
|
||||
|
||||
extern const struct _mp_obj_module_t mp_module_machine;
|
||||
extern const struct _mp_obj_module_t mp_module_socket;
|
||||
extern const struct _mp_obj_module_t mp_module_time;
|
||||
|
||||
#if MICROPY_PY_UTIME
|
||||
#define MICROPY_PY_UTIME_DEF { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_time) },
|
||||
#else
|
||||
#define MICROPY_PY_UTIME_DEF
|
||||
#endif
|
||||
#if MICROPY_PY_SOCKET
|
||||
#define MICROPY_PY_SOCKET_DEF { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_socket) },
|
||||
#else
|
||||
#define MICROPY_PY_SOCKET_DEF
|
||||
#endif
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \
|
||||
MICROPY_PY_SOCKET_DEF \
|
||||
MICROPY_PY_UTIME_DEF \
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
|
||||
static inline void mp_hal_set_interrupt_char(char c) {}
|
|
@ -0,0 +1,29 @@
|
|||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_CONSOLE_HANDLER=y
|
||||
CONFIG_NEWLIB_LIBC=y
|
||||
CONFIG_FLOAT=y
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NETWORKING_WITH_IPV4=y
|
||||
CONFIG_NETWORKING_WITH_TCP=y
|
||||
CONFIG_NETWORKING_WITH_LOOPBACK=y
|
||||
CONFIG_NETWORKING_UART=y
|
||||
CONFIG_NETWORKING_DEBUG_UART=y
|
||||
CONFIG_IP_BUF_RX_SIZE=17
|
||||
CONFIG_IP_BUF_TX_SIZE=10
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
|
||||
CONFIG_MBEDTLS=y
|
||||
CONFIG_MBEDTLS_BUILTIN=y
|
||||
CONFIG_MBEDTLS_CFG_FILE="mbedtls-config-upy.h"
|
||||
|
||||
CONFIG_RAM_SIZE=530
|
||||
|
||||
# Network debug logging
|
||||
CONFIG_NETWORKING_WITH_LOGGING=y
|
||||
#CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT=y
|
||||
#CONFIG_NETWORK_IP_STACK_DEBUG_TCP_PSOCK=y
|
||||
# Verbose net_buf-level logging
|
||||
#CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF=y
|
||||
#CONFIG_NET_BUF_DEBUG=y
|
|
@ -0,0 +1,5 @@
|
|||
% Application : MicroPython
|
||||
|
||||
% TASK NAME PRIO ENTRY STACK GROUPS
|
||||
% ==================================
|
||||
TASK MAIN 7 main 8192 [EXE]
|
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Copyright (c) 2016 Intel Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
obj-y += zephyr_start.o zephyr_getchar.o
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Linaro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <uart.h>
|
||||
#include <drivers/console/uart_console.h>
|
||||
#include <misc/printk.h>
|
||||
#include "zephyr_getchar.h"
|
||||
|
||||
static struct nano_sem uart_sem;
|
||||
#define UART_BUFSIZE 256
|
||||
static uint8_t uart_ringbuf[UART_BUFSIZE];
|
||||
static uint8_t i_get, i_put;
|
||||
|
||||
static int console_irq_input_hook(struct device *dev, uint8_t ch)
|
||||
{
|
||||
int i_next = (i_put + 1) & (UART_BUFSIZE - 1);
|
||||
if (i_next == i_get) {
|
||||
printk("UART buffer overflow - char dropped\n");
|
||||
return 1;
|
||||
}
|
||||
uart_ringbuf[i_put] = ch;
|
||||
i_put = i_next;
|
||||
//printk("%x\n", ch);
|
||||
nano_isr_sem_give(&uart_sem);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t zephyr_getchar(void) {
|
||||
nano_task_sem_take(&uart_sem, TICKS_UNLIMITED);
|
||||
unsigned int key = irq_lock();
|
||||
uint8_t c = uart_ringbuf[i_get++];
|
||||
i_get &= UART_BUFSIZE - 1;
|
||||
irq_unlock(key);
|
||||
return c;
|
||||
}
|
||||
|
||||
void zephyr_getchar_init(void) {
|
||||
nano_sem_init(&uart_sem);
|
||||
struct device *uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
|
||||
uart_irq_input_hook_set(uart_console_dev, console_irq_input_hook);
|
||||
// All NULLs because we're interested only in the callback above
|
||||
uart_register_input(NULL, NULL, NULL);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Linaro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void zephyr_getchar_init(void);
|
||||
uint8_t zephyr_getchar(void);
|
|
@ -0,0 +1,23 @@
|
|||
#include <zephyr.h>
|
||||
#include "zephyr_getchar.h"
|
||||
|
||||
int real_main(void);
|
||||
|
||||
void main(void) {
|
||||
#ifdef CONFIG_NETWORKING
|
||||
if (net_init() < 0) {
|
||||
printf("Error in net_init()\n");
|
||||
}
|
||||
#endif
|
||||
zephyr_getchar_init();
|
||||
real_main();
|
||||
}
|
||||
|
||||
// This gets pulled in when mbedTLS is enabled in Zephyr config.
|
||||
// It doesn't seem to be used by mbedTLS directly directly, but
|
||||
// rather pulled in for some other libc dependency. All in all,
|
||||
// this doesn't seem to be called, so included to avoid link
|
||||
// error.
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
printf("! dummy gettimeofday called\n");
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include <unistd.h>
|
||||
#include "py/mpconfig.h"
|
||||
#include "src/zephyr_getchar.h"
|
||||
|
||||
// Stopgap
|
||||
extern void printk(const char*, ...);
|
||||
|
||||
/*
|
||||
* Core UART functions to implement for a port
|
||||
*/
|
||||
|
||||
// Receive single character
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
return zephyr_getchar();
|
||||
}
|
||||
|
||||
// Send string of given length
|
||||
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
while (len--) {
|
||||
printk("%c", *str++);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
srctree = $(ZEPHYR_BASE)
|
||||
|
||||
include $(Z_DOTCONFIG)
|
||||
override ARCH = $(subst $(DQUOTE),,$(CONFIG_ARCH))
|
||||
SOC_NAME = $(subst $(DQUOTE),,$(CONFIG_SOC))
|
||||
SOC_SERIES = $(subst $(DQUOTE),,$(CONFIG_SOC_SERIES))
|
||||
SOC_FAMILY = $(subst $(DQUOTE),,$(CONFIG_SOC_FAMILY))
|
||||
ifeq ($(SOC_SERIES),)
|
||||
SOC_PATH = $(SOC_NAME)
|
||||
else
|
||||
SOC_PATH = $(SOC_FAMILY)/$(SOC_SERIES)
|
||||
endif
|
||||
|
||||
KBUILD_CFLAGS := -c
|
||||
include $(ZEPHYR_BASE)/scripts/Kbuild.include
|
||||
|
||||
include $(ZEPHYR_BASE)/arch/$(ARCH)/Makefile
|
Loading…
Reference in New Issue