This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Allocating memory from heap from within a ISR on Cortex

Is there is recommandations, hints on do-do-not-do when ISR requires to allocate dynamic memory?

Parents
  • If your blocks are always 100 bytes, I recommend making a simple super-quick allocator:

    1: You make a memory variable (for instance a 32-bit variable), which contains a bit representing a free/used block. This variable will accomodate up to 32 blocks.

    2: You make a fixed allocation of 32 x 100 bytes (or 32 x 128 bytes if you have enough memory).

    Finding the first free block (for your allocator) can be done very quickly by using the following piece of code:

    iBitMask = ~usedBlockMask;

    firstFree = ~(iBitMask & ~(iBitMask - 1));

    usedBlockMask |= firstFree;

    offset = clz(rbit(firstFree));

    return(&sFirstBlock[offset * blockSize]);

    Above, the CLZ instruction (Count Leading Zeros) is used with the RBIT instruction to form a Count Trailing Zeros; this will give us the position of the first set bit (which in this case is the first cleared bit we've found).

    Checking if a block is allocated (for your 'release block' routine) can be done by ...

    bitMask = 1 << ((address - sFirstBlock) / blockSize);

    if(usedBlockMask & bitMask)

    {

      usedBlockMask ^= bitMask;

    }

    else

    {

      // block was not previously allocated; report error somehow.

    }

    -The above is quick enough for an interrupt. It will be even quicker if you change the block size to 128 instead of 100 bytes, since bit-shifting can then be used.

Reply
  • If your blocks are always 100 bytes, I recommend making a simple super-quick allocator:

    1: You make a memory variable (for instance a 32-bit variable), which contains a bit representing a free/used block. This variable will accomodate up to 32 blocks.

    2: You make a fixed allocation of 32 x 100 bytes (or 32 x 128 bytes if you have enough memory).

    Finding the first free block (for your allocator) can be done very quickly by using the following piece of code:

    iBitMask = ~usedBlockMask;

    firstFree = ~(iBitMask & ~(iBitMask - 1));

    usedBlockMask |= firstFree;

    offset = clz(rbit(firstFree));

    return(&sFirstBlock[offset * blockSize]);

    Above, the CLZ instruction (Count Leading Zeros) is used with the RBIT instruction to form a Count Trailing Zeros; this will give us the position of the first set bit (which in this case is the first cleared bit we've found).

    Checking if a block is allocated (for your 'release block' routine) can be done by ...

    bitMask = 1 << ((address - sFirstBlock) / blockSize);

    if(usedBlockMask & bitMask)

    {

      usedBlockMask ^= bitMask;

    }

    else

    {

      // block was not previously allocated; report error somehow.

    }

    -The above is quick enough for an interrupt. It will be even quicker if you change the block size to 128 instead of 100 bytes, since bit-shifting can then be used.

Children
No data