バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
lwIPのUDP Socket生成について。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
UDP Socket生成

今回はlwIPのUDP Socket生成について。
- lwIP自身の初期化
- ネットワークインターフェースの追加
- マルチキャストグループの参加
- ネットワークインターフェースの初期化
- リンクアップ
- UDP Socket生成 ← これ
- IPアドレス、ポートへのBind
- UDP受信待ち
- EthnertFrameの疑似受信

おー。
Socket!!
いよいよ、それっぽくなってきたねー。

と言っても利用する側からすると
大したことはしないんだよねー。

そうなの?

うん。
udp_newって関数の戻り値をもらうだけ。

チョロい!!
udp_newの中身

一応、udp_newのコードを見てみよう。
/**
* @ingroup udp_raw
* Creates a new UDP pcb which can be used for UDP communication. The
* pcb is not active until it has either been bound to a local address
* or connected to a remote address.
*
* @return The UDP PCB which was created. NULL if the PCB data structure
* could not be allocated.
*
* @see udp_remove()
*/
struct udp_pcb *
udp_new(void)
{
struct udp_pcb *pcb;
LWIP_ASSERT_CORE_LOCKED();
pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB);
/* could allocate UDP PCB? */
if (pcb != NULL) {
/* UDP Lite: by initializing to all zeroes, chksum_len is set to 0
* which means checksum is generated over the whole datagram per default
* (recommended as default by RFC 3828). */
/* initialize PCB to all zeroes */
memset(pcb, 0, sizeof(struct udp_pcb));
pcb->ttl = UDP_TTL;
#if LWIP_MULTICAST_TX_OPTIONS
udp_set_multicast_ttl(pcb, UDP_TTL);
#endif /* LWIP_MULTICAST_TX_OPTIONS */
}
return pcb;
}
固定長メモリプール

んー。
memp_mallocってのでメモリ確保してるのかな?

うん。その通り。
まぁこのmemp_malloc何者かってところだねー。

あ、そういうえば、組み込み用途だからmallocがそもそも利用できない方が多いのか?

となると、memp_mallocは一体・・・。

所謂、「固定長メモリプール」という実装で
以下で各種処理が定義されてる。
core\memp.c

固定長メモリプール?

まずはメモリプールの概念から。
IT用語辞典 e-Wordsから引っ張ってきた。
メモリプールとは、コンピュータプログラムの実行時に素早く動的に必要なメモリ領域を確保するために、プログラムの起動時などにメインメモリの空き領域からある程度大きな領域を一括して確保したもの。リアルタイムOSなどで用いられるメモリ管理方式の一つで、頻繁にメモリの確保が必要な場合に、逐一オペレーティングシステム(OS)に割り当てを依頼するよりも高速に処理することができる。メモリプール単位で確保や解放を行なうことで、個々の領域の解放し忘れなどに起因するメモリリークなどの問題を低減することができる。
IT用語辞典 e-Wordsより

一言で言うと、高速な動的メモリ取得と解放の仕組みかな?

そうそう。
そして、固定長メモリプールは、取得メモリサイズを固定にすることで
管理し易くし、さらに高速な動的メモリ取得と解放が実現できる。
まぁITRONにも同一の機能が定義されてるから興味あったら調べてみるとよいよー。

うーん、一回調べてみるかー。

以下でITRONの仕様書が公開されてる。
cre_mpfってAPIを元に調べていくと良いね。


おー、ここを見ればいいのか。
ありがたい。
まとめ

まとめだよ。
- lwIPのUDP Socket生成についての説明。
- 内部で固定長メモリプールでメモリ領域の確保をしている。
- 固定長メモリプールはITRON等のRTOSにも実装されている高速な動的メモリ取得解放のロジック。
- 公開されているITRON4.0仕様を参照してみるのも良い。
バックナンバーはこちら。
コメント