Переменная определена, но не используется сообщение в модуле ядра

В моем модуле ядра есть два очень коротких исходных файла C (основной файл и файлы daq.c и daq.h). Заголовочный файл содержит ряд переменных и функций. Когда я обычно компилирую функции, объявляя переменную в файле daq.h:

volatile uint32_t *gpio;

Я получаю следующую ошибку:

error In function `.LANCHOR1': daq.c:(.bss+0x50): multiple definition of `gpio'

Эта ошибка решается только путем объявления переменной статической, как показано ниже:

static volatile uint32_t *gpio;

Модуль ядра работает нормально, но в этом случае я получаю следующее предупреждение, поскольку статическое объявление создает отдельную копию для каждого файла, в который он включен:

warning: ‘gpio’ defined but not used [-Wunused-variable]: static volatile uint32_t *gpio;

Я пытался объявить его внешним или просто объявить переменную как uint32_t *gpio вместо того, чтобы объявлять ее статической, но затем я получаю:

WARNING: "gpio" undefined!

за которым следует сообщение «определение вне дерева» в журнале dmesg, когда модуль вставлен (и модуль не загружен).

Итак, как в этом случае лучше всего поступить, чтобы объявить переменную? Правильно ли объявить это как:

static volatile uint32_t *gpio;

и просто опустить предупреждение «определено, но не используется», выданное компилятором? Я не думаю, что просто «исключать» предупреждения — это хорошая практика, особенно когда речь идет о модулях ядра.

Заранее спасибо.


person drsambernardo    schedule 23.11.2019    source источник
comment
В заголовочном файле вам нужно объявить переменную, используя ключевое слово extern. Множественное определение... ошибки компоновщика Затем вы можете определить переменная в файле .c (без static).   -  person Tsyvarev    schedule 23.11.2019
comment
В заголовочном файле переменные должны быть extern. В .c файле их быть не должно.   -  person S.S. Anne    schedule 23.11.2019


Ответы (1)


Ваш вопрос не очень ясен, потому что отсутствует полный контекст; но в любом случае, я думаю, что некоторые советы могут быть даны.

Во-первых, ваши исходники будут использоваться вместе с другими файлами; эти файлы определяют вещи, о которых вы должны знать, иначе вылезут такие вещи, как multiple definition of 'gpio'. В этом случае (gpio) вы должны решить, хотите ли вы взаимодействовать с переменной gpio "other" - если нет, вы должны использовать другое имя (это не обязательно, но лучше).

Во-вторых, вы должны понимать, как работает компилятор C, особенно если вы взаимодействуете с ядром, которое добавляет некоторые механизмы. Как правило, вы не хотите определять переменные в файле заголовка (.h); вместо этого вы объявляете их вместе с типами данных, макросами и прототипами функций. В исходных файлах (.c) вы #include заголовки, чтобы использовать найденные в них объявления.

Переменные определяются в файлах .c и при необходимости становятся доступными для других модулей через заголовочные файлы. В противном случае сделайте их статическими и не упоминайте в шапке.

Разница между объявлением и определением заключается в следующем: объявление сообщает компилятору, что «вы где-нибудь встретите (возможно) это имя, которое имеет следующие свойства»; вместо этого определение означает «Я создаю это имя с этими свойствами, и эта вещь находится именно здесь».

Когда более чем одна часть программного обеспечения используется вместе, часто случается, что одна часть делает что-то необходимое в другой... Декларация - это способ, позволяющий этим частям работать вместе.

Надеюсь, это немного поможет.

person linuxfan says Reinstate Monica    schedule 23.11.2019
comment
Ваш ответ был очень полезен из-за его ясности! Я взял статические переменные из файла daq.h и поместил их (без статики) в файл daq.c, и все заработало отлично! Большое спасибо! - person drsambernardo; 26.11.2019