Skip to content

Commit 8734076

Browse files
authored
Merge pull request #9199 from tannewt/renode
Add minimal Renode port
2 parents 49954d8 + a86a9b7 commit 8734076

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1990
-80
lines changed

docs/shared_bindings_matrix.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"mimxrt10xx",
4141
"nordic",
4242
"raspberrypi",
43+
"renode",
4344
"silabs",
4445
"stm",
4546
]

docs/supported_ports.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Additional testing is limited.
2020
../ports/mimxrt10xx/README
2121
../ports/nordic/README
2222
../ports/raspberrypi/README
23+
../ports/renode/README
2324
../ports/silabs/README
2425
../ports/stm/README
2526
../ports/unix/README

main.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
#include "supervisor/shared/tick.h"
5959
#include "supervisor/shared/traceback.h"
6060
#include "supervisor/shared/workflow.h"
61-
#include "supervisor/usb.h"
6261
#include "supervisor/workflow.h"
6362
#include "supervisor/shared/external_flash/external_flash.h"
6463

@@ -115,10 +114,14 @@
115114
#include "supervisor/shared/status_bar.h"
116115
#endif
117116

118-
#if CIRCUITPY_USB_HID
117+
#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_HID
119118
#include "shared-module/usb_hid/__init__.h"
120119
#endif
121120

121+
#if CIRCUITPY_TINYUSB
122+
#include "supervisor/usb.h"
123+
#endif
124+
122125
#if CIRCUITPY_WIFI
123126
#include "shared-bindings/wifi/__init__.h"
124127
#endif
@@ -429,7 +432,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
429432
}
430433
}
431434

432-
STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
435+
STATIC bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
433436
bool serial_connected_at_start = serial_connected();
434437
bool printed_safe_mode_message = false;
435438
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -1160,7 +1163,7 @@ void gc_collect(void) {
11601163
common_hal_bleio_gc_collect();
11611164
#endif
11621165

1163-
#if CIRCUITPY_USB_HID
1166+
#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_HID
11641167
usb_hid_gc_collect();
11651168
#endif
11661169

ports/espressif/common-hal/_bleio/Adapter.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "supervisor/shared/bluetooth/bluetooth.h"
3838
#include "supervisor/shared/safe_mode.h"
3939
#include "supervisor/shared/tick.h"
40-
#include "supervisor/usb.h"
4140
#include "shared-bindings/_bleio/__init__.h"
4241
#include "shared-bindings/_bleio/Adapter.h"
4342
#include "shared-bindings/_bleio/Address.h"
@@ -59,6 +58,10 @@
5958
#include "esp_bt.h"
6059
#include "esp_nimble_hci.h"
6160

61+
#if CIRCUITPY_TINYUSB
62+
#include "supervisor/usb.h"
63+
#endif
64+
6265
#if CIRCUITPY_OS_GETENV
6366
#include "shared-module/os/__init__.h"
6467
#endif

ports/espressif/supervisor/internal_flash.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@
4343

4444
#include "supervisor/filesystem.h"
4545
#include "supervisor/flash.h"
46+
47+
#if CIRCUITPY_USB_DEVICE
4648
#include "supervisor/usb.h"
49+
#endif
4750

4851
#define OP_READ 0
4952
#define OP_WRITE 1

ports/nordic/background.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@
2727
#include "background.h"
2828

2929
#include "py/runtime.h"
30-
#include "supervisor/filesystem.h"
3130
#include "supervisor/port.h"
32-
#include "supervisor/shared/stack.h"
33-
#include "supervisor/usb.h"
3431

3532
#if CIRCUITPY_DISPLAYIO
3633
#include "shared-module/displayio/__init__.h"

ports/nordic/common-hal/_bleio/Adapter.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
* THE SOFTWARE.
2727
*/
2828

29-
#include <math.h>
3029
#include <stdint.h>
3130
#include <stdio.h>
3231
#include <string.h>
@@ -43,14 +42,15 @@
4342
#include "supervisor/shared/bluetooth/bluetooth.h"
4443
#include "supervisor/shared/safe_mode.h"
4544
#include "supervisor/shared/tick.h"
46-
#include "supervisor/usb.h"
4745
#include "shared-bindings/_bleio/__init__.h"
4846
#include "shared-bindings/_bleio/Adapter.h"
4947
#include "shared-bindings/_bleio/Address.h"
5048
#include "shared-bindings/nvm/ByteArray.h"
5149
#include "shared-bindings/_bleio/Connection.h"
52-
#include "shared-bindings/_bleio/ScanEntry.h"
53-
#include "shared-bindings/time/__init__.h"
50+
51+
#if CIRCUITPY_USB_DEVICE
52+
#include "supervisor/usb.h"
53+
#endif
5454

5555
#if CIRCUITPY_OS_GETENV
5656
#include "shared-bindings/os/__init__.h"

ports/renode/Makefile

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# This file is part of the MicroPython project, http://micropython.org/
2+
#
3+
# The MIT License (MIT)
4+
#
5+
# SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
# THE SOFTWARE.
24+
25+
include ../../py/circuitpy_mkenv.mk
26+
27+
CROSS_COMPILE = arm-none-eabi-
28+
29+
INC += \
30+
-I. \
31+
-I../.. \
32+
-I../lib/mp-readline \
33+
-I../shared/timeutils \
34+
-Iboards/$(BOARD) \
35+
-Iboards/ \
36+
-isystem ./../../lib/cmsis/inc \
37+
-I$(BUILD)
38+
39+
CFLAGS += -ggdb3 -Os
40+
41+
DISABLE_WARNINGS = -Wno-cast-align
42+
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes
43+
44+
CFLAGS += \
45+
-march=armv6-m \
46+
-mthumb \
47+
-mabi=aapcs \
48+
-mcpu=cortex-m0plus \
49+
-msoft-float \
50+
-mfloat-abi=soft \
51+
--specs=nano.specs
52+
53+
# Use toolchain libm if we're not using our own.
54+
ifndef INTERNAL_LIBM
55+
LIBS += -lm
56+
endif
57+
58+
LIBS += -lc
59+
60+
SRC_C += \
61+
boards/$(BOARD)/board.c \
62+
boards/$(BOARD)/pins.c \
63+
background.c \
64+
mphalport.c \
65+
66+
67+
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
68+
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
69+
$(addprefix common-hal/, $(SRC_COMMON_HAL))
70+
71+
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
72+
$(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
73+
$(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
74+
75+
# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED,
76+
# because a few modules have files both in common-hal/ and shared-module/.
77+
# Doing a $(sort ...) removes duplicates as part of sorting.
78+
SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED))
79+
80+
SRC_S = supervisor/$(CPU)_cpu.s
81+
82+
OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
83+
OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
84+
ifeq ($(INTERNAL_LIBM),1)
85+
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
86+
endif
87+
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
88+
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
89+
OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o))
90+
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
91+
92+
$(BUILD)/%.o: $(BUILD)/%.S
93+
$(STEPECHO) "CC $<"
94+
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
95+
96+
SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON)
97+
98+
all: $(BUILD)/firmware.elf $(BUILD)/circuitpy.img
99+
100+
BOARD_LD := $(wildcard boards/$(BOARD)/link.ld)
101+
102+
ifneq ($(BOARD_LD),)
103+
LINKER_SCRIPTS = -Wl,-T,$(BOARD_LD)
104+
endif
105+
106+
LINKER_SCRIPTS += -Wl,-T,link.ld
107+
108+
$(BUILD)/circuitpy.img: circuitpy/code.py
109+
$(STEPECHO) "Create $@"
110+
$(Q)dd if=/dev/zero of=$(BUILD)/circuitpy.img bs=1 count=0 seek=512K
111+
$(Q)mkfs.fat -n CIRCUITPY --offset=0 $(BUILD)/circuitpy.img
112+
$(Q)mcopy -i $(BUILD)/circuitpy.img circuitpy/* ::
113+
114+
ifeq ($(VALID_BOARD),)
115+
$(BUILD)/firmware.elf: invalid-board
116+
else
117+
$(BUILD)/firmware.elf: $(OBJ) $(BOARD_LD) link.ld
118+
$(STEPECHO) "LINK $@"
119+
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
120+
$(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags
121+
$(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags $(LINKER_SCRIPTS) -Wl,--print-memory-usage -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc
122+
endif
123+
124+
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
125+
$(STEPECHO) "Create $@"
126+
$(Q)$(OBJCOPY) -O binary -R .dtcm_bss $^ $@
127+
128+
include $(TOP)/py/mkrules.mk

ports/renode/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Renode
2+
3+
Renode is an emulator targeting microcontroller-class devices. This port is a
4+
minimal version of CircuitPython that runs under Renode. Renode is designed to
5+
mimic full microcontrollers but CP uses more peripherals than what Renode has
6+
implemented so far. This port allows us to run on a variety of CPUs without
7+
worrying about peripherals.
8+
9+
## Running
10+
11+
1. Get Renode: https://renode.io/#downloads
12+
2. `cd ports/renode`
13+
3. `make BOARD=renode_cortex_m0plus`
14+
4. In another tab: `tio /tmp/cp-uart`
15+
5. `renode`
16+
6. In renode: `include @renode.resc`
17+
7. <Any other setup>
18+
8. `start`
19+
9. `pause`
20+
10. `quit`
21+
22+
Step 4 sets up `tio` to talk to CircuitPython via UART <-> PTY bridge.
23+
24+
## Other stuff
25+
26+
### Emulator logging
27+
Renode modules have debug logging that can be enabled with `logLevel` with an int
28+
between `-1` for `NOISY` and `3` for errors only.
29+
30+
### GDB
31+
32+
Renode can provide a GDB server. It is very useful for precisely controlling the
33+
emulator's execution.
34+
35+
```
36+
machine StartGdbServer 3333 true
37+
```
38+
39+
### Execution profiling
40+
41+
In renode do `cpu EnableProfiler CollapsedStack $ORIGIN/profile.folded` before starting
42+
the emulation. You can view it using [Speedscope](https://www.speedscope.app/). CircuitPython calls
43+
a lot of functions and may overwhelm speedscope. You can enable this tracing over a specific
44+
section of CircuitPython execution to limit the capture size.
45+
46+
[Related Renode Docs](https://renode.readthedocs.io/en/latest/advanced/execution-tracing.html)
47+
48+
### Execution tracing
49+
If you want to see every instruction run you can do: `cpu CreateExecutionTracing "tracer_name" $ORIGIN/instruction_trace.txt Disassembly`.

ports/renode/Simple32kHz.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// Copyright (c) 2010-2022 Antmicro
3+
// Copyright (c) 2011-2015 Realtime Embedded
4+
//
5+
// This file is licensed under the MIT License.
6+
// Full license text is available in 'licenses/MIT.txt'.
7+
//
8+
// This is modified for CircuitPython to tick at 32kHz like a slow external
9+
// crystal would.
10+
using System;
11+
using Antmicro.Renode.Core;
12+
using Antmicro.Renode.Peripherals.Bus;
13+
using Antmicro.Renode.Time;
14+
using Antmicro.Renode.Logging;
15+
using System.Threading;
16+
17+
namespace Antmicro.Renode.Peripherals.Timers
18+
{
19+
public class Simple32kHz : IDoubleWordPeripheral, IKnownSize
20+
{
21+
public long Size { get { return 0x4; } }
22+
23+
public Simple32kHz(IMachine machine)
24+
{
25+
machine.ClockSource.AddClockEntry(new ClockEntry(1, 32768, OnTick, this, String.Empty));
26+
}
27+
28+
public virtual uint ReadDoubleWord(long offset)
29+
{
30+
return (uint)counter;
31+
}
32+
33+
public virtual void WriteDoubleWord(long offset, uint value)
34+
{
35+
this.LogUnhandledWrite(offset, value);
36+
}
37+
38+
public virtual void Reset()
39+
{
40+
Interlocked.Exchange(ref counter, 0);
41+
}
42+
43+
private void OnTick()
44+
{
45+
Interlocked.Increment(ref counter);
46+
}
47+
48+
private int counter;
49+
}
50+
}

0 commit comments

Comments
 (0)