8000 ports/mimxrt: Add thread support. · micropython/micropython@d092ee8 · GitHub
[go: up one dir, main page]

Skip to content

Commit d092ee8

Browse files
committed
ports/mimxrt: Add thread support.
Signed-off-by: tonyzhangnxp <tony.zhang@nxp.com>
1 parent 31e131b commit d092ee8

File tree

19 files changed

+754
-10
lines changed

19 files changed

+754
-10
lines changed

ports/mimxrt/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ SRC_C += \
215215
systick.c \
216216
ticks.c \
217217
tusb_port.c \
218+
mpthreadport.c \
219+
pybthread.c\
220+
gccollect.c\
221+
218222

219223
SHARED_SRC_C += \
220224
shared/libc/printf.c \

ports/mimxrt/boards/ADAFRUIT_METRO_M7/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB
88
MICROPY_PY_NETWORK_NINAW10 ?= 1
99
MICROPY_PY_SSL ?= 1
1010
MICROPY_SSL_MBEDTLS ?= 1
11+
12+
CFLAGS += -DMICROPY_PY_THREAD=0

ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ else
1414
JLINK_CONNECTION_SETTINGS = -USB
1515
endif
1616

17+
CFLAGS += -DMICROPY_PY_THREAD=0
18+
1719
deploy_jlink: $(BUILD)/firmware.hex
1820
$(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT)
1921
$(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT)

ports/mimxrt/boards/MIMXRT1015_EVK/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ MICROPY_HW_FLASH_TYPE = qspi_nor_flash
66
MICROPY_HW_FLASH_SIZE = 0x1000000 # 16MB
77

88
MICROPY_BOOT_BUFFER_SIZE = (32 * 1024)
9+
1 F438 0+
CFLAGS += -DMICROPY_PY_THREAD=0

ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-1070evk"
55

6+
#if MICROPY_PY_THREAD
7+
#else
68
#define MICROPY_EVENT_POLL_HOOK \
79
do { \
810
extern void mp_handle_pending(bool); \
911
mp_handle_pending(true); \
1012
} while (0);
13+
#endif
1114

1215
// MIMXRT1170_EVK has 2 user LEDs
1316
#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_04)

ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ MICROPY_PY_LWIP = 1
1414
MICROPY_PY_SSL = 1
1515
MICROPY_SSL_MBEDTLS = 1
1616

17+
CFLAGS += -DMICROPY_PY_THREAD=1
18+
1719
FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py
1820

1921
CFLAGS += -DCPU_MIMXRT1176DVMAA_cm7 \

ports/mimxrt/boards/OLIMEX_RT1010/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ MICROPY_HW_FLASH_SIZE = 0x200000 # 2MB
77
MICROPY_HW_FLASH_RESERVED ?= 0x1000 # 4KB
88

99
CFLAGS += -DMICROPY_HW_FLASH_DQS=kFlexSPIReadSampleClk_LoopbackInternally
10+
CFLAGS += -DMICROPY_PY_THREAD=0
1011

1112
SRC_C += \
1213
hal/flexspi_nor_flash.c \

ports/mimxrt/gccollect.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/gc.h"
28+
#include "py/mpthread.h"
29+
#include "shared/runtime/gchelper.h"
30+
#include "shared/runtime/softtimer.h"
31+
#include "gccollect.h"
32+
33+
void gc_collect(void) {
34+
// start the GC
35+
gc_collect_start();
36+
37+
// trace the stack and registers
38+
gc_helper_collect_regs_and_stack();
39+
40+
// trace root pointers from any threads
41+
#if MICROPY_PY_THREAD
42+
mp_thread_gc_others();
43+
#endif
44+
45+
// trace soft timer nodes
46+
soft_timer_gc_mark_all();
47+
48+
// end the GC
49+
gc_collect_end();
50+
}

ports/mimxrt/gccollect.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
#ifndef MICROPY_INCLUDED_STM32_GCCOLLECT_H
27+
#define MICROPY_INCLUDED_STM32_GCCOLLECT_H
28+
29+
// variables defining memory layout
30+
// (these probably belong somewhere else...)
31+
extern uint32_t _etext;
32+
extern uint32_t _sidata;
33+
extern uint32_t _ram_start;
34+
extern uint32_t _sdata;
35+
extern uint32_t _edata;
36+
extern uint32_t _sbss;
37+
extern uint32_t _ebss;
38+
extern uint32_t _heap_start;
39+
extern uint32_t _heap_end;
40+
extern uint32_t _sstack;
41+
extern uint32_t _estack;
42+
extern uint32_t _ram_end;
43+
44+
#endif // MICROPY_INCLUDED_STM32_GCCOLLECT_H

ports/mimxrt/main.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
#include "systick.h"
5757
#include "extmod/modnetwork.h"
5858

59+
#if MICROPY_PY_THREAD
60+
static pyb_thread_t pyb_thread_main;
61+
#endif
62+
5963
extern uint8_t _sstack, _estack, _gc_heap_start, _gc_heap_end;
6064

6165
void board_init(void);
@@ -64,7 +68,9 @@ int main(void) {
6468
board_init();
6569
ticks_init();
6670
pendsv_init();
67-
71+
#if MICROPY_PY_THREAD
72+
pyb_thread_init(&pyb_thread_main);
73+
#endif
6874
#if MICROPY_PY_LWIP
6975
// lwIP doesn't allow to reinitialise itself by subsequent calls to this function
7076
// because the system timeout list (next_timeout) is only ever reset by BSS clearing.
@@ -96,6 +102,11 @@ int main(void) {
96102
led_init();
97103
#endif
98104

105+
// Python threading init
106+
#if MICROPY_PY_THREAD
107+
mp_thread_init();
108+
#endif
109+
99110
mp_stack_set_top(&_estack);
100111
mp_stack_set_limit(&_estack - &_sstack - 1024);
101112

@@ -163,12 +174,6 @@ int main(void) {
163174
return 0;
164175
}
165176

166-
void gc_collect(void) {
167-
gc_collect_start();
168-
gc_helper_collect_regs_and_stack();
169-
gc_collect_end();
170-
}
171-
172177
void nlr_jump_fail(void *val) {
173178
for (;;) {
174179
}

ports/mimxrt/mpconfigport.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ uint32_t trng_random_u32(void);
134134
#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL)
135135
// #define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL)
136136

137+
#ifndef MICROPY_PY_THREAD
138+
#define MICROPY_PY_THREAD (1)
139+
#endif
140+
141+
137142
#ifndef MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE
138143
#define MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE (1)
139144
#endif
@@ -182,6 +187,24 @@ extern const struct _mp_obj_type_t mp_network_cyw43_type;
182187

183188
#define MP_STATE_PORT MP_STATE_VM
184189

190+
#if MICROPY_PY_THREAD
191+
192+
#define MICROPY_EVENT_POLL_HOOK \
193+
do { \
194+
extern void mp_handle_pending(bool); \
195+
mp_handle_pending(true); \
196+
if (pyb_thread_enabled) { \
197+
MP_THREAD_GIL_EXIT(); \
198+
pyb_thread_yield(); \
199+
MP_THREAD_GIL_ENTER(); \
200+
} else { \
201+
__WFE(); \
202+
} \
203+
} while (0);
204+
205+
#define MICROPY_THREAD_YIELD() pyb_thread_yield()
206+
207+
#else
185208
// Miscellaneous settings
186209
#ifndef MICROPY_EVENT_POLL_HOOK
187210
#define MICROPY_EVENT_POLL_HOOK \
@@ -192,6 +215,10 @@ extern const struct _mp_obj_type_t mp_network_cyw43_type;
192215
} while (0);
193216
#endif
194217

218+
#define MICROPY_THREAD_YIELD()
219+
220+
#endif
221+
195222
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
196223

197224
#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) \

ports/mimxrt/mphalport.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include "ticks.h"
3535
#include "tusb.h"
3636
#include "fsl_snvs_lp.h"
37-
37+
#include "led.h"
3838
#ifndef MICROPY_HW_STDIN_BUFFER_LEN
3939
#define MICROPY_HW_STDIN_BUFFER_LEN 512
4040
#endif
@@ -112,6 +112,24 @@ int mp_hal_stdin_rx_chr(void) {
112112
}
113113
}
114114

115+
NORETURN void boardctrl_fatal_error(const char *msg) {
116+
for (volatile uint delay = 0; delay < 10000000; delay++) {
117+
}
118+
led_state(1, 1);
119+
120+
mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14);
121+
mp_hal_stdout_tx_strn(msg, strlen(msg));
122+
for (uint i = 0;;) {
123+
led_toggle(1);
124+
for (volatile uint delay = 0; delay < 10000000; delay++) {
125+
}
126+
if (i >= 16) {
127+
// to conserve power
128+
__WFI();
129+
}
130+
}
131+
}
132+
115133
mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
116134
mp_uint_t ret = len;
117135
bool did_write = false;

ports/mimxrt/mphalport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,5 @@ void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]);
154154
void mp_hal_get_mac(int idx, uint8_t buf[6]);
155155
void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest);
156156
void mp_hal_get_unique_id(uint8_t id[]);
157-
157+
NORETURN void boardctrl_fatal_error(const char *msg);
158158
#endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H

ports/mimxrt/mpthreadport.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <stdio.h>
28+
29+
#include "py/runtime.h"
30+
#include "py/gc.h"
31+
#include "py/mpthread.h"
32+
#include "gccollect.h"
33+
34+
#if MICROPY_PY_THREAD
35+
36+
// the mutex controls access to the linked list
37+
static mp_thread_mutex_t thread_mutex;
38+
39+
void mp_thread_init(void) {
40+
mp_thread_mutex_init(&thread_mutex);
41+
mp_thread_set_state(&mp_state_ctx.thread);
42+
}
43+
44+
void mp_thread_gc_others(void) {
45+
mp_thread_mutex_lock(&thread_mutex, 1);
46+
for (pyb_thread_t *th = pyb_thread_all; th != NULL; th = th->all_next) {
47+
gc_collect_root((void **)&th, 1);
48+
gc_collect_root(&th->arg, 1);
49+
gc_collect_root(&th->stack, 1);
50+
if (th != pyb_thread_cur) {
51+
gc_collect_root(th->stack, th->stack_len);
52+
}
53+
}
54+
mp_thread_mutex_unlock(&thread_mutex);
55+
}
56+
57+
mp_uint_t mp_thread_get_id(void) {
58+
return (uint32_t)pyb_thread_cur;
59+
}
60+
61+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
62+
if (*stack_size == 0) {
63+
*stack_size = 4096; // default stack size
64+
} else if (*stack_size < 2048) {
65+
*stack_size = 2048; // minimum stack size
66+
}
67+
68+
// round stack size to a multiple of the word size
69+
size_t stack_len = *stack_size / sizeof(uint32_t);
70+
*stack_size = stack_len * sizeof(uint32_t);
71+
72+
// allocate stack and linked-list node (must be done outside thread_mutex lock)
73+
uint32_t *stack = m_new(uint32_t, stack_len);
74+
pyb_thread_t *th = m_new_obj(pyb_thread_t);
75+
76+
mp_thread_mutex_lock(&thread_mutex, 1);
77+
78+
// create thread
79+
uint32_t id = pyb_thread_new(th, stack, stack_len, entry, arg);
80+
if (id == 0) {
81+
mp_thread_mutex_unlock(&thread_mutex);
82+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't create thread"));
83+
}
84+
85+
mp_thread_mutex_unlock(&thread_mutex);
86+
87+
// adjust stack_size to provide room to recover from hitting the limit
88+
*stack_size -= 1024;
89+
90+
return id;
91+
}
92+
93+
void mp_thread_start(void) {
94+
}
95+
96+
void mp_thread_finish(void) {
97+
}
98+
99+
#endif // MICROPY_PY_THREAD

0 commit comments

Comments
 (0)
0