Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
Arduinoソフトウェアの内部構造

はじめに

Arduinoソフトウェアが提供する関数の実装・内部構造を解析していきます。Arduino UnoとArduino Dueが対象です。

Arduino 1.8.3/Arduino 1.5をベースにしています。Arduino Uno向けにはarduino-1.8.3-windows.zip、Arduino Due向けにはarduino-1.5-windows.zipに入っているソースコードベースで極力最後まで追っていくことを目標としています。解説ではなく、解析なので注意してください。

Arduinoのリファレンスの翻訳はこちらです。

#if で区切られているところは、Arduino Uno/Due用のコードを見ていきます。このため、Arduino MegaやArduino Leonardoの場合は異なる実装になっている可能性があります。また、Due用のコードで、Atmel社が提供している部分については、__cplusplusが定義されているかどうかがよくわかっていません。このドキュメントでは、定義されていることを前提としています。ご存知の方がいらっしゃれば、ぜひ教えてください。

AVRボード(Arduino 1.8.3)

Arduinoソフトウェア本体

hardware/arduino/avr/cores/arduino/wiring_digital.c
pinMode() 指定したピンを、入力に利用するのか出力に利用するのかを設定する。
digitalRead() 指定したピンがHIGHなのかLOWなのかを返します。
digitalWrite() 指定したピンにHIGHもしくはLOWを出力します。
turnOffPWM() 指定したタイマのPWM出力を停止します。
hardware/arduino/avr/cores/arduino/wiring_analog.c
analogReference() アナログ入力を行う際の参照電圧を設定します。
analogRead() アナログ‐デジタル(AD)変換器を使って、アナログピンから値を読み取ります。
analogWrite() 指定したピンにPWM出力を行います。
hardware/arduino/avr/cores/arduino/Tone.cpp
tone() 指定した周波数の方形波(矩形波)をデューティー比50%で、指定したピンに生成します。
toneBegin() tone()関数で利用するタイマとピンの関連づけを管理します。
noTone() tone()関数で開始したピンへの方形波の出力を停止します。
disableTimer() tone()で設定したタイマ/カウンタを初期化します。
TIMER2_COMPA_vect タイマ/カウンタ(TCNT2)と比較レジスタ(OCR2A)が同じ値になったときに起動される割り込みハンドラです。
hardware/arduino/avr/cores/arduino/wiring.c
init() ATmega328Pのタイマ/カウンタとAD変換器、シリアル通信の初期化を行います。
millis() 内部で保持しているArduinoを起動してからの時間をミリ秒単位で返します。
micros() 内部で保持しているArduinoを起動してからの時間をマイクロ秒秒単位で返します。
TIMER0_OVF_vect タイマ/カウンタ0(TCNT0)がオーバーフローしたときに起動される割り込みハンドラです。
delay() 指定した値(ミリ秒単位)だけ待ちます。
delayMicroseconds() 指定した値(マイクロ秒単位)だけ待ちます。
hardware/arduino/avr/cores/arduino/WInterrupts.c
attachInterrupt() 外部割り込みが発生したときに呼び出す関数を設定します。
detachInterrupt() 外部割り込みが発生したときに呼び出す関数を解除します。
hardware/arduino/avr/cores/arduino/wiring_shift.c
shiftIn() 1ビットずつ送られてくるデータを取りこみ、1バイトのデータを作成します。
shiftOut() 1バイトのデータを1ビットずつ送信します。
hardware/arduino/avr/cores/arduino/wiring_pulse.c
pulseIn() ピンに入力されるパルスの時間を計測します。
hardware/arduino/avr/cores/arduino/wiring_pulse.S
countPulseASM() ピンに入力されるパルスの時間を計測します。
hardware/arduino/avr/cores/arduino/hooks.c
yield() yield()は、他のタスクに制御を移すために自らCPUを放棄するための関数です。
hardware/arduino/avr/cores/arduino/HardwareSerial0.cpp
Serial Serialオブジェクトの定義です。
USART_RX_vect シリアル通信でデータを受信したときに起動される割り込みハンドラです。
USART_UDRE_vect シリアル通信でデータを送信するための割り込みハンドラです。
hardware/arduino/avr/cores/arduino/HardwareSerial.cpp
レジスタ HardwareSerialで操作するレジスタ群です。
Serial.begin()/HardwareSerial::begin() シリアル通信を行う際の通信速度の設定や送受信の許可ビットの設定を行います。
Serial.end()/HardwareSerial::end() シリアル通信を終了し、RXピンとTXピンを通常の入出力を行うように設定します。
Serial.read()/HardwareSerial::read() シリアル通信の受信バッファから文字を読み出します。
Serial.peek()/HardwareSerial::peek() シリアル通信の受信バッファを変更せずに受信用バッファから文字を読み出します。
Serial.available()/HardwareSerial::available() シリアル通信の受信バッファ内の有効な文字数を返します。
Serial.flush()/HardwareSerial::flush() シリアル通信の送信バッファにあるデータをすべて送信します。
Serial.write()/HardwareSerial::write() バイナリデータをシリアルポートに書き込みます。
Serial.availableForWrite()/HardwareSerial::availableForWrite() シリアル通信の送信バッファ内に書き込み可能な文字数を返します。
HardwareSerial::_tx_udr_empty_irq() Arduinoのシリアル通信送信バッファからAtmeta328Pのデータ送信レジスタにデータをコピーします。
hardware/arduino/avr/cores/arduino/HardwareSerial_private.cpp
HardwareSerial::HardwareSerial() HardwareSerialのコンストラクタです。
_rx_complete_irq() シリアル通信で受信した文字を受信バッファに格納します。
hardware/arduino/avr/cores/arduino/HardwareSerial.h
HardwareSerial HardwareSerialのクラス定義です。
if(Serial)/HardwareSerial::operator bool() シリアルポートが利用可能かどうかを確認します。
hardware/arduino/avr/cores/arduino/wiring_private.h
sbi() 第1引数で指定したアドレスの内容の第2引数ビットを1に設定するマクロです。
cbi() 第1引数の第2引数ビットを0に設定するマクロです。
hardware/arduino/avr/cores/arduino/Arduino.h
digaitalPinToBitMask() 指定したピンが対応するピンのビットマスクを返すマクロです。
digitalPinToPort() 指定したピンに対応するポートを返すマクロです。
digitalPinToTimer() 指定したピンに対応するタイマを返すマクロです。
portModeRegister() 指定したポートのモードを制御するするレジスタを返すマクロです。
portOutputRegister() 指定したポートに対応するレジスタを返すマクロです。
portInputRegister() 指定したポートに対応するレジスタを返すマクロです。
bitRead() 変数の特定のビットを読み取ります。
bitSet() 変数の特定のビットを1にします。
bitClear() 変数の特定のビットを0にします。
bitWrite() 変数の特定のビットに値を書き込みます。
clockCyclesPerMicrosecond() 1マイクロ秒あたりのクロック数です。
clockCyclesToMicroseconds() 指定したクロック数をマイクロ秒に変換します。
microsecondsToClockCycles() 指定したマイクロ秒をクロック数に変換します。
interrupts() 割り込みを許可します。
noInterrupts() 割り込みを禁止します。

AVR-GCC関連

hardware/tools/avr/avr/include/avr/pgmspace.h
pgm_read_byte() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
pgm_read_byte_near() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
__LPM() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
__LPM_enhanced__() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのアセンブラコードです。
pgm_read_word() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
pgm_read_word_near() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
__LPM__word() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
__LPM_word_enhanced__() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのアセンブラコードです。
hardware/tools/avr/avr/include/avr/common.h
SREG ATmega328Pの状態レジスタです。
hardware/tools/avr/avr/include/avr/sfr_defs.h
_BV() 指定したビット数だけ1を左シフトするマクロです。
_SFR_ADDR() 指定した引数のアドレスを返すマクロです。
_SFR_MEM_ADDR() 指定した引数のアドレスを返すマクロです。
_SFR_BYTE() 指定したアドレスの内容(1バイト)を返却するマクロです。
_SFR_WORD() 指定したアドレスの内容(2バイト)を返却するマクロです。
_SFR_IO8() I/Oアドレスをメモリアドレスに変換します。指定したアドレスにオフセット(__SFR_OFFSET)を足して返却するマクロです。
_SFR_MEM8() 指定したアドレスの内容(1バイト)を返すマクロです。
_SFR_MEM16() 指定したアドレスの内容(2バイト)を返すマクロです。
_MMIO_BYTE() 指定したアドレスの内容(1バイト)を返すマクロです。
_MMIO_WORD() 指定したアドレスの内容(2バイト)を返すマクロです。
bit_is_set() 第1引数の第2引数ビット目が1かどうかを調べるマクロです。
bit_is_clear() 第1引数の第2引数ビット目が0かどうかを調べるマクロです。
_VECTOR() 割り込みベクタ番号を実際のアドレスに変換するマクロです。
hardware/tools/avr/avr/include/avr/iom328p.h
DDRx デジタルピンが入力か出力かを示すレジスタです。
PORTxn デジタルピンの入出力を行うためのレジスタです。
ADMUX 参照電圧の設定と出力値の形式(ビットを左詰めにするか右詰めにするか)、チャネル(アナログピン)の選択を制御するレジスタです。
ADCSRA AD変換器の制御を行うためのレジスタです。
ADCL/ADCH AD変換の結果を格納するレジスタです。
TCCRnx タイマカウンタを制御するレジスタです。
OCRnx PWMのデューティ比を制御するレジスタです。
TIMSKn タイマの割り込みに関するレジスタです。
割り込みベクタ 割り込みベクタの定義です。
TCNTn タイマクロックごとに1インクリメントされるレジスタです。
TIFRn タイマ割り込みを制御するレジスタです。
EICRA 外部割り込みを制御するレジスタです。
EIMSK 外部割り込みを制御するレジスタです。
USART0 シリアル通信を制御するレジスタです。
hardware/tools/avr/avr/include/avr/interrupt.h
cli() 割り込みを禁止するアセンブラ命令を実行するマクロです。
sei() 割り込みを許可するアセンブラ命令を実行するマクロです。
ISR() I割り込みベクタに登録する関数を定義するためのマクロです。

AVRボード(Arduino 1.0.5)

Arduinoソフトウェア本体(AVR)

hardware/arduino/avr/cores/arduino/wiring_digital.c
pinMode() 指定したピンを、入力に利用するのか出力に利用するのかを設定する。
digitalRead() 指定したピンがHIGHなのかLOWなのかを返します。
digitalWrite() 指定したピンにHIGHもしくはLOWを出力します。
turnOffPWM() 指定したタイマのPWM出力を停止します。
hardware/arduino/avr/cores/arduino/wiring_analog.c
analogReference() アナログ入力を行う際の参照電圧を設定します。
analogRead() アナログ‐デジタル(AD)変換器を使って、アナログピンから値を読み取ります。
analogWrite() 指定したピンにPWM出力を行います。
hardware/arduino/avr/cores/arduino/Tone.cpp
tone() 指定した周波数の方形波(矩形波)をデューティー比50%で、指定したピンに生成します。
toneBegin() tone()関数で利用するタイマとピンの関連づけを管理します。
noTone() tone()関数で開始したピンへの方形波の出力を停止します。
disableTimer() tone()で設定したタイマ/カウンタを初期化します。
TIMER2_COMPA_vect タイマ/カウンタ(TCNT2)と比較レジスタ(OCR2A)が同じ値になったときに起動される割り込みハンドラです。
hardware/arduino/avr/cores/arduino/wiring.c
init() ATmega328Pのタイマ/カウンタとAD変換器、シリアル通信の初期化を行います。
millis() 内部で保持しているArduinoを起動してからの時間をミリ秒単位で返します。
micros() 内部で保持しているArduinoを起動してからの時間をマイクロ秒秒単位で返します。
TIMER0_OVF_vect タイマ/カウンタ0(TCNT0)がオーバーフローしたときに起動される割り込みハンドラです。
delay() 指定した値(ミリ秒単位)だけ待ちます。
delayMicroseconds() 指定した値(マイクロ秒単位)だけ待ちます。
hardware/arduino/avr/cores/arduino/WInterrupts.c
attachInterrupt() 外部割り込みが発生したときに呼び出す関数を設定します。
detachInterrupt() 外部割り込みが発生したときに呼び出す関数を解除します。
hardware/arduino/avr/cores/arduino/wiring_shift.c
shiftIn() 1ビットずつ送られてくるデータを取りこみ、1バイトのデータを作成します。
shiftOut() 1バイトのデータを1ビットずつ送信します。
hardware/arduino/avr/cores/arduino/wiring_pulse.c
pulseIn() ピンに入力されるパルスの時間を計測します。
hardware/arduino/avr/cores/arduino/HardwareSerial.cpp
レジスタ HardwareSerialで操作するレジスタ群です。
HardwareSerial::HardwareSerial HardwareSerialのコンストラクタです。
Serial.begin()/HardwareSerial::begin() シリアル通信を行う際の通信速度の設定や送受信の許可ビットの設定を行います。
Serial.end()/HardwareSerial::end() シリアル通信を終了し、RXピンとTXピンを通常の入出力を行うように設定します。
Serial.read()/HardwareSerial::read() シリアル通信の受信用バッファから文字を読み出します。
Serial.peek()/HardwareSerial::peek() シリアル通信の受信用バッファを変更せずに受信用バッファから文字を読み出します。
Serial.available()/HardwareSerial::available() シリアル通信の受信バッファ内の有効な文字数を返します。
Serial.flush()/HardwareSerial::flush() シリアル通信の送信バッファが空になるのを待ちます。
Serial.write()/HardwareSerial::write() バイナリデータをシリアルポートに書き込みます。
if(Serial)/HardwareSerial::operator bool() シリアルポートが利用可能かどうかを確認します。
USART_RX_vect シリアル通信でデータを受信したときに起動される割り込みハンドラです。
USART_UDRE_vect シリアル通信でデータを送信するための割り込みハンドラです。
store_char シリアル通信で受信した文字をリングバッファに格納します。
hardware/arduino/avr/cores/arduino/HardwareSerial.h
HardwareSerial HardwareSerialのクラス定義です。
hardware/arduino/avr/cores/arduino/wiring_private.h
sbi() 第1引数で指定したアドレスの内容の第2引数ビットを1に設定するマクロです。
cbi() 第1引数の第2引数ビットを0に設定するマクロです。
hardware/arduino/avr/cores/arduino/Arduino.h
digaitalPinToBitMask() 指定したピンが対応するピンのビットマスクを返すマクロです。
digitalPinToPort() 指定したピンに対応するポートを返すマクロです。
digitalPinToTimer() 指定したピンに対応するタイマを返すマクロです。
portModeRegister() 指定したポートのモードを制御するするレジスタを返すマクロです。
portOutputRegister() 指定したポートに対応するレジスタを返すマクロです。
portInputRegister() 指定したポートに対応するレジスタを返すマクロです。
bitRead() 変数の特定のビットを読み取ります。
bitSet() 変数の特定のビットを1にします。
bitClear() 変数の特定のビットを0にします。
bitWrite() 変数の特定のビットに値を書き込みます。
clockCyclesPerMicrosecond() 1マイクロ秒あたりのクロック数です。
clockCyclesToMicroseconds() 指定したクロック数をマイクロ秒に変換します。
microsecondsToClockCycles() 指定したマイクロ秒をクロック数に変換します。
interrupts() 割り込みを許可します。
noInterrupts() 割り込みを禁止します。

AVR-GCC関連

hardware/tools/avr/avr/include/avr/pgmspace.h
pgm_read_byte() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
pgm_read_byte_near() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
__LPM() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのマクロです。
__LPM_enhanced__() 指定したアドレス(PROGMEM領域)に格納されているデータを1バイト読み取るためのアセンブラコードです。
pgm_read_word() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
pgm_read_word_near() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
__LPM__word() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのマクロです。
__LPM_word_enhanced__() 指定したアドレス(PROGMEM領域)に格納されているデータを2バイト読み取るためのアセンブラコードです。
hardware/tools/avr/avr/include/avr/common.h
SREG ATmega328Pの状態レジスタです。
hardware/tools/avr/avr/include/avr/sfr_defs.h
_BV() 指定したビット数だけ1を左シフトするマクロです。
_SFR_ADDR() 指定した引数のアドレスを返すマクロです。
_SFR_MEM_ADDR() 指定した引数のアドレスを返すマクロです。
_SFR_BYTE() 指定したアドレスの内容(1バイト)を返却するマクロです。
_SFR_WORD() 指定したアドレスの内容(2バイト)を返却するマクロです。
_SFR_IO8() I/Oアドレスをメモリアドレスに変換します。指定したアドレスにオフセット(__SFR_OFFSET)を足して返却するマクロです。
_SFR_MEM8() 指定したアドレスの内容(1バイト)を返すマクロです。
_SFR_MEM16() 指定したアドレスの内容(2バイト)を返すマクロです。
_MMIO_BYTE() 指定したアドレスの内容(1バイト)を返すマクロです。
_MMIO_WORD() 指定したアドレスの内容(2バイト)を返すマクロです。
bit_is_set() 第1引数の第2引数ビット目が1かどうかを調べるマクロです。
bit_is_clear() 第1引数の第2引数ビット目が0かどうかを調べるマクロです。
_VECTOR() 割り込みベクタ番号を実際のアドレスに変換するマクロです。
hardware/tools/avr/avr/include/avr/iom328p.h
DDRx デジタルピンが入力か出力かを示すレジスタです。
PORTxn デジタルピンの入出力を行うためのレジスタです。
ADMUX 参照電圧の設定と出力値の形式(ビットを左詰めにするか右詰めにするか)、チャネル(アナログピン)の選択を制御するレジスタです。
ADCSRA AD変換器の制御を行うためのレジスタです。
ADCL/ADCH AD変換の結果を格納するレジスタです。
TCCRnx タイマカウンタを制御するレジスタです。
OCRnx PWMのデューティ比を制御するレジスタです。
TIMSKn タイマの割り込みに関するレジスタです。
割り込みベクタ 割り込みベクタの定義です。
TCNTn タイマクロックごとに1インクリメントされるレジスタです。
TIFRn タイマ割り込みを制御するレジスタです。
EICRA 外部割り込みを制御するレジスタです。
EIMSK 外部割り込みを制御するレジスタです。
USART0 シリアル通信を制御するレジスタです。
hardware/tools/avr/avr/include/avr/interrupt.h
cli() 割り込みを禁止するアセンブラ命令を実行するマクロです。
sei() 割り込みを許可するアセンブラ命令を実行するマクロです。
ISR() I割り込みベクタに登録する関数を定義するためのマクロです。
SIGNAL() I割り込みベクタに登録する関数を定義するためのマクロです。

SAMボード(Arduino 1.5)

Arduinoソフトウェア本体(SAM)

hardware/arduino/sam/cores/arduino/wiring_digital.c
pinMode() 指定したピンを、入力に利用するのか出力に利用するのかを設定する。
digitalRead() 指定したピンがHIGHなのかLOWなのかを返します。
digitalWrite() 指定したピンにHIGHもしくはLOWを出力します。
hardware/arduino/sam/cores/arduino/wiring_analog.c
analogReference() アナログ入力を行う際の参照電圧を設定します。
analogRead() アナログ‐デジタル(AD)変換器を使って、アナログピンから値を読み取ります。
analogWrite() 指定したピンにPWM出力を行います。
analogReadResolution() analogRead()で返却する値の大きさ(ビット単位)を設定する。
analogWriteResolution() analogWrite()で設定する値の大きさ(ビット単位)を設定する。
mapResolution() AD変換の結果の分解能を変換します。
hardware/arduino/sam/cores/arduino/Arduino.h
PinDescription Arduino Dueの各ピンを定義するための型です。
EAnalogChannel アナログピンを区別するための列挙型です。
EPWMChannel PWMチャネルを区別するための列挙型です。
ETCChannel TC(Timer Counter)チャネルを区別するための列挙型です。

SAMシリーズ関連

hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/component/component_pio.h
Pio Atmel SAM3X8E ARM Cortex-M3プロセッサの並列入出力コントローラ(Parallel Input/Output Controller)のレジスタを定義する型です。
Pmc Atmel SAM3X8E ARM Cortex-M3プロセッサの電源管理コントローラ(Power Management Controller、PMC)のレジスタを定義する型です。
hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/component/sam3x8e.h
RoReg/WoReg/RwReg Atmel SAM3X8E ARM Cortex-M3プロセッサのレジスタを定義する型です。
ペリフェラルベースアドレス Atmel SAM3X8E ARM Cortex-M3プロセッサの各種ベースアドレスの定義です。
hardware/arduino/sam/system/libsam/include/pio.h
EPioType ピンに対応するタイプ(どのperipheralが対応しているかなど)を選択するための列挙型です。
hardware/arduino/sam/system/libsam/source/pmc.c
pmc_enable_periph_clk() 指定したピンに対応するペリフェラルクロックを有効にします。
pmc_disable_periph_clk() 指定したピンに対応するペリフェラルクロックを無効にします。
hardware/arduino/sam/system/libsam/source/pio.c
PIO_Configure() PIO(Parallel Input/Output Controller)の設定を行います。
PIO_SetPeripheral() PIO(Parallel Input/Output Controller)がペリフェラルによって制御されるように設定を行います。
PIO_DisableInterrupt() PIO(Parallel Input/Output Controller)の割り込みを禁止します。
PIO_PullUp() PIO(Parallel Input/Output Controller)の内蔵プルアップ抵抗を制御します。
PIO_SetInput() PIO(Parallel Input/Output Controller)コントローラを入力モードに設定しす。
PIO_SetOutput() PIO(Parallel Input/Output Controller)コントローラを出力モードに設定します。
PIO_GetOutputDataStatus() 指定したピンが出力モードに設定されているかどうかを調べます。
PIO_Get() 指定したピンにHIGHのものがあるときは1、そうでない場合は0を返します。
hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/component/component_adc.h
Adc Atmel SAM3X8E ARM Cortex-M3プロセッサのアナログ・デジタルコンバータ(Analog-to-Digital Converter、ADC)のレジスタを定義する型です。
hardware/arduino/sam/system/libsam/include/adc.h
adc_channel_num_t ADC(Analog-to-Digital Converter)チャネル番号を示す列挙型です。
hardware/arduino/sam/system/libsam/source/adc.c
adc_enable_channel() 指定したADC(Analog-to-Digital Converter)チャネルを有効にします。
adc_start() アナログ・デジタル変換を開始します。
adc_get_status() ADCの割り込み状態レジスタの値を返却します。
adc_get_latest_value() アナログ・デジタル変換の結果を返却します。
adc_disable_channel() 指定したADC(Analog-to-Digital Converter)チャネルを無効にします。

ライブラリ

libraries/SPI/SPI.cpp
SPI関連レジスタ SPI関連のレジスタです。
SPIClass::begin() SPI通信を行う際の、ピンモードの設定やレジスタの設定を行います。
SPIClass::end() SPI通信を終了します。
SPIClass::setBitOrder() データを送信する際のビットオーダを設定します。
SPIClass::setDataMode() クロック極性とクロックフェーズを設定します。
SPIClass::setClockDivider() クロックの分周比を設定します。
libraries/SPI/SPI.h
SPIClass::transfer() データを転送します。


メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2012 garretlab all rights reserved.
inserted by FC2 system