2016年1月26日火曜日

GR-PEACH MX25Lの操作とその効果

Renesas RZA1H は秋月電子通商に現れた。
http://akizukidenshi.com/catalog/g/gM-10094/
しかし、デバッガーがないと、苦しいよな。
そこで、EEPROM MX25L6435 を直接読み書き出来るように、細工してみた。

配線を追加した。

















裏はこんな感じ。























吸出してみた。



















吸出したデータを逆アセンブルすると
arm-none-eabi-objdump -b binary -m arm -D mx25.bin















それらしく、データが読めた。

RDID 時の波形を示す。









これで、EEPROM をいじり倒すことができるね。


2016.01.26
2016.01.27 波形追加

2015年3月28日土曜日

USBCAN 改造

USBCAN
変換器を購入したはいいが、ドライバーが不明なので、
ファームウエアを作り込むことにした。

まずは、ハードウエアの確認。
USBSerial:CH340
MCU: STM32F103C8
OSC 8MHz
EEPROM: ATMEL 24C02
CAN PHY: 82C250 (5V)

MCU PORT:
pin func
44 BOOT0
30 PA9 USART1RX CH340へ
31 PA10 USART1TX CH340へ
32 PA11 CANRX
33 PA12 CANTX
41 PB5 LED 赤
21 PB10 I2CSCL EEPROMへ
22 PB11 I2CSDA EEPROMへ
25 PB12 LED 緑

基板上でBOOT0 がスルホールに出ているので
コネクタにひきだしてみた。

あとは、BOOT0をショートさせてUSBコネクタを差し通電すれば
BOOTモードに移行する。

Flash書き換えツールは
stsw-mcu005.zip
を使用した

2015.03.28

2015年3月18日水曜日

疑似マルチタスク 850

hamayanさんのマルチタスク2 を RH850版で確認できた。
http://hamayan.blog.so-net.ne.jp/2012-12-27
修正箇所は2か所。
1. dispatch_850.asm
 ;/* RH850 CC-RH */  
  .section ".text", text  
  .public _swi_ctx ;/*実行コンテキストの切替*/  
  .public _sta_ctx ;/*コンテキストをロードし、タスクを開始*/  
 ;/************************************************  
 ; コンテキストをロードし、タスクを開始  
 ; void sta_ctx(  
 ;  void *exe ) //実行コンテキストの保存先  
 ;************************************************/  
 _sta_ctx:  
  push  lp  
  ld.w  [r6],sp   ;/*スタックポインタ設定*/  
  popsp r20,r31  
  jmp  [lp]  
 ;/************************************************  
 ; 実行コンテキストの切替  
 ; void swi_ctx(  
 ;  void *pre,  //現在のコンテキストの保存先  
 ;  void *post) //切り替えるコンテキスト  
 ;************************************************/  
 _swi_ctx:  
  pushsp r20,r31  
  st.w  sp,[r6]   ;/*スタックポインタ保存*/  
  ld.w  [r7],sp   ;/*スタックポインタ復帰*/  
  popsp r20,r31  
  jmp  [lp]  
2. mul_tsk.c
修正箇所reg_tsk()
 /****************************************************************************/  
 /* タスク登録                                */  
 /* タスクID、エントリーポイント、スタック領域、スタックサイズ、       */  
 /* 起動時引数を4つまで登録できる。              、       */  
 /****************************************************************************/  
 ER reg_tsk( ID tid, void *tsk, void *stk, int stk_sz,  
  VP_INT exinf1, VP_INT exinf2, VP_INT exinf3, VP_INT exinf4 )  
 {  
  VP_INT *ptr;  
  if( tid < 0 || tid >= MAX_TASK_NUMBER ) return E_ID;  
  /*タスクのスタックの初期化*/  
  tcb[tid].sp = (void *)((char *)stk + stk_sz - (4 * (12))); /*r20からr31までこの領域に保存される*/  
  ptr = (VP_INT *)tcb[tid].sp;  
  ptr[ 0] = (VP_INT)tsk; /*LP(R31)*/  
  ptr[ 1] = 0x30303030; /*EP(R30)*/  
  ptr[ 2] = 0x29292929; /*R29*/  
  ptr[ 3] = 0x28282828; /*R28*/  
  ptr[ 4] = 0x27272727; /*R27*/  
  ptr[ 5] = 0x26262626; /*R26*/  
  ptr[ 6] = 0x25252525; /*R25*/  
  ptr[ 7] = 0x24242424; /*R24*/  
  ptr[ 8] = 0x23232323; /*R23*/  
  ptr[ 9] = 0x22222222; /*R22*/  
  ptr[10] = 0x21212121; /*R21*/  
  ptr[11] = 0x20202020; /*R20*/  
  tcb[tid].exinf[0] = exinf1;  
  tcb[tid].exinf[1] = exinf2;  
  tcb[tid].exinf[2] = exinf3;  
  tcb[tid].exinf[3] = exinf4;  
  tcb[tid].rdy_flg = TTS_DMT;  
  return E_OK;  
 }  

2014年11月24日月曜日

socz80 Papilio Pro(2)

socz80 で SD Card が読めたのでメモします。
使用したSDCC はver 3.4.0です。
[crt.asm]
   ;.org  #0x0000  
   call  _main  
   ret  

[sfr_def.h]
 #ifndef _SFR_H_  
 #define _SFR_H_  
 __sfr __at 0x00 UART_ST;  
 __sfr __at 0x01 UART_TD;  
 __sfr __at 0x01 UART_RD;  
 __sfr __at 0x20 GPIO_SW;  
 __sfr __at 0x21 GPIO_LED;  
 __sfr __at 0x30 SPI1_CS;  
 __sfr __at 0x31 SPI1_BY;  
 __sfr __at 0x32 SPI1_TD;  
 __sfr __at 0x33 SPI1_RD;  
 __sfr __at 0x34 SPI1_DV;  
 #endif  

[SD.c]
 #include "sfr_def.h"  
 struct sd_def  
 {  
  unsigned char cmd[8];  
  unsigned char res[2];  
  unsigned char buf[512];  
 } sd;  
 void uart_print (const char *fmt, ...);  
 void SD_INIT (void);  
 void SD_READ (int sec);  
 int CRC7 (unsigned char c[], int n);  
 void  
 main ()  
 {  
  int led;  
  led = 0;  
  uart_print ("hello\r\n");  
  SD_INIT ();  
  SD_READ (0);  
  while (1)  
   {  
    led++;  
    uart_print ("%04x\r", led);  
    GPIO_LED = led;  
   }  
 }  
 int  
 SD_RW (int data)  
 {  
  SPI1_TD = data;  
  return SPI1_RD & 0xff;  
 }  
 void  
 SD_INIT (void)  
 {  
  int i;  
  SPI1_DV = 6;  
  SPI1_CS=1;  
  /* dummy clock */  
  for (i = 0; i < 10; i++)  
   {  
    SD_RW (0xff);  
   }  
  sd.cmd[0] = 0x40;  
  sd.cmd[1] = 0x00;  
  sd.cmd[2] = 0x00;  
  sd.cmd[3] = 0x00;  
  sd.cmd[4] = 0x00;  
  sd.cmd[5] = CRC7 (sd.cmd, 5) | 1;  
  SPI1_CS=0;  
  for (i = 0; i < 6; i++)  
   {  
    SD_RW (sd.cmd[i]);  
   }  
  do  
   {              /* response */  
    sd.res[0] = SD_RW (0xff);  
   } while (sd.res[0] == 0xff);  
  SPI1_CS=1;  
  sd.cmd[0] = 0x41;  
  sd.cmd[1] = 0x00;  
  sd.cmd[2] = 0x00;  
  sd.cmd[3] = 0x00;  
  sd.cmd[4] = 0x00;  
  sd.cmd[5] = CRC7 (sd.cmd, 5) | 1;  
    SPI1_CS=0;  
      for(;;){  
    for (i = 0; i < 6; i++)  
     {  
      SD_RW (sd.cmd[i]);  
     }  
    do  
     {            /* response */  
      sd.res[0] = SD_RW (0xff);  
     } while (sd.res[0] == 0xff);  
           sd.res[1] = SD_RW (0xff);  
       if(sd.res[0] ==0||sd.res[1] ==0)  
        break;  
      }  
    SPI1_CS=1;  
 }  
 void  
 SD_READ (int sec)  
 {  
  int i;  
  sd.cmd[0] = 0x51;  
  sd.cmd[1] = 0x00;  
  sd.cmd[2] = 0x00;  
  sd.cmd[3] = sec >> 8;  
  sd.cmd[4] = sec;  
  sd.cmd[5] = CRC7 (sd.cmd, 5) | 1;  
  SPI1_CS=0;  
  for (i = 0; i < 6; i++)  
   {  
    SD_RW (sd.cmd[i]);  
   }  
  do  
   {              /* response */  
    sd.res[0] = SD_RW (0xff);  
   }  
  while (sd.res[0] == 0xff);  
  do  
   {              /* start byte */  
    sd.res[1] = SD_RW (0xff);  
   }  
  while (sd.res[1] != 0xfe);  
  for (i = 0; i < 512; i++)  
   {  
    sd.buf[i] = SD_RW (0xff);  
   }  
  /* crc1 crc2 */  
  SD_RW (0xff);  
  SD_RW (0xff);  
  /* dummy clock */  
  SD_RW (0xff);  
  SPI1_CS=1;  
  for (i = 0; i < 512; i++)  
   {  
    if ((i & 15) == 0)  
     uart_print ("\n%03x", i);  
    uart_print (" %02x", sd.buf[i]);  
   }  
  uart_print ("\n");  
 }  
 void  
 SD_WRITE (int sec)  
 {  
 }  
 //------- CRC7 by K.I 051020 --------  
 int  
 CRC7 (unsigned char c[], int n)  
 {  
  int i, j;  
  unsigned char d, r = 0;  
  for (i = 0; i < n; i++)  
   {  
    d = c[i];  
    for (j = 0; j < 8; j++)  
     {  
      if ((d & 0x80) ^ (r & 0x80))  
       r = (r << 1) ^ 0x12;    // reverse of 0x48  
      else  
       r <<= 1;  
      d <<= 1;  
     }  
   }  
  return (r & 0xFE);  
 }  

[build.bat]
 sdasz80 -plosgff -o crt.rel crt.asm  
 sdcc -mz80 -c print.c   
 sdcc -mz80 -c SD.c   
 sdcc -mz80 --code-loc 0x100 --no-std-crt0 -Wlcrt.rel SD.rel print.rel  

cmd0

cmd17 コマンド受付

cmd17 データの開始 0xFE

cmd17 最終データ部 0xaa 0x55

セクタ#0


転送ツールとSDCard Read サンプル
https://www.dropbox.com/s/nm0vcrq0nfpjvrd/D2tool.zip?dl=0
https://www.dropbox.com/s/fpc7u1qoig1z1ug/sample_sdcard.zip?dl=0

socz80 Papilio Pro(1)

秋月電子で販売中のPapilio Proで socZ80 が動作したのでメモします。
物は
http://akizukidenshi.com/catalog/g/gM-06926/
これです。


socz80は
http://sowerbutts.com/socz80/
これです。
シールドはなくても、socz80は動作しますが、あったほうが気合いが入ります。



CPM disk imageをツールでSDRAMの転送後、rwrite コマンドで SDRAM->SPI FLASHに格納します。

rread コマンドで SPI FLASH->SDRAMに取り出し、rboot コマンドで CPMを起動します。

なお、disk image の転送ツール(write_phy_mem)はsocz80に添付されていますが、python で書かれており、Linuxを想定しています。
Windowsで使うには、不便なので、自家製のツールをつくり、転送に利用しました。
転送ツール
https://www.dropbox.com/s/s6fzqmcrcb8wzdx/D1tool.zip?dl=0

2014年8月15日金曜日

Em::Blocks/VirtualStaterKit(FM3 QEMU)

VirtualStaterKit を Em::Blocksで動作したのでメモしておく。
Spansionは FM3シリーズ(Cortex-M3)のQEMU環境を配布してる。
https://www.spansion.com/JP/Support/microcontrollers/development-environment/pages/virtual-starter-kit.aspx
開発環境はIAR EWARMとCodeBenchがお薦めらしい。

ここでは Em::Blocks でデバッグできることを示す。

VirtualStarterKit.bat を起動する。
Teraterm で localhost TCP:1204 で接続。

Em::Blocksでdebug接続する (TCP:1234)。

Em::Blocks でDebug Run

Em::Blocks の設定例(Project->Build Options...)

Em::Blocks の設定例(Debug->Interfaces)
gdb server は launchpad gcc のもの(arm-none-eabi-gdb)を流用しました。
https://launchpad.net/gcc-arm-embedded

VirtualStartKit.bat の修正


configuration\cpu.ini の修正(GDB Server接続を有効化)
GDB 接続しない場合は コメントのままとする

2014年7月23日水曜日

マルチタスク2::SH7216 STM32F30x

hamayan さんのマルチタスク2を SH2A:SH7216 で動作させたので差分をメモします。

GR-SAKURAではじめる超お手軽マルチタスク2
http://hamayan.blog.so-net.ne.jp/2012-12-27

修正箇所はdispatcher_sh2a.srcのみ
 ;/****************************************************************************/  
 ;/* コンテキストの切り替え処理                        */  
 ;/*                                     */  
 ;/* designed by hamayan                           */  
 ;/*             Copyright (C) 2012 hamayan All Rights Reserved. */  
 ;/****************************************************************************/  
  .export _swi_ctx ;/*実行コンテキストの切替*/  
  .export _sta_ctx ;/*コンテキストをロードし、タスクを開始*/  
 ;/************************************************  
 ; コンテキストをロードし、タスクを開始  
 ; void sta_ctx(  
 ;  void *exe ) //実行コンテキストの保存先  
 ;************************************************/  
  .section P,CODE,ALIGN=4  
 _sta_ctx:  
  sts   pr,@-r15  ;/* pr 退避 */  
  mov.l  @r4,r15   ;/*スタックポインタ設定*/  
  movmu.l @r15+,r6  ;/*r6-r14,prを復帰*/  
  rts/n  
 ;/************************************************  
 ; 実行コンテキストの切替  
 ; void swi_ctx(  
 ;  void *pre,  //現在のコンテキストの保存先  
 ;  void *post) //切り替えるコンテキスト  
 ;************************************************/  
  .section P,CODE,ALIGN=4  
 _swi_ctx:  
  movmu.l r6,@-r15  ;/*r6-r14,prを退避。r6が最も若いアドレスになる*/  
  mov.l  r15,@r4   ;/*スタックポインタ保存*/  
  mov.l  @r5,r15   ;/*スタックポインタ復帰*/  
  movmu.l @r15+,r6  ;/*r6-r14,prを復帰*/  
  rts/n  
  .end  
 ;/****************************************************************************/  
 ;/* designed by hamayan                           */  
 ;/*             Copyright (C) 2012 hamayan All Rights Reserved. */  
 ;/****************************************************************************/  
mul_tsk.c::reg_tsk() を修正したくないので、
R6,R7は余分ですが、退避、回復させています。

また、 STM32F30x での GCC版 のコードもメモしておきます。

修正箇所はdispatcher_cm3.sのみ
 ;/****************************************************************************/  
 ;/* コンテキストの切り替え処理                        */  
 ;/*                                     */  
 ;/* designed by hamayan                           */  
 ;/*             Copyright (C) 2012 hamayan All Rights Reserved. */  
 ;/****************************************************************************/  
  .syntax unified  
  .arch armv7-m  
  .globl swi_ctx ;/*実行コンテキストの切替*/  
  .globl sta_ctx ;/*コンテキストをロードし、タスクを開始*/  
  .section .text  
 ;/************************************************  
 ; コンテキストをロードし、タスクを開始  
 ; void sta_ctx(  
 ;  void *exe ) //実行コンテキストの保存先  
 ;************************************************/  
 sta_ctx:  
  push {lr}     ;/*lrを退避*/  
  ldr r13,[r0]   ;/*スタックポインタ設定*/  
  pop {r4-r12,pc} ;/*r4-r12,pcを復帰*/  
 ;/************************************************  
 ; 実行コンテキストの切替  
 ; void swi_ctx(  
 ;  void *pre,  //現在のコンテキストの保存先  
 ;  void *post) //切り替えるコンテキスト  
 ;************************************************/  
 swi_ctx:  
  push {r4-r12,lr} ;/*r4-r12,lrを退避。r4が最も若いアドレスになる*/  
  str r13,[r0]   ;/*スタックポインタ保存*/  
  ldr r13,[r1]   ;/*スタックポインタ復帰*/  
  pop {r4-r12,pc} ;/*r4-r12,pcを復帰*/  
  .end  
 ;/****************************************************************************/  
 ;/* designed by hamayan                           */  
 ;/*             Copyright (C) 2012 hamayan All Rights Reserved. */  
 ;/****************************************************************************/  

STM32Fシリーズの統合開発環境はEm::Blocksが便利です。
デバッガーにSTLinkが使えるのがうれしい。
http://www.emblocks.org/web/

2014.07.23

2014年7月14日月曜日

SEV SH7216 (2)

Windows8.1 で COM_class.zipがインストール失敗する理由を探ってみた。

http://blogs.msdn.com/b/jpwdkblog/archive/2013/12/27/dpinst-log.aspx
の記事を見ながら追跡してみたもの。
dpinst_x64.exeを実行すると

  • DPINST.LOG
    INFO: ENTER: DriverPackagePreinstallW
    INFO: RETURN: DriverPackagePreinstallW (0xE0000247)
    INFO: Returning with code 0x80010000M
  • setupapi.dev.log
    inf: Could not find include INF file "layout.inf". Error = 0x00000002
    ! sig: Verifying file against specific (valid) catalog failed! (0x00000057)
    ! sig: Error 87: The parameter is incorrect.
    ! sig: Verifying file against specific Authenticode(tm) catalog failed! (0x800b0100)
    ! sig: Error 0x800b0100: No signature was present in the subject.
    !!! sig: Driver package catalog file does not contain a signature, and Code Integrity is enforced.
    !!! sig: Driver package failed signature validation. Error = 0xE0000247
    !!! sig: Driver package failed signature verification. Error = 0xE0000247
    !!! sto: Failed to import driver package into Driver Store. Error = 0xE0000247

    2013.07.14
  • 2014年7月13日日曜日

    SEV SH7216 お薦めできない理由

    この記事は個人の感想です。
  • SH7216 だから当然Ether PHY実装されている?
    PHY 実装なし。
  • FDTv409r02でUSB経由(Generic Boot USB Direct)でファームアップデート可能?
    可能ではあるが Windows8.1上では安定しない。4回に1回ぐらいの成功率。
  • SH7216用COMクラスは64bit対応?
    http://japan.renesasrulz.com/partner_tools/marutsu/m/sh7216_board/default.aspx
    ここで配布しているのは、なんちゃって署名!?、Windows8.1ではインストールできない。
     Windows XPではインストールできた。

    正しく署名されたUSB CDC Driverでの確認。
    NXP LPC11U35用のVCOM で確認してみた。
    SetUsbInfo.h を修正

  • USB Bootが安定しない理由
    PB14 がpullupされていないから?
    pullupしてみたが現象変わらず!

    GR-SAKURAのほうが、USB Bootも安定している、Etherが使える分楽しめる。
    2014.07.13
  • 2014年6月25日水曜日

    STM32F429 uclinux(2)

    修正個所と、設定変更箇所を図で示します。
    u-boot/include/configs/stm32429-disco.h
    uclinux/arch/arm/mach-stm32/iomux.c
    uclinux/arch/arm/mach-stm32/spi.c

    2014.06.26

    2014年6月24日火曜日

    STM32F429 uclinux

    emcraft さんのソースをいじって、なんとかSD Cardがrootfs でmountできた。
    しかし、github上にはすでに、動作するものがあったようだ。
    https://github.com/Lefinnois/stm32f429-linux-builder

    主な変更箇所は
    u-boot:
    include/configs/stm32429-disco.h
    root=dev/mmcblk0p1 rootdelay=1 rdinit=/sbin/init
    uclinux:
    arch/arm/mach-stm32/spi.c
    arch/arm/mach-stm32/iomux.c

    あとは make menuconfig で
    http://blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:spi_mmc
    のような感じに設定


    2014.06.24

    2013年8月4日日曜日

    websocket RX63N その3

    websocketでバイナリとテキストの送信と受信をやってみた。

    ブラウザ等、クライアント側
    プログレスバーを追加してみた。
    http://www.html5.jp/library/progress.html

     <!DOCTYPE html>  
     <html>  
     <head>  
       <title>Websocket client</title>  
       <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">  
       <script src="http://code.jquery.com/jquery.js"></script>  
       <script src="../html5jp/progress.js"></script>  
     </head>  
     <body>  
       <div class="container">  
         <h1 class="page-header">Websocket client</h1>  
         <form action="" class="form-inline" id="connectForm">  
           <div class="input-append">  
             <input type="text" class="input-large" value="ws://192.168.1.63:8088/echo" id="wsServer">  
             <button class="btn" type="submit" id="connect">Connect</button>  
             <button class="btn" disabled="disabled" id="disconnect">Disconnect</button>  
           </div>  
         </form>  
         <form action="" id="sendForm">  
           <div class="input-append">  
             <input class="input-large" type="text" placeholder="message" id="message" disabled="disabled">  
             <button class="btn btn-primary" type="submit" id="send" disabled="disabled">send</button>  
           </div>  
         </form>  
         <form action="" id="ledForm">  
           <div class="input-append">  
             <button class="btn" value="1" disabled="disabled" id="led1">LED1</button>  
             <button class="btn" value="2" disabled="disabled" id="led2">LED2</button>  
           </div>  
         </form>   
         <hr>  
          <div id="sample"></div>  
         <hr>  
         <form name="mform">  
          <textarea name="messages" rows="5" cols="50"></textarea>  
         </form>  
         <hr>  
         <ul class="unstyled" id="log"></ul>  
       </div>  
       <script type="text/javascript">  
         $(document).ready(function() {  
           var ws;  
           var p = { to:50 };  
           var o = new html5jp.progress("sample",p);  
           o.draw();  
           $('#connectForm').on('submit', function() {  
             if ("WebSocket" in window) {  
               ws = new WebSocket($('#wsServer').val());  
               ws.binaryType = 'arraybuffer';  
               ws.onopen = function() {  
                 $('#log').append('<li><span class="badge badge-success">websocket opened</span></li>');  
                 $('#wsServer').attr('disabled', 'disabled');  
                 $('#connect').attr('disabled', 'disabled');  
                 $('#disconnect').removeAttr('disabled');  
                 $('#led1').removeAttr('disabled');  
                 $('#led2').removeAttr('disabled');  
                 $('#message').removeAttr('disabled').focus();  
                 $('#send').removeAttr('disabled');  
               };  
               ws.onerror = function() {  
                 $('#log').append('<li><span class="badge badge-important">websocket error</span></li>');  
               };  
               ws.onmessage = function(event) {  
                if(typeof event.data == 'string') {  
                var str = "String:";  
                str += event.data;  
                var percent = parseInt(event.data);  
                if(percent != NaN){  
                 o.set_val(percent);  
                }  
                } else if(typeof event.data == 'object') {  
                 var byteArray = new Uint8Array(event.data);  
                 var str = "Object:";  
                 for( var n = 0;n < byteArray.length;n++){  
                  str += " 0x" + ("0" + byteArray[n].toString(16)).slice(-2);  
                 }  
                } else {  
                 var str = "Unknown:";  
                }  
                var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;  
                if(num > 4){  
                  document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");  
                }  
                document.mform.messages.value = document.mform.messages.value + '\r\n'+ str;  
                //$('#log').append('<li>received: <span class="badge">' + str + '</span></li>');  
               };  
               ws.onclose = function() {  
                 $('#log').append('<li><span class="badge badge-important">websocket closed</span></li>');  
                 $('#wsServer').removeAttr('disabled');  
                 $('#connect').removeAttr('disabled');  
                 $('#disconnect').attr('disabled', 'disabled');  
                 $('#message').attr('disabled', 'disabled');  
                 $('#send').attr('disabled', 'disabled');  
               };  
             } else {  
               $('#log').append('<li><span class="badge badge-important">WebSocket NOT supported in this browser</span></li>');  
             }  
             return false;  
           });  
           $('#sendForm').on('submit', function() {  
             var message = $('#message').val();  
             ws.send(message);  
             $('#log').append('<li>sended: <span class="badge">' + message + '</span></li>');  
             return false;  
           });  
           $('#led1').on('click', function() {  
             var buffer = new ArrayBuffer(2);  
             var byteArray = new Uint8Array(buffer);  
             byteArray[0] = 0xf8;  
             byteArray[1] = 0x01;  
             var str = "";  
             for( var n = 0; n<byteArray.length;n++){  
              str += " 0x"+ ("0" + byteArray[n].toString(16)).slice(-2);  
             }  
             ws.send(buffer);  
             var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;  
             if(num > 4){  
               document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");  
             }  
             document.mform.messages.value = document.mform.messages.value + '\r\n'+ str;  
             return false;  
           });  
           $('#led2').on('click', function() {  
             var message = $(this).attr('value');  
             ws.send(message);  
             var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;  
             if(num > 4){  
                document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");  
             }  
             document.mform.messages.value = document.mform.messages.value + '\r\n'+ message;  
             return false;  
           });  
           $('#disconnect').on('click', function() {  
             ws.close();  
             return false;  
           });  
         });  
       </script>  
     </body>  
     </html>  
    

    RX63N側サーバー
    1)受信したら、送り返す動作。
    バイナリとテキストを区別しています。
    2)定期的にテキストで送信。
    freecounterの値
    ------------
     ...略
     #include "websocket.h"  
     #define BUF_LEN 512  
     void clientWorker(ID cepid);  
     /******************************************************************************  
     Exported global variables and functions (to be accessed by other files)  
     ******************************************************************************/  
     void error(const char *msg)  
     {  
          //  perror(msg);  
          return;  
          //  exit(EXIT_FAILURE);  
     }  
     int safeSend(ID cepid, const uint8_t *buffer, size_t bufferSize)  
     {  
          ER written;  
          written = tcp_snd_dat(cepid, buffer, bufferSize, 100);  
          if (written < 0) {  
               return EXIT_FAILURE;  
          }  
          return EXIT_SUCCESS;  
     }  
     static uint8_t freecounter=0;  
     void clientWorker(ID cepid)  
     {  
          uint8_t buffer[BUF_LEN];  
          uint8_t txbuffer[12];  
          int i;  
          memset(buffer, 0, BUF_LEN);  
          size_t readedLength = 0;  
          size_t frameSize = BUF_LEN;  
          enum wsState state = WS_STATE_OPENING;  
          uint8_t *data = NULL;  
          size_t dataSize = 0;  
          enum wsFrameType frameType = WS_INCOMPLETE_FRAME;  
          struct handshake hs;  
          nullHandshake(&hs);  
     #define prepareBuffer frameSize = BUF_LEN; memset(buffer, 0, BUF_LEN);  
     #define initNewFrame frameType = WS_INCOMPLETE_FRAME; readedLength = 0; memset(buffer, 0, BUF_LEN);  
          while (frameType == WS_INCOMPLETE_FRAME) {  
               ER readed = tcp_rcv_dat(cepid, buffer+readedLength, BUF_LEN-readedLength, 100);  
               if(readed == E_TMOUT){  
                    readed = sprintf((char *)txbuffer,  
                         "%d",freecounter);  
                    freecounter++;  
                    if(freecounter > 99) freecounter = 0;  
                    prepareBuffer;  
                    wsMakeFrame(txbuffer, readed, buffer, &frameSize, WS_TEXT_FRAME);  
                    if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                         break;  
                    initNewFrame;  
                    readed=0;  
               } else if (readed <= 0) {  
                    return;  
               }  
               if(readed){  
                    printk("(%3d)",readed);  
                    for(i=0;(i<16) && (i < readed);i++){  
                         printk(" %02x",buffer[i]);       
                    }  
                    printk("\n");  
               }  
               readedLength+= readed;  
               if (state == WS_STATE_OPENING) {  
                    frameType = wsParseHandshake(buffer, readedLength, &hs);  
               } else {  
                    dataSize=0;  
                    frameType = wsParseInputFrame(buffer, readedLength, &data, &dataSize);  
                    if(dataSize){  
                         printk("[%3d]",dataSize);  
                         for(i=0;(i<16) && (i < dataSize);i++){  
                              printk(" %02x",data[i]);       
                         }  
                         printk("\n");  
                    }  
               }  
               if ((frameType == WS_INCOMPLETE_FRAME && readedLength == BUF_LEN) || frameType == WS_ERROR_FRAME) {  
                    if (frameType == WS_INCOMPLETE_FRAME)  
                         printk("buffer too small\n");  
                    else  
                         printk("error in incoming frame\n");  
                    if (state == WS_STATE_OPENING) {  
                         prepareBuffer;  
                         frameSize = sprintf((char *)buffer,  
                              "HTTP/1.1 400 Bad Request\r\n"  
                              "%s%s\r\n\r\n",  
                              versionField,  
                              version);  
                         safeSend(cepid, buffer, frameSize);  
                         break;  
                    } else {  
                         prepareBuffer;  
                         wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);  
                         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                              break;  
                         state = WS_STATE_CLOSING;  
                         initNewFrame;  
                    }  
               }  
               if (state == WS_STATE_OPENING) {  
                    //assert(frameType == WS_OPENING_FRAME);  
                    if (frameType == WS_OPENING_FRAME) {  
                         // if resource is right, generate answer handshake and send it  
                         if (strcmp(hs.resource, "/echo") != 0) {  
                              frameSize = sprintf((char *)buffer, "HTTP/1.1 404 Not Found\r\n\r\n");  
                              if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                                   break;  
                         }  
                         prepareBuffer;  
                         wsGetHandshakeAnswer(&hs, buffer, &frameSize);  
                         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                              break;  
                         state = WS_STATE_NORMAL;  
                         initNewFrame;  
                    }  
               } else {  
                    if (frameType == WS_CLOSING_FRAME) {  
                         if (state == WS_STATE_CLOSING) {  
                              break;  
                         } else {  
                              prepareBuffer;  
                              wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);  
                              safeSend(cepid, buffer, frameSize);  
                              return;  
                         }  
                    } else if (frameType == WS_TEXT_FRAME) {  
                         uint8_t *recievedString = NULL;  
                         recievedString = malloc(dataSize+1);  
                         //assert(recievedString);  
                         memcpy(recievedString, data, dataSize);  
                         recievedString[ dataSize ] = 0;  
                         prepareBuffer;  
                         wsMakeFrame(recievedString, dataSize, buffer, &frameSize, WS_TEXT_FRAME);  
                         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                              break;  
                         initNewFrame;  
                    } else if (frameType == WS_BINARY_FRAME) {  
                         uint8_t *recievedString = NULL;  
                         recievedString = malloc(dataSize+1);  
                         //assert(recievedString);  
                         memcpy(recievedString, data, dataSize);  
                         recievedString[ dataSize ] = 0;  
                         prepareBuffer;  
                         wsMakeFrame(recievedString, dataSize, buffer, &frameSize, WS_BINARY_FRAME);  
                         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
                              break;  
                         initNewFrame;  
                    }  
               }  
          } // read/write cycle  
     }  
     void websocket_srv(ID id)  
     {  
          ID cepid, repid;  
          ER ercd;  
          T_IPV4EP dst_addr;  
          /* setting of reception point and communucation end point */  
          cepid = id;  
          repid = id;  
          /* TCP wait connection */  
          printk("wait tcp_acp_cep\n");  
          ercd = tcp_acp_cep(cepid, repid, &dst_addr, TMO_FEVR);  
          printk("connect\n");  
          if (ercd == E_OK)  
          {  
               clientWorker(cepid);  
          }  
          /* shutdown */  
          tcp_sht_cep(cepid);  
          tcp_cls_cep(cepid, 100);  
          printk("shutdown\n");  
          return;  
     }