よくある質問(営業)よくある質問(技術)
コンフィグレータで設定できる項目を教えてください。

コンフィグレータで設定できる項目は通常次のようになります。

  1. 弊社RTOS(μC3)のカーネルリソース設定
  2. 弊社TCPプロトコルスタック(μNet3)のネットワーク設定
  3. マイコンのクロック設定
  4. マイコンのUART設定
  5. マイコンのGPIO設定
  6. マイコンのEthernet設定

Tiva TM4Cパッケージの設定項目例

CPUによっては上記の設定項目がサポートされていないコンフィグレータも存在します。
弊社ダウンロードサイトより評価版がダウンロード可能です。詳細はこちらを参照願います。

ダウンロード

※評価版を用意していないCPUについては弊社営業までお問い合わせください。

お問い合わせ
プロジェクトライセンスの定義を教えて下さい

ライセンス形態は下記3種類が用意されています。
1.研究・開発ライセンス(量産に使用不可)
2.プロジェクトライセンス(量産に使用可)
3.プラットフォームライセンス(量産に使用可)
プロジェクトライセンスにおけるプロジェクトの定義とは、
計測機器などの抽象的な名称ではなく、
具体的な製品シリーズ名称とさせていただいております。

詳しくは、「製品ガイド」の17ページにも記載がございますが、
まずは、弊社営業にご相談ください。

「製品ガイド」は下記URLから入手可能です。

ダウンロード
製品の価格を教えてください。

製品の価格情報は「製品ガイド」の18ページを参照ください。
製品ガイドは下記ダウンロードページから入手可能です。

ダウンロード
代理店を紹介してください。

Q.代理店を紹介してください。

A.当社では、特に指定の代理店はございませんので、下記のいずれかの方法でご購入いただく形となります。

1)当社から直接購入
2)これまでお付き合いのある、ツール系販社及び商社様経由でご購入
3)CPUメーカー様の販社様からご購入

どの経路からご購入いただいても、サポート等は変わりませんので、ご安心ください。

技術的なご質問はeForumをご覧ください。

eForum

μC3について

Cortex-Mで管理外割込みをつかうと動きがおかしい。

Cortex-Mでの割込みレベルは以下のように設定してください。

(高優先) 0 ≦ カーネルの管理外の割込みで使用可能な割込みレベル ≦ カーネルレベル < 割込みサービスルーチンで使用可能な割込みレベル ≦ 255

管理外割り込み処理中にカーネルのシステムコールを呼ぶことはできません。誤動作の原因になりますのでご注意下さい。

標準COMドライバ、割込みサービスルーチンで使用することができますか?

μC3の標準COMドライバは、タスクからの呼び出しのみに対応しています。各APIは、タスクから呼び出しをしてください。なお、タスクからの呼び出しであっても、CPUロック中や、ディスパッチ禁止中の場合には、呼び出しができません。

[Standard+M]Zynq7000シリーズのJTAGモードでのデバッグ時にコア1が動作しない

JTAGモードで起動すると”0xfffffe18″などの後半のアドレスにPCが割り当てられこのままではCPU1はうまく作動しません。
CPU1が動かないとCPU0もuC3のカーネル起動前にCPU1を待つ状態に入ってしまいます。
解決するためには手動でPCに有効なアドレス(コア0のスタートアドレスである”_PRST=0x00100000″)を指定して実行してください。

参考
・ JTAG からブートすると CPU1 のプログラム カウンター (PC) に無効なアドレスが指定される
 ⇒ http://japan.xilinx.com/support/answers/47567.html
・Zynq-7000 AP SoC Technical Reference Manual
 ⇒ 6.1.10 Starting Code on CPU 1

Zynq7000シリーズのSDK版サンプルのBSPのコンパイルがとおらない。

サンプル内のBSPのプロジェクトのバージョンとSDKのバージョンの違いによるものによるものとおもわれますので
以下の手順でBSPのプロジェクトを削除して再作成してください。

1.インポートしたプロジェクトのBSPのプロジェクトを削除(ファイルも残さずに削除を実施)
 sample_bsp_0

2.以下の手順で新たにBSPのプロジェクトを作り直し。

 SDKのメニューから

 [File]→[Board Support Package]を選択
 project名 standalone_bsp_0 を sample_bsp_0 に変更
      Target Hardware:ZC702_hw_platform を選択
      CPU:ps7_coretexa9_0を選択

 その後はすべてOKを選択

3.プロジェクトのビルドのしなおし。

これでビルドが通らない場合はワークスペースとプロジェクトのパスの関係によるものと考えられます。
sampleプロジェクトとsample_bsp_0のプロジェクトは相対パスで参照しているため、同じフォルダ配下になるように
ワークスペースの場所を調整してください。

DS-5版に統合開発環境(Eclispe)用のプロジェクトファイルはないのでしょうか?

現状ではuC3/Standard DS-5版はプラットフォームによってはMakefileによるビルドが前提のご提供になっております。
(例)Xilinx Zynq7000シリーズ,Toshiba TZ3000シリーズ
makefileプロジェクトとしてEclipseにmakefileを取り込むか、自前でEclipseプロジェクトを作成してください。

メールボックスのメッセージパケットの先頭4バイトが壊れます。

メールボックスで送受信するメッセージパケットは、先頭フィールドにOSが管理するメッセージヘッダ(4バイト)があります。このメッセージヘッダはOSが値を書き換えます。
メッセージヘッダの後にアプリケーションが使用するメッセージフィールドが続きます。

–メールボックスのメッセージパケットの例–

typedef struct t_msgblk {
T_MSG header; /* メッセージヘッダが必要 (OSが管理) */
:
: /* アプリケーションで使用するメッセージの本体 */
:
} T_MSGBLK;

[μC3/Compact]OSの管理外割込みについて教えてください。

カーネルのオーバヘッドに影響されない最速の応答性を持つ割込みとして、カーネルの管理外の割込みをサポートしています。カーネルが排他制御に用いる割込みレベルを「カーネル割込みレベル」と呼び、これを下げることにより常に許可状態にある割込みレベルを設けて、これにカーネルの管理外の割込みを割り当てます。
μC3/Compactでは、「カーネル割込みレベル」の指定をコンフィグレータの「カーネル全般」部分で設定することができます。
なお、このカーネルの管理外の割込みは最速の応答性を持つ代わりに、この処理の中では、システムコールを呼び出すことはできません。

制限事項
【Ver.1.xカーネル】
カーネルの管理外の割込みをサポートしていません。ご使用中のパッケージのカーネルのバージョンを確認してください。

ご使用にあたっては
μC3のシステムコールが呼び出すことができないなどの制限があります。
ご使用される場合にも、最優先の割込みに限って使用するなど、限定した処理に使用してください。

[μC3/Standard]横河デジタル製のシステムマクロトレースを使用したいのですが?

システムマクロトレースを利用するにはSMTライブラリ(libsmt.a)をお客様のボードの環境に
あわせてポーティングしリンクする必要があります。
参考サイト
http://www2.yokogawa-digital.com/support/support_advice/?m=AdviceDl&item=1
http://www2.yokogawa-digital.com/support/support_advice/?m=AdviceSmtapilib&item=1

ポーティングに関しての詳細はポーティングのマニュアルを参照していただき横河様にご相談をお願い申し上げます。
uC3/StandardのOSのトレースにはスタートアップ時にcsys.traceに以下から設定して設定を行ってください。

  • ADVICE_TASK_TRACE      タスクのコンテキストスイッチのトレース
  • ADVICE_TASK_SYSCALL_TRACE タスクのコンテキストスイッチ・システムコールのトレース
コード
    csys.sysidl = SYSTEM_IDLE;
    csys.inistk = STACK_ID_INIT;
//    csys.trace = TRACE_DISABLE;
//    csys.trace = ADVICE_TASK_TRACE;
    csys.trace = ADVICE_TASK_SYSCALL_TRACE;
    csys.agent = AGENT_DISABLE;
    return start_uC3(&csys, initpr0);

以下はシステムコールのIDを定義したコンテキストID変換ファイルになります。
これをお客様がカスタマイズいただきシステムマクロトレースに設定することにより、システムコール名が表示されるようになります。

コード
[TID]
[PID]
[IRQ]
[SYS]
0xFFFE, get_pri
0xFFFB, cre_tsk
0xFFFA, del_tsk
0xFFF9, act_tsk
0xFFF8, can_act
0xFFF7, sta_tsk
0xFFF6, ext_tsk
0xFFF5, exd_tsk
0xFFF4, ter_tsk
0xFFF3, chg_pri
0xFFF1, ref_tsk
0xFFF0, ref_tst
0xFFEF, slp_tsk
0xFFEE, tslp_tsk
0xFFED, wup_tsk
0xFFEC, can_wup
0xFFEB, rel_wai
0xFFEA, sus_tsk
0xFFE9, rsm_tsk
0xFFE8, frsm_tsk
0xFFE7, dly_tsk
0xFFDF, cre_sem
0xFFDE, del_sem
0xFFDD, sig_sem
0xFFDB, wai_sem
0xFFDA, pol_sem
0xFFD9, twai_sem
0xFFD8, ref_sem
0xFFD7, cre_flg
0xFFD6, del_flg
0xFFD5, set_flg
0xFFD4, clr_flg
0xFFD3, wai_flg
0xFFD2, pol_flg
0xFFD1, twai_flg
0xFFD0, ref_flg
0xFFCF, cre_dtq
0xFFCE, del_dtq
0xFFCB, snd_dtq
0xFFCA, psnd_dtq
0xFFC9, tsnd_dtq
0xFFC8, fsnd_dtq
0xFFC7, rcv_dtq
0xFFC6, prcv_dtq
0xFFC5, trcv_dtq
0xFFC4, ref_dtq
0xFFC3, cre_mbx
0xFFC2, del_mbx
0xFFC1, snd_mbx
0xFFBF, rcv_mbx
0xFFBE, prcv_mbx
0xFFBD, trcv_mbx
0xFFBC, ref_mbx
0xFFBB, cre_mpf
0xFFBA, del_mpf
0xFFB9, ref_mpf
0xFFB7, get_mpf
0xFFB6, pget_mpf
0xFFB5, tget_mpf
0xFFB4, ref_mpf
0xFFB3, set_tim
0xFFB2, get_tim
0xFFB1, cre_cyc
0xFFAF, sta_cyc
0xFFAE, stp_cyc
0xFFAD, ref_cyc
0xFFAB, rot_rdq
0xFFAA, get_tid
0xFFA7, loc_cpu
0xFFA6, unl_cpu
0xFFA5, dis_dsp
0xFFA4, ena_dsp
0xFFA3, sns_ctx
0xFFA2, sns_loc
0xFFA1, sns_dsp
0xFFA0, sns_dpn
0xFF9F, ref_sys
0xFF9A, cre_isr
0xFF9B, def_inh
0xFF99, del_isr
0xFF98, ref_isr
0xFF97, dis_int
0xFF96, ena_int
0xFF95, chg_ims
0xFF94, get_ims
0xFF91, ref_cfg
0xFF90, ref_ver
0xFF8F, iact_tsk
0xFF8E, iwup_tsk
0xFF8D, irel_wai
0xFF8B, isig_sem
0xFF87, irot_rdq
0xFF8A, iset_flg
0xFF89, ipsnd_dtq
0xFF88, ifsnd_dtq
0xFF83, isig_tim
0xFF7F, cre_mtx
0xFF7E, del_mtx
0xFF7D, unl_mtx
0xFF7B, loc_mtx
0xFF7A, ploc_mtx
0xFF79, tloc_mtx
0xFF78, ref_mtx
0xFF77, cre_mbf
0xFF76, del_mbf
0xFF73, snd_mbf
0xFF72, psnd_mbf
0xFF71, tsnd_mbf
0xFF6F, rcv_mbf
0xFF6E, prcv_mbf
0xFF6D, trcv_mbf
0xFF6C, ref_mbf
0xFF6B, cre_por
0xFF6A, del_por
0xFF69, cal_por
0xFF68, tcal_por
0xFF67, acp_por
0xFF66, pacp_por
0xFF65, tacp_por
0xFF64, fwd_por
0xFF63, rpl_rdv
0xFF62, ref_por
0xFF61, ref_rdv
0xFF5F, cre_mpl
0xFF5E, del_mpl
0xFF5D, ref_mpl
0xFF5B, get_mpl
0xFF5A, pget_mpl
0xFF59, tget_mpl
0xFF58, ref_mpl
0xFF57, cre_alm
0xFF56, del_alm
0xFF55, sta_alm
0xFF54, stp_alm
0xFF53, ref_alm
0xFF50, del_cyc
0xFF4F, def_ovr
0xFF4E, sta_ovr
0xFF4D, stp_ovr
0xFF4C, ref_ovr
0xFF3F, acre_tsk
0xFF3E, acre_sem
0xFF3D, acre_flg
0xFF3C, acre_dtq
0xFF3B, acre_mbx
0xFF3A, acre_mtx
0xFF39, acre_mbf
0xFF38, acre_por
0xFF37, acre_mpf
0xFF36, acre_mpl
0xFF35, acre_cyc
0xFF34, acre_alm
0xFF33, acre_isr
0xFF1F, vact_tsk
0xFF1E, vsta_tsk
0xFF1D, vwup_tsk
0xFF1C, vrel_wai
0xFF1B, vsig_sem
0xFF1A, vpol_sem
0xFF19, vset_flg
0xFF18, vclr_flg
0xFF17, vpol_flg
0xFF16, vpsnd_dtq
0xFF15, vfsnd_dtq
0xFF14, vprcv_dtq
0xFF13, vrot_rdq
0xFF09, ivsig_ovr
μC3/Compactで可変長メモリプールを使用したい

μC3/Compactでは可変長メモリプールはサポートしておりません。
固定長メモリプールで代用していただくか、メモリ管理のコードを書いていただくことになるかと思います。

タスク生成時にE_NOID(-34) が返ってきます。

タスクのIDの最大値を大きくしてください。
関数のstart_uC3でOSを起動します。この関数の引数のcsys.tskid_maxはタスクのIDの最大値(1?255)を設定します。

コード
csys.tskpri_max = 8; /* 大きな数値に変更します */
/* .... */
ercd = start_uC3(&csys, initpr);

イベントフラグのクリア属性(TA_CLR)について教えてください。

クリア属性(TA_CLR)が設定されているイベントフラグについては、対象のイベントフラグの待ち状態となっているタスクが存在する場合、set_flg又は、iset_flgを呼出すことで、条件成立により、タスクの待ち解除されるときに、イベントフラグのビットパターンについて、すべてのビットがクリアされます。

注意事項:
複数のタスクが待ち状態となっている場合、最初のタスクの待ち解除を実施した時点で、イベントフラグのビットパターンをクリアすることになります。そうすると、対象のイベントフラグに対して、2個目以降の待ち状態となっているタスクについては、同時に待ち解除することができないことになります。
そのため、同時に複数のタスクの待ち解除を実施したい場合には、クリア属性(TA_CLR)の指定はしないでください。

[μC3/Compact]kerrnel_cfg.cでワーニングが発生します。

kernel_cfg.cで回避できないワーニングが発生します。このワーニングを抑止する場合、以下手順で行えます。
(ワーニングを無視しても、OSの機能としての問題は全くありません)

EWARMの場合
 プロジェクトのオプション画面を開き、「C/C++コンパイラ」→「診断」画面と選択します。
 「診断を無効化」エディットに「Pe170」と入力します。画面は「OK」ボタン押下で閉じます。

MDK-ARMの場合
 kernel_cfg.c のオプション画面を開きます。
 「Misc Controls」エディットに「–diag_suppress=170」と入力します。画面は「OK」ボタン押下で閉じます。

C++に対応していますか。

μITRON自体がC++言語を考慮していないため、C++非対応とさせていただいています。
ただし、システムコールの呼び出しだけであれば、「extern “C”」を付ければ可能です。

kernel.hの変更

コード
#ifdef __cplusplus
extern "C" {
#endif
   :
   kernel.hの本体
   :
#ifdef __cplusplus
}
#endif

その他,μC3が提供するソースでコンパイルエラーとなる箇所(変数宣言や関数)が
あれば,extern “C”を付与してください。
(“C”リンケージであることを明示的に指定してください。)

その他、現時点で分かる範囲で注意点を記載します。
1. 静的なオブジェクト
 グローバルなコンストラクタやデストラクタは、カーネルが動作していない状態で呼び出されます。
 従って、これらの関数内では、μC3のサービスコールを呼び出すことはできません。
2.new演算子、delete演算子
 コンパイラ処理系に依存するかと思いますが、マルチタスク環境では排他制御が必要になる
 場合があります。
3.例外処理
 throwやcatch時における処理系の挙動が想定できないため、
 タスク内でtry/throw/catchは使用しないでください。

C++に対応していますか。(Q&A形式の補足)

上記についての、Q&A形式の補足となります。

***
Q.1 フォーラム上ではC++は非対応とございました。μC3上でC++で作ったもの
  が動いている、という例はあまり(全く?)ないのでしょうか。
A.1 使用されているお客様は、少ないですが、いらっしゃいます。
  念のためですが、弊社では、C++言語を用いてμC3の動作検証を完全に行っていないため、
  正式サポートをしておりません。また、μC3はμITRON仕様なので基本C++には正式に
  対応していません。

Q.2 システムコールの時だけextern “C”をつける事と、その他いくつかの注意点
  が挙げられておりましたが、それらに気を付けていれば、C++で実装された
  ものでも動かす事は出来るのでしょうか。
A.2 注意点(C++に対応していますか。に記載)を守って頂ければ動かすことは可能です。
  追加情報としましては、動作させることは可能ですが,C++の機能をフルに
  使った場合に懸念(弊社では、詳細に調査できていないこともあります)があります。
  また、TOPPERS/JSPにて公開されている「2.C++バインディングの機能」
  を削除したC++のソースコードであれば一応利用可能と考えています。

Q.3 フォーラムの注意点の中に、new演算子、delete演算子につきまして、
  マルチタスク環境では排他制御が必要になる場合がある、とございましたが、
  これはどういう意味でしょうか。
A.3 new演算子、delete演算子では、mallocなどの処理が使用されている
  可能性があり、コンパイラが用意している malloc関数はリエントラント
  (再入可能)に作られていません。そのため、複数のタスクから呼び出され
  ると mallocの管理領域が破壊されてしまいます。
  その場合、複数のタスクで使う場合には排他制御が必要になります。
  こちらは、参考情報ですが、メモリを取得する場合、uITRONではmallocは
  なく、通常は固定長のメモリプールから取得・解放(get_mpf, rel_mpf)する
  ことを推奨しています。

mallocを使用する.(コンパイラがEWARMの場合)

mallocを使用する場合には、拡張子が.icfのファイルに下記の記述を追加して頂くことで、
RAM上にHEAPエリアが確保され、mallocで領域が取得され、freeで解放されるようになります。

****リンカ設定ファイルに追加****

コード
 
define block HEAP with size = 0x400, alignment = 8{ };
 place in RAM_region {block HEAP};

コンフィグレータが生成した****.icfファイルを使用される場合は、
上記の変更を実施した後にコード生成を実行すると、上書きされるので注意してください。
また、コンパイラが用意している malloc関数はリエントラント(再入可能)に作られていません。
μITRON OSでは、マルチタスクでアプリケーションを作成することを前提としているため、複数のタスクから呼び出されると mallocの管理領域が破壊されてしまいます。
1つのタスクのみが使うのであれば、そのままで使用可能ですが、複数のタスクで使う場合には排他制御(セマフォで管理するなど)が必要になります。

このような訳で、デフォルトでは mallocが使えないような設定としています。(HEAPエリアを確保していません)
基本的には、μC3/Compact上でmalloc等を使用することは、推奨していません。
uITRONではmallocはなく、メモリを取得する場合、通常は固定長のメモリ
プールから取得・解放(get_mpf, rel_mpf)して頂くことを推奨いたします。

アンインストール方法がわかりません。

インストール実行時に、ハードディスク上(標準ではC:\uC3フォルダ)にファイルの展開を実施するのみで、レジストリの設定などは行いません。
そのため、アンインストールにつきましては、インストール時に展開されたファイルをフォルダごと削除することで完了となります。

rcv_mbxの呼出で、コンテキストエラーが発生する

rcv_mbxについては、タスクコンテキストのみで呼び出しが
できるシステムコールです。(ユーザーズガイドの呼出コンテキストを参照)

なお、タスクコンテキストから呼び出した場合においても、
以下のシステムコールを利用していると、コンテキストエラーとなります。
・loc_cpu()にてCPUロックしたままになっていないか?
・dis_dsp()にてディスパッチを禁止したままになっていないか?
・chg_imsにより割込みレベルを上げている箇所はないか?

上記の状態を判定するシステムコールもありますので、こちらも
参考にしてください。
・sns_ctx : タスクコンテキストから呼び出されているかの判定
・sns_loc : CPUロック状態の判定
・sns_dsp : ディスパッチ禁止状態の判定

DS-5の環境でヒープ領域を使用したい場合どうすればよいですか?

uITRONの環境でmalloc関数が規定されていないことと、ARM社をはじめとする
ベアメタル環境のmalloc等をご使用されますとuITRONの環境ではメモリ管理領域を破壊する等mallocがリエントラントでないために期待しない動作を動作を行う恐れがあるためにヒープ領域の使用を推奨しておりません。
メモリ領域の取得には固定長メモリプールや可変長メモリプールのAPIを使用することを推奨しております。
独自にヒープ領域をご使用になられる場合は以下の設定が必要になります。(使用する場合は自己責任でお願いいたします。)

1.__use_no_heapを定義しないようにする。

コード
/******************************************************************
        ヒープ不使用を宣言
 ******************************************************************/
#if 0 /*def __CC_ARM */
#pragma import(__use_no_heap)
#endif

2.scatファイルにヒープ領域の設定の追加
(0x00002000がヒープ領域のサイズになります)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206ij/CJAJBEFD.html
ここではヒープ領域はARM_LIB_HEAPとしておきます。
ヒープ領域はSTACK領域やSTKMEM領域よりもアドレスを前にしてください。
しない場合は、該当する割込みハンドラ内のスタックやタスクのスタックとの衝突チェックでエラーになり期待した動作にならない場合があります。
また、このスタックの衝突チェックの機能はOSレス(ベアメタル)の環境を期待したチェックですので、uC3上では正確な衝突チェックはできませんのでご了承ください。

コード
    ARM_LIB_HEAP +0x0 EMPTY 0x00002000
    {

    }

3.1標準のスタートアップにおいて__user_setup_stackheap関数の設定
必要に応じてImage$$ARM_LIB_HEAP$$BaseからImage$$ARM_LIB_HEAP$$ZI$$Limitの領域を0に初期化しておいてください。

 (シングルコアのサンプルが該当)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0492bj/CJAGAAHA.html

コード
        EXPORT  __user_setup_stackheap
__user_setup_stackheap
        ldr     r0,  =|Image$$ARM_LIB_HEAP$$Base|
        ldr     r2,  =|Image$$ARM_LIB_HEAP$$ZI$$Limit|
        bx      lr

3.2標準のスタートアップを使用されない場合(DUALコアのサンプル等が該当)
(※こちらは検証していません)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0349bj/Cihfiabf.html
 _init_alloc(base, , top) を使用してヒープ領域を設定

4.ヒープ領域の自動拡張を無効にする
これを行わないと、ヒープサイズ以上の領域の確保が成功してしまう場合があり、予期しない動作になります。

コード
        EXPORT  __rt_heap_extend
__rt_heap_extend
        mov     r0, #0
        bx      lr

5.コンパイル後にヒープ領域の確認
lstファイルでアドレスを確認しておく。

コード
    Image$$ARM_LIB_HEAP$$Base                0x004f13c4   Number         0  anon$$obj.o(linker$$defined$$symbols)
    Image$$ARM_LIB_HEAP$$ZI$$Limit           0x004f33c4   Number         0  anon$$obj.o(ARM_LIB_HEAP.bss)

6.タスクでヒープ領域がmalloc,freeで使用できることの確認
ヒープ領域から取得できていることを確認する。
メモリ取得・開放時はCPUロックやディスパッチ禁止などにして、ヒープ領域の処理中に他のタスクへのディスパッチや割込みが発生してリエントラントで呼び出されないようにしてください。

コード

void* pmem[3] = NULL;

/*******************************
       Main Task
*******************************/

void MainTask(VP_INT exinf)
{

        dis_dsp();
        pmem[0] = (void*)malloc(1000); /* 0x004F13D8が取得 */
        pmem[1] = (void*)malloc(1000); /* 0x004F17C8が取得 */
        pmem[2] = (void*)malloc(1000); /* 0x004F1BB8が取得 */
        ena_dsp();
    for(;;) {
        dis_dsp();
        free(pmem[0]);
        free(pmem[1]);
        free(pmem[2]);
        ena_dsp();
        dly_tsk(1000);
        dis_dsp();
        pmem[0] = (void*)malloc(1000);
        pmem[1] = (void*)malloc(1000);
        pmem[2] = (void*)malloc(1000);
        ena_dsp();
    }
}
使用する予定の評価ボードのサンプルプログラムがない

μC3には各社から販売している評価ボード向けのサンプルプログラムを収録しておりますが、お客様がご使用予定の評価ボード向けのサンプルプログラムがない場合もございます。
ご相談いただければ、ご指定の評価ボード向けのサンプルプログラムをご提供できるケースもございます。
お気軽にお問い合わせください。

お問い合わせ
IAR Embedded Workbenchで動作するRTOSプラグイン

はい、ございます。
無償で提供させていただいております。

■ダウンロード
弊社のダウンロードページ(↓)よりダウンロードしてください。

ダウンロード


「デバッガ用プラグイン」をクリック後、ダウンロードするファイルを選択してください。

■機能
添付のファイルを参照してください。

μC3/Compact用
ダウンロード(490.31 KiB)

μC3/Standard用
ダウンロード(719.33 KiB)
dly_tskとtslp_tskについて

μC3においては、dly_tskの場合、0指定で次回のチック割込みまで待ち状態になり、1指定で2回目のチック割込みまで待ち状態になります。
そのため、遅延時間は(指定時間+チック時間)未満になりますので、dly_tsk(1)とした場合には、チック時間の設定を1(msec)のときに、1msec≦遅延時間<2msecとなります。

これはμITRON4.0の仕様書では、dly_tskの部分では、「時間経過待ち状態からの解除は、このサービスコールが呼び出されてからdly_timで指定された以上の時間が経過した後に行うことを保証しなければならない」ことに沿ったものとなります。

なお、txxx_yyyの場合は、txxx_yyyでは0指定がポーリング動作になるため、1指定で次のチック割込みまで待ってタイムアウトになります。そのため、上記のdly_tsk(1)と同等の処理としたい場合は、txxx_yyy( ,1+1)として頂く必要がございます。

STのマイコンでCubeMXとの共存はできますか?

共存は可能です。
まだ、内容が整理できておりませんが、「STM32CubeMX とμC3/Compact(RTOS)の共存例」の資料を作成しております。
 -> まずは、参照して頂ければと思います。

*****
また、注意点ですが、CubeMXから生成されるソースコードでは、割込み処理が割込みハンドラとなっており、このままですと、割込み処理からμC3/Compactのシステムコールを呼び出すことができません。
そのため、割込み処理は、μC3/CompactのOSが管理する割込みサービスルーチンに置き換えをお願いいたします。

*****
なお、CubeMXでの割込み処理についても、割込みの優先度については、標準では、優先度の設定が一番高い状態となっている可能性があります。この状態で使用されますと、μC3/Compactのカーネルの動作を阻害する恐れがありますので、調整をお願いいたします。

参考となるのは、

「STM32CubeMX とμC3/Compact(RTOS)の共存例」のP.22と、

「μC3/Compact ユーザーズガイドプロセッサ依存部 Cortex-M※ 編」
 「1.2 割込みレベル」となります。
 具体的には、以下の関係が必須となります。
 カーネルレベル < 割込みサービスルーチンで使用可能な割込みレベル ≦ 255

STM32CubeMX とμC3/Compact(RTOS)の共存例
ダウンロード(2.24 MiB)
RZ/T1のSerialBootサンプルをTHUMB命令で実行したい。

対象パッケージ:µC3/Standard RZ/T1 EWARM版 Release 1.0.1 以降
利用サンプル:uC3\Standard\Sample\RTK7910022C00000BR\EWARM\SerialBoot

1.サンプルフォルダにある,Readme_EWARM.txtに従いソース生成します。

2.Thumb命令用ビルド構成を追加

IAR Embedded Workbench for ARM(以降EWARM)を起動して,sample.ewwを読込みます。

メニューのプロジェクト→ビルドの編集 を選択

新規作成をクリック

名前に”Thumb_ATCM_Debug”を入力
基になる構成に”ATCM_Debug”を選択

ワークスペースのカレントプロジェクトに”Thumb_ATCM_Debug”が選択されている状態で,プロジェクトのオプションを変更します。

C/C++コンパイラのコードオプションにてThumbモードを選択

リンクするカーネルライブラリをARM用からThumb用に変更
uC3cortexrfl.a → uC3cortexrftl.a

3.リンカ設定ファイルの変更
変更ファイル
uC3\Standard\Sample\RTK7910022C00000BR\EWARM\SerialBoot\serial_boot\rzt1_serial_boot2ATCM.icf

161行,162行を変更します。

コード:
define block USER_PRG_RBLOCK with fixed order { ro code object prst_rtk79.o, ro code, section .rodata_init};
define block USER_PRG_WBLOCK with fixed order { rw code object prst_rtk79.o, rw code, section .rodata };

↓ fixed order属性を削除

コード
define block USER_PRG_RBLOCK { ro code object prst_rtk79.o, ro code, section .rodata_init};
define block USER_PRG_WBLOCK { rw code object prst_rtk79.o, rw code, section .rodata };

あとはビルドして動作確認いただけます。

コンフィグレータ - 追加ヘッダーファイルで複数のヘッダーファイル追加したい

コンフィグレータの追加ヘッダーファイルでは1つのファイルしか追加できません。

複数のヘッダファイルを追加するには、追加するヘッダファイルを定義したヘッダファイルを作成して、コンフィグレータへそのファイルを追加してください。

例 header1.hとheader2.hを追加する
(1) common.hを作成します。common.hの内容は次のようにheader1.hとhdear2.hを#includeします。

コード
#include "header1.h"
#include "header2.h"

(2) common.hをコンフィグレータへ設定します。

common.hは、コンパイラのインクルードパスが通るディレクトリへ置いてください。

以上で複数のヘッダファイルを追加できます。

標準COMドライバ、使用方法についての補足

内容:
標準COMドライバの使用方法について

本文:
μC3のユーザーズガイドに、標準COMポートドライバの説明がございますので、
まずは、こちらを参照してください。
下記に補足を記載します。

【注意事項】
標準COMポートドライバを利用した、送信・受信については、複数のタスクからの呼び出しを実施することは可能ですが、その場合、同時に呼び出しを実施しないようにセマフォ等を利用し、アプリケーション側で排他制御をすることが
前提(必要)となります。
例えば、複数のアプリケーションから、送信処理(puts_com)を実施する場合には、アプリケーション側で、送信処理に対して、セマフォ等を利用することで、排他制御をお願いします。
また、排他の方法としては、下記の概要図のように、セマフォ以外に、シリアル出力を実施するタスクを一つにし、複数のタスクから、出力するタスクに送信するデータを渡す例などもありますので、参考にしてください。

なお、関連する情報として、ctr_com サービスコールの制御コマンドをLOC_TXまたは、LOC_RXとして呼び出すことで、ctr_comを呼び出したタスク以外から、標準COMポートドライバの送信または、受信のサービスコールを呼び出した場合には、送受信処理は実施させないことができます(この場合には、E_OBJが返ります)。

μNet3について

HTTPサーバで複数のレスポンスで応答するにはどうすればよいですか?

たとえば動的にコンテンツサイズが決定するケースなど、Content-Length:が未定の場合、以下のようにCGI関数にて複数回のレスポンスでコンテンツを返却します。

コード
/* 100回のレスポンスでコンテンツを返却する例 */

#define REPEAT 100
void cgi_func(T_HTTP_SERVER *http)
{
    int i;
    char contents[] = "Divide Contents Test <p>";

    HttpSetContent(http, 0);
    HttpSetContent(http, "HTTP/1.1 200 OK\r\n");
    HttpSetContent(http, "Content-Type: text/html\r\n");
    HttpSetContentLen(http, "Content-Length: ", (sizeof(contents)-1)*REPEAT);
    HttpSetContent(http, "\r\n");

    HttpSendContent(http, NULL, 0);       /* レスポンスヘッダのみ送信 */

    i = 0;
    while (i < REPEAT) {
        HttpSetContent(http, 0);
        HttpSetContent(http, contents);   /* 部分的なコンテンツを送信 */
        HttpSendContent(http, NULL, 0);
        i++;
    }
}
TCPタイマとソケットタイマの違いを教えて下さい

TCPタイマはTCPのレイヤで作用するタイマで、ソケットタイマはソケットレイヤ(API)で作用するタイマです。
TCPではデータやフラグを送信すると相手からACK応答を得るまで再送します。
このとき再送を止めるまでの時間をTCPのタイマで設定します。
SYN、再送、切断、それぞれのタイマは以下の状況で動作します。

SYNタイムアウト
SYNを送信した(con_soc())時にかかるタイマです。
状態遷移で言うとSYN-RECEIVED(パッシブオープン)もしくはSYN-SENT(アクティブオープン)になります。
このときACKを得るとタイマは停止しESTABLISHED状態に移行します。もしタイマが満了した場合
アクティブオープンならcon_soc()はE_TMOUTを返却します。パッシブオープンならLISTEN状態に
戻りcon_soc()は戻ってきません。(ソケットタイマがexpireしていないことが前提)

再送タイムアウト
データを送信した(snd_soc())時にかかるタイマです。
uNet3のTCPはESTABLISHEDかCLOSE-WAIT状態でしかデータを送信できません。
もしタイマが満了した場合、TCPはRSTを送信してCLOSED状態に戻ります。

切断タイムアウト
FINを送信した(cls_soc())時にかかるタイマです。
状態遷移で言うとFIN-WAIT1(アクティブクローズ)もしくはLAST-ACK(パッシブクローズ)になります。
このときACKを得るとFIN-WAIT2 or CLOSED状態に移行します。
もしタイマが満了した場合TCPはRSTを送信しcls_soc()はE_TMOUTを返却します。(状態はCLOSEDへ)

一方ソケット(API)のタイマはAPIを呼び出した時に待ちが発生する場合に作用します。

snd_socのタイムアウト
送信バッファに空き領域が無い場合に待つ時間を設定します。
TCPのsnd_soc()ではアプリケーションの送信データは送信バッファにコピーしますが
確認応答が取れていない送信データが送信バッファを占有した場合はsnd_soc()は待ち状態になります。
このタイマがexpireした場合、snd_soc()はE_TMOUTを返却しますがTCPの状態は変化しません。

rcv_socのタイムアウト
パケット未受信の場合に待つ時間を設定します。
このタイマがexpireした場合、rcv_soc()はE_TMOUTを返却しますがTCPの状態は変化しません。

con_socのタイムアウト
パッシブオープンの場合、SYNを受信するまでの待ち時間を設定します。
このタイマがexpireした場合、con_soc()はE_TMOUTを返却しTCPの状態はLISTENからCLOSEDに移行します。
アクティブオープンの場合、SYN/ACKを受信するまでの待ち時間を設定します。
このタイマがexpireした場合、con_soc()はE_TMOUTを返却しTCPはSYNの再送を停止して状態は
SYN-SENTからCLOSEDに移行します。

cls_socのタイムアウト
アクティブクローズの場合、FINを受信するまでの待ち時間を設定します。
パッシブクローズの場合、送信したFINに対するACKを受信するまでの待ち時間を設定します。
このタイマがexpireした場合、cls_soc()はE_TMOUTを返却しTCPはRSTを送信して状態はCLOSEDに移行します。
シャットダウンの場合は待ちになりません。

μNet3/CompactのサンプルCGIの詳細動作を教えて下さい

uNet3/Compactに収録しているHTTPサーバのコンテンツはFORMによって次のようなURLクエリパラメータを送信します。

led=10&btn=LED&remote=192.168.1.1&sntp=133.243.238.243&fqdn=eforce.co.jp&dns=192.168.1.1

CGIサンプルではPOSTされるこれらのURLクエリパラメータに対応して次の動作を行います。

  • LEDの点滅間隔の設定
  • pingによる疎通確認
  • SNTPによる時刻取得
  • DNSによる名前解決

それぞれの動作が完了するとCGI関数ではHttpSendText()を使ってコンテンツおよび200OKをHTTPクライアント(ブラウザ)に応答します。
またCGIのサンプルでは固定長メモリプールを使ってコンテンツの生成に必要なバッファを動的に確保しています。
以下にcgi_sample.cで実装している各関数の仕様を説明します。

void sample_fnc(T_HTTP_SERVER *http)
CGIの本体関数です。この関数は予めHTTPサーバのコンテンツ設定時に登録されます。
引数httpはこのCGI関数を呼び出したHTTPサーバの管理情報です。
本関数では受信したコンテンツからURLクエリパラメータを取得し、どのボタンが押されたかによって(*)対応する処理関数を呼び出します。
URLクエリパラメータを解析するにはCgiGetParam()関数を使用します。
(*)パラメータ名”btn”に設定された値によって分岐判定します。例えばPINGボタンでsubmitした場合は”&btn=PING”となります。

ER led_blink(T_HTTP_SERVER *http, int cnt, char *name[], char *value[])
LEDの点滅間隔の設定を行うサブ関数です。
引数のURLクエリパラメータ群からパラメータ名”led”の値を取得し、LEDの点滅間隔変数であるLedTmoに設定します。

ER ping_send(T_HTTP_SERVER *http, int cnt, char *name[], char *value[])
pingによる疎通確認を行うサブ関数です。
引数のURLクエリパラメータ群からパラメータ名”remote”の値を取得し、pingを送信する宛先のIPアドレスに設定します。
その後pingクライアントの送信関数(ping_client())を呼び出します。

ER sntp_send(T_HTTP_SERVER *http, int cnt, char *name[], char *value[])
SNTPによる時刻取得を行うサブ関数です。
引数のURLクエリパラメータ群からパラメータ名”sntp”の値を取得し、SNTPサーバのIPアドレスに設定します。
その後SNTPクライアントの時刻取得関数(sntp_client())を呼び出します。

ER dns_resolve(T_HTTP_SERVER *http, int cnt, char *name[], char *value[])
DNSによる名前解決を行うサブ関数です。
引数のURLクエリパラメータ群からパラメータ名”dns”と”fqdn”の値を取得し、DNSサーバのIPアドレスと解決するホスト名に設定します。
その後DNSクライアントの名前解決関数(dns_get_ipaddr())を呼び出します。

ER get_contents_buf(char**buf)
CGI用動的バッファの取得関数です。tget_mpf()を呼び出して固定長メモリプールをカーネルから取得します。
引数にはバッファのアドレスを格納するポインタを指定します。

void ret_contents_buf(char *buf)
CGI用動的バッファの解放関数です。rel_mpf()を呼び出して固定長メモリプールをカーネルへ返却します。
引数には解放するバッファのアドレスを指定します。

ソケットAPIをノンブロッキングモードで実行できますか?

はいできます。ソケットAPIをノンブロッキングモードで実行するには、そのAPIのイベントタイプ(送信、受信、接続、切断)を指定してcfg_soc()によってモードを設定します。

またμNet3はノンブロッキング受付後(E_WBLKがAPIによって返却された)に対象のイベントが発生したことをアプリケーションに通知するコールバック関数の登録も可能です。
アプリケーションはコールバック関数から同期オブジェクトを使用することで、複数ソケットのイベントを一つのタスクで待つことが可能です。

マルチキャスト宛のパケットが受信できない

■質問
マルチキャストパケットが受信できません。設定等が必要ですか?

■回答
イーサネットドライバでマルチキャストパケットを受信しない設定になっているかもしれません。
イーサネットドライバのFilterモードの設定をMulticastに変更してください。
パッケージのサンプルプログラムではPerfect filterが設定されているケースが多いので、マルチキャストパケットは受信しません。

コンフィグレータに対応しているパッケージについては下図のように、コンフィグレータでイーサネットドライバの設定を変更後、ソースコードを再生成してください。(画面はパッケージ毎に多少異なります。)

コンフィグレータに対応していないパッケージについては次のファイルを参照してください。
 ・インストールフォルダ\Standard\Document\uNet3_XXXX_ETH.txt
*uNet3_XXXX_ETH.txtのXXXXはCPU名

ネットワークアプリケーションが使用するファイルシステムを変更したい。

対象:
μNet3/Compact、μNet3/Standard

質問:
ネットワークアプリケーションが使用するファイルシステムを任意のものに変更したい。

回答:
弊社で提供しているいくつかのネットワークアプリケーションは動作にファイルシステムを必要とします。
デフォルト状態では特定の変数をファイルシステムに見立てた「簡易ファイルシステム」が使用されます。

これを変更するには以下の手順で行います。

【コンフィグレータ付きパッケージの場合】
1. [ネットワークアプリケーション] → [File System]画面の設定を変更します。
2. [他ファイルシステムを使用する]にチェックを入れ、直下のエディットボックスに対象となるファイルシステムのインクルードファイルを指定します。
3. 上記後、ソース生成を実施すると変更内容が適用されたソースが出力されます。

【コンフィグレータなしパッケージの場合】
1. 対象となるネットワークアプリケーションの設定ファイルを開きます。
ここではFTPサーバを対象に説明を行うため ftp_server_cfg.h を開きます。

コード
//#include "ffsys.h" // 簡易ファイルシステムのヘッダ ★削除する
#include "target_filesystem.h" // 対象のファイルシステム ★追加する

/* Configuration */
#define CFG_FTPS_DRV_NAME 'C'
#define CFG_FTPS_PATH_MAX PATH_MAX
#define CFG_FTPS_CMD_TMO 5000
#define CFG_FTPS_DAT_TMO 5000
#define CFG_FTPS_IDLE_TMO (5 * 60 * 1000)

2. 上記の★箇所が変更箇所となります。対象のファイルシステムのヘッダを
インクルードするようにしてください。

—-
【その他注意点について】
弊社ネットワークアプリケーションでは、ファイル・フォルダ操作にANSIの
C言語標準ライブラリの以下関数を想定しています。(2016/3 現時点)
opendir  readdir  closedir  mkdir  rmdir  fopen  fclose  fread  fwrite  remove  stat

こちらの関数がご使用されるファイルシステムに含まれない場合は、
ユーザ側で当該関数のラッパ処理を作成するようにしてください。

UDPの受信パケットをアプリで取りこぼさないようにするには?

μNet3では受信パケットをアプリケーションが読み込むまでソケット内でいくつまで保持するかをコンフィグレーションすることができます。
これは「受信キューサイズ」と呼ばれるコンフィグレーションでデフォルトの設定では1つのパケットしか保持しないようになっています。

たとえばアプリケーションがrcv_soc()を実行する前に2個以上のパケットを受信すると最初に受信したパケット以外は破棄されるのでアプリケーションは受信することはできません。
またこれはコールバックを利用したノンブロッキング設定でも同じです。
もし数usecオーダーで連続して受信するUDPパケットをアプリケーションで取りこぼさないようにする必要がある場合、コンフィグレータ(UDP設定)で受信キューサイズを2以上に設定して下さい。

(※注意※)
UDPの受信キューサイズを増やした場合、受信パケットはアプリケーションが読み込むまでソケット内に保持します。もしアプリケーションが意図しないパケットを受信していた場合、不要なネットワークバッファの使用や枯渇する可能性がありますのでご注意下さい。

1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Compact版)

本手順は、μNet3/Compact版のパッケージの手順となります。
μNet3/Standard版をご使用の場合、「1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Standard版)」を参照ください。
※使用した評価ボードのメモリ上限の関係で、32739バイトの送受信となっています。実際のμNet3のUDPフラグメントパケットの上限は65507バイトとなります。

32739バイト(※1)のUDPパケットの送受信など大きなフレームのやり取りをする場合は、以下の手順を踏む事で実現する事が出来ます。
※1:20(IPヘッダ) + 8(UDPヘッダ) + 32739(ペイロード) = 32767

■ネットワークライブラリの再作成
ユーザが任意でネットワークバッファの確保処理やネットワークバッファの
大きさ、種類、それぞれの数を管理を行う機能を有効にするため以下の手順でμNet3ライブラリを再作成します。

1.「\Network\lib\M4\uNet3cortexm4.eww」などのソリューションファイルをIDEで起動

2.コンパイル時のプリプロセッサ定義に「EXT_ALOC_SUP」を追加

3.全ライブラリプロジェクトにプリプロセッサ定義を追加し、リビルドを行う

4.Configurator.exeにて、以下のリソース定義を追加/変更

5.「netmem_cfg.c」のソースファイルを追加し、以下のネットワークバッファ拡張管理処理を追加

コード
#include "kernel.h"
#include "net_hdr.h"
#include "net_sts.h"
#include "net_def.h"
#include "net_cfg.h"
#include "kernel_id.h"
#include "net_id.h"

#define NET_LARGE_BUF_SZ 32767 + 76;

ER net_memini(void)
{
    extern UW NET_BUF_SZ;
   
    NET_BUF_SZ = NET_LARGE_BUF_SZ;
   
    return E_OK;
}

ER net_memext(void)
{
    return E_OK;
}

ER net_memget(VP *adr, UINT len, TMO tmo, ID *id)
{
    if ( len > NET_BUF_SZ ) {
        return E_NOMEM;
    }

    if ( len > CFG_NET_BUF_SZ ) {
        *id = ID_NET_MPF_32767;
    } else {
        *id = ID_NET_MPF;
    }
    return tget_mpf( *id, adr, tmo );
}

ER net_memret(VP adr, ID id)
{
    return rel_mpf( id, adr );
}

6.32739バイトのパケットを送信するテストコードを追加

コード
    {
        static UB buf[32739];   /* 自動変数によるスタック消費回避の為、static */
        T_NODE remote = { 0 };

        remote.ver = IP_VER4;
        remote.num = 1;     /* ネットワークデバイス番号 */
        remote.ipa = ip_aton( "192.168.1.76" );
        remote.port = 12345;

        ercd = con_soc( ID_PROTO_UDP, &remote, 0 );
        ercd = snd_soc( ID_PROTO_UDP, &buf[0], 32739 );

        slp_tsk();
    }

7.Wireshark上で正常にパケットが送信されている事を確認

8.32739バイトのパケットを受信するテストコードを追加

コード
    {
        static UB buf[32739];   /* 自動変数によるスタック消費回避の為、static */

        ercd = rcv_soc( ID_PROTO_UDP, &buf[0], sizeof(buf) );
       
        slp_tsk();
    }

9.32739バイトのパケットが受信される事を確認

■補足
65507バイトなど、より大きなUDPフラグメントパケットを送受信する場合は、Configurator.exeの設定にて「ネットワークバッファの数」を増やしてください。

1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Standard版)

本手順は、μNet3/Standard版のパッケージの手順となります。
μNet3/Compact版をご使用の場合、「1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Compact版)」を参照ください。

65507バイト(※1)のUDPパケットの送受信など大きなフレームのやり取りをする場合は、以下の手順を踏む事で実現する事が出来ます。
※1:20(IPヘッダ) + 8(UDPヘッダ) + 65507(ペイロード) = 65535

■ネットワークライブラリの再作成
ユーザが任意でネットワークバッファの確保処理やネットワークバッファの
大きさ、種類、それぞれの数を管理を行う機能を有効にするため以下の手順でμNet3ライブラリを再作成します。

1.「\Network\lib\CortexA\uNet3cortexa.eww」などのソリューションファイルをIDEで起動

2.コンパイル時のプリプロセッサ定義に「EXT_ALOC_SUP」を追加

3.全ライブラリプロジェクトにプリプロセッサ定義を追加し、リビルドを行う

4.「net_cfg.c」に以下の固定長メモリプールの定義を追加
#define NET_LARGE_BUF_CNT 2
#define NET_LARGE_BUF_SZ 65535 + 76

const T_CMPF c_net_mpf_65535 = {TA_TFIFO, NET_LARGE_BUF_CNT, NET_LARGE_BUF_SZ, NULL, NULL};

5.「net_cfg.c」に以下のネットワークバッファ拡張管理処理を追加

コード
ID ID_NET_MPF = -1;
ID ID_NET_MPF_65535 = -1;

ER net_memini(void)
{
    extern UW NET_BUF_SZ;
    ER ercd;
   
    NET_BUF_SZ = NET_LARGE_BUF_SZ;

    ercd = acre_mpf((T_CMPF *)&c_net_mpf);
    if ( ercd < 0 ) {
        ID_NET_MPF = -1;
        return ercd;
    }
    ID_NET_MPF = ercd;
   
    ercd = acre_mpf((T_CMPF *)&c_net_mpf_65535);
    if ( ercd < 0 ) {
        del_mpf(ID_NET_MPF);
        ID_NET_MPF = -1;
        return ercd;
    }
    ID_NET_MPF_65535 = ercd;
   
    return E_OK;
}

ER net_memext(void)
{
    if ( ID_NET_MPF > 0 ) {
        del_mpf( ID_NET_MPF );
    }
    if ( ID_NET_MPF_65535 > 0 ) {
        del_mpf( ID_NET_MPF_65535 );
    }
    return E_OK;
}

ER net_memget(VP *adr, UINT len, TMO tmo, ID *id)
{
    if ( len > NET_BUF_SZ ) {
        return E_NOMEM;
    }

    if ( len > CFG_NET_BUF_SZ ) {
        *id = ID_NET_MPF_65535;
    } else {
        *id = ID_NET_MPF;
    }
    return tget_mpf( *id, adr, tmo );
}

ER net_memret(VP adr, ID id)
{
    return rel_mpf( id, adr );
}

6.65507バイトのパケットを送信するテストコードを追加

コード
    {
        SID sid;
        T_NODE host = { 0 };
        T_NODE remote = { 0 };
   
        host.num  = DEV_ANY;
        host.ver  = IP_VER4;
        host.ipa  = INADDR_ANY;
        host.port = 10000;
        sid = (SID)cre_soc( IP_PROTO_UDP, &host );

        remote.ver = IP_VER4;
        remote.num = 1;     /* ネットワークデバイス番号 */
        remote.ipa = ip_aton( "172.16.0.14" );
        remote.port = 12345;

        ercd = con_soc( sid, &remote, 0 );
        ercd = snd_soc( sid, &buf[0], 65507 );

        slp_tsk();
    }

7.Wireshark上で正常にパケットが送信されている事を確認

8.65507バイトのパケットを受信するテストコードを追加

コード
    {
        SID sid;
        T_NODE host = { 0 };
        T_NODE remote = { 0 };
   
        host.num  = DEV_ANY;
        host.ver  = IP_VER4;
        host.ipa  = INADDR_ANY;
        host.port = 10000;
        sid = (SID)cre_soc( IP_PROTO_UDP, &host );

        ercd = rcv_soc( sid, &buf[0], sizeof(buf) );
       
        slp_tsk();
    }

9.65507バイトのパケットが受信される事を確認

■補足
サンプルプログラムでは、net_cfg.hで定義される標準ネットワークバッファの数を以下のように定義しています。

#define CFG_NET_BUF_CNT 91

「91」という数字の内訳は「45 + 45 + 1」となっており、詳細としては以下の様になっています。
45 = IPフラグメント受信(分割パケット)の最大発生を想定した数
45 = IPフラグメント送信(分割パケット)の最大発生を想定した数
1 = ARPパケットで最低限必要なネットワークバッファの数

ただ、上記の数値は瞬間的に必要とされる理論値(最大値)なのでアプリケーションの設計に応じて適宜変更してください。
※最低45 + 1あれば、65507バイトのパケットの送受信を行う事が可能です。

大きなサイズのUDPパケットを送受信したい

下記のトピックを参照ください。

■トピック
1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Standard版)
1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Compact版)

TCP/UDPの通信速度を向上させたい

以下の手順を実施する事でネットワーク通信性能を向上させる事が出来ます。
但し、基本的に通信性能向上とメモリ使用量はトレードオフとなる為、最終的なコンフィグレーション設定値は、アプリケーションの設計に適した値を検討した上でカスタマイズしてください。

注意:評価版ではコンフィグレーション制限がある為、この手順を実施する事は出来ません。

1.通信速度を計測するテストプログラムヘッダ(sample_throughput.h)を作成

コード
#ifndef SAMPLE_THROUGHPUT_H_
#define SAMPLE_THROUGHPUT_H_

extern UW total_byte;
extern UW pps;

typedef ER (*FP_SNDRCV)(SID sid, VP data, UH len);

typedef struct t_task_param
{
    UB proto;          // 生成するソケットのプロトコル(IP_PROTO_TCP or IP_PROTO_UDP)
    UH data_size;      // 送受信サイズ(1-32768)
    UB con_flg;        // 接続モード(0 or SOC_SER or SOC_CLI)
    FP_SNDRCV api;     // 使用する関数ポインタ(&snd_soc or &rcv_soc)
} T_TASK_PARAM, *PT_TASK_PARAM;

void ThroughputTask(VP_INT exinf);

#endif

2.通信速度を計測するテストプログラムソース(sample_throughput.c)を作成

コード
#include "kernel.h"
#include "net_hdr.h"
#include "net_strlib.h"
#include "sample_throughput.h"

static char buf[32768];

UW total_byte = 0UL;
UW pps = 0UL;

void ThroughputTask(VP_INT exinf)
{
    PT_TASK_PARAM pParam;
    SID sid;
    T_NODE host;
    T_NODE remote;
    ER ercd;

    sid = 0U;
    pParam = (PT_TASK_PARAM)exinf;

    /* ソケット生成 */
    host.num  = 1;
    host.ver  = IP_VER4;
    host.ipa  = INADDR_ANY;
    host.port = 12345;
    ercd = cre_soc( pParam->proto, &host );
    if ( ercd <= 0 ) {
       goto TASK_END;
    }
    sid = (SID)ercd;

    /* TCPクライアント接続 */
    remote.ver = IP_VER4;
    remote.num = 1;     /* ネットワークデバイス番号 */
    remote.ipa = ip_aton( "172.16.0.1" );
    remote.port = 10000;
    ercd = con_soc( sid, &remote, pParam->con_flg );
    if ( ercd != E_OK ) {
       goto TASK_END;
    }

    /* スループット計測 */
    for ( ; ; ) {
        ercd = (pParam->api)( sid, &buf[0], pParam->data_size );
        if ( ercd <= 0 ) {
           break;
        }

        total_byte += (UW)ercd;
        pps++;
    }

TASK_END:
    /* 後始末 */
    if ( sid != 0U ) {
        cls_soc( sid, 0 );
        del_soc( sid );
        sid = 0U;
    }
    ext_tsk();
}

3.テストプログラムを起動するロジックを実装
※このトピックの例では、HELIO.NETサンプルプログラムのmain.c内にあるMainTaskをベースに実装しました

コピーペースト用テンプレート

コード
#define TCP_THROUGHPUT_ENABLE

T_CTSK ctsk_throughput = { TA_HLNG | TA_ACT | TA_FPU, (VP_INT)0, (FP)ThroughputTask, 5, 0x400, 0, "ThroughputTask" };


void MainTask(VP_INT exinf)
{
    T_TASK_PARAM param = { 0 };
    VB msg[32];
    ER ercd;

    ini_com(ID_UART, &uart_ini);
    ctr_com(ID_UART, STA_COM, 0);

    ctr_com(ID_UART, SND_BRK, 100);
    puts_com_opt((VB *)demo_str);

    /* Initialize Network */
    ercd = net_setup();
    if (ercd != E_OK) {
        return;
    }

    /* スループット計測タスク生成 */
#ifdef TCP_THROUGHPUT_ENABLE
#if 1
    param.proto = IP_PROTO_TCP;
    param.data_size = 32768;
    param.con_flg = SOC_CLI;
    param.api = &snd_soc;
#else
    param.proto = IP_PROTO_TCP;
    param.data_size = 32768;
    param.con_flg = SOC_SER;
    param.api = &rcv_soc;
#endif
#else
#if 1
    param.proto = IP_PROTO_UDP;
    param.data_size = 1472;
    param.con_flg = 0;
    param.api = &snd_soc;
#else
    param.proto = IP_PROTO_UDP;
    param.data_size = 1472;
    param.con_flg = 0;
    param.api = &rcv_soc;
#endif
#endif
    ctsk_throughput.exinf = (VP_INT)&param;
    acre_tsk( (T_CTSK *)&ctsk_throughput );

    for ( ; ; ) {
        tslp_tsk( 1000 );

        sprintf( &msg[0], "%dMbps, pps = %d\r\n", (total_byte * 8) / 1000 / 1000, pps );
        puts_com_opt( &msg[0] );

        total_byte = 0UL;
        pps = 0UL;
    }

#if 0
    /* Start UART console */
    net_sta_console();
#endif

    return;
}

4.これで性能計測する準備が出来ました。まず、デフォルトのコンフィグレーション内容で速度計測してみます。
■TCP送信性能
計測コマンド:「iperf -s -p 10000 -i 10」

■TCP受信性能
以下を変更してリビルドし実行

計測コマンド:「iperf -c 172.16.0.95 -p 12345 -i 10 -w 64000 -t 200」

■UDP送信性能
以下を変更してリビルドし実行

計測コマンド:「iperf -s -u -p 10000 -i 10 -l 1472」

■UDP受信性能
以下を変更してリビルドし実行

計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 1472 -i 10 -b 810M -t 200」

■デフォルト設定のスループット性能
TCP送信性能:55Kbps
TCP受信性能:90Mbps
UDP送信性能:495Mbps
UDP受信性能:500Mbps

5.次に通信性能に関わるコンフィグレーションのカスタマイズを行います。
■net_cfg.h

■DDR_CYCLONEV_ETH_cfg.h(ドライバによって名称が異なります)

CFG_TCP_SND_WNDの値をデフォルト1024から16384に変更(TCPの送信性能に影響します)
CFG_TCP_RCV_WNDの値をデフォルト1024から32768に変更(TCPの受信性能に影響します)
CFG_PKT_RCV_QUEの値をデフォルト1から255に変更(UDPの受信性能に影響します。また、UDPパケット取りこぼしにも影響します)
ETH1_RXDESC_CNTの値をデフォルト4から18に変更(Ethernetドライバのパケット受信性能に影響します)

■TCP送信性能
計測コマンド:「iperf -s -p 10000 -i 10」

■TCP受信性能
計測コマンド:「iperf -c 172.16.0.95 -p 12345 -i 10 -w 64000 -t 200」

■UDP送信性能
計測コマンド:「iperf -s -u -p 10000 -i 10 -l 1472」

■UDP受信性能
計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 1472 -i 10 -b 810M -t 200」

1472バイトを超えるUDPパケットの送受信が失敗してしまう
上記トピックにてIPフラグメントの受信を行える形にした上で受信処理を行うとUDP受信性能の向上が確認出来ます。送信処理はIPフラグメントを行わない方が性能が出るみたいです。

トピック対応を行い、UDP送受信バイト数の設定を変更

トピック対応を行い、スループット計測を行う処理を一部変更

■UDP送信性能(IPフラグメント)
計測コマンド:「iperf -s -u -p 10000 -i 10 -l 5888」

■UDP受信性能(IPフラグメント)
計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 5888 -i 10 -b 960M -t 200」

■カスタマイズ設定後のスループット性能
TCP送信性能:434Mbps
TCP受信性能:948Mbps
UDP送信性能:518Mbps(IPフラグメント無しの場合) → 376Mbps(IPフラグメント有りの場合)
UDP受信性能:813Mbps(IPフラグメント無しの場合) → 960Mbps(IPフラグメント有りの場合)

■コンフィグレーション内容まとめ(※1)
Ethernetドライバの送受信タスクの優先度 = 4(※2)
スループット計測タスク(ThroughputTask)の優先度 = 5(※2)
TCP送信バッファサイズ(CFG_TCP_SND_WND) = 16384
TCP受信ウィンドウサイズ(CFG_TCP_RCV_WND) = 32768
UDP受信キュー数(CFG_PKT_RCV_QUE) = 255
Ethernetドライバ送信ディスクリプタ数 = 4
Ethernetドライバ受信ディスクリプタ数 = 18

※1:色々試した結果、上記の設定で一番性能を出す事が出来ました。
   ただ、環境によって適切な値があると思うので参考値としてください。
※2:性能的にはEthernetドライバ > アプリケーションタスクの優先度の方が良い結果が出ます

■その他・補足
本サンプルはuC3/Standardをベースでのサンプルとなっています。
uC3/Compactで同様の事をやる場合は以下の点に注意してカスタマイズしてください。

1.CompactではコンフィグレータでTCPソケットの送信バッファや受信ウィンドウサイズをカスタマイズする機能があります。
従って、送信バッファや受信ウィンドウサイズを変更する場合はコンフィグレータから変更してください。
※ソケット生成の仕組みがStandardとは異なる為、net_cfg.hのCFG_TCP_SND_WNDやCFG_TCP_RCV_WNDの値を直接変更したとしても設定値として反映されないので注意が必要です。
2.CompactとStandardでは、del_soc()などいくつかサポートされていないAPIが存在します。
従って、Compactに本サンプルを適用する場合はサポートされていないAPIの処理は削除してください。

ネットワークの初期化直後に通信ができない場合がある

対象:
μNet3/Compact、μNet3/Standard

質問:
ネットワークの初期化処理(net_dev_ini())直後の通信に失敗することがあります。

回答:
弊社提供のEthernetドライバではnet_dev_ini()完了直後にはリンクアップが完了していない場合がございます。PHYの設定でオートネゴシエーションを有効の場合、net_dev_ini() 後に3秒程度のウェイトを入れるようにして下さい。オートネゴシエーションが無効(速度モード固定)の場合は即座にリンクアップは完了するため、ウェイトを特に入れる必要はありません。

HTTPサーバが正常に動作しません。

HTTPサーバが正常に動作していない場合は以下をチェックして下さい。

1. Webブラウザからの SYN に対して RST を返却してしまい、ページが表示されない。
PC用Webブラウザは通常複数のソケットを使用して並列的にHTTPサーバに対して要求を行います。
コンフィグレータのHTTPサーバ画面のセッション最大数はデフォルトで 1 となり、この場合は1度に1つのソケットからの要求にしてしか答えられず、HTML上に複数の画像やオブジェクトが存在する場合には画像・オブジェクトが読み込まれないことがあります。
対象画面:コンフィグレータ起動 → [TCP/IP] → [ネットアプリケーション] → [HTTP Server] → [セッション最大数] 

2. HTTPサーバは1セッション(1タスク)あたり、ネットワークバッファを2つ消費します。
HTTPサーバは送受信用のバッファとして、ネットワークバッファを2つ消費します。
“HTTPサーバのセッション数×2″のネットワークバッファ数を加算する必要があります。
uNet3フォルト設定はネットワークバッファ数が 4 です。そのため、セッション数が 5 の場合、
5 * 2 + 4 = 14 以上をネットワークバッファ数に設定してください。
対象画面:コンフィグレータ起動 → [TCP/IP] → [uNet3全般] → [詳細設定する] → [ネットワークバッファ数] 

3. CGIを実行すると、例外が発生する。
HTTPサーバタスクがスタックオーバフローを起こしている可能性があります。CGIはHTTPサーバタスク上で動作するコールバック関数です。そのため、HTTPサーバタスクのスタックを消費して動作します。スタックオーバフローが発生すると、例外や不正な動作をすることがあります。CGI用関数で消費するスタックを予めHTTPサーバタスクに加算するようにして下さい。
対象画面:コンフィグレータ起動 → [Kernel] → [タスク] → [タスク一覧]から “ID_HTTPD_TSKx” のスタックサイズ 

4. あるクライアントから接続を行うと、一定時間他のクライアントから接続が行えない。
HTTP Keep-Alive機能が動作している可能性があります。HTTP Keep-Alive機能は一旦接続を行うと、一定時間の間、クライアントとの接続を維持します。その間、対象セッションには他のクライアントから接続が行えません。HTTPサーバの設定画面より、HTTP Keep-Alive機能を無効にするか、最大セッション数を増やしてください。
対象画面:コンフィグレータ起動 → [TCP/IP] → [ネットアプリケーション] → [HTTP Server] → [機能設定] → [HTTP Keep-Alive機能を有効にする]

HTTPサーバのマルチパート受信CGI機能 実装サンプル

弊社HTTPサーバアプリで大きなファイルのアップロードを実現するマルチパート受信CGI機能の実装サンプルです。詳細は添付ファイルの Readme を参照してください。

また、併せて「μNet3 ネットワークアプリケーションガイド」の「9.5 HTTPサーバ API」にある
「【マルチパート受信/ストリーム受信 CGI 拡張用 API】 」を参照してください。

添付ファイル
xxxxxx.NET.MULTIPART.zip(8.9 KiB)
ダウンロード
パスワードは「eforce_multipart_201703」です。
Ethernetのリンク状態を参照したい

対象:
μNet3/Compact、μNet3/Standard

質問:
Ethernetのリンク状態(リンクダウン、リンクアップ・通信速度)をアプリから参照したい

回答:
Ethernetドライバが認識しているリンク状態は net_dev_sts() にパラメータ「REF_ETH_LINK_STS」を渡すことで取得が可能です。(※)
取得した値をマスク値「PHY_STS_MSK」でANDします。その値が「PHY_STS_LINK_DOWN 」でなければリンクアップ状態です。

※Ethernetドライバの参照関数(eth_ref)がパラメータ「REF_ETH_LINK_STS」に対応している必要があります。

コード
/*【サンプルコード】*/
  ER ercd;
  UH val;

  ercd = net_dev_sts(1, REF_ETH_LINK_STS, (VP)&val); /* 1 はデバイス番号 */
  if (E_OK == ercd) {
    if (PHY_STS_LINK_DOWN != (val & PHY_STS_MSK)) {
     /* リンクアップ状態 */
    }
    else {
      /* リンクダウン状態 */
    }
  }
  else {
     /* エラー(ドライバ初期化前など、ステータス取得可能状態ではない。) */
  }

--
/*【REF_ETH_LINK_STSパラメータで取得可能な値】*/
#define PHY_STS_LINK_DOWN 0x0000U /* PHY media link down */
#define PHY_STS_10HD 0x0100U /* PHY 10M/Half-Duplex */
#define PHY_STS_10FD 0x0200U /* PHY 10M/Full-Duplex */
#define PHY_STS_100HD 0x0400U /* PHY 100M/Half-Duplex */
#define PHY_STS_100FD 0x0800U /* PHY 100M/Full-Duplex */
#define PHY_STS_1000FD 0x1000U /* PHY 1000M/Full-Duplex */
#define PHY_STS_MSK 0xff00U /* PHY mask */
HTTPクライアント 大きいサイズのデータをPOSTする方法

http_cmd_postを使用してサーバへPOSTしたいが、
データサイズが大きいので、全データをバッファへ展開できない場合は、
次の手順で関数を実行してください。

1.http_cmd_postを実行
  T_HTTP_CLINET型の引数のメンバ変数flagのHTTPC_FLG_SND_BODY_LATERビットをセットします。
2.POSTするデータの一部をバッファへ展開します。
3.http_sndで2.のデータをサーバへ送信します。
4.次のデータをバッファへ展開します。
5.http_sndで4.のデータをサーバへ送信します。
以降、バッファへデータを展開する、http_sndでデータを送信するを、POSTするデータのサイズ分繰り返します。
6.http_rcv_statusでサーバからのレスポンス(ステータスラインとヘッダ)を受信、処理します。

以降はhttp_cmd_postでHTTPC_FLG_SND_BODY_LATERをセットしない場合と同じです。
(http_rcv_resでコンテンツを受信します。)

ジャンボフレームに対応していますか?

ご利用されるプロセッサによります。
μNet3でジャンボフレームをあつかった実績はあります。

ご利用されるプロセッサがμNet3でジャンボフレームに対応しているかは、
お問い合わせください。
弊社のホームページからお問い合わせいただけます。

お問い合わせ
OpenSSLを使った証明書生成手順

OpenSSLを使った証明書生成手順 (RSA編)

OpenSSLで証明書を作成するにはいくつかやり方がありますが、基本的には以下の2つの手順で行います。
またこの方法はサーバの証明書、クライアントの証明書、また私設のCAの証明書に関しても同じです。

  1. 証明書要求(CSR)作成
  2. CSRを署名して証明書を発行

1-1.CSRを作成するにはまず鍵交換用の秘密鍵(RSA)を生成します。
openssl genrsa -out my_rsa.key 2048
(-aes128や-des3オプションでパスフレーズ付きの秘密鍵となる)

1-2.次にreqコマンドでCSRを出力します。
openssl req -new -key my_rsa.key -out my_csr.csr
(-newkeyオプションで秘密鍵生成も一緒に行う)

2-1.my_rsa.keyで署名する場合(自己署名)
openssl x509 -in my_csr.csr -req -signkey my_rsa.key -out my_crt.crt -days 365

2-2.私設CAで署名する(openssl caコマンド)場合

まずは私設CAを作成する必要があります。
CA(認証局)をつくるには、CA.shスクリプト(/usr/lib/ssl/misc or /usr/ssl/misc)を-newcaオプション付きで実行します。
途中秘密鍵ファイル(cakey.pem)に暗号をかけるためのパスワードを聞かれるので任意のパスワードを入力します。(以下の3か所)

  Enter PEM pass phrase:

  Verifying – Enter PEM pass phrase:
  :
  :

  Enter pass phrase for ./demoCA/private/./cakey.pem:

入力が終了すると、demoCAフォルダに認証局用のファイルが生成されます。
次に1.で作成したCSRファイルをdemoCA/フォルダと同じ階層に格納し、caコマンドで署名します。

  openssl ca -in my_csr.csr

このときもcakey.pemに対するパスワードを聞かれます。
またcaコマンドではopenssl.cnfのポリシー(# For the CA policy)に従いますので、
(たとえば主体者と発行者でcountryNameが同じでなければならないなど・・・)、適宜変更して下さい。

  Enter pass phrase for ./demoCA/private/cakey.pem:

正常に入力が完了すると、demoCA/newcerts/にCAによって署名された証明書が出力されます。
my_rsa.key:秘密鍵として使用します。
emoCA/newcerts/xxxx.crt 証明書として使用します。

μNet3 TCPソケットのTCPステータスを確認したい

本トピックで掲載されている参照オプションは、μNet3 ver3.13以降でサポートされています。

対象:
μNet3/Compact、μNet3/Standard

質問:
TCPソケットのTCPステータスを確認する方法はありますか。

回答:
以下の処理にて確認する事が出来ます。

コード
#include "net_hdr.h"

UB sts;
ref_soc(sid, SOC_TCP_STATE, (VP)&sts)
※sid = ソケットID

変数stsは以下の値のいずれかが設定されます。

コード
#define TCP_UNUSED          0x00    /* 未使用状態 */
#define TCP_CLOSED          0x01    /* TCP接続無しの状態 */
#define TCP_LISTEN          0x02    /* TCPサーバとしてSYN要求を待っている状態 */
#define TCP_SYN_SENT        0x03    /* TCPクライアントとして、SYN要求を送ってTCPサーバからの応答を待っている状態 */
#define TCP_SYN_RECEIVED    0x04    /* TCPサーバとしてSYN要求を受信し、SYN/ACKを送信してTCPクライアントからのACKを待っている状態 */
#define TCP_ESTABLISHED     0x05    /* TCPハンドシェークが成立し、TCP接続済の状態 */
#define TCP_FIN_WAIT1       0x06    /* ESTABLISHED状態の時、FINを送信して、対向からのFINまたはACKを待っている状態 */
#define TCP_FIN_WAIT2       0x07    /* FIN-WAIT1状態の時、送信したFINに対するACKを受信した状態 */
#define TCP_CLOSE_WAIT      0x08    /* ESTABLISHED状態の時、対向からのFINを受信した状態 */
#define TCP_CLOSING         0x09    /* FIN-WAIT1状態の時、FINを受信後そのFINに対するACKを送信した状態 */
#define TCP_LAST_ACK        0x0A    /* CLOSE-WAIT状態の時、FINを送信して、ACKを待っている状態 */
#define TCP_TIME_WAIT       0x0B    /* FIN-WAIT2からの遷移の場合、FIN受信のACKを送信した状態。CLOSINGからの遷移の場合、送信FINのACKを受信した状態 */
ARP操作用のAPIは提供されていますか?

対象:
μNet3/Compact、μNet3/Standard

質問:
ARP操作をユーザアプリから実施したいと考えていますが、ARP操作用のAPIは提供されていますか?

回答:
標準のμNet3ライブラリではARP操作を未サポートのため、μNet3ライブラリのリビルドが必要となります。
ライブラリのプロジェクトで「ARP_API_SUP」定義をpre-define してビルドすることで、ARP APIが利用可能なμNet3ライブラリが生成されます。利用可能なAPIについては以下をご確認ください。

コード
/* ARPキャッシュ登録 ... 引数IPアドレス(ip)とMACアドレス(mac)の対をARPキャッシュに登録します */
ER arp_set(UH dev_num, UW ip, UB *mac);

/* 使用例 */
ER ercd;
UB mac[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc };

ercd = arp_set(1, ip_aton("192.168.1.110"), mac);
if (E_OK == ercd) {
  /* ARPキャッシュ登録 成功 (ip=192.168.1.110, mac=12:34:56:78:9a:bc のエントリが登録された) */
}
else {
  /* ARPキャッシュ登録 失敗 (E_ID: デバイス番号不正, E_NOMEM: ARPキャッシュに空きなし) */
}
コード
/* ARPキャッシュ参照 ... 引数IPアドレス(ip)をキーに、ARPキャッシュからMACアドレス(mac)を取得します */
ER arp_ref(UH dev_num, UW ip, UB *mac);

/* 使用例 */
ER ercd;
UB mac[6];

ercd = arp_ref(1, ip_aton("192.168.1.110"), mac);
if (E_OK == ercd) {
  /* ARPキャッシュ参照 成功 (macに指定IPアドレスに対応したMACアドレスが入る) */
}
else {
  /* ARPキャッシュ参照 失敗 (E_ID: デバイス番号不正, E_NOEXS: ARPキャッシュに登録なし) */
}
コード
/* ARPリクエスト送信 ... 引数IPアドレス(ip)を解決するARPリクエストを送信します */
ER arp_req(UH dev_num, UW ip);

/* 使用例 */
ER ercd;

ercd = arp_req(1, ip_aton("192.168.1.110"));
if (E_OK == ercd) {
  /* ARP送信 成功 (ARP送信はしたが、ARP応答があるかはこの時点では不明) */
}
else {
  /* ARP送信 失敗 (E_ID: デバイス番号不正, E_PAR: デバイスタイプがEthernet以外 ...) */
}
コード
/* ARPキャッシュクリア ... 手動で登録したものも含めてARPキャッシュをクリアします */
ER arp_clr(void);
HTTPクライアント SSL(TLS)に対応していますか?

質問:
uNet3-Professionalに収録されているHTTPクライアントはSSL(TLS)に対応していますか?

回答:
はい、対応しています。
HTTPクライアントで、SSL(TLS)を使用するには、uNet3-SSLが必要となります。
uNet3-SSLはuNet3で使用できるオプション製品で、別途ご購入いただく必要があります。

uNet3-SSLの詳細は、uNet3の製品情報を参照してください。

uNet3
μNet3のTCPスタックからRSTが送信される条件を教えてください。

質問:
μNet3のTCPスタックからRSTが送信される条件を教えてください。

回答:
RSTを送信する契機はいくつかありますが大別すると以下のパターンになります。

1.TCPのセッションがすでに閉じているときにTCPのセグメント受信。
(未使用ポートやdel_soc()やcls_soc()後にTCPを受信した場合)

2.アプリケーションがabt_soc()でセッションを強制終了した場合。

3.データを受信後にrcv_soc()をせずにcls_soc(SOC_TCP_CLS)を実行した。

4.TCPタイマ(再送、接続、切断)や、ソケットの切断タイマの満了によりセッションを持続できない場合。

デフォルトゲートウェイを未設定としたい

質問:
デフォルトゲートウェイを未設定とするにはどのアドレスを設定しておけばよいですか?

回答:
0.0.0.0を設定してください。
この場合サブネット外に送信しようとするとEV_ADDR(-98)が返却されます。

uNet3 - ノンブロッキングモードでコールバックがコールされません。

質問:
ソケットをノンブロッキングモードに設定したが、コールバックが実行されません。

回答:
事前にソケットAPI(接続:con_soc(),送信:snd_soc(), 受信:rcv_soc(), 切断:cls_soc())を実行した上で、
ソケットAPIの戻り値がE_WBLK(ノンブロッキング受付)の状態にしておく必要があります。

ソケットAPIの戻り値がその他の場合は、ソケットAPIで実行しようとした処理が完了したか、
エラーで終了しているのでコールバックは実行されません。

関連トピック:
ノンブロッキングモードを使って複数のソケットを1つのタスクで処理したい

ノンブロッキングモードを使って複数のソケットを1つのタスクで処理したい

μNet3のノンブロッキングモードを使用することで、1つのタスクで複数のソケットの送受信が可能になります。

ノンブロッキングモードを使用する上で注意が必要なのは

1.ソケットに対してノンブロッキングモードの設定とコールバック関数の登録を行います。
2.ソケットAPIの戻り値がE_WBLK(ノンブロッキング受付)の時のみコールバックされます。
3.コールバック関数はイベント発生時に呼ばれますが、コールバック関数からソケットAPIを呼ぶことはできません。
4.1度ノンブロッキングを受け付けたソケットに対して、コールバック前に同じソケットAPIを呼ぶとE_QOVRが返却されます。(API実行はキューイングされません)

本トピックにTCPソケット(10000ポート)とUDPソケット(20000ポート)を使って受信したパケットを送信元に返却する(エコーバックサーバ)サンプルを掲載します。
μC3コンパクトを使用する場合はコンフィグレータで次のIDを定義して下さい。

・イベントフラグ(ID_FLG_ECHO) (TA_WMUL)
・TCPソケット(TCP_SOC_ID) (ローカルポート10000)
・UDPソケット(UDP_SOC_ID) (ローカルポート20000)

コード
/***********************************************************************
          Non-blocking echo server program ***********************************************************************/

#include "kernel.h"
#include "net_hdr.h"

#define TCP_CONN_PTN 0x00000001
#define TCP_RECV_PTN 0x00000002
#define TCP_CLSE_PTN 0x00000004
#define UDP_RECV_PTN 0x00000008

#define ALL_PTN (TCP_CONN_PTN | TCP_RECV_PTN | TCP_CLSE_PTN | UDP_RECV_PTN)

/*
  Resources
*/
#ifdef NET_S_OS
  ID ID_FLG_ECHO = 0;
  SID TCP_SOC_ID = 0;
  SID UDP_SOC_ID = 0;
  UH TCP_SOC_PORT = 10000;
  UH UDP_SOC_PORT = 20000;
#else
  #include "kernel_id.h"
  #include "net_id.h"
#endif

UB TcpEchoBuffer[512];
UB UdpEchoBuffer[512];

/* Callback function */
ER EchoServerCallback(SID SocketId, UH CallbackEvent, ER ReturnValue) {

FLGPTN ptn;

  ptn = 0;
  if (ReturnValue >= E_OK) {
    /* TCP Socket */
     if (SocketId == TCP_SOC_ID) {
       /* Passive Open */
       if (CallbackEvent & EV_SOC_CON) {
        ptn |= TCP_CONN_PTN;
       }
       /* Receive Packet */
       if (CallbackEvent & EV_SOC_RCV) {
        ptn |= TCP_RECV_PTN;
       }
       /* Receive FIN */
       if (CallbackEvent & EV_SOC_CLS) {
        ptn |= TCP_CLSE_PTN;
       }      /* UDP Socket */
     } else if (SocketId == UDP_SOC_ID) {
       /* Receive Packet */
      if (CallbackEvent & EV_SOC_RCV) {
         ptn |= UDP_RECV_PTN;
       }      }     set_flg(ID_FLG_ECHO, ptn);
   }
  return E_OK;
}

ER EchoServer(void)
{
  ER ReturnValue;
  FLGPTN EventPattern;
  T_NODE HostEndPoint;

#ifdef NET_S_OS
  T_CFLG cflg_echo = {TA_TPRI | TA_WMUL, 0};

  ReturnValue = acre_flg(&cflg_echo);
  if (ReturnValue < 0) {
    return ReturnValue;
  }
  ID_FLG_ECHO = ReturnValue;
#endif

  EventPattern = 0;
  net_memset(&HostEndPoint, 0, sizeof(HostEndPoint));

  /*
    TCP echo server
*/

/* 1. Create TCP Socket */
#ifdef NET_S_OS
  HostEndPoint.port = TCP_SOC_PORT;
  HostEndPoint.num = 1; /* device number */

  ReturnValue = (ER)cre_soc(IP_PROTO_TCP, &HostEndPoint);
  if (ReturnValue < E_OK) {
     return ReturnValue;
  }
  TCP_SOC_ID = (SID)ReturnValue;
#endif

  /* 2. Register callback function */
  cfg_soc(TCP_SOC_ID, SOC_CBK_HND, (VP)&EchoServerCallback);

  /* 3. Set Socket API blocking mode as Non-Blocking (Connect, Receive, Close)*/
  cfg_soc(TCP_SOC_ID, SOC_CBK_FLG, (VP)
(EV_SOC_CON|EV_SOC_RCV|EV_SOC_CLS));


  /*
    UDP echo server
  */
  /* 1. Create UDP Socket */
#ifdef NET_S_OS
  HostEndPoint.port = UDP_SOC_PORT;
  HostEndPoint.num = 1; /* device number */

  ReturnValue = (ER)cre_soc(IP_PROTO_UDP, &HostEndPoint);
  if (ReturnValue < E_OK) {
    return ReturnValue;
  }
  UDP_SOC_ID = (SID)ReturnValue;
#endif

  /* 2. Register callback function */
  cfg_soc(UDP_SOC_ID, SOC_CBK_HND, (VP)&EchoServerCallback);

  /* 3. Set Socket API blocking mode as Non-Blocking (Receive)*/
  cfg_soc(UDP_SOC_ID, SOC_CBK_FLG, (VP)EV_SOC_RCV);


/*
    Echoback Process
  */

  /* give opportunity of first for TCP connect */
  EventPattern |= TCP_CLSE_PTN;

  /* give opportunity of first for UDP receive */
  EventPattern |= UDP_RECV_PTN;

  while (1) {

/* TCP Passive open */
    if (EventPattern & TCP_CLSE_PTN) {
       ReturnValue = con_soc(TCP_SOC_ID, &HostEndPoint, SOC_SER);
       if (ReturnValue != E_WBLK) {
         return ReturnValue;
       }
    }

     /* packet in socket until empty */
    while (EventPattern & TCP_RECV_PTN) {

     ReturnValue = rcv_soc(TCP_SOC_ID, TcpEchoBuffer,
sizeof(TcpEchoBuffer));
       /* Receive data */
         if (ReturnValue > 0) {
         /* Send data to Echo Client */
         snd_soc(TCP_SOC_ID, TcpEchoBuffer, ReturnValue);
       }
       /* Socket has no pakcet */
      else if (ReturnValue == E_WBLK) {
         EventPattern &= ~TCP_RECV_PTN;
       }
       /* Finished TCP session */
       else if (ReturnValue == 0 || ReturnValue == E_CLS) {
         ReturnValue = cls_soc(TCP_SOC_ID, SOC_TCP_CLS);
         if (ReturnValue != E_WBLK) {
            return ReturnValue;
         }
         EventPattern &= ~TCP_RECV_PTN;
       }
      /* rcv_soc() error */
       else {
         return EventPattern;
       }
    }


    /* UDP */
    /* packet in socket until empty */
     while (EventPattern & UDP_RECV_PTN) {

      ReturnValue = rcv_soc(UDP_SOC_ID, UdpEchoBuffer,
sizeof(UdpEchoBuffer));
       /* Receive data */
       if (ReturnValue > 0) {

         /* Get the IP Address and Port number information of Echo Clien */
         ref_soc(UDP_SOC_ID, SOC_IP_REMOTE, (VP)&HostEndPoint);

         /* Set the IP Address and Port number for data Transmission */
         con_soc(UDP_SOC_ID, (VP)&HostEndPoint, 0);

         /* Send data to Echo Client */
         snd_soc(UDP_SOC_ID, UdpEchoBuffer, ReturnValue);
       }
       /* Socket has no pakcet */
       else if (ReturnValue == E_WBLK) {
         EventPattern &= ~UDP_RECV_PTN;
       }
       /* rcv_soc() error */
       else {
         return EventPattern;
       }
    }

    EventPattern = 0;

    /* Wait callback event */
    ReturnValue = wai_flg(ID_FLG_ECHO, ALL_PTN, TWF_ORW, &EventPattern);
    clr_flg(ID_FLG_ECHO, ~EventPattern);

    if (ReturnValue != E_OK) {
       return ReturnValue;
     }

    if (EventPattern & TCP_CONN_PTN) {
      /* give opportunity of first for TCP receive */
       EventPattern |= TCP_RECV_PTN;
     }
  } /* while (1)*/
}

その他

製品のバージョン履歴を見たい。

弊社一部の製品について、以下にバージョン履歴を公開しました。
ご参考に願います。(閲覧にはユーザー登録(無料)が必要となります)

# 掲示板トップ > eForceからのお知らせ > 製品バージョンアップ / 不具合情報

コンパイラのバージョン対応表記についての補足説明

弊社パッケージの先頭にある「Readme_xxxx_xxxx.txt」ファイルのコンパイラのバージョン対応表記についての補足をいたします。

********
例えば、下記のような表記や、
:IAR Embedded Workbench (EWARM) v6.60 に対応
下記のような表記があります。
:RealView Microcontroller Development Kit (MDK-ARM) Version 4.72a に対応

********
この記載の意味については、お客様が弊社のパッケージを用いてアプリケーションを開発する場合に推奨する開発環境を示しているのではなく、弊社のパッケージの以下の部分を記載しているバージョンのコンパイラを用いて、コンパイルまたは、動作確認を実施していることを示しています。
例. μC3/Compactパッケージの場合
1. \uC3\Compact\Kernelフォルダ内のカーネルのライブラリファイル
“2. \uC3\Compact\Networkフォルダ内のカーネルのライブラリファイル
 =>μNet3パッケージをご利用の場合”
3. \uC3\Compact\Sample内のサンプルプログラム

例. μC3/Standardパッケージの場合
1. \uC3\Standard\Kernelフォルダ内のカーネルのライブラリファイル
“2. \uC3\Standard\Networkフォルダ内のカーネルのライブラリファイル
 =>μNet3パッケージをご利用の場合”
3. \uC3\Standard\Sample内のサンプルプログラム

********
この対応表記についてですが、必ずしも、対応時に最新のコンパイラを利用していません。
その理由は、弊社パッケージ製品につきましては、標準パッケージとしまして、
複数のお客様に提供をしております。
全てお客様が常に最新バージョンのコンパイラを利用しているとは限らず、古いバージョンのコンパイラを継続利用されるお客様も中にはいらっしゃいます。
各コンパイラについては、下位互換機能はない可能性があるため、パッケージに含めるサンプル等を最新バージョン利用して作成してしまうと,古いバージョンのコンパイラで開くことでできなくなる可能性もあります。
このため,弊社では利用するコンパイラのバージョンについては、お客様の利用状況を鑑みてから判断させていただいております。

********
弊社パッケージはコンパイラバージョンに依存したソースコードは含まれておりませんので、現在ご提供しているパッケージは上位バージョンのコンパイラ環境でも問題なく
ご利用いただけると判断しています。

もし、弊社パッケージをお使いの場合において、不明点がございましたらば、
サポート宛にご連絡をお願いいたします。

コンフィグレータ画面のコントロール表示がずれてしまう

コンフィグレータはDPIスケーリング100%(DPI値=96)を前提で作成されています。
Windows8以降のOSをご使用の場合、既定のディスプレイ設定でDPIスケーリングが125%(DPI値=120)または150%(DPI値=144)になっているケースがある為、コンフィグレータ画面のコントロールなどが表示ずれを起こしているケースがあります。

この場合、コントロールパネルのディスプレイ設定で拡大率を100%にする事で表示ずれを解消出来ます。

WYSACVLXY-XZ(太陽誘電社製の無線LANモジュール)のJTAG回路

質問
太陽誘電社の無線LANモジュールWYSACVLXY-XZとeForceのWLAN SDKの採用を検討しています。
ハードウェアを設計する際に、JTAGの回路をどのように組めばよいでしょうか?

回答
太陽誘電社から評価ボードの回路図が公開されていますので、参考にしてください。

ワイヤレス LAN モジュール評価ボード WBSACVLXY-1
https://www.yuden.co.jp/wireless_module/document/evbmanual2/jp/TY_WLAN_WBSACVLXY-1_EVBManual_V1.1J_20171005.pdf

WLAN SDKのサンプルプログラムは上記の評価ボードで動作します。
JTAGは、J-LINK(Segger社)、i-Jet (IAR systems社)の使用実績がございます。

評価ボードの詳細は太陽誘電社へお問い合わせください。