Division by zero usage fault from MAX817048 fuel-guage

Hi,

we are using MAX817048 fuel guage in our project which uses nrf5340 brd. we are using the max817048 fuel guage drivers provided by zephyr  in sdk version v2.4.2 to integrate this fuel guage. but  upon testing we are facing this division by zero error when trying to read the soc of the battery.

We found that this is caused because the division by zero case is not handled inside the driver provided by sdk v2.4.2. Unfortunatly we can't change the version of the sdk due to many other dependencies in our project.

Is there a way to resolve this issue without changing the sdk version in our project.

Parents
  • Hi,

    Which specific bug is this / where is the bug? That said, if you don't want to update to a newer SDK where this may be fixed, you can fix it yourself in your fork (which you probably want to make when you start modifying SDK code to keep track of it and keep it maintainable).

  • Hi,

    By debugging we understood that the error occurs when 'crate=0' when the 'max17048_get_props()' function is called. This function is provided in the max817048 driver included in the sdk.

    /**
     * Get all possible properties from the fuel gague
     */
    static int max17048_get_props(const struct device *dev, struct fuel_gauge_get_property *props,
    			      size_t len)
    {
    	int err_count = 0;
    	struct max17048_data *data = dev->data;
    	int rc = max17048_percent(dev, &data->charge);
    	int16_t crate;
    
    	if (rc < 0) {
    		LOG_ERR("Error while reading battery percentage");
    		return rc;
    	}
    
    	rc = max17048_voltage(dev, &data->voltage);
    	if (rc < 0) {
    		LOG_ERR("Error while reading battery voltage");
    		return rc;
    	}
    
    	/**
    	 * Crate (current rate) is the current percentage of the battery charged or drained
    	 * per hour
    	 */
    	rc = max17048_crate(dev, &crate);
    	if (rc < 0) {
    		LOG_ERR("Error while reading battery current rate");
    		return rc;
    	}
    
    	/**
    	 * May take some time until the chip detects the change between discharging to charging
    	 * (and vice versa) especially if your device consumes little power
    	 */
    	data->charging = crate > 0;
    
    
    	/**
    	 * In the following code, we multiply by 1000 the charge to increase the precision. If we
    	 * just truncate the division without this multiplier, the precision lost is very
    	 * significant when converting it into minutes (the value given is in hours)
    	 *
    	 * The value coming from crate is already 1000 times higher (check the function
    	 * max17048_crate to
    	 * see the reason) so the multiplier for the charge
    	 * will be 1000000
    	 */
    	if (data->charging) {
    		uint8_t percentage_pending = 100 - data->charge;
    		uint32_t hours_pending = percentage_pending * 1000000 / crate;
    
    		data->time_to_empty = 0;
    		data->time_to_full = hours_pending * 60 / 1000;
    	} else {
    		/* Discharging */
    		uint32_t hours_pending = data->charge * 1000000 / -crate;
    
    		data->time_to_empty = hours_pending * 60 / 1000;
    		data->time_to_full = 0;
    	}
    
    	for (int i = 0; i < len; i++) {
    		int ret = max17048_get_prop(dev, props + i);
    
    		err_count += ret ? 1 : 0;
    	}
    
    	err_count = (err_count == len) ? -1 : err_count;
    
    	return err_count;
    }

  • Hi,

    I see. That is fixed in newer SDK versions. If you do not want to migrate, you can cherry pick the relevant changes yourself.

Reply Children
No Data
Related