mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #489 from kwagyeman/kwabena/fb_extra_alloc_fix
Fix exceptions from freeing fb_alloc_mark
This commit is contained in:
commit
bd41774802
@ -12,6 +12,7 @@
|
||||
|
||||
extern char _fballoc;
|
||||
static char *pointer = &_fballoc;
|
||||
static int marks = 0;
|
||||
|
||||
__weak NORETURN void fb_alloc_fail()
|
||||
{
|
||||
@ -23,6 +24,7 @@ __weak NORETURN void fb_alloc_fail()
|
||||
void fb_alloc_init0()
|
||||
{
|
||||
pointer = &_fballoc;
|
||||
marks = 0;
|
||||
}
|
||||
|
||||
uint32_t fb_avail()
|
||||
@ -48,15 +50,18 @@ void fb_alloc_mark()
|
||||
// we will use a size value of 4 as a marker in the alloc stack.
|
||||
*((uint32_t *) new_pointer) = sizeof(uint32_t); // Save size.
|
||||
pointer = new_pointer;
|
||||
marks += 1;
|
||||
}
|
||||
|
||||
void fb_alloc_free_till_mark()
|
||||
{
|
||||
if (!marks) return;
|
||||
while (pointer < &_fballoc) {
|
||||
int size = *((uint32_t *) pointer);
|
||||
pointer += size; // Get size and pop.
|
||||
if (size == sizeof(uint32_t)) break; // Break on first marker.
|
||||
}
|
||||
marks -= 1;
|
||||
}
|
||||
|
||||
// returns null pointer without error if size==0
|
||||
@ -128,4 +133,5 @@ void fb_free_all()
|
||||
while (pointer < &_fballoc) {
|
||||
pointer += *((uint32_t *) pointer); // Get size and pop.
|
||||
}
|
||||
marks = 0;
|
||||
}
|
||||
|
||||
@ -151,6 +151,7 @@ static float calculate_Ta() // ambient temp
|
||||
|
||||
static void calculate_To(float Ta, float *To)
|
||||
{
|
||||
fb_alloc_mark();
|
||||
int16_t *v_ir = fb_alloc(64 * sizeof(int16_t));
|
||||
// Read IR sensor result
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
@ -190,6 +191,7 @@ static void calculate_To(float Ta, float *To)
|
||||
To[i] = sqrtf(sqrtf((v_ir_comp/alpha_comp_ij)+Tak4))-273.15f;
|
||||
}
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
}
|
||||
|
||||
static mp_obj_t py_fir_deinit()
|
||||
@ -260,6 +262,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
b_ij = xalloc(64 * sizeof(*b_ij));
|
||||
alpha_ij = xalloc(64 * sizeof(*alpha_ij));
|
||||
|
||||
fb_alloc_mark();
|
||||
uint8_t *eeprom = fb_alloc(256 * sizeof(uint8_t));
|
||||
// Read the whole eeprom.
|
||||
test_ack(soft_i2c_write_bytes(FIR_EEPROM_ADDR,
|
||||
@ -336,6 +339,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
powf(2,b_i_scale+(3-ADC_resolution));
|
||||
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
case FIR_MLX90640:
|
||||
@ -363,6 +367,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
error |= MLX90640_SetResolution(MLX90640_ADDR, ADC_resolution);
|
||||
error |= MLX90640_SetRefreshRate(MLX90640_ADDR, IR_refresh_rate);
|
||||
|
||||
fb_alloc_mark();
|
||||
uint16_t *eeprom = fb_alloc(832 * sizeof(uint16_t));
|
||||
error |= MLX90640_DumpEE(MLX90640_ADDR, eeprom);
|
||||
error |= MLX90640_ExtractParameters(eeprom, (paramsMLX90640 *) alpha_ij);
|
||||
@ -370,6 +375,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
PY_ASSERT_TRUE_MSG(error == 0, "Failed to init the MLX90640!");
|
||||
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
case FIR_AMG8833:
|
||||
@ -441,11 +447,13 @@ mp_obj_t py_fir_read_ta()
|
||||
case FIR_SHIELD: return mp_obj_new_float(calculate_Ta());
|
||||
case FIR_MLX90640:
|
||||
{
|
||||
fb_alloc_mark();
|
||||
uint16_t *data = fb_alloc(834 * sizeof(uint16_t));
|
||||
PY_ASSERT_TRUE_MSG(MLX90640_GetFrameData(MLX90640_ADDR, data) >= 0,
|
||||
"Failed to read the MLX90640 sensor data!");
|
||||
mp_obj_t result = mp_obj_new_float(MLX90640_GetTa(data, (paramsMLX90640 *) alpha_ij));
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
case FIR_AMG8833:
|
||||
@ -468,6 +476,7 @@ mp_obj_t py_fir_read_ir()
|
||||
case FIR_NONE: return mp_const_none;
|
||||
case FIR_SHIELD:
|
||||
{
|
||||
fb_alloc_mark();
|
||||
float *To = fb_alloc(64 * sizeof(float)), *To_rot = fb_alloc(64 * sizeof(float));
|
||||
float Ta = calculate_Ta();
|
||||
float min = FLT_MAX, max = FLT_MIN;
|
||||
@ -496,10 +505,12 @@ mp_obj_t py_fir_read_ir()
|
||||
|
||||
fb_free();
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
}
|
||||
case FIR_MLX90640:
|
||||
{
|
||||
fb_alloc_mark();
|
||||
uint16_t *data = fb_alloc(834 * sizeof(uint16_t));
|
||||
// Calculate 1st sub-frame...
|
||||
PY_ASSERT_TRUE_MSG(MLX90640_GetFrameData(MLX90640_ADDR, data) >= 0,
|
||||
@ -533,6 +544,7 @@ mp_obj_t py_fir_read_ir()
|
||||
|
||||
fb_free();
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
}
|
||||
case FIR_AMG8833:
|
||||
@ -545,6 +557,7 @@ mp_obj_t py_fir_read_ir()
|
||||
float Ta = temp * 0.0625;
|
||||
|
||||
test_ack(soft_i2c_write_bytes(AMG8833_ADDR, (uint8_t [1]){0x80}, 1, true));
|
||||
fb_alloc_mark();
|
||||
int16_t *data = fb_alloc(64 * sizeof(int16_t));
|
||||
test_ack(soft_i2c_read_bytes(AMG8833_ADDR, (uint8_t *) data, 128, true));
|
||||
float To[64], min = FLT_MAX, max = FLT_MIN;
|
||||
@ -569,6 +582,7 @@ mp_obj_t py_fir_read_ir()
|
||||
}
|
||||
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
}
|
||||
}
|
||||
@ -647,6 +661,7 @@ mp_obj_t py_fir_draw_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
mp_obj_t *arg_To;
|
||||
mp_obj_get_array_fixed_n(args[1], width*height, &arg_To);
|
||||
|
||||
fb_alloc_mark();
|
||||
float *To = fb_alloc(width*height * sizeof(float)), min = FLT_MAX, max = FLT_MIN;
|
||||
for (int i=0; i<width*height; i++) {
|
||||
float temp = To[i] = mp_obj_get_float(arg_To[i]);
|
||||
@ -711,6 +726,7 @@ mp_obj_t py_fir_draw_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
}
|
||||
}
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_draw_ir_obj, 2, py_fir_draw_ir);
|
||||
|
||||
@ -6095,11 +6095,13 @@ static mp_obj_t py_image_find_template(uint n_args, const mp_obj_t *args, mp_map
|
||||
// Find template
|
||||
rectangle_t r;
|
||||
float corr;
|
||||
fb_alloc_mark();
|
||||
if (search == SEARCH_DS) {
|
||||
corr = imlib_template_match_ds(arg_img, arg_template, &r);
|
||||
} else {
|
||||
corr = imlib_template_match_ex(arg_img, arg_template, &roi, step, &r);
|
||||
}
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (corr > arg_thresh) {
|
||||
mp_obj_t rec_obj[4] = {
|
||||
@ -6130,7 +6132,9 @@ static mp_obj_t py_image_find_features(uint n_args, const mp_obj_t *args, mp_map
|
||||
"Region of interest is smaller than detector window!");
|
||||
|
||||
// Detect objects
|
||||
fb_alloc_mark();
|
||||
array_t *objects_array = imlib_detect_objects(arg_img, cascade, &roi);
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
// Add detected objects to a new Python list...
|
||||
mp_obj_t objects_list = mp_obj_new_list(0, NULL);
|
||||
@ -6209,7 +6213,9 @@ static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_ma
|
||||
#endif
|
||||
|
||||
// Find keypoints
|
||||
fb_alloc_mark();
|
||||
array_t *kpts = orb_find_keypoints(arg_img, normalized, threshold, scale_factor, max_keypoints, corner_detector, &roi);
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (array_length(kpts)) {
|
||||
py_kp_obj_t *kp_obj = m_new_obj(py_kp_obj_t);
|
||||
@ -6245,11 +6251,15 @@ static mp_obj_t py_image_find_edges(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
|
||||
switch (edge_type) {
|
||||
case EDGE_SIMPLE: {
|
||||
fb_alloc_mark();
|
||||
imlib_edge_simple(arg_img, &roi, thresh[0], thresh[1]);
|
||||
fb_alloc_free_till_mark();
|
||||
break;
|
||||
}
|
||||
case EDGE_CANNY: {
|
||||
fb_alloc_mark();
|
||||
imlib_edge_canny(arg_img, &roi, thresh[0], thresh[1]);
|
||||
fb_alloc_free_till_mark();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6270,7 +6280,9 @@ static mp_obj_t py_image_find_hog(uint n_args, const mp_obj_t *args, mp_map_t *k
|
||||
|
||||
int size = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), 8);
|
||||
|
||||
fb_alloc_mark();
|
||||
imlib_find_hog(arg_img, &roi, size);
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
}
|
||||
@ -7389,6 +7401,7 @@ static mp_obj_t py_image_match_descriptor(uint n_args, const mp_obj_t *args, mp_
|
||||
mp_obj_t match_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
if (array_length(kpts1->kpts) && array_length(kpts1->kpts)) {
|
||||
fb_alloc_mark();
|
||||
int *match = fb_alloc(array_length(kpts1->kpts) * sizeof(int) * 2);
|
||||
|
||||
// Match the two keypoint sets
|
||||
@ -7405,6 +7418,7 @@ static mp_obj_t py_image_match_descriptor(uint n_args, const mp_obj_t *args, mp_
|
||||
|
||||
// Free match list
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (filter_outliers == true) {
|
||||
count = orb_filter_keypoints(kpts2->kpts, &r, &c);
|
||||
|
||||
@ -310,6 +310,7 @@ static mp_obj_t py_lcd_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_a
|
||||
return mp_const_none;
|
||||
case LCD_SHIELD:
|
||||
lcd_write_command_byte(0x2C);
|
||||
fb_alloc_mark();
|
||||
uint8_t *zero = fb_alloc0(width*2);
|
||||
uint16_t *line = fb_alloc(width*2);
|
||||
for (int i=0; i<t_pad; i++) {
|
||||
@ -339,6 +340,7 @@ static mp_obj_t py_lcd_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_a
|
||||
}
|
||||
fb_free();
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
return mp_const_none;
|
||||
@ -351,11 +353,13 @@ static mp_obj_t py_lcd_clear()
|
||||
return mp_const_none;
|
||||
case LCD_SHIELD:
|
||||
lcd_write_command_byte(0x2C);
|
||||
fb_alloc_mark();
|
||||
uint8_t *zero = fb_alloc0(width*2);
|
||||
for (int i=0; i<height; i++) {
|
||||
lcd_write_data(width*2, zero);
|
||||
}
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
return mp_const_none;
|
||||
|
||||
@ -149,15 +149,17 @@ static mp_obj_t py_sensor_alloc_extra_fb(mp_obj_t w_obj, mp_obj_t h_obj, mp_obj_
|
||||
break;
|
||||
}
|
||||
|
||||
fb_alloc_mark();
|
||||
img.pixels = fb_alloc0(image_size(&img));
|
||||
return py_image_from_struct(&img);
|
||||
// Alloc image first (could fail) then alloc RAM so that there's no leak on failure.
|
||||
mp_obj_t r = py_image_from_struct(&img);
|
||||
// Don't mark before on purpose.
|
||||
((image_t *) py_image_cobj(r))->pixels = fb_alloc0(image_size(&img));
|
||||
return r;
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_dealloc_extra_fb()
|
||||
{
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
// Don't free till mark aftwards on purpose.
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
|
||||
@ -555,6 +555,7 @@ static mp_obj_t py_tv_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_ar
|
||||
uint16_t x = x1;
|
||||
uint16_t y = y1;
|
||||
|
||||
fb_alloc_mark();
|
||||
uint8_t *line = fb_alloc(w*2);
|
||||
|
||||
while (y < y2) {
|
||||
@ -586,6 +587,7 @@ static mp_obj_t py_tv_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_ar
|
||||
y++;
|
||||
}
|
||||
fb_free();
|
||||
fb_alloc_free_till_mark();
|
||||
return mp_const_none;
|
||||
}
|
||||
static mp_obj_t py_tv_palettes()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user