hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t) Topic is solved

Use this forum for requesting small changes in ChibiOS. Large changes should be discussed in the development forum. This forum is NOT for support.
Post Reply
faisal
Posts: 382
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 45 times
Been thanked: 62 times

hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by faisal »

Being able to map between a flash offset and the sector is useful (similar to the sector to offset func that currently exists).

So, something like this:

Code: Select all

flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)
faisal
Posts: 382
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 45 times
Been thanked: 62 times

Re: hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by faisal »

Here's an implementation (untested).

Code: Select all

/**
 * @brief   Returns the sector of an offset.
 *
 * @param[in] devp      pointer to a @p BaseFlash object
 * @param[in] offset    flash offset
 *
 * @return the sector of the offset
 */
flash_sector_t flashGetOffsetSector(BaseFlash *devp,
                                    flash_offset_t offset)
{
  flash_sector_t sector;
  const flash_descriptor_t *descriptor = flashGetDescriptor(devp);

  osalDbgAssert(offset > (descriptor->address + descriptor->size),
          "invalid offset");

  if (descriptor->sectors != NULL) {
      flash_offset_t sector_start;
      flash_offset_t sector_end;
      for (int i = 0; i < descriptor->sectors_count; i++)
      {
          sector_start = descriptor->sectors[i].offset;
          sector_end = sector_start + descriptor->sectors[i].size - 1;
          if ((offset >= sector_start) && (offset <= sector_end))
          {
              return sector;
          }
      }
      osalDbgAssert(TRUE, "invalid offset");
  }
  else {
      sector = (descriptor->address + offset)/descriptor->sectors_size;
  }

  return sector;
}
faisal
Posts: 382
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 45 times
Been thanked: 62 times

Re: hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by faisal »

A small update:

Code: Select all

flash_sector_t flashGetOffsetSector(BaseFlash *devp,
                                    flash_offset_t offset)
{
  flash_sector_t sector;
  const flash_descriptor_t *descriptor = flashGetDescriptor(devp);

  osalDbgAssert(offset > ((flash_offset_t)descriptor->address + descriptor->size),
          "invalid offset");

  if (descriptor->sectors != NULL) {
      flash_offset_t sector_start;
      flash_offset_t sector_end;
      for (flash_sector_t i = 0; i < descriptor->sectors_count; i++)
      {
          sector_start = descriptor->sectors[i].offset;
          sector_end = sector_start + descriptor->sectors[i].size - 1;
          if ((offset >= sector_start) && (offset <= sector_end))
          {
               sector = i;
               break;
          }
      }
      osalDbgAssert(TRUE, "invalid offset");
  }
  else {
      sector = ((flash_offset_t)descriptor->address + offset)/descriptor->sectors_size;
  }

  return sector;
}
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by Giovanni »

Hi,

Is it tested now?

Giovanni
faisal
Posts: 382
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 45 times
Been thanked: 62 times

Re: hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by faisal »

Now it is tested (fixed a few bugs) but only the descriptor->sectors == NULL path (uniform sector sizes). I also added some more helpful functions that are commonly needed when interacting with hal-flash.

Code: Select all

/**
 * @brief   Get absolute address from offset
 *
 * @param[in] ip                    pointer to a @p BaseFlash or derived class
 * @param[in] offset                offset
 * @return                          A pointer to the offset
 *
 * @api
 */
void * flashGetOffsetAddress(BaseFlash *devp, flash_offset_t offset)
{
    osalDbgCheck(devp != NULL);

    const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
    osalDbgAssert(offset < descriptor->size, "invalid offset");

    return (void *)((flash_offset_t)descriptor->address + offset);
}

/**
 * @brief   Get offset from absolute address
 *
 * @param[in] ip                    pointer to a @p BaseFlash or derived class
 * @param[in] addr                  pointer
 * @return                          offset
 *
 * @api
 */
flash_offset_t flashGetAddressOffset(BaseFlash *devp, void * addr)
{
    osalDbgCheck(devp != NULL);

    const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
    osalDbgAssert(((flash_offset_t)addr >=
                (flash_offset_t)descriptor->address)
            && ((flash_offset_t)addr < (flash_offset_t)descriptor->address +
                descriptor->size),
            "invalid address");

    return (flash_offset_t)addr - (flash_offset_t)descriptor->address;
}

/**
 * @brief   Returns the sector of an offset.
 *
 * @param[in] devp      pointer to a @p BaseFlash object
 * @param[in] offset    flash offset
 *
 * @return the sector of the offset
 */
flash_sector_t flashGetOffsetSector(BaseFlash *devp,
                                    flash_offset_t offset)
{
  flash_sector_t sector;
  const flash_descriptor_t *descriptor = flashGetDescriptor(devp);

  osalDbgAssert(offset < descriptor->size, "invalid offset");

  if (descriptor->sectors != NULL) {
      flash_offset_t sector_start;
      flash_offset_t sector_end;
      for (flash_sector_t i = 0; i < descriptor->sectors_count; i++)
      {
          sector_start = descriptor->sectors[i].offset;
          sector_end = sector_start + descriptor->sectors[i].size - 1;
          if ((offset >= sector_start) && (offset <= sector_end))
          {
               sector = i;
               break;
          }
      }
      osalDbgAssert(FALSE, "invalid offset");
  }
  else {
      sector = offset/descriptor->sectors_size;
  }

  return sector;
}
faisal
Posts: 382
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 45 times
Been thanked: 62 times

Re: hal_flash add flash_sector_t flashGetSector(BaseFlash *, flash_offset_t)

Post by faisal »

Got an F769 Disco board, and finally was able to get better test coverage with a device with non-uniform sector sizes. Of_course it uncovered some bugs :). Updates below:

Code: Select all

/**
 * @brief   Get absolute address from offset
 *
 * @param[in] ip                    pointer to a @p BaseFlash or derived class
 * @param[in] offset                offset
 * @return                          A pointer to the offset
 *
 * @api
 */
void * flashGetOffsetAddress(BaseFlash *devp, flash_offset_t offset)
{
    osalDbgCheck(devp != NULL);

    const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
    osalDbgAssert(offset < descriptor->size, "invalid offset");

    return (void *)((flash_offset_t)descriptor->address + offset);
}

/**
 * @brief   Get offset from absolute address
 *
 * @param[in] ip                    pointer to a @p BaseFlash or derived class
 * @param[in] addr                  pointer
 * @return                          offset
 *
 * @api
 */
flash_offset_t flashGetAddressOffset(BaseFlash *devp, void * addr)
{
    osalDbgCheck(devp != NULL);

    const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
    osalDbgAssert(((flash_offset_t)addr >=
                (flash_offset_t)descriptor->address)
            && ((flash_offset_t)addr <= (flash_offset_t)descriptor->address +
                descriptor->size),
            "invalid address");

    return (flash_offset_t)addr - (flash_offset_t)descriptor->address;
}

/**
 * @brief   Returns the sector of an offset.
 *
 * @param[in] devp      pointer to a @p BaseFlash object
 * @param[in] offset    flash offset
 *
 * @return the sector of the offset
 */
flash_sector_t flashGetOffsetSector(BaseFlash *devp,
                                    flash_offset_t offset)
{
  flash_sector_t sector;
  const flash_descriptor_t *descriptor = flashGetDescriptor(devp);

  osalDbgAssert(offset < descriptor->size, "invalid offset");

  if (descriptor->sectors != NULL) {
      flash_offset_t sector_start;
      flash_offset_t sector_end;
      for (flash_sector_t i = 0; i < descriptor->sectors_count; i++)
      {
          sector_start = descriptor->sectors[i].offset;
          sector_end = sector_start + descriptor->sectors[i].size - 1U;
          if ((offset >= sector_start) && (offset <= sector_end))
          {
               sector = i;
               return sector;
          }
      }
  }
  else {
      sector = offset/descriptor->sectors_size;
      return sector;
  }

  osalDbgAssert(FALSE, "invalid offset");

  return 0;
}
Post Reply