BLE Throughput Test¶
Two IPRO7AI Reef EVK boards run the same ipro_throughput_test firmware: one is the slave (peripheral), the other the master (central), and they flood each other through a custom GATT service. At the end you have throughput figures for both directions on the 1M and 2M PHY, which you can compare with the SDK's measurements under the same conditions: Reef to Reef, 1.34 Mbps on the 2M PHY and 747 kbps on the 1M PHY.
Prerequisites¶
- Two IPRO7AI Reef EVK boards, each powered from USB-C with SW8 on PWR, and each with an IPRO Debug Probe (or a 3.3 V USB-UART cable) on U6; wiring in IPRO7AI Reef EVK.
- First FreeRTOS Application done, and the IntelProCube 0.7.0.1 command-line flasher installed as in Set Up Your Host.
- One serial terminal per board in which you can type commands (115200 8N1; see Flashing & Serial Console).
Tell the two serial ports apart
An IPRO Debug Probe shows up as IPRO7 CMSIS_DAP with two serial ports: the one whose name ends in 02 is the board's console (the Reef's UART0), 04 is the CCI bridge. Plug in the first board's probe alone and note the ports that appear (ls /dev/cu.* on macOS, ls /dev/ttyACM* /dev/ttyUSB* on Linux, the COM ports in Device Manager on Windows), then plug in the second. Below, the boards are called the slave board and the master board; a label on each helps.
Steps¶
-
Build the Reef configuration:
Output:
apps/bluetooth/ble/ipro_throughput_test/build_reef/build_out/ipro_throughput_test_IPRO7.bin. The linker's memory usage table shows about 360 KB of flash and about 205 KB of the 224 KB OCRAM region. -
Flash both boards: flash the same file into each board through its own port, one board at a time. First put the board in download mode: hold SW1 (BOOT), tap SW2 (RESET), release SW1; if the board already runs firmware with a shell, typing
reboot_dlat its console does the same. Then, from the IntelProCube directory:Both runs must print
[All Success](the tool exits with 0 even on failure). Close any terminal that holds the port before you flash. -
Open both consoles and reset: open both terminals at 115200 baud and tap SW2 on each board. About 7 seconds after reset the console prints
BLE initialized: the Reef has no 32.768 kHz crystal, so the controller first qualifies its 32 kHz clock source, printsXTAL32K rejectedand falls back to RC32K, which takes a moment. The messages below omit the level, time and thread fields at the start of each line. -
Connect the boards: on the slave, type:
Then on the master:
The master scans for
IPRO-TP-TESTand connects on its own. Wait for the last line on the master before you continue: -
Set the connection interval and PHY: on the master, type (
tp conncounts in 1.25 ms units, so 40 is 50 ms):Both boards print
Connection params updated: interval=40 …andPHY updated: TX=2 RX=2;tp statusshowsConnection Interval: 50.00 msandPHY: 2M. -
Measure downlink (slave to master, notifications): type
tp statson the master and note the RX bytes, then on the slave type:During the test the slave prints one line per second, and a summary after 10 seconds:
[TP] TX: <packets> pkts, <bytes> bytes, <rate> Kbps | RX: 0 pkts, 0 bytes, 0.0 Kbps | Err: 0 ... === Throughput Test Statistics === Duration: <ms> ms TX: <packets> packets, <bytes> bytes, <rate> Kbps (<rate> KBps) RX: 0 packets, 0 bytes, 0.00 Kbps (0.00 KBps) Errors: 0 Connection: interval=50.00ms, PHY=2M ==================================When the test ends, type
tp statson the master again. -
Measure uplink (master to slave, write without response): do the reverse:
tp statson the slave,tp start 244 10on the master, andtp statson the slave once it ends. -
Repeat on the 1M PHY: type
tp phy 1on the master and repeat steps 6 and 7. To measure both directions at once, typetp start 244 10on both boards at the same time.
Verify¶
The TX rate in the sender's summary counts the packets the host stack accepted, which is within a few packets of what was delivered. The receiver's RX counters accumulate across tests, so the RX rate in its summary is not meaningful. To get the delivered rate, take the difference in RX bytes between the receiver's two tp stats readings:
Compare the result with the reference figures in the next section. If it is far below them, check the interval and PHY with tp status, then see What limits throughput.
Reference figures¶
These are the measurements published in the README of ipro_throughput_test (2026-10-07): two IPRO7AI Reef EVK boards, the prebuilt link2 controller library, ATT MTU 247, DLE 251 octets, 244-byte payloads, an 8-second flood, rates counted from the packets the receiver actually got. "Down" is slave-to-master notifications; "up" is master-to-slave writes without response.
| PHY | Interval | Down / up, CONFIG_IPRO7_BLE_HOTCODE=y (shipped configuration) |
Down / up, option off |
|---|---|---|---|
| 2M | 7.5 ms | 1055 / 1056 kbps | 891 / 957 kbps |
| 2M | 15 ms | 1180 / 1180 kbps | 921 / 930 kbps |
| 2M | 30 ms | 1315 / 1315 kbps | 737 / 788 kbps |
| 2M | 50 ms | 1342 / 1333 kbps | 593 / 642 kbps |
| 1M | 7.5 ms | 526 / 525 kbps | 437 / 492 kbps |
| 1M | 15 ms | 656 / 656 kbps | 559 / 554 kbps |
| 1M | 30 ms | 722 / 721 kbps | 584 / 551 kbps |
| 1M | 50 ms | 747 / 746 kbps | 535 / 568 kbps |
Both directions at once (CONFIG_IPRO7_BLE_HOTCODE=y, rate per direction): on the 2M PHY, 782 / 783 kbps at 50 ms, 719 / 719 kbps at 30 ms and 653 / 654 kbps at 15 ms; on the 1M PHY, 389 / 390 kbps at 50 ms. With 20-byte payloads (sized for MTU 23) on the 1M PHY the rate is about 165 kbps; the Coded S8 PHY gives about 34 kbps downlink.
What limits throughput¶
- Air time: one 251-octet data PDU plus the empty acknowledgment and two inter-frame spaces takes about 1.39 ms on the 2M PHY and 2.47 ms on the 1M PHY, so 244-byte payloads top out at about 1.40 Mbps on 2M and 790 kbps on 1M.
- Connection event length: the controller ends each connection event early enough to schedule the next one, and the shorter the interval, the larger the share lost. A 7.5 ms interval carries only about four 2M packets (about 1.05 Mbps), so bulk transfers suit 30–50 ms intervals; when latency matters, 15 ms still gives 1.18 Mbps on 2M.
- CPU: with the code running from flash, handling each packet takes longer than the packet spends on air, and the CPU sets the throughput. The shipped
CONFIG_IPRO7_BLE_HOTCODE=yruns the BLE per-packet path from OCRAM. It needs about 88 KB of OCRAM and cannot be combined with the AI+MM memory layout or with low-power settings (CONFIG_HAL_LP,CONFIG_IPRO_PM_*,CONFIG_OCRAM_NORET_SPLIT). - Check the CPU before changing buffers: type
tp cpuon the sender, start a test, and typetp cpuagain when it ends. AnIDLEshare far below 50 % means the CPU is the limit; more host or controller buffers will not help. - Small packets: with an ATT MTU of 23 (20-byte payloads) the interval hardly matters; expect about 165 kbps on the 1M PHY.
- The Coded PHY is not tuned: the application asks for a 2120 µs maximum TX time, which fits only about 27 octets per PDU on Coded S8.
defconfig_reef is .config with CONFIG_EVB=y replaced by the Reef board selection; the BLE settings are the same:
CONFIG_IPRO_BLE_CTLR_LIB="link2"
CONFIG_IPRO_BLE_CTLR_FEATURE="bt52"
CONFIG_BT_CONN=2
CONFIG_EM_SIZE=32
CONFIG_BT_L2CAP_TX_BUF_COUNT=10
CONFIG_BT_CONN_TX_MAX=10
CONFIG_IPRO7_BLE_HOTCODE=y
CONFIG_FREERTOS_TIMER_TASK_STACK_WORDS=1024
Command reference¶
| Command | Description |
|---|---|
tp slave |
Start as peripheral and advertise IPRO-TP-TEST |
tp master [addr] |
Start as central, scan and connect; optionally to address XX:XX:XX:XX:XX:XX |
tp start [size] [sec] [interval_ms] |
Start sending from this board |
tp stop |
Stop the test, or disconnect when idle |
tp stats |
Print statistics |
tp status |
Print role, state, connection interval and PHY |
tp phy <1\|2\|3> |
Request the 1M, 2M or Coded PHY |
tp conn <min> <max> |
Request a connection interval in 1.25 ms units (latency 0, supervision timeout 1 s) |
tp interval <ms> |
Change the TX interval of a running test |
tp cpu |
CPU share per task since the previous tp cpu, and each task's minimum free stack |
tp help |
Print command help |
tp start parameters: size defaults to 244 (20–244 bytes); sec defaults to 10, 0 runs until tp stop; leave out interval_ms for flood mode, or give 1–1000 ms between packets.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
flash jedec id: 00000000 or IPRO FLASH MATCH TYPE FAIL while flashing |
Wrong flash pin setting, or the board is not in download mode | Make sure the command has --chip-variant IPRO7AI and enter download mode first |
| The flasher cannot open the port | A terminal still holds the same port | Close the terminal before flashing |
IPRO FLASH WRITE CHECK FAIL on every retry |
Seen with some images | Set decompress_write = false in the IntelProCube ini, flash, then restore it |
| The master connects to another board | More than one IPRO-TP-TEST is advertising nearby |
Switch the other test boards off, or give the slave's address: tp master XX:XX:XX:XX:XX:XX |
Cannot start test - notifications not enabled by client |
Service discovery after connecting has not finished | Wait until the master prints Notifications enabled - ready for test |
| Rates far below the reference figures | Unexpected interval or PHY, or a busy CPU | Check the interval and PHY with tp status, then the sender's tp cpu |
The link drops about 1 s after tp phy 3 (reason 0x08) |
Happens occasionally when switching to the Coded PHY | Reconnect and switch again |
Next steps¶
- BLE Development: controller libraries (
link1_periph,link1,link2,link4) and host settings. - Getting Started with LE Audio: run the LE Audio headset example on the Reef.
- Examples: the other BLE applications and their Reef configurations.
- Test Your Application: send commands to each board with
serial_monitor.pyand wait for the result, to script the measurement.