Создание настройки структуры драйвера устройства I2C - PullRequest
1 голос
/ 18 ноября 2011

Я пишу драйвер устройства, который использует I2C для связи с хостом.

Ниже приведен код, который я хотел выучить и понять.Помогите мне, если мое понимание неверно в отношении кода ниже.«//» - это мои собственные комментарии и мое понимание кода.

// declare there will be a member struct inside the class example_state. This member is pointing to i2c_client.
struct example_state {
struct i2c_client *client; 
};

static int example_probe(struct i2c_client *client, const struct i2c_device_id *id{

// declare this to be a local struct inside the example_probe
struct example_state *state;

// get "struct device" to be pointed client's member name dev
// Question: is "struct device *dev" part of "struct i2c_client"?
// if "struct device *dev" imported from somewhere that why there is no need to allocate memory?
struct device *dev = &client->dev;

// allocate a memory space for "struct example_state"
// at this point "struct example_state" is still empty/NULL
// **Question:** but what is the relationship of this local "struct example_state"
// with the one declared before entering struct example_state function?
state = kzalloc(sizeof(struct example_state), GFP_KERNEL); 
if (state == NULL) {
    dev_err(dev, "failed to create our state\n");
    return -ENOMEM;
}

    // after memory allocated set the "struct i2c_client" point to "struct example_state"'s member namely "client".
state->client = client; 

   // set the our device I2C driver information to the host.
   // Question: Where to we set our device driver data?
i2c_set_clientdata(client, state); 

/* rest of the initialisation goes here. */

dev_info(dev, "example client created\n");

return 0;
}

static int __devexit example_remove(struct i2c_client *client){
  // get the loaded value from host, i guess is like unregister
  // my device driver information from the host when i exited.
struct example_state *state = i2c_get_clientdata(client);

kfree(state);
return 0;
}

static struct i2c_device_id example_idtable[] = {
{ "example", 0 },
{ }
};

1 Ответ

2 голосов
/ 18 ноября 2011

Я собираюсь предположить, что вместо изучения поддержки i2c в ядре Linux вам следует еще раз взглянуть на K & R 2 вместо этого:

// declare there will be a member struct inside the class example_state. This member is pointing to i2c_client.
struct example_state {
struct i2c_client *client; 
};

C неесть занятия.sysfs абстракция ядра Linux представила ядру собственную идею о том, что такое "класс" - см. drivers/base/class.c - но он вообще не имеет отношения к классам в C ++, Java, C # или любом другом языке, который вы используете.

static int example_probe(struct i2c_client *client, const struct i2c_device_id *id{

// declare this to be a local struct inside the example_probe
struct example_state *state;

Это объявляет state как указатель на struct example_state часть памяти.(Я бы обычно использовал здесь слово object , но я не хочу противодействовать речи «C не имеет классов» из предыдущего абзаца. Это кусок памяти, который так же велик, как илибольше, чем необходимо для хранения всех членов struct example_state, и компилятор знает, как проверять операции на согласованность типов. Может быть, я должен был просто сказать «объект» ...)

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

// get "struct device" to be pointed client's member name dev
// Question: is "struct device *dev" part of "struct i2c_client"?
// if "struct device *dev" imported from somewhere that why there is no need to allocate memory?
struct device *dev = &client->dev;

struct device *dev в этой строке выделяет достаточно памяти для указатель и сообщает компилятору, что указатель будет указывать только на struct device объекты.=&client->dev просматривает параметр client, чтобы найти элемент dev, и создает псевдоним для более удобного использования в этой подпрограмме.

// allocate a memory space for "struct example_state"
// at this point "struct example_state" is still empty/NULL
// **Question:** but what is the relationship of this local "struct example_state"
// with the one declared before entering struct example_state function?
state = kzalloc(sizeof(struct example_state), GFP_KERNEL); 
if (state == NULL) {
    dev_err(dev, "failed to create our state\n");
    return -ENOMEM;
}

struct example_state { .. } из ранеебыло объявление типа.Он только проинструктировал компилятор об именах, размерах и типах членов, хранящихся в структурах с тегом struct example_state.Он не выделяет никакой памяти.Вызов kzalloc() здесь выделяет память, размер наших struct example_state объектов и запрашивает использование обычного пула выделения памяти GFP_KERNEL.См. include/linux/gfp.h для получения подробной информации о различных «пулах» доступной памяти.В зависимости от флагов, переданных распределителю памяти ядра, выделение памяти может произойти только через после , когда ядро ​​было вынуждено выполнить «сборку мусора» - запись буферов грязной памяти обратно на диск, сброс страницыкэши, подкачка процессов, возможно, даже вызов убийцы памяти OOM для выделения памяти.Пул GFP_ATOMIC используется, когда ядро ​​абсолютно не должно спать в этот момент - отлично подходит для использования, когда удерживаются спин-блокировки или в контексте прерываний.

Хотя возможно изучение C и внутренних компонентов ядра одновременно, оноэто очень неумолимая среда, чтобы делать ошибки.После случайного указателя в обычной программе в пользовательском пространстве происходит сбой процесса, но после случайного указателя в ядре происходит паника компьютера или повреждение памяти, файловых систем и т. Д.

...