Skip to content

Commit fb6fa96

Browse files
committed
Use html tables instead of images, add missing details.
1 parent a30366f commit fb6fa96

File tree

5 files changed

+190
-20
lines changed

5 files changed

+190
-20
lines changed

docs/design-documents/hal/0003-explicit-pinmap-extension.md

Lines changed: 190 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1. [HAL API changes](#hal-api-changes).
1616
1. [Drivers API changes](#drivers-api-changes).
1717
1. [`constexpr` utility functions](#constexpr-utility-functions).
18-
1. [`Example usage](#constexpr-utility-functions).
18+
1. [Example usage](#constexpr-utility-functions).
1919

2020
# Introduction
2121

@@ -38,25 +38,179 @@ This extension should give the following savings:
3838
4. Provide default weak implementations of `xxx_init_direct(explicit_pinmap_t *)` functions. These functions will call standard `xxx_init(xxx_t *obj, PinName, ...)` function (backward compatibility for targets which do not support explicit pinmap mechanism).
3939
5. Provide `constexpr` utility functions to lookup for pin mapping in compile time (requires C++14).
4040
6. Initialize console using explicit pinmap mechanism, so `hal\mbed_pinmap_common library` is not needed and can be removed.
41-
7. Modify FPGA tests to verify also `xxx_init_direct(xxx_t *obj, explicit_pinmap_t*)` APIs.
41+
7. Modify FPGA tests to verify `xxx_init_direct(xxx_t *obj, explicit_pinmap_t*)` APIs.
4242

4343
# System architecture and high-level design
4444

4545
### Explicit pinmap mechanism
4646

4747
The explicit pinmap mechanism with backward compatibility is shown below on PWM peripheral example.
4848

49-
![alt text](img/explicit_pinmap.png "Explicit pinmap model")
49+
![Explicit pinmap model](img/explicit_pinmap.png)
5050

5151
For targets which do not provide explicit pinmap support standard initialization will be performed (which uses pinmap tables) even if direct API is selected.
5252

5353
### How much we can save
5454

55-
Tables below show how much ROM we can save using explicit pinmap for each peripheral:
55+
Example code used to test memory usage for peripheral with and without explicit pinmap extension can be found below:
5656

57-
![alt text](img/explicit_pinmap_gcc.png "GCC ROM savings")
58-
![alt text](img/explicit_pinmap_arm.png "ARM ROM savings")
59-
![alt text](img/explicit_pinmap_iar.png "IAR ROM savings")
57+
```
58+
#ifndef USE_EXPLICIT_PINMAP
59+
#define USE_EXPLICIT_PINMAP 1
60+
#endif
61+
62+
// SPI app for build test
63+
static void test_spi()
64+
{
65+
#if !USE_EXPLICIT_PINMAP
66+
/* Regular use (master) */
67+
SPI spi(D1, D2, D3, D4);
68+
#else
69+
/* Explicit pinmap */
70+
constexpr spi_pinmap_t explicit_spi_pinmap = get_spi_pinmap(D1, D2, D3, D4);
71+
SPI spi(explicit_spi_pinmap);
72+
#endif
73+
spi.format(8,0);
74+
}
75+
76+
// PWM app for build test
77+
static void test_pwm()
78+
{
79+
#if !USE_EXPLICIT_PINMAP
80+
PwmOut led(LED1);
81+
#else
82+
constexpr PinMap explicit_pinmap = get_pwm_pinmap(LED1);
83+
PwmOut led(explicit_pinmap);
84+
#endif
85+
led.period(4.0f);
86+
}
87+
88+
// ANALOGIN app for build test
89+
static void test_analogin()
90+
{
91+
#if !USE_EXPLICIT_PINMAP
92+
AnalogIn ain(A0);
93+
#else
94+
constexpr PinMap explicit_pinmap = get_analogin_pinmap(A0);
95+
AnalogIn ain(explicit_pinmap);
96+
#endif
97+
if(ain > 0.3f) {
98+
while(1);
99+
}
100+
}
101+
102+
// ANALOGOUT app for build test
103+
static void test_analogout()
104+
{
105+
#if !USE_EXPLICIT_PINMAP
106+
AnalogOut aout(D1);
107+
#else
108+
constexpr PinMap explicit_pinmap = get_analogout_pinmap(D1);
109+
AnalogOut aout(explicit_pinmap);
110+
#endif
111+
aout = 0.1;
112+
}
113+
114+
// I2C app for build test
115+
static void test_i2c()
116+
{
117+
#if !USE_EXPLICIT_PINMAP
118+
I2C i2c(D1, D2);
119+
#else
120+
constexpr i2c_pinmap_t explicit_pinmap = get_i2c_pinmap(D1, D2);
121+
I2C i2c(explicit_pinmap);
122+
#endif
123+
i2c.frequency(1000000);
124+
}
125+
126+
// SERIAL app for build test
127+
static void test_serial()
128+
{
129+
#if !USE_EXPLICIT_PINMAP
130+
Serial serial(D0, D1);
131+
serial.set_flow_control(Serial::RTSCTS, D2, D3);
132+
#else
133+
constexpr serial_pinmap_t explicit_pinmap = get_uart_pinmap(D0, D1);
134+
constexpr serial_fc_pinmap_t explicit_pinmap_fc = get_uart_fc_pinmap(D2, D3);
135+
Serial serial(explicit_pinmap);
136+
serial.set_flow_control(Serial::RTSCTS, explicit_pinmap_fc);
137+
#endif
138+
if (serial.readable()) {
139+
while(1);
140+
}
141+
}
142+
143+
// QSPI app for build test
144+
static void test_qspi()
145+
{
146+
#if !USE_EXPLICIT_PINMAP
147+
QSPI qspi_device(D1, D2, D3, D4, D5, D6);
148+
#else
149+
constexpr qspi_pinmap_t explicit_pinmap = get_qspi_pinmap(D1, D2, D3, D4, D5, D6);
150+
QSPI qspi_device(explicit_pinmap);
151+
#endif
152+
153+
qspi_device.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE,
154+
QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
155+
QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
156+
}
157+
158+
// CAN app for build test
159+
static void test_can()
160+
{
161+
char counter;
162+
163+
#if !USE_EXPLICIT_PINMAP
164+
CAN can(D0, D1);
165+
#else
166+
constexpr can_pinmap_t explicit_pinmap = get_can_pinmap(D0, D1);
167+
CAN can(explicit_pinmap, 10000);
168+
#endif
169+
can.write(CANMessage(1337, &counter, 1));
170+
}
171+
172+
```
173+
174+
175+
Detailed information about the memory savings for K64F and all compilers can be found below:
176+
177+
<table>
178+
<tr><th colspan='7'>GCC_ARM/K64F [bytes]</th></tr>
179+
<tr><th>Peripheral</th><th>Pinmap size</th><th>Master</th><th>Explicit pinmap</th><th>Explicit pinmap constexpr</th><th>constexpr diff</th><th>Saved ROM</th></tr>
180+
<tr><th>PWM</th><td>468</td><td>54743</td><td>53810</td><td>53810</td><td>0</td><td>933</td></tr>
181+
<tr><th>Analogin</th><td>288</td><td>59967</td><td>59202</td><td>59202</td><td>0</td><td>765</td></tr>
182+
<tr><th>Analogout</th><td>24</td><td>53619</td><td>53094</td><td>53094</td><td>0</td><td>525</td></tr>
183+
<tr><th>SPI</th><td>408</td><td>57216</td><td>56227</td><td>56227</td><td>0</td><td>989</td></tr>
184+
<tr><th>I2C</th><td>204</td><td>54600</td><td>53915</td><td>53915</td><td>0</td><td>685</td></tr>
185+
<tr><th>Serial</th><td>288</td><td>59824</td><td>59371</td><td>59355</td><td>-16</td><td>453</td></tr>
186+
</table>
187+
188+
<table>
189+
<tr><th colspan='7'>ARM/K64F [bytes]</th></tr>
190+
<tr><th>Peripheral</th><th>Pinmap size</th><th>Master</th><th>Explicit pinmap</th><th>Explicit pinmap constexpr</th><th>constexpr diff</th><th>Saved ROM</th></tr>
191+
<tr><th>PWM</th><td>468</td><td>45564</td><td>44554</td><td>44554</td><td>0</td><td>1010</td></tr>
192+
<tr><th>Analogin</th><td>288</td><td>44469</td><td>43643</td><td>43643</td><td>0</td><td>826</td></tr>
193+
<tr><th>Analogout</th><td>24</td><td>43840</td><td>43274</td><td>43274</td><td>0</td><td>566</td></tr>
194+
<tr><th>SPI</th><td>408</td><td>47535</td><td>46471</td><td>46471</td><td>0</td><td>1064</td></tr>
195+
<tr><th>I2C</th><td>204</td><td>44876</td><td>44110</td><td>44110</td><td>0</td><td>766</td></tr>
196+
<tr><th>Serial</th><td>288</td><td>46554</td><td>46034</td><td>46034</td><td>0</td><td>520</td></tr>
197+
</table>
198+
199+
<table>
200+
<tr><th colspan='7'>IAR/K64F [bytes]</th></tr>
201+
<tr><th>Peripheral</th><th>Pinmap size</th><th>Master</th><th>Explicit pinmap</th><th>Explicit pinmap constexpr</th><th>constexpr diff</th><th>Saved ROM</th></tr>
202+
<tr><th>PWM</th><td>468</td><td>41125</td><td>40114</td><td>40103</td><td>-11</td><td>1011</td></tr>
203+
<tr><th>Analogin</th><td>288</td><td>39913</td><td>39073</td><td>39061</td><td>-12</td><td>840</td></tr>
204+
<tr><th>Analogout</th><td>24</td><td>39913</td><td>38645</td><td>38633</td><td>-12</td><td>1268</td></tr>
205+
<tr><th>SPI</th><td>408</td><td>41759</td><td>40685</td><td>40685</td><td>0</td><td>1074</td></tr>
206+
<tr><th>I2C</th><td>204</td><td>40480</td><td>39713</td><td>39713</td><td>0</td><td>767</td></tr>
207+
<tr><th>Serial</th><td>288</td><td>41427</td><td>40883</td><td>40883</td><td>0</td><td>544</td></tr>
208+
</table>
209+
210+
The tables contain two columns for explicit pinmap case: `Explicit pinmap` (pinmap specified manually), `Explicit pinmap constexpr` (`constexpr` utility function used to create pinmap table). We expect that in both cases memory usage should be the same. Above results proves this assumption. In some cases we can get few bytes of extra savings when `constexpr` utility function is used.
211+
For more details about `constexpr` utility functions please check [constexpr utility functions](#constexpr-utility-functions), [example usage](#constexpr-utility-functions).
212+
213+
Note that on the master pinmap tables are used by the: serial console and tested peripheral. So in case of explicit pinmap we have savings from removing pinmap tables used by serial console and tested peripheral.
60214

61215
Example memory usage change for ARM/PWM example: master vs constexpr explicit pinmap:
62216

@@ -75,14 +229,30 @@ Example memory usage change for ARM/PWM example: master vs constexpr explicit pi
75229
| hal\mbed_ticker_api.o           |      978(+0) |   0(+0) |      0(+0) |
76230
| hal\mbed_us_ticker_api.o        |      114(+0) |   4(+0) |     65(+0) |
77231
| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for explicit pinmap structure in application
78-
| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |
232+
| platform\source                 |    5683(+46) |  64(+0) |    249(+0) | // extra space for UART explicit pinmap structure to initialize the console
79233
| rtos\source                     |     8990(+0) | 168(+0) |   6626(+0) |
80234
| targets\TARGET_Freescale        |  16581(-816) |  12(+0) |    340(+0) |  // removed pinmaps + driver code reduction
81235
| Subtotals                       | 44290(-1010) | 264(+0) | 205518(+0) |
82236
Total Static RAM memory (data + bss): 205782(+0) bytes
83237
Total Flash memory (text + data): 44554(-1010) bytes
84238
```
85239

240+
Below table contains memory savings when explicit pinmap is used for supported targets (ARM compiler):
241+
242+
<table>
243+
<tr><th colspan='9'>ARM/supported Targets [bytes]</th></tr>
244+
<tr><th>BOARD/PERIPHERAL</th><th>PWM</th><th>AnalogIn</th><th>AnalogOut</th><th>SPI</th><th>I2C</th><th>Serial</th><th>CAN</th><th>QSPI</th></tr>
245+
<tr><th>NUCLEO_F429ZI</th><th>-1720</th><th>-1544</th><th>-928</th><th>-1464</th><th>-948</th><th>-976</th><th>-924</th><th>-</th></tr>
246+
<tr><th>NUCLEO_F411RE</th><th>-1060</th><th>-908</th><th>-</th><th>-1140</th><th>-732</th><th>-628</th><th>-</th><th>-</th></tr>
247+
<tr><th>DISCO_L475VG_IOT01A</th><th>-1644</th><th>-1324</th><th>-852</th><th>-1256</th><th>-848</th><th>-988</th><th>-788</th><th>-904</th></tr>
248+
<tr><th>NRF52840_DK</th><th>-</th><th>-160</th><th>-</th><th>-</th><th>-</th><th>-</th><th>-</th><th>-</th></tr>
249+
<tr><th>NUCLEO_F303RE</th><th>-1620</th><th>-1256</th><th>-820</th><th>-1120</th><th>-860</th><th>-792</th><th>-740</th><th>-</th></tr>
250+
<tr><th>LPC55S69_NS</th><th>-</th><th>-460</th><th>-</th><th>-718</th><th>-452</th><th>-400</th><th>-</th><th>-</th></tr>
251+
<tr><th>NUCLEO_L073RZ</th><th>-1116</th><th>-1088</th><th>-864</th><th>-1092</th><th>-952</th><th>-958</th><th>-</th><th>-</th></tr>
252+
</table>
253+
254+
The memory savings are very target specific, but always proportional to size of the pinmap table.
255+
86256
# Detailed design
87257

88258
### Pinmap types
@@ -91,25 +261,25 @@ For peripherals which require only one pin (`AnalogIn`, `AnalogOut`, `PWM`) stan
91261

92262
```
93263
typedef struct {
94-
    PinName pin;
95-
    int peripheral;
96-
    int function;
264+
    PinName pin; // selected pin name
265+
    int peripheral; // peripheral that we want to use
266+
    int function; // pin alternative function associated with the peripheral
97267
} PinMap;
98268
```
99269

100270
Example pinmap type for SPI:
101271

102272
```
103273
typedef struct {
104-
    int peripheral;
105-
    PinName mosi_pin;
106-
    int mosi_function;
107-
    PinName miso_pin;
108-
    int miso_function;
109-
    PinName sclk_pin;
110-
    int sclk_function;
111-
    PinName ssel_pin;
112-
    int ssel_function;
274+
    int peripheral; // peripheral that we want to use
275+
    PinName mosi_pin; // mosi pin name
276+
    int mosi_function; // mosi pin alternative function
277+
    PinName miso_pin; // miso pin name
278+
    int miso_function; // miso pin alternative function
279+
    PinName sclk_pin; // sclk pin name
280+
    int sclk_function; // slck pin alternative function
281+
    PinName ssel_pin; // ssel pin name
282+
    int ssel_function; // ssel pin alternative function
113283
} spi_pinmap_t;
114284
```
115285

Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)