Armadilloフォーラム

デバイスドライバでのUART5制御について

sudohayato

2017年2月1日 20時56分

お世話になっております。須藤と申します。

基本的な質問になってしますかもしれませんがデバイスドライバでのUART5の制御について教えてください。
「i.MX25 Multimedia Applications Processor Reference Manual」でi.MX25のメモリマップを参照し、
UART5に対して読み書きするデバイスドライバを作成しております。
下記URLの書き込みを参考に、以下のような処理でUART5のメモリアクセスを試みています。

#define UART5_ADDRESS 0x5002C000
#define REMAP_SIZE 0x4000
void *cookie;
char data;

cookie = ioremap(UART5_ADDRESS, REMAP_SIZE);
data = ioread8(cookie);

上記ドライバを実行するとioread8の箇所で以下のエラーが発生してしまいます。

 Unhandled fault: external abort on non-linefetch (0x008) at 0xc49c0000
 Internal error: : 8

1.上記エラーの原因は何が考えられますでしょうか?

2.同様にioctlでUART5のRTS信号を切り替えることも想定しております。
  下記レジスタを操作すれば実現可能でしょうか?
  IOMUXC_UART5_IPP_UART_RTS_B_SELECT_INPUT

以上、よろしくお願い致します。

コメント

補足いたします。
使用しているのはArmadillo-420です。

> お世話になっております。須藤と申します。
>
> 基本的な質問になってしますかもしれませんがデバイスドライバでのUART5の制御について教えてください。
> 「i.MX25 Multimedia Applications Processor Reference Manual」でi.MX25のメモリマップを参照し、
> UART5に対して読み書きするデバイスドライバを作成しております。
> 下記URLの書き込みを参考に、以下のような処理でUART5のメモリアクセスを試みています。
>
>
> #define UART5_ADDRESS 0x5002C000
> #define REMAP_SIZE 0x4000
> void *cookie;
> char data;
>
> cookie = ioremap(UART5_ADDRESS, REMAP_SIZE);
> data = ioread8(cookie);
>
> 上記ドライバを実行するとioread8の箇所で以下のエラーが発生してしまいます。
>
>  Unhandled fault: external abort on non-linefetch (0x008) at 0xc49c0000
>  Internal error: : 8
>
>
> 1.上記エラーの原因は何が考えられますでしょうか?
>
> 2.同様にioctlでUART5のRTS信号を切り替えることも想定しております。
>   下記レジスタを操作すれば実現可能でしょうか?
>   IOMUXC_UART5_IPP_UART_RTS_B_SELECT_INPUT
>
>
> 以上、よろしくお願い致します。
>

調査状況について補足します。
何か気になった点などコメントいただけると幸いです。

imx.c を参考にして以下のように修正しました。

=== ここから ===

#define UART5_ADDRESS 0x5002C000
#define REMAP_SIZE 0x4000
#define URXD 0x0
void *cookie;
unsigned int data;

cookie = ioremap(UART5_ADDRESS, REMAP_SIZE);
data = ioread32(cookie+URXD);

=== ここまで ===

一度だけ正常に動作したように見えましたが、再起動後にまた以下のエラーが発生しました。

>  Unhandled fault: external abort on non-linefetch (0x008) at 0xc49c0000
>  Internal error: : 8

なお、オフセットをUCR1やUCR2にした場合にはR/Wできているため仮想空間へのマッピングは正常にできていると思われます。
URXDはリードオンリーなのでリードしかしておりません。
ioread32で32bit読み取りなので予約領域に踏み込んで読み込みしているとも思えないのですが、何が原因かわかりますでしょうか?

以上、よろしくお願いいたします。

at_takashi.sasayama

2017年2月10日 9時00分

笹山です。

> ioread32で32bit読み取りなので予約領域に踏み込んで読み込みしているとも思えないのですが、何が原因かわかりますでしょうか?

以下のコードの様に、URXD,UTXD にアクセスする前に UCR1とUCR2の各ビットをセットしてみていただけないでしょうか?

====================================
#define UART_UCR1 0x80
#define UART_UCR2 0x84

#define UCR1_UARTEN (0x1 << 0)
#define UCR2_RXEN (0x1 << 1)
#define UCR2_TXEN (0x1 << 2)

void __iomem *uart;
unsigned int temp;

uart = ioremap_nocache(UART5_ADDRESS, REMAP_SIZE);

temp = ioread32(uart + UART_UCR1);
iowrite32(temp | UCR1_UARTEN, uart + UART_UCR1);

temp = ioread32(uart + UART_UCR2);
iowrite32(temp | UCR2_RXEN | UCR2_TXEN, uart + UART_UCR2);

//以降にURXD,UTXDにアクセスする
====================================

笹山さん

お世話になっております。須藤です。

ご指摘ありがとうございます。

UARTEN、TXEN、RXENをenableにすることでURXD、UTXDにアクセスすることができました。

以上、よろしくお願いいたします。