4 Replies Latest reply on Jun 2, 2019 7:14 PM by TaDa_1980266

    UART通信で8byteまでしか受信できない

    TaDa_1980266

      パソコンからUnixTimeを含む14byteの文字列データをUART通信で送信しましたが、
      UART_1_SpiUartGetRxBufferSize(); の戻り値が 8(byte) となり、
      UART_1_UartGetByte()×8回実行で "E0031559" しか受信出来ません。

       

      残りの6byteも遅れて受信する事も無く、"209375"が消えている状態です。

       

      受信でも UART_PutString() の様に一度にデータを取得するAPIはありませんでしょうか?

       

      PC->IC送信データ"E0031559209375"
      E003      : 内部コマンド種別
      1559209375: Unix Time

        • 1. Re: UART通信で8byteまでしか受信できない
          MoTa_728816

          こんばんは、

           

          おそらくUARTのバファーサイズが8byte になっているのだと思います。

          PSoC Creator の回路図上で UART のコンフィグの UART Advanced タブで

          16文字&Byte mode にしておくと、16文字(含む最後のNULL)までの

          文字列なら送受信できるのではないかと思います。

          000-Uart-Config.JPG

           

          また、デバイス・基板は異なるかもしれませんが、

          私の下記のサンプル等はご参考にならないでしょうか?

          TSoC トラ技基板 UART 入出力サンプル

           

          moto

          • 2. Re: UART通信で8byteまでしか受信できない
            TaDa_1980266

            moto様

             

            ご指摘通り、UART AdvancedタブのRx buffer size が 8 になっており、

            サイズを増やす事でデータ受信出来る様になりました。

             

            問題解決しました。

             

            本件クローズさせたいですが、

            参考までにサンプルコードについて2点教えて下さい。

             

            1. UART受信処理

             

               test001_190414.cyprj.Archive01.zip で、

               UART受信処理を割込み(CY_ISR(usr_isr))で1byte毎に処理している意図は

               メインループfor(;;)の処理負荷軽減(固まらない様にする)でしょうか?

             

               私は main.cの メインループfor(;;) 内で UART_SpiUartGetRxBufferSize()が0以外の場合、

               データ長分、UART_UartGetByte()で受信データを取得しているのですが、

               問題ありますでしょうか?

             

            2. クリティカルセクション

             

               CY_ISR(usr_isr)内の受信データの書込み処理をクリティカルセクションで

               別スレッドから更新されない様に保護していますが、

               このサンプルの受信データ(rx_buf[])更新はCY_ISR(usr_isr) 内の1箇所のみの為、

               rx_buf[]に対する同時書込みのリスクは無く、クリティカルセクションを外しても

               問題無い認識ですが、認識合っていますでしょうか?

             

               それともクリティカルセクションがないと、

               rx_buf[]のデータ参照時に不定な値(データ書込み中)となるリスクがありますでしょうか?

            • 3. Re: UART通信で8byteまでしか受信できない
              MoTa_728816

              takayama-様、

               

              > 1. UART受信処理

              >

              >  test001_190414.cyprj.Archive01.zip で、

              >   UART受信処理を割込み(CY_ISR(usr_isr))で1byte毎に処理している意図は

              >   メインループfor(;;)の処理負荷軽減(固まらない様にする)でしょうか?

              主に文字列の後のデリミタを検出し次第、対応した処理を起動できることを

              想定して一文字単位での処理としていました。

               

              >  私は main.cの メインループfor(;;) 内で UART_SpiUartGetRxBufferSize()が0以外の場合、

              >  データ長分、UART_UartGetByte()で受信データを取得しているのですが、

              >  問題ありますでしょうか?

              基本的に問題ないと考えます。

              あるいは、受信バッファの容量を異常に大きくしている場合は問題になるかも知れません。

               

              > 2. クリティカルセクション

              >

              >   CY_ISR(usr_isr)内の受信データの書込み処理をクリティカルセクションで

              >   別スレッドから更新されない様に保護していますが、

              >   このサンプルの受信データ(rx_buf[])更新はCY_ISR(usr_isr) 内の1箇所のみの為、

              >   rx_buf[]に対する同時書込みのリスクは無く、クリティカルセクションを外しても

              >   問題無い認識ですが、認識合っていますでしょうか?

              ご指摘の通り、少し神経質すぎる記述だったかと思います。

              ちょうど、その時期にマルチ割込みの発生時にデータを保護する話題が出ていた為

              実装してみましたが、rx_buf[] 自体をリングバッファにしていますので、

              書き込みと読み出しが同時に発生しても同じデータに対して行われることはないはずですね。

               

              >  それともクリティカルセクションがないと、

              >   rx_buf[]のデータ参照時に不定な値(データ書込み中)となるリスクがありますでしょうか?

              厳格な条件については確信がありませんが、私の経験上では、このクリティカルセクションの保護は必須ではないと思います。

              あえて考えた場合、他の割込み処理で、当該データに変更をかけるようなことがあるアプリケーションでは必要とされると思います。

               

              moto

              • 4. Re: UART通信で8byteまでしか受信できない
                TaDa_1980266

                moto様

                 

                早速の回答ありがとうございます。

                認識合っており安心しました。

                 

                サンプルコードにより、これまで意識していなかった

                クリティカルセクションを思い出す事が出来ましたので大変参考になりました。

                ありがとうございます。

                 

                本件Closeします。