質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

2971閲覧

Linuxでデバイスドライバーが管理しているI2Cデバイスにアクセスしたい

ysh_ktd

総合スコア11

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2019/06/26 00:57

(概要)
Linuxのシステムを開発しています。時計ICとして、I2C接続のRTCを使用しています。このRTCのレジスタ設定で異常が発生することが分かりました。
異常が発生しているかは、I2Cレジスタで確認できます。

(問題点)
通常はデバイスドライバー経由なので、該当するI2Cアドレスはシステムが管理しています。
そのため、ユーザーアプリでI2cアクセスでレジスタを読もうとするとエラーになってしまいます。

(質問内容)
システム(デバイスドライバー)が管理しているデバイスにユーザーがアクセスする方法をお教えください。
具体的には、RTCはデバイスドライバーの管理下にあり、通常はアクセスできないのですが、これをアクセスすには、どうしたら良いでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

結論として、読込方/書込方を変えることによりアクセスが可能になりました。

最初、WEB検索で良く見つかる、以下のコードを使用していました。
static int Ioctl(int fd, int request, void * arg)
{
int ret;
ret = ioctl(fd, request, arg);
if ( ret == -1 ) printf("ioctl");
return ret;
}
static void read_rtc(int fd , struct rtc_time * rtc_tm)
{
/* 現在の RTC 時刻を読み出して rtc_tm にセットする。 */
Ioctl( fd, RTC_RD_TIME, rtc_tm );

/* 現在の RTC 時刻を表示する。 */ printf("RTC Now time: %d / %d / %d - %02d : %02d : %02d \n", rtc_tm->tm_year + 1900, rtc_tm->tm_mon + 1, rtc_tm->tm_mday, rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec );

}
void write_rtc(int year,int month,int day,int hour,int min,int sec)
{
struct rtc_time rtc_tm;
int m_fd;
rtc_tm.tm_year = year - 1900;
rtc_tm.tm_mon = month - 1;
rtc_tm.tm_mday = day;
rtc_tm.tm_hour = hour;
rtc_tm.tm_min = min;
rtc_tm.tm_sec = sec;

m_fd = open( RTC_DEVICE_FILE , O_RDWR ); /* device file open */ if (m_fd < 0){ printf("rtc open error !\n"); return; } if (ioctl(m_fd, RTC_SET_TIME, &rtc_tm) < 0) printf("rtc set error !\n"); close(m_fd);

}

上記を、以下の様に変更すると、アクセス可能でした。
なぜ、アクセス可能になるかは、良く分かりませんでした。
ioctrl()の使い方なのかもしれません。

int readI2cReg(int regNo, unsigned char *pValue) {
struct {
unsigned char number;
unsigned char value;
} reg;
int fd, retval;
if ((fd = open("/dev/rtc1", O_RDWR)) < 0) {return -1;}
reg.number = regNo;
retval = ioctl(fd, _IOWR('p', 0x20, reg), &reg);
close(fd);
if (retval == -1) {return -1;}
*pValue = reg.value;
return 0;
}

int writeI2cReg(int regNo, unsigned char value) {
struct {
unsigned char number;
unsigned char value;
} reg;
int fd, retval;
if ((fd = open("/dev/rtc1", O_RDWR)) < 0) {return -1;}
reg.number = regNo;
reg.value = value;
retval = ioctl(fd, _IOW('p', 0x21, reg), &reg);
close(fd);
if (retval == -1) {return -1;}
return 0;
}

投稿2019/06/28 02:33

ysh_ktd

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ysh_ktd

2019/06/28 02:37

もともとは、某社のRTCのデバイスドライバーのバグ解析に必要でした。 ドライバー経由で10月の日付を設定し、そのまま歩進させると、12月以降、月が狂うというものです。ご注意を!
guest

0

まともな方法としては、そのデバイスを駆動するデバイスドライバを新たに書いて、その既存のドライバから置き換えるという方法になります

投稿2019/06/26 01:41

y_waiwai

総合スコア88171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問