Skip to content

Commit 60929ec

Browse files
committed
extmod/machine_wdt: Factor ports' WDT Python bindings to common code.
There are currently 7 ports that implement machine.WDT and a lot of code is duplicated across these implementations. This commit factors the common parts of all these implementations to a single location in extmod/machine_wdt.c. This common code provides the top-level Python bindings (class and method wrappers), and then each port implements the back end specific to that port. With this refactor the ports remain functionally the same except for: - The esp8266 WDT constructor now takes keyword arguments, and accepts the "timeout" argument but raises an exception if it's not the default value (this port doesn't support changing the timeout). - The mimxrt and samd ports now interpret the argument to WDT.timeout_ms() as signed and if it's negative truncate it to the minimum timeout (rather than it being unsigned and a negative value truncating to the maximum timeout). Signed-off-by: Damien George <damien@micropython.org>
1 parent 2590a34 commit 60929ec

38 files changed

Lines changed: 235 additions & 304 deletions

extmod/extmod.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ set(MICROPY_SOURCE_EXTMOD
1414
${MICROPY_EXTMOD_DIR}/machine_pwm.c
1515
${MICROPY_EXTMOD_DIR}/machine_signal.c
1616
${MICROPY_EXTMOD_DIR}/machine_spi.c
17+
${MICROPY_EXTMOD_DIR}/machine_wdt.c
1718
${MICROPY_EXTMOD_DIR}/modbluetooth.c
1819
${MICROPY_EXTMOD_DIR}/modframebuf.c
1920
${MICROPY_EXTMOD_DIR}/modlwip.c

extmod/extmod.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SRC_EXTMOD_C += \
1111
extmod/machine_signal.c \
1212
extmod/machine_spi.c \
1313
extmod/machine_timer.c \
14+
extmod/machine_wdt.c \
1415
extmod/modasyncio.c \
1516
extmod/modbinascii.c \
1617
extmod/modbluetooth.c \

extmod/machine_wdt.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020-2023 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/runtime.h"
28+
29+
#if MICROPY_PY_MACHINE_WDT
30+
31+
#include "extmod/modmachine.h"
32+
33+
// The port must provide implementations of these low-level WDT functions.
34+
STATIC machine_wdt_obj_t *mp_machine_wdt_make_new_instance(mp_int_t id, mp_int_t timeout_ms);
35+
STATIC void mp_machine_wdt_feed(machine_wdt_obj_t *self);
36+
#if MICROPY_PY_MACHINE_WDT_TIMEOUT_MS
37+
STATIC void mp_machine_wdt_timeout_ms_set(machine_wdt_obj_t *self_in, mp_int_t timeout_ms);
38+
#endif
39+
40+
// The port provides implementations of the above in this file.
41+
#include MICROPY_PY_MACHINE_WDT_INCLUDEFILE
42+
43+
STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
44+
enum { ARG_id, ARG_timeout };
45+
static const mp_arg_t allowed_args[] = {
46+
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
47+
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} },
48+
};
49+
50+
// Parse the arguments.
51+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
52+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
53+
54+
// Create WDT instance.
55+
machine_wdt_obj_t *self = mp_machine_wdt_make_new_instance(args[ARG_id].u_int, args[ARG_timeout].u_int);
56+
57+
return MP_OBJ_FROM_PTR(self);
58+
}
59+
60+
// WDT.feed()
61+
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
62+
machine_wdt_obj_t *self = MP_OBJ_TO_PTR(self_in);
63+
mp_machine_wdt_feed(self);
64+
return mp_const_none;
65+
}
66+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);
67+
68+
#if MICROPY_PY_MACHINE_WDT_TIMEOUT_MS
69+
// WDT.timeout_ms(timeout)
70+
STATIC mp_obj_t machine_wdt_timeout_ms(mp_obj_t self_in, mp_obj_t timeout_in) {
71+
machine_wdt_obj_t *self = MP_OBJ_TO_PTR(self_in);
72+
mp_int_t timeout_ms = mp_obj_get_int(timeout_in);
73+
mp_machine_wdt_timeout_ms_set(self, timeout_ms);
74+
return mp_const_none;
75+
}
76+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_wdt_timeout_ms_obj, machine_wdt_timeout_ms);
77+
#endif
78+
79+
STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = {
80+
{ MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&machine_wdt_feed_obj) },
81+
#if MICROPY_PY_MACHINE_WDT_TIMEOUT_MS
82+
{ MP_ROM_QSTR(MP_QSTR_timeout_ms), MP_ROM_PTR(&machine_wdt_timeout_ms_obj) },
83+
#endif
84+
};
85+
STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table);
86+
87+
MP_DEFINE_CONST_OBJ_TYPE(
88+
machine_wdt_type,
89+
MP_QSTR_WDT,
90+
MP_TYPE_FLAG_NONE,
91+
make_new, machine_wdt_make_new,
92+
locals_dict, &machine_wdt_locals_dict
93+
);
94+
95+
#endif // MICROPY_PY_MACHINE_WDT
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2016 Damien P. George
6+
* Copyright (c) 2023 Damien P. George
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -23,9 +23,21 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2424
* THE SOFTWARE.
2525
*/
26-
#ifndef MICROPY_INCLUDED_STM32_WDT_H
27-
#define MICROPY_INCLUDED_STM32_WDT_H
2826

29-
extern const mp_obj_type_t pyb_wdt_type;
27+
#ifndef MICROPY_INCLUDED_EXTMOD_MODMACHINE_H
28+
#define MICROPY_INCLUDED_EXTMOD_MODMACHINE_H
3029

31-
#endif // MICROPY_INCLUDED_STM32_WDT_H
30+
#include "py/obj.h"
31+
32+
// A port must provide these types, but they are otherwise opaque.
33+
typedef struct _machine_wdt_obj_t machine_wdt_obj_t;
34+
35+
// These classes correspond to machine.Type entries in the machine module.
36+
// Their Python bindings are implemented in extmod, and their implementation
37+
// is provided by a port.
38+
extern const mp_obj_type_t machine_i2c_type;
39+
extern const mp_obj_type_t machine_spi_type;
40+
extern const mp_obj_type_t machine_timer_type;
41+
extern const mp_obj_type_t machine_wdt_type;
42+
43+
#endif // MICROPY_INCLUDED_EXTMOD_MODMACHINE_H

ports/cc3200/application.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ APP_MODS_SRC_C = $(addprefix mods/,\
9393
pybspi.c \
9494
pybtimer.c \
9595
pybuart.c \
96-
pybwdt.c \
9796
)
9897

9998
APP_CC3100_SRC_C = $(addprefix drivers/cc3100/src/,\
Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#include <stdint.h>
27+
// This file is never compiled standalone, it's included directly from
28+
// extmod/machine_wdt.c via MICROPY_PY_MACHINE_WDT_INCLUDEFILE.
2829

29-
#include "py/mpconfig.h"
30-
#include "py/obj.h"
31-
#include "py/runtime.h"
3230
#include "py/mperrno.h"
3331
#include "py/mphal.h"
3432
#include "inc/hw_types.h"
@@ -40,8 +38,6 @@
4038
#include "prcm.h"
4139
#include "utils.h"
4240
#include "pybwdt.h"
43-
#include "mperror.h"
44-
4541

4642
/******************************************************************************
4743
DECLARE CONSTANTS
@@ -52,18 +48,18 @@
5248
/******************************************************************************
5349
DECLARE TYPES
5450
******************************************************************************/
55-
typedef struct {
51+
typedef struct _machine_wdt_obj_t {
5652
mp_obj_base_t base;
5753
bool servers;
5854
bool servers_sleeping;
5955
bool simplelink;
6056
bool running;
61-
} pyb_wdt_obj_t;
57+
} machine_wdt_obj_t;
6258

6359
/******************************************************************************
6460
DECLARE PRIVATE DATA
6561
******************************************************************************/
66-
STATIC pyb_wdt_obj_t pyb_wdt_obj = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
62+
STATIC machine_wdt_obj_t machine_wdt_obj = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
6763

6864
/******************************************************************************
6965
DEFINE PUBLIC FUNCTIONS
@@ -74,39 +70,28 @@ void pybwdt_init0 (void) {
7470
}
7571

7672
void pybwdt_srv_alive (void) {
77-
pyb_wdt_obj.servers = true;
73+
machine_wdt_obj.servers = true;
7874
}
7975

8076
void pybwdt_srv_sleeping (bool state) {
81-
pyb_wdt_obj.servers_sleeping = state;
77+
machine_wdt_obj.servers_sleeping = state;
8278
}
8379

8480
void pybwdt_sl_alive (void) {
85-
pyb_wdt_obj.simplelink = true;
81+
machine_wdt_obj.simplelink = true;
8682
}
8783

8884
/******************************************************************************/
8985
// MicroPython bindings
9086

91-
STATIC const mp_arg_t pyb_wdt_init_args[] = {
92-
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
93-
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, // 5 s
94-
};
95-
STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
96-
// check the arguments
97-
mp_map_t kw_args;
98-
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
99-
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_wdt_init_args)];
100-
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_wdt_init_args, args);
101-
102-
if (args[0].u_obj != mp_const_none && mp_obj_get_int(args[0].u_obj) > 0) {
87+
STATIC machine_wdt_obj_t *mp_machine_wdt_make_new_instance(mp_int_t id, mp_int_t timeout_ms) {
88+
if (id != 0) {
10389
mp_raise_OSError(MP_ENODEV);
10490
}
105-
uint timeout_ms = args[1].u_int;
10691
if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
10792
mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
10893
}
109-
if (pyb_wdt_obj.running) {
94+
if (machine_wdt_obj.running) {
11095
mp_raise_OSError(MP_EPERM);
11196
}
11297

@@ -116,10 +101,10 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
116101
// Unlock to be able to configure the registers
117102
MAP_WatchdogUnlock(WDT_BASE);
118103

119-
#ifdef DEBUG
104+
#ifdef DEBUG
120105
// make the WDT stall when the debugger stops on a breakpoint
121106
MAP_WatchdogStallEnable (WDT_BASE);
122-
#endif
107+
#endif
123108

124109
// set the watchdog timer reload value
125110
// the WDT trigger a system reset after the second timeout
@@ -128,33 +113,16 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
128113

129114
// start the timer. Once it's started, it cannot be disabled.
130115
MAP_WatchdogEnable(WDT_BASE);
131-
pyb_wdt_obj.base.type = &pyb_wdt_type;
132-
pyb_wdt_obj.running = true;
116+
machine_wdt_obj.base.type = &machine_wdt_type;
117+
machine_wdt_obj.running = true;
133118

134-
return (mp_obj_t)&pyb_wdt_obj;
119+
return &machine_wdt_obj;
135120
}
136121

137-
STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) {
138-
pyb_wdt_obj_t *self = self_in;
122+
STATIC void mp_machine_wdt_feed(machine_wdt_obj_t *self) {
139123
if ((self->servers || self->servers_sleeping) && self->simplelink && self->running) {
140124
self->servers = false;
141125
self->simplelink = false;
142126
MAP_WatchdogIntClear(WDT_BASE);
143127
}
144-
return mp_const_none;
145128
}
146-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_wdt_feed_obj, pyb_wdt_feed);
147-
148-
STATIC const mp_rom_map_elem_t pybwdt_locals_dict_table[] = {
149-
{ MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&pyb_wdt_feed_obj) },
150-
};
151-
STATIC MP_DEFINE_CONST_DICT(pybwdt_locals_dict, pybwdt_locals_dict_table);
152-
153-
MP_DEFINE_CONST_OBJ_TYPE(
154-
pyb_wdt_type,
155-
MP_QSTR_WDT,
156-
MP_TYPE_FLAG_NONE,
157-
make_new, pyb_wdt_make_new,
158-
locals_dict, &pybwdt_locals_dict
159-
);
160-

ports/cc3200/mods/modmachine.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "py/runtime.h"
3232
#include "py/mphal.h"
33+
#include "extmod/modmachine.h"
3334
#include "inc/hw_types.h"
3435
#include "inc/hw_gpio.h"
3536
#include "inc/hw_ints.h"
@@ -51,7 +52,6 @@
5152
#include "pybadc.h"
5253
#include "pybi2c.h"
5354
#include "pybsd.h"
54-
#include "pybwdt.h"
5555
#include "pybsleep.h"
5656
#include "pybspi.h"
5757
#include "pybtimer.h"
@@ -189,7 +189,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
189189
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_spi_type) },
190190
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
191191
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&pyb_timer_type) },
192-
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&pyb_wdt_type) },
192+
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) },
193193
{ MP_ROM_QSTR(MP_QSTR_SD), MP_ROM_PTR(&pyb_sd_type) },
194194

195195
// class constants

ports/cc3200/mods/pybwdt.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@
2626
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBWDT_H
2727
#define MICROPY_INCLUDED_CC3200_MODS_PYBWDT_H
2828

29-
#include "py/obj.h"
30-
31-
extern const mp_obj_type_t pyb_wdt_type;
29+
#include <stdbool.h>
3230

3331
void pybwdt_init0 (void);
3432
void pybwdt_srv_alive (void);

ports/cc3200/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@
120120
#define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1)
121121
#define MICROPY_PY_TIME_TIME_TIME_NS (1)
122122
#define MICROPY_PY_TIME_INCLUDEFILE "ports/cc3200/mods/modtime.c"
123+
#define MICROPY_PY_MACHINE_WDT (1)
124+
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/cc3200/mods/machine_wdt.c"
123125

124126
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
125127
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)

ports/esp32/esp32_common.cmake

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ list(APPEND MICROPY_SOURCE_PORT
8686
esp32_ulp.c
8787
modesp32.c
8888
machine_hw_spi.c
89-
machine_wdt.c
9089
mpthreadport.c
9190
machine_rtc.c
9291
machine_sdcard.c

0 commit comments

Comments
 (0)