Well, yes, there are “definitions” for these things. They are in various places 
but they are there. Using them might get a bit tricky as you have mentioned; 
not sure. You would have to make sure the right header files get included in 
the proper places...

Anyway, here are the definitions:
os mbuf header: sizeof(struct os_mbuf). Size = 16
os mbuf packet header: sizeof(struct os_mbuf_pkthdr) Size = 8
user header: sizeof(struct ble_mbuf_hdr) Size = 8 or 12
The HCI ACL data header: BLE_HCI_DATA_HSDR_SZ. 4 bytes
The LL PDU header: BLE_LL_PDU_HDR_LEN. 2 bytes

I would always make the size a multiple of 4 but the code should do that for 
you; I just like to do it so the size you see in the syscfg variable is the 
actual memory block size.

Another thing I should mention: you should never add a buffer pool to msys 
smaller than the minimum size I mentioned if you are using the controller. This 
is something we will address in the future but for now it would be bad. :-)



> On Jan 11, 2017, at 3:49 PM, Simon Ratner <[email protected]> wrote:
> 
> Thanks for the detailed write-up, Will - very useful.
> 
> Are there defines for these things?
> Ideally, if I want a payload size of N, I'd like to specify in syscfg.yml:
> 
>    MSYS_1_BLOCK_SIZE: '(N + MBUF_HEADER + PKT_HEADER + LL_OVERHEAD + ...)'
> 
> And magically have optimally-sized buffers.
> 
> 
> On Wed, Jan 11, 2017 at 11:00 AM, will sanfilippo <[email protected]> wrote:
> 
>> Hello:
>> 
>> Since this has come up on a number of different occasions I wanted to send
>> out an email which discusses how the nimble stack uses mbufs. This will be
>> a controller-centric discussion but the concepts apply to the host as well.
>> 
>> A quick refresher on mbufs: Mynewt, and the nimble stack, use mbufs for
>> networking stack packet data. A “packet” is simply a chain of mbufs with
>> the first mbuf in the chain being a packet header mbuf and all others being
>> “normal” mbufs. A packet header mbuf contains a mbuf header, a packet
>> header and an optional user-defined header.
>> 
>> The length of the packet (i.e. all the data contained in all the mbuf
>> chains) is stored in the packet header. Each individual mbuf in the chain
>> also contains a length which is the length of the data in that mbuf. The
>> sum of all the mbuf data lengths = length of packet.
>> 
>> The amount of overhead in an mbuf and its size determine the amount of
>> data that can be carried in a mbuf. All mbufs have a 16-byte mbuf header.
>> Packet header mbufs have an additional 8 bytes for the packet header
>> structure and an optional user-data header. The nimble stack uses either an
>> 8-byte or 12-byte user data header. If you turn on multi-advertising
>> support, the user header is 12 bytes; otherwise it is 8 bytes. This means
>> the total packet header mbuf overhead is 32 or 36 bytes.
>> 
>> The total mbuf size is defined by the various MSYS_X_BLOCK_SIZE syscfg
>> variables. Currently, there is one mbuf pool added to msys (MSYS_1) with a
>> block size of 292 bytes.
>> 
>> Controller constraints:
>> The controller assumes that a certain minimum data size is available in a
>> packet header mbuf. This size is equal to the largest advertising PDU, or
>> 37 bytes, and must also contain the 2-byte LL PDU header (for a total of 39
>> bytes). Additionally, the controller requires an additional 4 bytes at the
>> start of the packet header mbuf to prepend the HCI ACL data packet header.
>> This means that the minimum mbuf size that can be allocated in any msys
>> mbuf pool is: packet header overhead + 4 + 39 = 75 (79 for multi-adv).
>> Since memory pools are always rounded up to the nearest 4 byte boundary,
>> this means that the minimum size should be 76 (or 80) bytes.
>> 
>> For most applications that dont use large packets, setting the mbuf size
>> to 80 should be fine as this will accommodate the typical BLE PDU and also
>> meets the minimum requirement. If your application generally uses larger
>> packets it might be benefical to allocate large mbufs as you dont lose the
>> 16-byte overhead per mbuf.
>> 
>> Finally, here is an example of how many mbufs will be used by the
>> controller for received packets. This assumes multi-advertising enabled (36
>> byte packet header overhead).
>> 
>> Example 1: PDU length = 251, msys_1_block_size = 80
>> 
>> Controller needs to store 251 + 2 = 253 total bytes.
>> 
>> Packet header mbuf can hold 80 - 36 - 4 bytes, or 40 bytes.
>> Each additional mbuf can hold 80 - 16 bytes, or 64 bytes.
>> Total mbufs = 5. First mbuf holds 40 bytes, the next three hold 64 bytes
>> while the final mbuf holds 21 bytes (40 + 64*3 + 21 = 253).
>> 
>> Example 2: PDU length = 251, msys_1_block_size = 112
>> Total mbufs: 3 (72 + 96 + 85)
>> 
>> Hope this helps.
>> 
>> 
>> 
>> 
>> 
>> 

Reply via email to