More Related Content
PDF
PPTX
C#や.NET Frameworkがやっていること PPTX
大規模データ処理の定番OSS Hadoop / Spark 最新動向 - 2021秋 -(db tech showcase 2021 / ONLINE 発... PDF
PDF
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」 PDF
0章 Linuxカーネルを読む前に最低限知っておくべきこと PDF
PDF
What's hot
PDF
Intro to SVE 富岳のA64FXを触ってみた PDF
PDF
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発... PPTX
今こそ知りたいSpring Batch(Spring Fest 2020講演資料) PDF
PDF
Magnum IO GPUDirect Storage 最新情報 PPTX
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料) PDF
Apache Arrow - データ処理ツールの次世代プラットフォーム PDF
Profiling your Applications using the Linux Perf Tools PDF
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 PPTX
PPTX
ポスト・ラムダアーキテクチャの切り札? Apache Hudi(NTTデータ テクノロジーカンファレンス 2020 発表資料) PPTX
PDF
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで PDF
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料) PDF
PPTX
リアルタイムOSの必要性とTOPPERS/SSPの紹介 PDF
不揮発メモリ(NVDIMM)とLinuxの対応動向について PDF
PDF
Similar to ラズパイでデバイスドライバを作ってみた。
PDF
PDF
PDF
PPTX
PDF
PDF
2011.09.18 v7から始めるunix まとめ PDF
PDF
PDF
PDF
PDF
【学習メモ#3rd】12ステップで作る組込みOS自作入門 PDF
PDF
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係 PDF
2011.06.11 v7から始めるunix まとめ PDF
第3回ローレイヤー勉強会 : FPGAでコンピュータを作ってみた PPTX
あなたのAppleにもEFIモンスターはいませんか? by Pedro Vilaça - CODE BLUE 2015 PDF
PDF
retrobsd-2012-JUL-07 at JNUG BSD BoF PDF
PDF
ラズパイでデバイスドライバを作ってみた。
- 1.
- 2.
- 3.
- 4.
環境
PaspberryPi3ModelB
$ sudo cat/etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ sudo uname -a
Linux raspberrypi 4.9.41-v7+ #1023 SMP Tue Aug 8 16:00:15 BST 2
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
/proc/iomem からもメモリマップが確認できる。
$ sudocat /proc/iomem
00000000-3b3fffff : System RAM
00008000-00afffff : Kernel code
00c00000-00d3da63 : Kernel data
3f006000-3f006fff : dwc_otg
3f007000-3f007eff : /soc/dma@7e007000
3f00b840-3f00b84e : /soc/vchiq
3f00b880-3f00b8bf : /soc/mailbox@7e00b880
3f101000-3f102fff : /soc/cprman@7e101000
3f200000-3f2000b3 : /soc/gpio@7e200000
3f201000-3f201fff : /soc/serial@7e201000
3f201000-3f201fff : /soc/serial@7e201000
3f202000-3f2020ff : /soc/sdhost@7e202000
3f215000-3f215007 : /soc/aux@0x7e215000
3f300000-3f3000ff : /soc/mmc@7e300000
3f980000-3f98ffff : dwc_otg
- 11.
- 12.
Address Field
Name DescriptionSize Read/Write
0x7E200000 GPFSEL0 GPIOFunction
Select0 32 R/W
0x7E200004 GPFSEL1 GPIOFunction
Select1 32 R/W
0x7E200008 GPFSEL2 GPIOFunction
Select2 32 R/W
0x7E20000C GPFSEL3 GPIOFunction
Select3 32 R/W
0x7E200010 GPFSEL4 GPIOFunction
Select4 32 R/W
0x7E200014 GPFSEL5 GPIOFunction
Select5 32 R/W
- 13.
Address Field
Name DescriptionSize Read/Write
0x7E20001C GPSET0 GPIOPinOutput
Set0 32 W
0x7E200020 GPSET1 GPIOPinOutput
Set1 32 W
0x7E200024 ‑ Reserved ‑ ‑
0x7E200028 GPCLR0 GPIOPinOutput
Clear0 32 W
0x7E20002C GPCLR1 GPIOPinOutput
Clear1 32 W
0x7E200030 ‑ Reserved ‑ ‑
0x7E200034 GPLEV0 GPIOPinLevel0 32 R
0x7E200038 GPLEV1 GPIOPinLevel1 32 R
- 14.
- 15.
Bit(s) FieldName DescriptionType Reset
29‑27 FSEL9
FSEL9‑FunctionSelect9
000=GPIOPin9isaninput
001=GPIOPin9isanoutput
R/W 0
26‑24 FSEL8 FSEL8‑FunctionSelect8 R/W 0
23‑21 FSEL7 FSEL7‑FunctionSelect7 R/W 0
20‑18 FSEL6 FSEL6‑FunctionSelect6 R/W 0
17‑15 FSEL5 FSEL5‑FunctionSelect5 R/W 0
- 16.
Bit(s) FieldName DescriptionType Reset
14‑12 FSEL4 FSEL4‑FunctionSelect4 R/W 0
11‑9 FSEL3 FSEL3‑FunctionSelect3 R/W 0
8‑6 FSEL2 FSEL2‑FunctionSelect2 R/W 0
5‑3 FSEL1 FSEL1‑FunctionSelect1 R/W 0
2‑0 FSEL0 FSEL0‑FunctionSelect0 R/W 0
3bitずつが各ピンに対応しており、同じ要領で GPFSEL5 まで続き54ピ
ン全てに対応する。
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
システムコール対応の関数テーブル作成
struct file_operations my_file_ops= {
.owner = THIS_MODULE,
.open = my_open,
.release = my_close,
.read = my_read,
.write = my_write,
.unlocked_ioctl = my_ioctl, /* 64 bits */
.compat_ioctl = my_ioctl, /* 32 bits */
};
open 及び release で物理アドレスと仮想アドレスのマッピングを行
い、 ioctl で操作対象のピンの変更、そして実際の読み書きは read 及
び write で行う。
- 27.
file_operations は実装できるシステムコールに対応した処理を保持
する構造体で以下のように定義されている。
struct file_operations{
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t
ssize_t (*aio_read) (struct kiocb *, char __user *,
ssize_t (*write) (struct file *, const char __user *,
ssize_t (*aio_write) (struct kiocb *, const char __user
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_
int (*ioctl) (struct inode *, struct file *, unsigned
long (*unlocked_ioctl) (struct file *, unsigned int
long (*compat_ioctl) (struct file *, unsigned int,
int (*mmap) (struct file *, struct vm_area_struct *);
- 28.
int (*open) (structinode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datas
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *,
ssize_t (*writev) (struct file *, const struct iovec *,
ssize_t (*sendfile) (struct file *, loff_t *, size_t
ssize_t (*sendpage) (struct file *, struct page *,
unsigned long (*get_unmapped_area)(struct file *,
int (*check_flags)(int);
int (*dir_notify)(struct file *filp, unsigned long
int (*flock) (struct file *, int, struct file_lock *);
};
- 29.
- 30.
dev_t は以下のように定義されており unsignedint であることがわ
かる。そしてその変数から決められた上位12ビットをメジャー番号とし
ている。
typedef __u32 __kernel_dev_t;
typedef __kernel_dev_t dev_t;
// include/linux/kdev_t.h
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
static ssize_t my_read(structfile* file,
char __user* buff,
size_t count, loff_t *pos)
{
int num_reg = (pin_number / NUM_PIN_EACH_REG);
int offset = (pin_number % NUM_PIN_EACH_REG);
int addr = base_address + GPLEV0_OFFSET
+ (REG_GAP * num_reg);
unsigned int reg_value = MEMORY(addr);
int value = ((reg_value >> offset) & 1UL);
put_user(value + '0', &buff[0]);
return count;
}
- 44.