STM32のFreeRTOSを使ってみる

STコアのハードウェアシリアル


mapleコアではSerial/Serial2/Serial3の3つのハードウェアシリアルが使えますが、
STコアでも、複数のハードウェアシリアルが使えることが分かりました。
こ ちらに複数のシリアルポートに関する情報が公開されています。
これもSTのエンジニアに教えてもらいました。
STのエンジニアのレスポンスはものすごく早く、分からないことも丁寧に教えてくれます。
何処に拠点があるのか知りませんが、日本時間で夜遅くにgithubにIssuesを投げると、その日のうちにレスポンスが有ります。
メチャクチャ好感度高いです。

STコアは沢山のボードをサポートしているので、UARTの数も、アサインされているGPIOもボードごとに違います。
各ボードのUART定義はこ ちらに公開されている各ボードのハードウェア資源を見ないと分かりません。
辿っていくとvariant_generic.hにSPI、I2Cのデフォルトピン、Serialオブジェクトの定義、オンボード上のLEDなど が定義されています。
PeripheralPins.cには、代替として使えるピンが定義されています。

こちらがSTM32F103RCのPeripheralPins.cのUART定義です。
STM32F103RCでは、UART1、USART2、USART3、UART4、UART5が使えることが分かります。
//*** UART ***

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};
#endif

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};
#endif

シリアルオブジェクトを使う場合、USARTやUARTのシンボルをSerial1、Serial2、Serial3(名前は何でもいい)に マッピン グします。
マッピングの手順は、コードの先頭にHardwareSerialを指定します。
HardwareSerialには、以下の3つの書式が有ります。

ピン番号を指定
HardwareSerial(uint32_t _rx, uint32_t _tx, uint32_t _rts = NUM_DIGITAL_PINS, uint32_t _cts = NUM_DIGITAL_PINS);

ピンの名前を指定
HardwareSerial(PinName _rx, PinName _tx, PinName _rts = NC, PinName _cts = NC);

UARTのシンボルを指定
HardwareSerial(void *peripheral, HalfDuplexMode_t halfDuplex = HALF_DUPLEX_DISABLED);

以下のコードの先頭3行は、どれを使っても同じ結果となります。
HardwareSerial Serial1(PA10, PA9); // uint32_t _rx, uint32_t _tx
//HardwareSerial Serial1(PA_10, PA_9); //  PinName _rx, PinName _txPinName, PinName
//HardwareSerial Serial1(USART1); // void *peripheral

void setup() {
  Serial1.begin(115200);
}

void loop() {
  Serial1.println("Hello World!");
  delay(1000);
}

こちらはnucleo_f446reの例です。
USART1はPA_9/PA_10 と、PB_6/PB_7に定義されていますが、デフォルトでは上の定義が使われます。
USART3も2組定義されていますが、デフォルトでは上の定義が使われます。
UART4とUART5は1組しか定義されていないので、そのままです。
USART6も定義されていますが、PC_6がNUCLEOボードのどこにも出ていません。
#if 0
WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PC_5,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};
#endif

HardwareSerial Serial1(USART1);
HardwareSerial Serial3(USART3);
HardwareSerial Serial4(UART4);
HardwareSerial Serial5(UART5);

#define BAUDRATE 115200

void setup() {
  Serial5.begin(BAUDRATE); Serial5.println("serial 5"); // PD2:PC12
  Serial4.begin(BAUDRATE); Serial4.println("serial 4"); // PA1:/PA0
  Serial3.begin(BAUDRATE); Serial3.println("serial 3"); // PC5:PB10
  Serial2.begin(BAUDRATE); Serial2.println("serial 2"); // USB
  Serial1.begin(BAUDRATE); Serial1.println("serial 1"); // PA10:PA9
  /* Serial.begin(BAUDRATE); */
  Serial.println("serial (same as 2)");
  Serial.println("*****");
}

void loop() {
  Serial5.println("serial 5");
  Serial4.println("serial 4");
  Serial3.println("serial 3");
  Serial2.println("serial 2");
  Serial1.println("serial 1");
  Serial.println("serial (same as 2)");
  Serial.println("*****");
  delay(1000);
}

こちらはgenericSTM32F407VGT6の例です。
6個のUARTを使うことができます。
#if 0
WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_5,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_8,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_6,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_9,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};
#endif

HardwareSerial Serial1(USART1);
HardwareSerial Serial2(USART2);
HardwareSerial Serial3(USART3);
//HardwareSerial Serial4(UART4);
HardwareSerial Serial5(UART5);
HardwareSerial Serial6(USART6);

#define BAUDRATE 115200

void setup() {
  Serial6.begin(BAUDRATE); Serial6.println("serial 6"); // PC7:PC6
  Serial5.begin(BAUDRATE); Serial5.println("serial 5"); // PD2:PC12
  Serial4.begin(BAUDRATE); Serial4.println("serial 4"); // PA1:PA0
  Serial3.begin(BAUDRATE); Serial3.println("serial 3"); // PB11:PB10
  Serial2.begin(BAUDRATE); Serial2.println("serial 2"); // PA3:PA2
  Serial1.begin(BAUDRATE); Serial1.println("serial 1"); // PA10:PA9
  /* Serial.begin(BAUDRATE); */
  Serial.println("serial (same as 4)");
  Serial.println("*****");
}

void loop() {
  Serial6.println("serial 6");
  Serial5.println("serial 5");
  Serial4.println("serial 4");
  Serial3.println("serial 3");
  Serial2.println("serial 2");
  Serial1.println("serial 1");
  Serial.println("serial (same as 4)");
  Serial.println("*****");
  delay(1000);
}

持ってないですが、STM32F413V(100Pinモデル)や、F413Z(144Pinモデル)だと、10個 (4*USART+6*UART)までのUARTが使えるみたいです。
こ ちらに定義が有ります。



Maple Coreと同様にSoftwareSerialライブラリは使えません。
Software Serialライブラリを使っているコードは、以下の様にHardwareSerialに書き換える必要が有ります。
Atemga328は1つしかハードウェアシリアルを持っていないので、SoftwareSerialライブラリが必要でしたが、
STM32の場合、ハードウェアシリアルが沢山あるので、SoftwareSerialライブラリは必要ありません。

//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(10, 9); // RX, TX

HardwareSerial mySerial(PA10, PA9); // RX, TX




デフォルトでSerialオブジェクトが使えるように、起動時にSerialオブジェクトがアサイ ンされます。
STM32F103RCのvariant_generic.hを見ると、Serialオブジェクトとして、PA3/PA2(=USART2)が使 われることが分かりま す。
起動時に以下(の様なコード)が自動的に実行されます。
HardwareSerial Serial(PIN_SERIAL_RX, PIN_SERIAL_TX);
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
  #define PIN_SERIAL_RX         PA3
#endif
#ifndef PIN_SERIAL_TX
  #define PIN_SERIAL_TX         PA2
#endif

この結果、コードの先頭でUSART2(=PA3,PA2)をHardwareSerialとして定義すると、2重定義のエラーとなります。
これが、ただでさえも複雑なUARTの扱いをさらに複雑にしています。

以下のコードで、Serial1、Serial2(=Serial)、Serial3、Seial4、Serial5を使うことが出来るようにな ります。
Serial2とSerialは同じオブジェクトなので、どちらもPA2/PA3のペアが使われます。
HardwareSerial Serial1(USART1); // PA10:PA9
//HardwareSerial Serial2(USART2); // PA3:PA2
HardwareSerial Serial3(USART3); // PB11:PB10
HardwareSerial Serial4(UART4); // PC11:PC10
HardwareSerial Serial5(UART5); // PD2/PC12

#define BAUDRATE 115200

void setup() {
  Serial.begin(BAUDRATE);
  Serial1.begin(BAUDRATE);
  Serial2.begin(BAUDRATE);
  Serial3.begin(BAUDRATE);
  Serial4.begin(BAUDRATE);
  Serial5.begin(BAUDRATE);
}

void loop() {
  Serial.println("serial");
  Serial.println("*****");
  Serial1.println("serial 1");
  Serial2.println("serial 2");
  Serial3.println("serial 3");
  Serial4.println("serial 4");
  Serial5.println("serial 5");
  delay(1000);
}



こちらがSTM32F103RCのPeripheralPins.cのUART定義です。
USART1はPA9/PA10のペア以外に、PB6/PB7のペアに切り替えて使うことができます。
これを代替機能(Alternative Function)と呼びます。
//*** UART ***

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};
#endif

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};
#endif

以下のコードを実行するとSerial1オブジェクトとして、PA9/PA10が使 われます。
HardwareSerial Serial1(USART1); // PA10:PA9

#define BAUDRATE 115200

void setup() {
  Serial.begin(BAUDRATE);
  Serial1.begin(BAUDRATE);
}

void loop() {
  Serial.println("serial");
  Serial.println("*****");
  Serial1.println("serial 1");
  delay(1000);
}

以下のコードを実行するとSerial1オブジェクトが、PB6/PB7に切り替わります。
//HardwareSerial Serial1(USART1); // PA10:PA9
HardwareSerial Serial1(PB7, PB6); // uint32_t _rx, uint32_t _tx

#define BAUDRATE 115200

void setup() {
  Serial.begin(BAUDRATE);
  Serial1.begin(BAUDRATE);
}

void loop() {
  Serial.println("serial");
  Serial.println("*****");
  Serial1.println("serial 1");
  delay(1000);
}



Serialオブジェクトが使用するGPIOを別のGPIOに変更することができます。
こちらがSTM32G431CBUのPeripheralPins.cのUART定義です
//*** UART ***

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,      LPUART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_LPUART1)},
  {PA_2_ALT1, USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,      USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_14,     USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_3,      USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_6,      USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_9,      USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PB_10,     USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PB_11,     LPUART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_LPUART1)},
  {PC_4,      USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PC_10,     USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,        NP,      0}
};
#endif

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,      LPUART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_LPUART1)},
  {PA_3_ALT1, USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,     USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_15,     USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_4,      USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_7,      USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_8,      USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PB_10,     LPUART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_LPUART1)},
  {PB_11,     USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_11,     USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,        NP,      0}
};
#endif

variant_generic.hにはデフォルトのGPIOが定義されています。
SerialオブジェクトのデフォルトはPA2/PA3に定義されています。
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
  #define PIN_SERIAL_RX         PA3
#endif
#ifndef PIN_SERIAL_TX
  #define PIN_SERIAL_TX         PA2
#endif

Serialオブジェクトが使用するGPIOを変更することができます。
#define BAUDRATE 115200

void setup() {
  //Serial.setTx(PB3);
  //Serial.setRx(PB4);
  //Serial.setTx(PB6);
  //Serial.setRx(PB7);
  Serial.setTx(PB9);
  Serial.setRx(PB8);
  Serial.begin(BAUDRATE);
}

void loop() {
  Serial.println("serial");
  Serial.println("*****");
  delay(1000);
}


NUCLEO F103RB

PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_9,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_6,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {NC,    NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,  USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_10, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_7,  USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {NC,    NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial2は同じオブジェクトです。

TX RX
Serial USB USB
Serial1 PA9 PA10
Serial2 USB USB
Serial3 PB10 PB11

HardwareSerial Serial3(USART3) を HardwareSerial Serial3(PC11, PC10) に変更すると、以下の様になります。

TX RX
Serial USB USB
Serial1 PA9 PA10
Serial2 USB USB
Serial3 PC10 PC11


NUCLEO F446RE

PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PC_5,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial2は同じオブジェクトです。

TX RX
Serial USB USB
Serial1 PA9 PA10
Serial2 USB USB
Serial3 PB10 PB11
Serial4 PA0 PA1
Serial5 PC12 PD2
Serial6 PC6 PC7


STM32F407G-DISC1

PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_5,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_8,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_6,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_9,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial2は同じオブジェクトです。

TX RX
Serial PA2 PA3
Serial1 PB6 PB7
Serial2 PA2 PA3
Serial3 PB10 PB11
Serial4 PA0 PA1
Serial5 PC12 PD2
Serial6 PC6 PC7


BluePill F103C8/BlackPill F103C8

これらのボードを使う場合、Arduino-IDEのシリアルモニターは使えません。
USB-TTL変換アダプターを使って、TeraTermなどを使ってモニターする必要が有ります。
→ Arduino-IDEのシリアルモニターも、使えることが分かりました。末尾に追記しています。
PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_9,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_6,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {NC,    NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,  USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_10, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_7,  USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {NC,    NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial1は同じオブジェクトです。

TX RX
Serial PA9 PA10
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11

(※)
ST-LINKポートから給電している場合は、絶対にUSBポートから給電してはいけません。
ボード本体から不思議な煙が出てきます


genericSTM32F103C8

BluePillもBlackPillも実装されているMCUはSTM32F103C8です。
BluePillやBlackPillをこちらのVariantでビルドするとSerialのマッピングが変わります。
SerialとSerial2が同じオブジェクトとなります。
このあたりがSTM32のシリアルの面倒なところです。
BluePillやBlackPillのソフトを公開する場合、どのVariantでビルドするかを明確にしておかないと、動かなくなります。

TX RX
Serial PA2 PA3
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11


genericSTM32F103RC

F103でも64ピン以上のCoreになると、使えるUARTの数も増えます。
100ピン仕様のF103VEも同じです。
PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_DISABLE)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_DISABLE)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)},
  {NC,         NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial2は同じオブジェクトです。

TX RX
Serial PA2 PA3
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11
Serial4 PC10 PC11
Serial5 PC12 PD2


RobotDyn BlackPill F303CC

Arduino_Core_STM32のV1.6.1からRobotDynのBlackPill F303CCのサポートが追加され ました。
PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_14, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_3,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_6,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,    NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_15, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_4,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PB_7,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,    NP,     0}
};

48ピン仕様のコアは、全て3組のUARTの定義みたいです。
以下のポートをUARTとして使うことができます。
SerialとSerial1は同じオブジェクトです。

TX RX
Serial PA9 PA10
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11


BlackPill F401CC

PeripheralPins.cで、UARTは以下の様に定義されています。
なぜか、USART1 USART2 USART6 です。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_11, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PB_6,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {NC,    NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PB_7,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {NC,    NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial1は同じオブジェクトです。

TX RX
Serial PA9 PA10
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial6 PA11 PA12


BlackPill F411CC

PeripheralPins.cで、UARTは以下の様に定義されています。
こちらもなぜか、USART1 USART2 USART6です。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_2,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_11, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PA_15, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {NC,    NP,     0}
};
#endif

#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
  {PA_3,  USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PA_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PB_3,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,  USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {NC,    NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial1は同じオブジェクトです。

TX RX
Serial PA9 PA10
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial6 PA11 PA12


Pyboard(STM32F405RGT6)

このボードは公式にはサポートされていませんが、genericSTM32F405RGのVariantでビルドすることができます。
ボードのシルクがY1 Y2などのPin Nameになっているので、こ ちらなどを参照してCPU Nameに置き換える必要が有ります。
PeripheralPins.cで、UARTは以下の様に定義されています。
64ピンのコアが採用されていますが、全てのGPIOがピンヘッダーに出ていません。
UART1、UART5が定義されていますが、ボードにこれらのGPIOが出ていません。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {NC,         NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial4は同じオブジェクトです。

TX RX
Serial PA0 PA1
Serial1 --- ---
Serial2 PA2 PA3
Serial3 PA11 PA12
Serial4 PA0 PA1
Serial5 --- ---
Serial6 PC6 PC7

回路図がこ ちらに公開されています。
オンボードに4つのLED(PA13/PA14/PA15/PB4)と、MMA7660の3軸加速度センサーが実装されています。


DIYMORE STM32F407VGT

1.6.1まではDIYMROEのボード名(ボード上のシルク印刷の誤記のまま)でしたが、1.7.0で誤記が訂正されて DIYMOREにボード名が変わりました。
PeripheralPins.cで、UARTは以下の様に定義されています。
//*** UART ***

WEAK const PinMap PinMap_UART_TX[] = {
  {PA_0,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_2,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_9,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_6,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_10,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_6,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_10,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_12,      UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_5,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_8,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};

WEAK const PinMap PinMap_UART_RX[] = {
  {PA_1,       UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PA_3,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PA_10,      USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_7,       USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
  {PB_11,      USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PC_7,       USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
  {PC_11,      UART4,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
  {PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {PD_2,       UART5,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
  {PD_6,       USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
  {PD_9,       USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
  {NC,         NP,     0}
};

以下のポートをUARTとして使うことができます。
SerialとSerial1は同じオブジェクトです。

TX RX
Serial PA9 PA10
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11
Serial4 PA0 PA1
Serial5 PC12 PD2
Serial6 PC6 PC7


BLACK F407VG

このVariantでビルドしても、シリアルに関しては上と同じです。


genericSTM32F407VGT6

このVariantでビルドすると、なぜかSerialオブジェクトのマッピングが変わり、SerialとSerial4が同じオブジェクトにな ります。
同じF407VGボードを使っても、Serialの出先が変わるのが厄介です。

TX RX
Serial PA0 PA1
Serial1 PA9 PA10
Serial2 PA2 PA3
Serial3 PB10 PB11
Serial4 PA0 PA1
Serial5 PC12 PD2
Serial6 PC6 PC7


この様に同じSTM32F407VGT6ボードでも、ビルド時に選択できるVariantが幾つか有ります。
black_f407vg
diymore_f407vgt
disco_f407vg
genericSTM32F407VGT6

こ ちらに各Variantで使われるビルドオプションが公開されています。
F407VGの定義だけを抜き出してみました。
FLASHサイズ、SRAMサイズ、基本となるvariantは全て同じですが、variant_hの有無やperipheral_pinsの有 無など、微妙に違いがあります。
この違いが、シリアルオブジェクトのマッピングの違いとなります。
# Generic F407VGTx
GenF4.menu.pnum.GENERIC_F407VGTX=Generic F407VGTx
GenF4.menu.pnum.GENERIC_F407VGTX.upload.maximum_size=1048576
GenF4.menu.pnum.GENERIC_F407VGTX.upload.maximum_data_size=131072
GenF4.menu.pnum.GENERIC_F407VGTX.build.board=GENERIC_F407VGTX
GenF4.menu.pnum.GENERIC_F407VGTX.build.product_line=STM32F407xx
GenF4.menu.pnum.GENERIC_F407VGTX.build.variant=STM32F4xx/F407V(E-G)T_F417V(E-G)T


# DIYMORE STM32F407VGT board
GenF4.menu.pnum.DIYMORE_F407VGT=DIYMORE STM32F407VGT
GenF4.menu.pnum.DIYMORE_F407VGT.upload.maximum_size=1048576
GenF4.menu.pnum.DIYMORE_F407VGT.upload.maximum_data_size=131072
GenF4.menu.pnum.DIYMORE_F407VGT.build.board=DIYMORE_F407VGT
GenF4.menu.pnum.DIYMORE_F407VGT.build.product_line=STM32F407xx
GenF4.menu.pnum.DIYMORE_F407VGT.build.variant=STM32F4xx/F407V(E-G)T_F417V(E-G)T
GenF4.menu.pnum.DIYMORE_F407VGT.build.variant_h=variant_{build.board}.h


# DISCO_F407VG board
Disco.menu.pnum.DISCO_F407VG=STM32F407G-DISC1
Disco.menu.pnum.DISCO_F407VG.node=DIS_F407VG
Disco.menu.pnum.DISCO_F407VG.upload.maximum_size=1048576
Disco.menu.pnum.DISCO_F407VG.upload.maximum_data_size=131072
Disco.menu.pnum.DISCO_F407VG.build.mcu=cortex-m4
Disco.menu.pnum.DISCO_F407VG.build.flags.fp=-mfpu=fpv4-sp-d16 -mfloat-abi=hard
Disco.menu.pnum.DISCO_F407VG.build.board=DISCO_F407VG
Disco.menu.pnum.DISCO_F407VG.build.series=STM32F4xx
Disco.menu.pnum.DISCO_F407VG.build.product_line=STM32F407xx
Disco.menu.pnum.DISCO_F407VG.build.variant=STM32F4xx/F407V(E-G)T_F417V(E-G)T
Disco.menu.pnum.DISCO_F407VG.build.cmsis_lib_gcc=arm_cortexM4lf_math


# Black F407VG
# https://github.com/mcauser/BLACK_F407VEZ with bigger chip
GenF4.menu.pnum.BLACK_F407VG=Black F407VG
GenF4.menu.pnum.BLACK_F407VG.upload.maximum_size=1048576
GenF4.menu.pnum.BLACK_F407VG.upload.maximum_data_size=131072
GenF4.menu.pnum.BLACK_F407VG.build.board=BLACK_F407VG
GenF4.menu.pnum.BLACK_F407VG.build.product_line=STM32F407xx
GenF4.menu.pnum.BLACK_F407VG.build.variant_h=variant_BLACK_F407VX.h
GenF4.menu.pnum.BLACK_F407VG.build.variant=STM32F4xx/F407V(E-G)T_F417V(E-G)T
GenF4.menu.pnum.BLACK_F407VG.build.peripheral_pins=-DCUSTOM_PERIPHERAL_PINS



今までNUCLEO以外のBluePillやBlcakPillなどでは、Arduino-IDEのシリアルモニターが使えないと思っていました が、
こ ちらに解決策が公開されていました。

まず、BluePillやBlackPillのUSBポートをWindowsに繋ぎます。
この様に不明なデバイスとして認識されます。


スケッチの書き込み時にツール→USB supportでCDCを選びます。
書き込み時に使用するポートはST-Linkのポートです。
なお、ツール→USB speedをLow/Full Speed以外にするとビルドが通りません。


スケッチの書き込みが終わると、新しいVirtual COM Portが出現します。


このCOMポートはSTM32のUARTに繋がっています。
Arduino IDEのポートをこちらに変更すると、Arduino-IDEのシリアルモニターが使えるようになります。
PA9などのUARTポートは使えなくなります。

ただし、この方法には欠点があります。
リセットするたびに(スケッチをアップロードするたびに発生します)、USBポートもリセットされます。
ボードのUSBシリアルポートがArduino IDEシリアルモニターから切断され、ポートを再び開くには、シリアルモニターを閉じて再度開く必要があります。
従って、起動直後のメッセージは見ることができません。
Vertual COM Portはデバッグ用ではなく、USB通信用のポートです。


続く....