/* store default values so that no crash due to undefined variable */ if (v->flags & PY_FLAG_ARRAY) { v->index = MP_OBJ_NEW_SMALL_INT(0); v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items); obj = v->list; } else { obj = v->items[0]; } mp_store_name(v->name, obj); if (v->flags & PY_FLAG_FLOAT) { size = dim * sizeof(mp_float_t); data = (void**)&v->data.f; } else { size = dim * sizeof(mp_int_t); data = (void**)&v->data.i; } *data = malloc(size); if (*data == NULL) goto on_error_2; return v; on_error_2: free(v->items); on_error_1: free(v); on_error_0: return NULL; } static py_var_t* py_create_scalar (py_handle_t* py, const char* name, uint32_t flags) { return py_create_var(py, name, 1, flags); } static py_var_t* py_create_array (py_handle_t* py, const char* name, size_t dim, uint32_t flags) { return py_create_var(py, name, dim, flags | PY_FLAG_ARRAY); } static void py_destroy_var(py_var_t* v) { void* data; if (v->flags & PY_FLAG_FLOAT) data = (void*)v->data.f; else data = (void*)v->data.i; free(data); free(v->items); free(v); } static void py_print_var(py_var_t* v) { size_t i; for (i = 0; i != v->dim; ++i) { if (v->flags & PY_FLAG_INT) printf(" %d", v->data.i[i]); else printf(" %lf", v->data.f[i]); } printf("\n"); } static void py_print_out_vars(py_handle_t* py) { size_t i; for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; if ((v->flags & PY_FLAG_OUT) == 0) continue ; py_print_var(v); } } static int py_compile(py_handle_t* py, const char* s) { static const mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT; static const uint emit_opt = MP_EMIT_OPT_NATIVE_PYTHON; nlr_buf_t nlr; int err = -1; if (nlr_push(&nlr)) return -1; py->lex = mp_lexer_new_from_str_len (MP_QSTR__lt_stdin_gt_, s, strlen(s), false); if (py->lex == NULL) goto on_error_0; py->parse_tree = mp_parse(py->lex, input_kind); py->module_fun = mp_compile (&py->parse_tree, py->lex->source_name, emit_opt, false); err = 0; on_error_0: nlr_pop(); return err; } static int py_open(py_handle_t* py) { py->lex = NULL; py->nvar = 0; return 0; } static int py_close(py_handle_t* py) { size_t i; for (i = 0; i != py->nvar; ++i) py_destroy_var(py->vars[i]); return 0; } #if 0 /* does not work, should recompile entirely */ static int py_collect(py_handle_t* py) { mp_obj_t obj; size_t i; size_t j; gc_collect(); for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; v->name = qstr_from_str(v->_name); if (v->flags & PY_FLAG_INT) { for (j = 0; j != v->dim; ++j) { if (v->flags & PY_FLAG_IN) obj = MP_OBJ_NEW_SMALL_INT(v->in.i[j]); else obj = MP_OBJ_NEW_SMALL_INT(v->data.i[j]); v->items[j] = obj; } } else { for (j = 0; j != v->dim; ++j) { if (v->flags & PY_FLAG_IN) obj = mp_obj_new_float(v->in.f[j]); else obj = mp_obj_new_float(v->data.f[j]); v->items[j] = obj; } } /* store default values so that no crash due to undefined variable */ if (v->flags & PY_FLAG_ARRAY) { v->index = MP_OBJ_NEW_SMALL_INT(0); v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items); obj = v->list; } else { obj = v->items[0]; } mp_store_name(v->name, obj); } return 0; }
static int py_store_vars(py_handle_t* py) { mp_obj_t obj; size_t i; size_t j; for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; if ((v->flags & PY_FLAG_IN) == 0) continue ; if (v->flags & PY_FLAG_ARRAY) { if (v->flags & PY_FLAG_INT) { for (j = 0; j != v->dim; ++j) { v->items[j] = MP_OBJ_NEW_SMALL_INT(v->data.i[j]); v->index = MP_OBJ_NEW_SMALL_INT(j); mp_obj_list_store(v->list, v->index, v->items[j]); } } else { for (j = 0; j != v->dim; ++j) { mp_obj_set_float(v->items[j], v->data.f[j]); v->index = MP_OBJ_NEW_SMALL_INT(j); mp_obj_list_store(v->list, v->index, v->items[j]); } } obj = v->list; } else /* scalar */ { if (v->flags & PY_FLAG_INT) v->items[0] = MP_OBJ_NEW_SMALL_INT(v->data.i[0]); else mp_obj_set_float(v->items[0], v->data.f[0]); obj = v->items[0]; } mp_store_name(v->name, obj); } return 0; }
static py_var_t* py_create_var (py_handle_t* py, const char* name, size_t dim, uint32_t flags) { py_var_t* v; mp_obj_t obj; size_t i; size_t size; void** data; v = malloc(sizeof(py_var_t)); if (v == NULL) goto on_error_0; py->vars[py->nvar] = v; ++py->nvar; v->name = qstr_from_str(name); v->flags = flags; v->dim = dim; v->items = malloc(dim * sizeof(mp_obj_t)); if (v->items == NULL) goto on_error_1; if (v->flags & PY_FLAG_INT) { for (i = 0; i != dim; ++i) v->items[i] = MP_OBJ_NEW_SMALL_INT(0); } else { for (i = 0; i != dim; ++i) v->items[i] = mp_obj_new_float(0.0); } /* store default values so that no crash due to undefined variable */ if (v->flags & PY_FLAG_ARRAY) { v->index = MP_OBJ_NEW_SMALL_INT(0); v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items); obj = v->list; } else { obj = v->items[0]; } mp_store_name(v->name, obj); if (v->flags & PY_FLAG_FLOAT) { size = dim * sizeof(mp_float_t); data = (void**)&v->data.f; } else { size = dim * sizeof(mp_int_t); data = (void**)&v->data.i; } *data = malloc(size); if (*data == NULL) goto on_error_2; return v; on_error_2: free(v->items); on_error_1: free(v); on_error_0: return NULL; }
int main(int argc, char **argv) { volatile int stack_dummy; stack_top = (void*)&stack_dummy; pre_process_options(argc, argv); #if MICROPY_ENABLE_GC char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif qstr_init(); mp_init(); char *home = getenv("HOME"); char *path = getenv("MICROPYPATH"); if (path == NULL) { path = "~/.micropython/lib:/usr/lib/micropython"; } uint path_num = 1; // [0] is for current dir (or base dir of the script) for (char *p = path; p != NULL; p = strchr(p, ':')) { path_num++; if (p != NULL) { p++; } } mp_obj_list_init(mp_sys_path, path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); char *p = path; for (int i = 1; i < path_num; i++) { char *p1 = strchr(p, ':'); if (p1 == NULL) { p1 = p + strlen(p); } if (p[0] == '~' && p[1] == '/' && home != NULL) { // Expand standalone ~ to $HOME CHECKBUF(buf, PATH_MAX); CHECKBUF_APPEND(buf, home, strlen(home)); CHECKBUF_APPEND(buf, p + 1, p1 - p - 1); path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(buf, CHECKBUF_LEN(buf))); } else { path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p)); } p = p1 + 1; } mp_obj_list_init(mp_sys_argv, 0); mp_store_name(qstr_from_str("test"), test_obj_new(42)); mp_store_name(qstr_from_str("mem_info"), mp_make_function_n(0, mem_info)); mp_store_name(qstr_from_str("qstr_info"), mp_make_function_n(0, qstr_info)); #if MICROPY_ENABLE_GC mp_store_name(qstr_from_str("gc"), (mp_obj_t)&pyb_gc_obj); #endif // Here is some example code to create a class and instance of that class. // First is the Python, then the C code. // // class TestClass: // pass // test_obj = TestClass() // test_obj.attr = 42 mp_obj_t test_class_type, test_class_instance; test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0)); mp_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = mp_call_function_0(test_class_type)); mp_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42)); /* printf("bytes:\n"); printf(" total %d\n", m_get_total_bytes_allocated()); printf(" cur %d\n", m_get_current_bytes_allocated()); printf(" peak %d\n", m_get_peak_bytes_allocated()); */ bool executed = false; for (int a = 1; a < argc; a++) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-c") == 0) { if (a + 1 >= argc) { return usage(argv); } do_str(argv[a + 1]); executed = true; a += 1; } else if (strcmp(argv[a], "-X") == 0) { a += 1; } else { return usage(argv); } } else { char *basedir = realpath(argv[a], NULL); if (basedir == NULL) { fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno); perror(""); // CPython exits with 2 in such case exit(2); } // Set base dir of the script as first entry in sys.path char *p = strrchr(basedir, '/'); path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir)); free(basedir); for (int i = a; i < argc; i++) { mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } do_file(argv[a]); executed = true; break; } } if (!executed) { do_repl(); } mp_deinit(); //printf("total bytes = %d\n", m_get_total_bytes_allocated()); return 0; }
int main(int argc, char **argv) { mp_stack_set_limit(32768); pre_process_options(argc, argv); #if MICROPY_ENABLE_GC char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif mp_init(); char *home = getenv("HOME"); char *path = getenv("MICROPYPATH"); if (path == NULL) { path = "~/.micropython/lib:/usr/lib/micropython"; } mp_uint_t path_num = 1; // [0] is for current dir (or base dir of the script) for (char *p = path; p != NULL; p = strchr(p, PATHLIST_SEP_CHAR)) { path_num++; if (p != NULL) { p++; } } mp_obj_list_init(mp_sys_path, path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); char *p = path; for (int i = 1; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); } if (p[0] == '~' && p[1] == '/' && home != NULL) { // Expand standalone ~ to $HOME CHECKBUF(buf, PATH_MAX); CHECKBUF_APPEND(buf, home, strlen(home)); CHECKBUF_APPEND(buf, p + 1, p1 - p - 1); path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(buf, CHECKBUF_LEN(buf))); } else { path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p)); } p = p1 + 1; } mp_obj_list_init(mp_sys_argv, 0); mp_store_name(qstr_from_str("mem_info"), (mp_obj_t*)&mem_info_obj); mp_store_name(qstr_from_str("qstr_info"), (mp_obj_t*)&qstr_info_obj); // Here is some example code to create a class and instance of that class. // First is the Python, then the C code. // // class TestClass: // pass // test_obj = TestClass() // test_obj.attr = 42 // // mp_obj_t test_class_type, test_class_instance; // test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0)); // mp_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = mp_call_function_0(test_class_type)); // mp_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42)); /* printf("bytes:\n"); printf(" total %d\n", m_get_total_bytes_allocated()); printf(" cur %d\n", m_get_current_bytes_allocated()); printf(" peak %d\n", m_get_peak_bytes_allocated()); */ const int NOTHING_EXECUTED = -2; int ret = NOTHING_EXECUTED; for (int a = 1; a < argc; a++) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-c") == 0) { if (a + 1 >= argc) { return usage(argv); } ret = do_str(argv[a + 1]); a += 1; } else if (strcmp(argv[a], "-X") == 0) { a += 1; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; } else if (strncmp(argv[a], "-O", 2) == 0) { if (isdigit(argv[a][2])) { mp_optimise_value = argv[a][2] & 0xf; } else { mp_optimise_value = 0; for (char *p = argv[a] + 1; *p && *p == 'O'; p++, mp_optimise_value++); } } else { return usage(argv); } } else { char *pathbuf = malloc(PATH_MAX); char *basedir = realpath(argv[a], pathbuf); if (basedir == NULL) { fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[a], errno); perror(""); // CPython exits with 2 in such case ret = 2; break; } // Set base dir of the script as first entry in sys.path char *p = strrchr(basedir, '/'); path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir)); free(pathbuf); for (int i = a; i < argc; i++) { mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } ret = do_file(argv[a]); break; } } if (ret == NOTHING_EXECUTED) { do_repl(); ret = 0; } mp_deinit(); //printf("total bytes = %d\n", m_get_total_bytes_allocated()); return ret; }
int main(void) { // TODO disable JTAG // update the SystemCoreClock variable SystemCoreClockUpdate(); // set interrupt priority config to use all 4 bits for pre-empting NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // enable the CCM RAM and the GPIO's RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN; #if MICROPY_HW_HAS_SDCARD { // configure SDIO pins to be high to start with (apparently makes it more robust) // FIXME this is not making them high, it just makes them outputs... GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure PD.02 CMD line GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); } #endif #if defined(NETDUINO_PLUS_2) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; #if MICROPY_HW_HAS_SDCARD // Turn on the power enable for the sdcard (PB1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET); #endif // Turn on the power for the 5V on the expansion header (PB2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); } #endif // basic sub-system init sys_tick_init(); pendsv_init(); led_init(); #if MICROPY_HW_ENABLE_RTC rtc_init(); #endif // turn on LED to indicate bootup led_state(PYB_LED_G1, 1); // more sub-system init #if MICROPY_HW_HAS_SDCARD sdcard_init(); #endif storage_init(); // uncomment these 2 lines if you want REPL on USART_6 (or another usart) as well as on USB VCP //pyb_usart_global_debug = PYB_USART_YA; //usart_init(pyb_usart_global_debug, 115200); int first_soft_reset = true; soft_reset: // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init qstr_init(); mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); exti_init(); #if MICROPY_HW_HAS_SWITCH switch_init(); #endif #if MICROPY_HW_HAS_LCD // LCD init (just creates class, init hardware by calling LCD()) lcd_init(); #endif #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif #if MICROPY_HW_ENABLE_TIMER // timer timer_init(); #endif #if MICROPY_HW_ENABLE_RNG // RNG RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); RNG_Cmd(ENABLE); #endif pin_map_init(); // add some functions to the builtin Python namespace mp_store_name(MP_QSTR_help, mp_make_function_n(0, pyb_help)); mp_store_name(MP_QSTR_open, mp_make_function_n(2, pyb_io_open)); // load the pyb module mp_module_register(MP_QSTR_pyb, (mp_obj_t)&pyb_module); // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; #if MICROPY_HW_HAS_SWITCH if (switch_get()) { reset_filesystem = true; for (int i = 0; i < 50; i++) { if (!switch_get()) { reset_filesystem = false; break; } sys_tick_delay_ms(10); } } #endif // local filesystem init { // try to mount the flash FRESULT res = f_mount(&fatfs0, "0:", 1); if (!reset_filesystem && res == FR_OK) { // mount sucessful } else if (reset_filesystem || res == FR_NO_FILESYSTEM) { // no filesystem, so create a fresh one // TODO doesn't seem to work correctly when reset_filesystem is true... // LED on to indicate creation of LFS led_state(PYB_LED_R2, 1); uint32_t stc = sys_tick_counter; res = f_mkfs("0:", 0, 0); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("could not create LFS"); } // create src directory res = f_mkdir("0:/src"); // ignore result from mkdir // create empty main.py FIL fp; f_open(&fp, "0:/src/main.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } else { __fatal_error("could not access LFS"); } } // make sure we have a /boot.py { FILINFO fno; FRESULT res = f_stat("0:/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file // LED on to indicate creation of boot.py led_state(PYB_LED_R2, 1); uint32_t stc = sys_tick_counter; FIL fp; f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } } // run /boot.py if (!pyexec_file("0:/boot.py")) { flash_error(4); } if (first_soft_reset) { #if MICROPY_HW_HAS_MMA7660 // MMA accel: init and reset address to zero accel_init(); #endif } // turn boot-up LED off led_state(PYB_LED_G1, 0); #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on 1:/ if (sdcard_is_present()) { FRESULT res = f_mount(&fatfs1, "1:", 1); if (res != FR_OK) { printf("[SD] could not mount SD card\n"); } else { if (first_soft_reset) { // use SD card as medium for the USB MSD usbd_storage_select_medium(USBD_STORAGE_MEDIUM_SDCARD); } } } #endif #ifdef USE_HOST_MODE // USB host pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); #endif // run main script { vstr_t *vstr = vstr_new(); vstr_add_str(vstr, "0:/"); if (pyb_config_source_dir == MP_OBJ_NULL) { vstr_add_str(vstr, "src"); } else { vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_source_dir)); } vstr_add_char(vstr, '/'); if (pyb_config_main == MP_OBJ_NULL) { vstr_add_str(vstr, "main.py"); } else { vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main)); } if (!pyexec_file(vstr_str(vstr))) { flash_error(3); } vstr_free(vstr); } #if MICROPY_HW_HAS_MMA7660 // HID example if (0) { uint8_t data[4]; data[0] = 0; data[1] = 1; data[2] = -2; data[3] = 0; for (;;) { #if MICROPY_HW_HAS_SWITCH if (switch_get()) { data[0] = 0x01; // 0x04 is middle, 0x02 is right } else { data[0] = 0x00; } #else data[0] = 0x00; #endif accel_start(0x4c /* ACCEL_ADDR */, 1); accel_send_byte(0); accel_restart(0x4c /* ACCEL_ADDR */, 0); for (int i = 0; i <= 1; i++) { int v = accel_read_ack() & 0x3f; if (v & 0x20) { v |= ~0x1f; } data[1 + i] = v; } accel_read_nack(); usb_hid_send_report(data); sys_tick_delay_ms(15); } } #endif #if MICROPY_HW_HAS_WLAN // wifi pyb_wlan_init(); pyb_wlan_start(); #endif pyexec_repl(); printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); first_soft_reset = false; goto soft_reset; }