Wie initialisiere ich die Attributgruppe korrekt für einen Plattformtreiber?

EDIT # 4: Ich fand heraus, dass ich das nicht zuweisen sollteattr_groups zumgroups Feld in derdriver Bereich derstruct platform_driver Struktur. Suchen Sie nach dem Kommentar/* WRONGO: should not be assigned here. */ unten.

Ich habe nicht herausgefunden, wo ich binsollte werde es noch zuweisen ...

Mein Code für einen Plattformtreiber kann beim Lesen eines sysfs-Attributs aufgrund eines NULL-Verweises ein Kernel-OOPS verursachen. Ich bin mir sicher, dass es sich bei dem folgenden Code um ein einfaches Versehen handelt, aber ich kann es nicht sehen:

...

static int samples_per_frame = SAMPLE_CHANNEL_COUNT;

DEVICE_INT_ATTR(samples_per_frame, S_IRUGO | S_IWUSR, samples_per_frame);

static struct attribute *attrs[] = {
    &dev_attr_samples_per_frame.attr.attr, NULL,
};

static struct attribute_group attr_group = {
    .attrs = attrs,
};

static const struct attribute_group *attr_groups[] = {
    &attr_group, NULL,
};

static struct platform_driver platform = {
    .remove = my_remove,
    .probe = my_probe,
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .groups = attr_groups, /* WRONGO: should not be assigned here. */
        .of_match_table = of_match,
    },
};

...

Was, sauber kompiliert (Linux 3.12), und wenn das Modul geladen ist, die Installation und der Test reibungslos ablaufen, erscheint das Attribut im sysfs, aber wenn ich es zu lesen versuche, entsteht ein Kernel "oops".

/sys/bus/platform/drivers/my_driver# ls
ff250000.my_driver   samples_per_frame  uevent
/sys/bus/platform/drivers/my_driver#
/sys/bus/platform/drivers/my_driver# cat samples_per_frame
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = bf1e0000
[00000000] *pgd=3f1d8831, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] SMP ARM
Modules linked in: my_driver(O)
CPU: 1 PID: 194 Comm: cat Tainted: G           O 3.12.0 #6
task: bf054000 ti: bf194000 task.ti: bf194000
PC is at device_show_int+0x2c/0x38
LR is at drv_attr_show+0x2c/0x38
pc : [<80308f58>]    lr : [<8030b6fc>]    psr: a0000013
sp : bf195ee8  ip : 00000d58  fp : bf195ef4
r10: bf1d1380  r9 : 7e946c20  r8 : bf195f78
r7 : bf1d13d8  r6 : bf1d13c0  r5 : bfbc9e00  r4 : 8055d520
r3 : 00000000  r2 : 80620d58  r1 : 00001000  r0 : bf190000
Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: 3f1e004a  DAC: 00000015
Process cat (pid: 194, stack limit = 0xbf194248)
Stack: (0xbf195ee8 to 0xbf196000)
5ee0:                   bf195f04 bf195ef8 8030b6fc 80308f38 bf195f44 bf195f08
5f00: 80166118 8030b6dc 8076ed30 bf14b000 bfbd8d80 00001000 bfbd8d88 bfbd8d80
5f20: 00001000 7e946c20 bf195f78 00000000 bf194000 00001000 bf195f74 bf195f48
5f40: 8010722c 80166084 801061e4 801118c0 00000000 00000000 bfbd8d80 7e946c20
5f60: 00000000 00001000 bf195fa4 bf195f78 8010741c 80107190 00000000 00000000
5f80: 00001000 7e946c20 00000003 00000003 8000ec88 00000000 00000000 bf195fa8
5fa0: 8000ea40 801073dc 00001000 7e946c20 00000003 7e946c20 00001000 00000000
5fc0: 00001000 7e946c20 00000003 00000003 00000001 00000001 00000001 00000003
5fe0: 00000000 7e946bfc 0001079d 76f5e1cc 40000010 00000003 00000000 00000000
[<80308f58>] (device_show_int+0x2c/0x38) from [<8030b6fc>] (drv_attr_show+0x2c/0x38)
[<8030b6fc>] (drv_attr_show+0x2c/0x38) from [<80166118>] (sysfs_read_file+0xa0/0x144)
[<80166118>] (sysfs_read_file+0xa0/0x144) from [<8010722c>] (vfs_read+0xa8/0x148)
[<8010722c>] (vfs_read+0xa8/0x148) from [<8010741c>] (SyS_read+0x4c/0x80)
[<8010741c>] (SyS_read+0x4c/0x80) from [<8000ea40>] (ret_fast_syscall+0x0/0x30)
Code: e5913010 e1a0200c e3a01a01 e3482062 (e5933000)
---[ end trace 5cdf9dda0d86a7db ]---
Segmentation fault

Warum erhalte ich eine Nullreferenz?

EDIT # 1:

Wenn ich das ersetzeDEVICE_INT_ATTR() Makro mitDEVICE_ATTR() und meine eigenen zur Verfügung stellenshow() & store() funktioniert, es funktioniert gut.

EDIT # 2:

Es scheint dieDEVICE_INT_ATTR() Makro setzt dasvar Feld auf NULL. Hmmm....

EDIT # 3: Wenn ich das erstellestruct dev_ext_attribute Struktur mitDEVICE_INT_ATTR() Makro, ich kann die Variablen ausgeben. Das ist; Die Adressen der Struktur, die Funktionszeiger und die Adresse der Ganzzahl, die ich in sysfs verfügbar machen möchte, sind alle korrekt, wenn sie mit angezeigt werdenprintk() in meiner Sondenfunktion, aber als mein Zuhause sich drehteshow() Funktion schaut auf die Struktur, die Struture ist an einer anderen Adresse und dievar Feld ist NULL.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage