Você está na página 1de 17

28 -Requisitos da API do driver GIPIO e estrutura do identificador

***

104 - Criando o cabeçalho do driver GPIO e o arquivo de origem. ***


Vamos criar o driver .c. E arquivo .h do driver
Para que os drivers de expansão cliquem em src clique direito e novo.
Eu sugiro que você crie um arquivo fonte.

E aqui o nosso primeiro driver é stm32f407xx_gpio.c apenas dê um nome nome apropriado.


Este é o nosso arquivo de driver.
Eu posso até dar _driver.c

Depois disso, clique em Concluir. ! !!


Isso é um vazio.

1
E também vá para inc, clique com o botão direito do mouse em Novo arquivo de cabeçalho, Mesmo
nome que temos para dar, mas .h
f407xx_ gpio_driver.h
Este é o nosso arquivo de cabeçalho do driver e este é o nosso arquivo de origem do driver.
O arquivo de origem do driver deve sempre conter o arquivo de cabeçalho do driver.
É por isso que a primeira coisa que temos que fazer é incluir o arquivo de cabeçalho no respectivo
arquivo de cabeçalho que é stm32f407xx_gpio_driver.h.

O arquivo de cabeçalho do driver deve conter o arquivo de cabeçalho específico do MCU Vamos
incluir stm32f407xx.h
Tudo bem..por isso não temos 2 arquivos de cabeçalho, um é o arquivo de cabeçalho específico do
MCU, onde ele contém dados específicos do MCU e esse arquivo de cabeçalho contém dados
específicos do driver.

2
Então, vamos ver quais são os dados específicos desses drivers na próxima aula.
Então, complete até aqui e eu vou te ver na próxima palestra.

105 - Definindo o identificador e estrutura de configuração do GPIO ***

Bem-vindo de volta à palestra, agora nesta palestra vamos discutir os dados específicos do driver que
é a estrutura de configuração e manipulação do GPIO que será usada para trabalhar com o periférico
do GPIO. O driver que estavam desenvolvendo são as APIs do driver que estamos prestes a escrever
neste curso.

Então, em última análise, quem vai usar isso, que vai ser usado pelo aplicativo de usuário certo?
O aplicativo do usuário pode querer inicializar ou usar portas GPIO diferentes ou o aplicativo do
usuário pode alterar o PIN.
Pode mudar os modos de GPIO, velocidade, tipo de saída etc.
Como todas essas configurações de aplicativos do usuário são livres para fazer, não é?
E a aplicação do usuário leva a ajuda das APIs do driver que vamos desenvolver neste curso.
É por isso que a camada de driver deve fornecer uma estrutura de configuração para o aplicativo do
usuário. Portanto, o aplicativo de usuário inicializará ou preencherá essa estrutura e passará essa
estrutura para as APIs do driver.
E as APIs do driver decodificarão a estrutura e tomarão as ações apropriadas, como a inicialização dos
registros periféricos.
Agora existe a necessidade de criar uma estrutura de configuração.
Vamos criar duas estruturas.
Um é chamado de estrutura de tratamento e o segundo é chamado de estrutura de configuração.
Agora vamos entrar no driver GPIO.h e vamos criar a estrutura de identificador para um pino GPIO.
Vamos usar uma estrutura typedef e eu chamaria GPIOx ou GPIO.
Assim, você pode usar apenas a estrutura de manipulação do GPIO Handle_t.
Agora, o primeiro elemento membro aqui deve ser um ponteiro para manter o endereço base do
periférico GPIO.
É por isso que podemos criar uma variável de ponteiro para a estrutura de definição de registro que
nós criamos.
Vamos criar uma variável de ponteiro e vamos chamá-la como GPIOBaseAddr. Isso realmente
mantém o endereço base do GPIO periférico, então você pode apenas inicializá-lo para GPIO A ou B
ou C ou qualquer outra coisa. Essas definições periféricas são definidas aqui, certo? no arquivo de
cabeçalho específico do MCU.

3
Que realmente dá o endereço de base.
E já é typecasted para este tipo de ponteiro.
É por isso que este será nosso primeiro elemento membro.
Deixe-me dar uma pequena descrição sobre esse elemento membro.
Isso mantém o endereço base da porta GPIO à qual o pino pertence.
Então, antes de trabalhar com qualquer periférico, precisávamos de um endereço base.
Esse ponteiro irá manter esse endereço base.

Agora, em vez de usar esse nome longo.


O que eu gostaria de usar é que eu gostaria de usar apenas o GPIO x aqui.

Esse é realmente o nome mais sensato.


Ok, então GPO x significa x você pode substituir por qualquer valor que existe nesta definição
periférica e também observar que eu usei uma minúscula p aqui.
Isso é para indicar que essa variável é, na verdade, um tipo de ponteiro, portanto, você pode usar
essa convenção de nomenclatura para que também possa escrever dessa maneira.
Não tem problema, mas sempre que é uma variável de ponteiro, basta usar minúsculas p aqui. E
depois disso.

4
Deixe-me remover este comentário. E o segundo elemento membro é criar uma estrutura de
configuração para GPIO_PinConfig_t porque um pin pode ter muitos itens de configuração certos e
criará uma variável chamada GPIO_pin_Config.
Agora essa estrutura ainda não foi criada.
Vamos criar isso.
Então, basicamente, essa variável mantém as configurações do GPIO.

Tudo bem então agora vamos criar essa estrutura aqui mesmo.
Deixe-me criar essa estrutura.
E então, quais são os itens configuráveis?
Estes são os itens configuráveis certos.

Vamos criar um elemento membro para manter cada item configurável.


Vamos voltar e vamos criar aqui.

Eu usei unsigned int 8, Então isso é byte, não é?

5
Para manter o PIN, os números PIN podem variar de 0 a 15.
É por isso que um byte é suficiente aqui.
Esta variável é para manter o modo pin.
Isso é para manter a velocidade, etc. Os nomes são autoexplicativos aqui.
Isso completa a criação da estrutura de configuração para um pino GPIO.
E esta é na verdade a estrutura que contém o endereço base do GPIO e as configurações do pin.
Então, complete até aqui e eu vou te ver na próxima palestra.

106 - Requisitos da API do driver e inclusão de protótipos da API

Nesta palestra vamos entender quais são as APIs do driver.


Vamos apoiar neste projeto de desenvolvimento de drivers GPIO.
Vamos discutir quais são as APIs necessárias.
Um driver GPIO deve ser capaz de fornecer todas essas APIs para o aplicativo do usuário.

Deve dar uma API para inicializar os periféricos da porta GPIO. E também deve fornecer uma API para
ativar ou desativar o relógio periférico da porta GPIO e também deve fornecer uma API para o
aplicativo do usuário ler de nosso pino GPIO ou ler a partir da porta GPIO.
Assim, nosso aplicativo de usuário pode ler de um pino ou ler toda a porta do GPIO.
Da mesma forma, o driver deve fornecer uma API para gravar em um determinado pino GPIO ou
gravar em toda a porta GPIO. Além disso, você deve fornecer uma API que ajude a usar o aplicativo do
usuário para configurar a funcionalidade alternativa e também o driver deve cuidar da interrupção
também deve dar capacidade de manipulação de interrupção.
Também no recurso de configuração de interrupção, em que o aplicativo do usuário pode ativar a
interrupção para desativar a interrupção.
Altere a prioridade, etc. Portanto, todas essas APIs devem ser suportadas pelo driver GPIO e veremos
como fazer isso?
Não se preocupe com isso, Então, passo a passo, vamos desenvolver, e vamos apoiar todas essas
funcionalidades em nosso driver. e agora antes disso Vamos criar os protótipos da API, o que é muito
importante.
Os protótipos devem ser criados primeiro no arquivo de cabeçalho, protótipos temporários ou
temporários, protótipos de função ou o que você pode chamar como protótipo de API no arquivo de
cabeçalho do driver e implementá-lo no arquivo de origem do driver.
Agora vamos para o nosso arquivo de cabeçalho, mas vamos para o arquivo de cabeçalho, então eu
estou no driver do GPO .h

6
E aqui vamos escrever os protótipos para as APIs suportadas por este driver.
Agora vamos começar a escrever os protótipos, agora primeiro para inicializar o GPIO, para inicializar
o GPIO podemos escrever uma função e o nome da função é GPIO init.
Então, por enquanto, deixe-me não decidir os parâmetros que esta API vai tomar.
Deixe-me apenas escrever void.Primeiro vamos fazer tudo como nulo e vazio que é o tipo de retorno
também é nulo e os parâmetros também são nulos.
Posteriormente, decidiremos o que exatamente devemos fazer, na seção de parâmetros e o que essa
API deve retornar.
Mais tarde podemos discutir isso. Mas vamos primeiro corrigir os nomes das funções ou os nomes das
APIs.
Então, essa será a API para inicializar a porta e o pino GPIO fornecidos.
Agora vamos criar mais uma API e nomearemos como DeInit.
Isso é para reinicializar a porta GPIO.
Ele retornará as configurações da porta GPIO para o estado de reinicialização e também fornecerá
mais API para controlar ou ativar ou desativar o relógio periférico. GPIO controle de clock periférico e
depois disso vamos criar mais uma "API" para ler a partir do pino, então leia a partir do pino de
entrada, e também podemos escrever mais uma API para ler a partir da porta de entrada.
Esta é a leitura do pino de entrada, isto é para ler da porta de entrada a porta inteira! ..
Trata-se de ler e vamos criar algumas APIs para escrever o pino GPIO_WriteToOutput.
Certo ?? então isso faz sentido.
E anule GPIO_WritetoOutputPort bem.
E depois disso, vamos criar mais uma API para digamos, alternar o pin GPIO, alternar pin para que
possamos apenas escrever o pino de alternância ou você também pode chamá-lo como alternar pino
de saída e depois disso vamos dar algumas APIs para gerenciar a interrupção.
Então, void GPIO_IRQConfig. Então vamos criar uma função chamada IRQ config para esta
configuração de IRQ.

7
Na verdade, eu usei para configurar o número de IRQ do pino GPIO, como habilitá-lo, configurar a
prioridade, etc., para que esta configuração de IRQ ou interrupção de configuração.
Então vamos dar outra API chamada GPIO IRQ Handling. Portanto, o manuseio de IRQ significa que
sempre que a interrupção ocorre, o aplicativo do usuário pode chamar essa função para processar
essa interrupção.
Então, vamos chamá-lo como IRQ Handling.
Se é confuso, não se preocupe com isso.
Então, quando implementarmos essa API, você saberá exatamente o que é essa finalidade e por que
ela é necessária.

Manipulação de IRQ significa que sempre que a interrupção disparar o aplicativo de usuário, poderá
chamar essa função de manipulação de IRQ para processar essa interrupção. Agora vamos usar vazio
aqui.
Vamos nos separar de acordo com o propósito deles.
Vamos manter o relógio dos periféricos configurado aqui.
Eu vou cortar isso e vou continuar aqui.

E depois disso vamos manter o init e deinit aqui e os dados são lidos, escreva aqui.

8
E depois disso e essas duas APIs para configuração de IRQ e manipulação de ISR. E complete Upto
aqui, e veremos na próxima palestra como decidir os parâmetros de entrada, bem como os valores de
retorno.
Antes de terminar este vídeo, deixe-me apenas construir este projeto e ver se funciona ou não.
Sim, de fato.
Sem erros...

107 - Parâmetros de entrada da API do driver e tipos de retorno ****

Hey bem vindo de volta à palestra.


Na palestra anterior, na verdade, terminamos de escrever os protótipos das APIs.
E agora vamos decidir os parâmetros de entrada, bem como os valores de retorno.
Primeiro de todos os GPIO controle de clock periférico.
Portanto, ao usar essa função, você ativará ou desativará o relógio periférico para um determinado
endereço base do GPIO.

É por isso que o primeiro parâmetro será o endereço base do ponteiro para o endereço base.
É por isso que vamos usar o nosso GPIO_regDef_t e isso será * pGPIOx. Então, no segundo parâmetro
você tem que dizer se está habilitado ou desabilitado.
Eu usaria o tipo de dados uint8_t.
Deixe-me criar uma variável En ou Di ativar ou desativar.

Agora vamos criar duas macros, habilitar ou desabilitar, para que seja criado em nosso arquivo de
cabeçalho específico de MCU.

No arquivo de cabeçalho específico do MCU, deixe-me criar duas macros.

9
Talvez depois disso. Algumas macros genéricas .. tudo bem .. então #definido habilitado significa
sempre 1 e #define
disable means 0.! .. e também deixe-me criar uma macro chamada set. set significa digamos habilitar
e redefinir.

Então, reset significa desabilitar. Algumas macros diversas que você pode usar em nosso trabalho.
Agora vamos voltar ao nosso driver.h

Isso levaria ou ativar ou desativar. se estiver habilitado você tem que habilitar o clock, se estiver
desabilitado você tem que desabilitar o clock ..! .. e para o GPIO init você tem que levar um ponteiro
para a estrutura do handle. Então, temos que levar o ponteiro para a estrutura do manipulador. e é
isso. Embora não seja preciso nada extra.

10
Apenas um parâmetro é suficiente.

Isso é ponteiro para o identificador GPIO.


Isso significa que o aplicativo de usuário deve criar uma variável desse tipo para inicializar isso e
enviar o ponteiro dessa variável para a função init GPIO para inicializar a porta e o pino GPIO.
E essa função não retorna nada, então vamos manter o vazio.
Tudo bem, então agora vamos passar para a próxima API.
Isso é GPIO deInit..Então, o GPIO DeInit é usado para desinicializar os registros do periférico GPIO
dado. Assim, o registro Deinitializing significa enviar aquele registro de volta ao seu estado de reset
ou valor de reset.
Para fazer isso, é um registro importante disponível na seção RCC ou no RCC Peripheral.
Então, você não precisa passar por cada registro e você não precisa enviar manualmente para
registrar o valor de volta para redefinir o valor para que não seja necessário em um tiro.
Nós podemos fazer isso.

Então, para isso você tem que ir e consultar o registrador de reset periférico presente na seção RCC.
Por exemplo, há um registro de reset para periféricos AHB1.
Por exemplo, digamos que eu queira redefinir todos os registros do GPIO A periférico em um único
disparo.
Então, o que eu faria seria simplesmente chegar a esse registro e farei essa pequena posição como
uma.
Se eu fizer essa posição de bit como um, todos os registros de um periférico GPIO A serão redefinidos.

11
É por isso que parâmetro deve tomar?

Deve levar apenas o endereço base do periférico ..

É por isso que eu posso usar isso.

Agora vamos seguir em frente e agora vamos definir os parâmetros e retornar os valores para leitura
GPIO do pino de entrada.
Este nome em si sugere que você precisa de um número PIN ...

E os endereços de base do GPIO periférico e o valor de retorno devem ser 0 ou 1 .. Então, qual seria
o estado do pino?
Seria 0 ou 1.
Eu posso apenas usar o Boolean ou posso usar o uint8_t aqui, como um tipo de retorno.
E leia a partir da porta de entrada.

Então, quanto tempo é o porto? Então port é de 16 pinos. Isso significa que eu tenho que usar
uint16_t aqui.

12
O valor de retorno e o que eu só preciso é este. O endereço base da porta GPIO.
Isso retornará o conteúdo do registro de dados de entrada para que possamos ver quando
implementamos isso.
Leia da porta de entrada.
E depois disso.
Escreva para o pino de saída.
Mais uma vez eu precisaria desses dois parâmetros aqui e o valor de retorno não será nada, será
anulado porque está escrito.
E aqui eu precisaria de mais um argumento.
Ou parâmetro que é valor certo? Então, uint8_t eu precisaria de valor. Então, o valor é 0 ou 1.
Direito ??

Ou definir ou redefinir. Então, esse valor pode levar pin set ou pin reset.
É por isso que vamos definir essas macros aqui.
Todas essas coisas que estou fazendo no arquivo de cabeçalho específico do MCU porque esse
arquivo de cabeçalho será usado por muitos drivers.

Se eles quiserem acessar essas macros, estarão disponíveis para eles também.
Portanto, não faça essas macros específicas para o cabeçalho do GPIO.

É por isso que não estou escrevendo esses cabeçalhos aqui porque mais tarde esse driver I2C pode
usar essas macros.
É por isso que eu precisaria disso mais tarde.

13
É por isso que estou escrevendo no arquivo de cabeçalho específico do MCU. E depois disso, vamos
para o próximo.
Novamente aqui eu precisaria. Eu não preciso pin não, na verdade, eu só preciso de valor.
Certo.
E novamente o valor deve ser uint16_t porque existem 16 pinos em uma porta. Correto?
E depois disso, alterne o pino de saída.
Agora, novamente, para alternar, você precisa apenas de um endereço base e o pino é isso. Todos
esses tipos de retorno serão anulados.

Essas são as APIs de leitura e gravação.


E depois disso.
Vamos seguir para as APIs de configuração de IRQ.
Configuração de IRQ para configurar a interrupção do que você precisa, você precisa do número de
IRQ, não é?
Então, uint8_t IRQNumber e depois disso você precisa de IRQPriority.
E também você tem que mencionar aqui se você quer habilitar isso.
IRQ ou desabilitar esse IRQ.
Eu daria um outro parâmetro aqui que está habilitado ou desabilitado. Então isso iria permitir ou
desabilitar a macro. Aqui você deve mencionar a prioridade desse IRQ.
Aqui você tem que mencionar esse número de IRQ. Então, isso é sobre o GPIO.
Configuração de IRQ.

Você também pode usar mais um parâmetro aqui que é o agrupamento de IRQ.
Isso na verdade eu não considero para este projeto.
Mas você pode fazer isso.
Vamos simplificar.
Vamos apenas pegar o IRQ
Número de prioridade de IRQ.
E este é o comando se o IRQ precisa ser ativado ou desativado. e aqui
o manipulador de IRQ e isso também não retorna nada tão vazio.
E depois disso, lidar com o IRQ.
Então, aqui a interrupção para esse pino GPIO será gerenciada.
É por isso que só precisamos pegar o pin.

Então, porque as funções de manipulação de IRQs devem saber de qual pino a interrupção é
acionada.
É isso aí.
Estas são nossas APIs.

E nós fixamos os parâmetros de entrada, bem como os tipos de retorno.


E se qualquer alteração for necessária, faremos isso mais tarde.

14
Alterações podem ser necessárias.
Nós não sabemos
Mas assim que começarmos a codificar, só saberemos se há alguma alteração necessária ou não.
Apenas compile este código e veja se ele é construído ou não.
Deixe-me apenas construir este projeto e ele realmente constrói.
Sem erros.
E eu vou te ver na próxima palestra.

108 - Implementação e documentação da API do driver vazio ***

Na palestra anterior, acabamos de criar protótipos de nossas APIs.


Agora, vamos começar a implementar essas APIs.
Para que vamos copiar todos esses protótipos de função e vamos ao arquivo driver.c e vamos colar
aqui.

(tem mais do que essa parte selecionada***)

Está criando os arquivos .c e .h com uso de funcoes com sua transcrição em .c e seus respectivos
prototipos na .h***)

E depois disso, agora dê a definição da função. Portanto, remova todos esses pontos-e-vírgulas e crie
a função.
Acabei de criar a definição da função.
Temos que codificar todas essas funções ou APIs.
Para cada função, deve haver uma seção de documentação ou comentário onde você deve
documentar o propósito dessa API. E você também deve explicar os vários parâmetros que você usou
para essa função, também, você deve explicar o que exatamente é um tipo de retorno ou valor de
retorno. Agora, para isso, vamos criar a seção de documentação aqui.
Esta será minha seção de documentação.
Agora isso você também pode obter do nosso repositório github.***localizar esse arquivo

Nesta seção de documentação, haverá um nome de função e você deve descrever brevemente o que
essa função faz e você deve explicar todos os parâmetros. Por exemplo, este é o primeiro parâmetro,
esta é a segunda descrição do parâmetro e esta é a terceira descrição do parâmetro. E então, se

15
houver alguma nota especial para usar esta API, você deve mencionar isso. Às vezes, haverá uma nota
especial para usar uma API.
E também você deve mencionar o tipo de retorno.
Então, o tipo de retorno aqui não será nenhum.
Você pode escrever apenas uma nota especial.
Acho que não temos nenhuma nota especial. Se houver alguma nota especial, então nós a
escreveremos.
Então, atualmente eu vou manter nenhum e aqui você menciona apenas o nome da função. O nome
da função é o controle de periféricos GPIO e também fornece uma breve descrição sobre essa função.

Portanto, uma descrição breve seria essa função ativa ou desativa o relógio periférico para a porta
GPIO especificada.
Então, qual é o primeiro parâmetro ??
O primeiro parâmetro seria o endereço base do GPIO periférico, certo ?? E o segundo será macros
que estão lá no arquivo de cabeçalho específico do MCU. Você deve mencionar ativar ou desativar
macros visíveis.

Tudo bem. E o retorno é nenhum e a nota é nenhuma.

16
Isso é sobre a documentação.
Então, complete até aqui e também adicione a seção de comentários ou a seção de documentação
para outras APIs.
E eu vou te ver na próxima palestra.

17

Você também pode gostar