Merge pull request #489 from kwagyeman/kwabena/fb_extra_alloc_fix

Fix exceptions from freeing fb_alloc_mark
This commit is contained in:
Ibrahim Abd Elkader 2019-03-18 17:08:09 +02:00 committed by GitHub
commit bd41774802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 4 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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()