@@ -94,6 +94,22 @@ uintptr_t mp_os_dupterm_poll(uintptr_t poll_flags) {
94
94
}
95
95
96
96
int mp_os_dupterm_rx_chr (void ) {
97
+ #if MICROPY_PY_OS_DUPTERM_NOTIFY
98
+ // When os.dupterm_notify() is enabled it is usually called from a scheduled
99
+ // function, via mp_os_dupterm_notify(). That can lead to recursive calls of
100
+ // this function when this function is called from mp_hal_stdin_rx_chr():
101
+ // - mp_hal_stdin_rx_chr()
102
+ // - mp_os_dupterm_rx_chr()
103
+ // - <Python code>
104
+ // - os.dupterm_notify() is scheduled via interrupt/event
105
+ // - <Python code> runs scheduled code (eg WebREPL -> rp2.Flash().writeblocks())
106
+ // - mp_os_dupterm_notify()
107
+ // - mp_os_dupterm_rx_chr()
108
+ // Break that cycle by locking the scheduler during this function's duration.
109
+ mp_sched_lock ();
110
+ #endif
111
+
112
+ int ret = -1 ; // no chars available
97
113
for (size_t idx = 0 ; idx < MICROPY_PY_OS_DUPTERM ; ++ idx ) {
98
114
if (MP_STATE_VM (dupterm_objs [idx ]) == MP_OBJ_NULL ) {
99
115
continue ;
@@ -106,7 +122,8 @@ int mp_os_dupterm_rx_chr(void) {
106
122
const mp_stream_p_t * stream_p = mp_get_stream (MP_STATE_VM (dupterm_objs [idx ]));
107
123
mp_uint_t out_sz = stream_p -> read (MP_STATE_VM (dupterm_objs [idx ]), buf , 1 , & errcode );
108
124
if (errcode == 0 && out_sz != 0 ) {
109
- return buf [0 ];
125
+ ret = buf [0 ];
126
+ break ;
110
127
} else {
111
128
continue ;
112
129
}
@@ -132,20 +149,24 @@ int mp_os_dupterm_rx_chr(void) {
132
149
} else {
133
150
// read 1 byte
134
151
nlr_pop ();
135
- if (buf [0 ] == mp_interrupt_char ) {
152
+ ret = buf [0 ];
153
+ if (ret == mp_interrupt_char ) {
136
154
// Signal keyboard interrupt to be raised as soon as the VM resumes
137
155
mp_sched_keyboard_interrupt ();
138
- return -2 ;
156
+ ret = -2 ;
139
157
}
140
- return buf [ 0 ] ;
158
+ break ;
141
159
}
142
160
} else {
143
161
mp_os_deactivate (idx , "dupterm: Exception in read() method, deactivating: " , MP_OBJ_FROM_PTR (nlr .ret_val ));
144
162
}
145
163
}
146
164
147
- // No chars available
148
- return -1 ;
165
+ #if MICROPY_PY_OS_DUPTERM_NOTIFY
166
+ mp_sched_unlock ();
167
+ #endif
168
+
169
+ return ret ;
149
170
}
150
171
151
172
void mp_os_dupterm_tx_strn (const char * str , size_t len ) {
0 commit comments