前提・実現したいこと
初質問です。
組み込みLinuxでi2cドライバ開発中です。
マルチスレッドアプリで使うドライバのためmutexを使用してます。
mutex本体はi2cバスごとにlock/unlock出来るように配列になっているのですが
配列のアクセスに引数のchを使用した時、実体がないと怒られました。
例
if(pthread_mutex_lock(&dev_mutex[ch]) == 0){
pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock
なお、dev_mutexは別ファイルにグローバル宣言しており、
本ファイル(掲載コードのファイル)の先頭でexternして使用しています。
main.c(仮称)
// Global pthread_mutex_t dev_mutex[3];
i2c_common.c(掲載コードのファイル)
extern pthread_mutex_t dev_mutex[3]; // デバイスアクセス用mutex 0~2 I2Cバス
コード
質問1
添字を定数に変えたらエラーは消えるのですが、納得いかないです。
この時点でなぜ実体が存在しないのでしょうか?
質問2
引数のchを添字として使うスマートな方法はありませんでしょうか?
よろしくお願いします。
発生している問題・エラーメッセージ
i2c_common.c:113: `dev_mutex' に対する定義されていない参照です (同様に参照している箇所にも同じエラーが出ます)
該当のソースコード
C
1 2extern pthread_mutex_t dev_mutex[3]; // デバイスアクセス用mutex 0~2 I2Cバス 3 4/**************************************************************** 5* 関数名:i2c_write 6* 引数 :ch I2CバスNo(0~2) 7* slave_addr スレーブアドレス 8* reg レジスタアドレス 9* data データ 10* len 送信byteレングス(1 or 2) 11* 戻値 :正常 0 異常 -1 12* 説明 :スレーブデバイスに対し、I2Cライトを行う 13* データフォーマット:Start, slave_addr(w), reg, data, Stop 14****************************************************************/ 15int i2c_write(uint8_t ch, uint8_t slave_addr, uint8_t reg, uint8_t *wdata, uint8_t len) 16{ 17 int ret; 18 if(ch > 2){ 19 printf("Invalid ch : %u \r\n", ch); 20 return -1; 21 } 22 /* device mutex Ch bus*/ 23 if(pthread_mutex_lock(&dev_mutex[ch]) == 0){ 24 /* I2C open */ 25 int i2c_fd = i2c_open(ch); 26 if(i2c_fd < 0){ 27 printf("I2C write open error. ch=%u addr=0x%02x reg=0x%02x \r\n", ch, slave_addr, reg); 28 sysinfo.err.bit.state_err = true; 29 pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock 30 return -1; 31 }else{} 32 ret = ioctl(i2c_fd, I2C_SLAVE, slave_addr); 33 if(ret<0){ 34 printf("I2C write ioctl error. ch=%u addr=0x%02x reg=0x%02x \r\n", ch, slave_addr, reg); 35 close(i2c_fd); 36 syslog(LOG_ERR, "%s: Can not ioctl addr 0x%02x: %s", __func__, slave_addr, strerror(errno)); 37 sysinfo.err.bit.state_err = true; 38 pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock 39 return -1; 40 }else{} 41 if(len > I2C_BYTE_MAX){ 42 printf("I2C write size over\r\n"); 43 close(i2c_fd); 44 syslog(LOG_ERR, "%s: I2C write size over : %u", __func__, len); 45 sysinfo.err.bit.state_err = true; 46 pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock 47 return -1; 48 }else{} 49 uint8_t buf[I2C_BYTE_MAX+1] = {0}; //4byte + 1byte(アドレス分) 50 buf[0] = reg; // アドレス設定 51 for(uint8_t i=1, j=0; i<(len+1); i++,j++){ 52 buf[i] = wdata[j]; // データ設定 53 } 54 /* write */ 55 ret = write(i2c_fd, buf, len+1); //アドレス分レングス++ 56 if(ret<0){ 57 printf("I2C write write error. ch=%u addr=0x%02x reg=0x%02x \r\n", ch, slave_addr, reg); 58 close(i2c_fd); 59 sysinfo.err.bit.state_err = true; 60 pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock 61 return -1; 62 }else{} 63 /* I2C close */ 64 close(i2c_fd); 65 pthread_mutex_unlock(&dev_mutex[ch]); // mutex unlock 66 }else{ 67 printf("%s():device mutex error. I2C Ch%d\r\n", __func__, ch); 68 syslog(LOG_ERR, "%s: device mutex error I2C Ch%d", __func__, ch); 69 return -1; 70 } 71 return 0; 72}
試したこと
dev_mutex[0]の様に定数に変更した場合エラーメッセージが消えました。
2018/10/15 追記
回答ありがとうございました。
大変参考になりました。
具体的な原因は分かりませんでしたが、yumetodoさんの解答に有ったようにgetter関数を用意して回避しようと思います。
(回避策を提案頂いたのでベストアンサーとさせていただきます。)
本日をもって回答を締め切らせていただきます。
回答4件
あなたの回答
tips
プレビュー