Skip to content

Commit ad7b84a

Browse files
committed
stmhal: Add os module with a few basic functions.
1 parent 684164a commit ad7b84a

7 files changed

Lines changed: 201 additions & 3 deletions

File tree

stmhal/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ SRC_C = \
7373
gccollect.c \
7474
pyexec.c \
7575
pybmodule.c \
76+
osmodule.c \
7677
import.c \
7778
lexerfatfs.c \
7879
gpio.c \

stmhal/main.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "pendsv.h"
1111
#include "mpconfig.h"
1212
#include "qstr.h"
13-
#include "nlr.h"
1413
#include "misc.h"
1514
#include "lexer.h"
1615
#include "parse.h"
@@ -23,6 +22,7 @@
2322
#include "gccollect.h"
2423
#include "pyexec.h"
2524
#include "pybmodule.h"
25+
#include "osmodule.h"
2626
#include "usart.h"
2727
#include "led.h"
2828
#include "exti.h"
@@ -276,6 +276,10 @@ int main(void) {
276276
// probably shouldn't do this, so we are compatible with CPython
277277
rt_store_name(MP_QSTR_pyb, (mp_obj_t)&pyb_module);
278278

279+
// pre-import the os module
280+
// TODO don't do this! (need a way of registering builtin modules...)
281+
rt_store_name(MP_QSTR_os, (mp_obj_t)&os_module);
282+
279283
// check if user switch held (initiates reset of filesystem)
280284
bool reset_filesystem = false;
281285
#if MICROPY_HW_HAS_SWITCH
@@ -475,10 +479,8 @@ int main(void) {
475479

476480
pyexec_repl();
477481

478-
#if 0
479482
printf("PYB: sync filesystems\n");
480483
storage_flush();
481-
#endif
482484

483485
printf("PYB: soft reboot\n");
484486

stmhal/osmodule.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include <string.h>
2+
3+
#include "nlr.h"
4+
#include "misc.h"
5+
#include "mpconfig.h"
6+
#include "qstr.h"
7+
#include "obj.h"
8+
#include "map.h"
9+
#include "systick.h"
10+
#include "rng.h"
11+
#include "storage.h"
12+
#include "ff.h"
13+
#include "osmodule.h"
14+
15+
#if _USE_LFN
16+
static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */
17+
#endif
18+
19+
STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) {
20+
const mp_obj_type_t *local_str_type = &str_type;
21+
const char *path;
22+
if (n_args == 1) {
23+
if (mp_obj_get_type(args[0]) == &bytes_type) {
24+
local_str_type = &bytes_type;
25+
}
26+
path = mp_obj_str_get_str(args[0]);
27+
} else {
28+
path = "0:";
29+
}
30+
31+
FRESULT res;
32+
FILINFO fno;
33+
DIR dir;
34+
#if _USE_LFN
35+
fno.lfname = lfn;
36+
fno.lfsize = sizeof lfn;
37+
#endif
38+
39+
res = f_opendir(&dir, path); /* Open the directory */
40+
if (res != FR_OK) {
41+
// TODO should be mp_type_FileNotFoundError
42+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
43+
}
44+
45+
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
46+
47+
uint path_len = strlen(path);
48+
if (path[path_len - 1] == '/') {
49+
path_len--;
50+
}
51+
52+
for (;;) {
53+
res = f_readdir(&dir, &fno); /* Read a directory item */
54+
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
55+
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
56+
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
57+
58+
#if _USE_LFN
59+
char *fn = *fno.lfname ? fno.lfname : fno.fname;
60+
#else
61+
char *fn = fno.fname;
62+
#endif
63+
64+
if (fno.fattrib & AM_DIR) { /* It is a directory */
65+
} else { /* It is a file. */
66+
}
67+
68+
// make a string object for this entry
69+
byte *data;
70+
uint fn_len = strlen(fn);
71+
mp_obj_t entry_o = mp_obj_str_builder_start(local_str_type, path_len + 1 + fn_len, &data);
72+
memcpy(data, path, path_len);
73+
data[path_len] = '/';
74+
memcpy(data + path_len + 1, fn, fn_len);
75+
76+
// add the entry to the list
77+
mp_obj_list_append(dir_list, mp_obj_str_builder_end(entry_o));
78+
}
79+
80+
f_closedir(&dir);
81+
82+
return dir_list;
83+
}
84+
85+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
86+
87+
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
88+
const char *path = mp_obj_str_get_str(path_o);
89+
FRESULT res = f_mkdir(path);
90+
switch (res) {
91+
case FR_OK:
92+
return mp_const_none;
93+
case FR_EXIST:
94+
// TODO should be FileExistsError
95+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
96+
default:
97+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
98+
}
99+
}
100+
101+
MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
102+
103+
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
104+
const char *path = mp_obj_str_get_str(path_o);
105+
// TODO check that path is actually a file before trying to unlink it
106+
FRESULT res = f_unlink(path);
107+
switch (res) {
108+
case FR_OK:
109+
return mp_const_none;
110+
default:
111+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
112+
}
113+
}
114+
115+
MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
116+
117+
STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
118+
const char *path = mp_obj_str_get_str(path_o);
119+
// TODO check that path is actually a directory before trying to unlink it
120+
FRESULT res = f_unlink(path);
121+
switch (res) {
122+
case FR_OK:
123+
return mp_const_none;
124+
default:
125+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
126+
}
127+
}
128+
129+
MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
130+
131+
STATIC mp_obj_t os_sync(void) {
132+
storage_flush();
133+
return mp_const_none;
134+
}
135+
136+
MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
137+
138+
STATIC mp_obj_t os_urandom(mp_obj_t num) {
139+
machine_int_t n = mp_obj_get_int(num);
140+
byte *data;
141+
mp_obj_t o = mp_obj_str_builder_start(&bytes_type, n, &data);
142+
for (int i = 0; i < n; i++) {
143+
data[i] = rng_get();
144+
}
145+
return mp_obj_str_builder_end(o);
146+
}
147+
148+
MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
149+
150+
STATIC const mp_map_elem_t os_module_globals_table[] = {
151+
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_os) },
152+
153+
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
154+
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
155+
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
156+
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
157+
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
158+
159+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
160+
161+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
162+
163+
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
164+
};
165+
166+
STATIC const mp_map_t os_module_globals = {
167+
.all_keys_are_qstrs = 1,
168+
.table_is_fixed_array = 1,
169+
.used = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t),
170+
.alloc = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t),
171+
.table = (mp_map_elem_t*)os_module_globals_table,
172+
};
173+
174+
const mp_obj_module_t os_module = {
175+
.base = { &mp_type_module },
176+
.name = MP_QSTR_os,
177+
.globals = (mp_map_t*)&os_module_globals,
178+
};

stmhal/osmodule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extern const mp_obj_module_t os_module;

stmhal/qstrdefsport.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,14 @@ Q(PULL_UP)
5555
Q(PULL_DOWN)
5656
Q(PUSH_PULL)
5757
Q(OPEN_DRAIN)
58+
59+
// for os module
60+
Q(os)
61+
Q(/)
62+
Q(listdir)
63+
Q(mkdir)
64+
Q(remove)
65+
Q(rmdir)
66+
Q(unlink)
67+
Q(sep)
68+
Q(urandom)

stmhal/rng.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ void rng_init(void) {
1414
HAL_RNG_Init(&RngHandle);
1515
}
1616

17+
uint32_t rng_get(void) {
18+
return HAL_RNG_GetRandomNumber(&RngHandle);
19+
}
20+
1721
STATIC mp_obj_t pyb_rng_get(void) {
1822
return mp_obj_new_int(HAL_RNG_GetRandomNumber(&RngHandle) >> 2);
1923
}

stmhal/rng.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
void rng_init(void);
2+
uint32_t rng_get(void);
23

34
MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj);

0 commit comments

Comments
 (0)