Na primeira parte do artigo, expliquei como gerar código sem suporte à biblioteca KSDK e sem suporte ao Processor Expert. Dando continuidade ao assunto, neste artigo explicarei como gerar código com suporte ao KSDK e sem suporte ao Processor Expert.
Apenas para informação, esta é a sequencia de post proposta na primeira parte:
-
Projeto com a FRDM-K64F e KDS: Codificação sem suporte ao KSDK e ao Processor Expert;
-
Projeto com a FRDM-K64F e KDS – Suporte ao KSDK: Codificação com suporte ao KSDK e sem suporte ao Processor Expert;
- Projeto com a FRDM-K64F e KDS – Suporte ao KSDK e Processor Expert: Codificação com suporte ao KSDK e ao Processor Expert.
O que é o KSDK?
É uma coleção de códigos-fontes que auxiliam no acesso aos periféricos e em alguns casos já tem algum algoritmo de tratamento de dados.
Um exemplo de tratamento dos dados é aplicado na UART, onde existe um prévio tratamento de interrupção e os dados que chegam pelo pino de RX já são armazenados em um Buffer. Um dos campos da estrutura é a quantidade de bytes recebidos, e uma função de callback é chamada. Esta funcionalidade ajuda bastante, pois faz alguns tratamentos críticos no momento que uma interrupção ocorre.
No manual do KSDK (Kinetis SDK v.1.2.0 API Reference Manual.pdf), esta e outras funcionalidades são muito bem explicadas. Este manual fica na pasta “doc” de onde foi instalado o KSDK.
Criando o projeto com o Gerador Automático de Projeto
Para auxiliar no desenvolvimento de firmware, a Freescale desenvolveu uma ferramenta bem interessante para gerar um projeto base que utiliza a biblioteca KSDK, o KSDK Project Generator.
É necessário aceitar um acordo, e ter um registro no site. A instalação não é necessária, apenas descompacte em uma pasta, e rode o programa de acordo com o seu sistema operacional. Ao executar o programa, a seguinte tela é apresentada:
Onde:
- KSDK Path: caminho onde foi instalado o KSDK;
- Project Name: nome do projeto;
- Choose board: selecionar a placa Freedom como base de projeto;
- Quick Generate!: Botão para gerar o projeto.
Neste programa é necessário indicar onde foi instalado o KSDK, o nome do projeto, qual a placa Freedom que receberá o código.
Pressionar o botão “Quick Generate!”. O caminho base onde o projeto é gravado é:
<caminho KSDK>/examples/<placa>/user_apps/<nome_do_projeto>
Sugestão de nome para o projeto: PiscaLedComSuporteKSDK.
Abrindo o programa gerado usando o KDS
Para abrir o projeto feito pelo KSDK-Project-Generator no KDS, é necessário importar o projeto. Clicar com o botão direito na área do “Project Explorer” e selecionar a opção “Import”.
Selecione a opção General -> Existing Projects into Workspace.
Selecionar a opção “Select root directory”. Clicar em “Browse”. Selecionar a pasta do projeto, de acordo com o que foi apresentado no programa de geração de projetos. Escolher a pasta kds.
Clicar em “OK”. Certificar que no campo “Projects” o projeto criado está marcado. Clicar em “Finish”. O arquivo “main.c” ficará da seguinte maneira.
Perceba que, tem um “PRINTF” no código. Pois é, a porta serial que passa pelo debugger já está configurada e pronta para uso. É só configurar um terminal serial e selecionar a porta serial virtual gerada em conjunto com o driver OpenSDA mostrada no Gerenciador de Dispositivos.
A configuração dessa porta é:
- Baudrate: 115200
- Número de bits: 8
- Paridade: Nenhum
- Stop bits: 1
Criando o código
Criei alguns defines para facilitar a codificação:
#define VAL_DELAY 5000000 #define PORT_LED_VERMELHO PORTB #define BIT_LED_VERMELHO 22 #define PT_LED_VERMELHO PTB #define PORT_LED_VERMELHO PORTE #define BIT_LED_VERMELHO 26 #define PT_LED_VERMELHO PTE #define PORT_LED_VERMELHO PORTB #define BIT_LED_VERMELHO 21 #define PT_LED_VERMELHO PTB
Os blocos que devem ser configurados são os mesmos que o projeto anterior, mas agora utilizando as APIs do KSDK. Devemos fazer:
- Habilitar o fornecimento de clock para os ports. Já foi feito na função “hardware_init().
- Configurar os pinos para operar como GPIO.
- Configurar a direção dos pinos.
- Operar no acionamento dos pinos.
Configurar os pinos para operar como GPIO:
Um dos módulos criados automaticamente é o “board”. Neste módulo existem alguns arquivos de configuração. Porém se referem diretamente ao esquema desta placa (FRDM-K64F). Para configurar algum pino específico que não esteja no esquema da placa, é necessário utilizar algumas funções do KSDK.
Seguindo as configurações feitas no projeto anterior, é necessário acessar as seguintes funções: MUX, DSE, ODE, PFE, SER, PE, PS. Existem chamadas prontas para configurar cada uma das funções:
- MUX: PORT_HAL_SetMuxMode
- DSE: PORT_HAL_SetDriveStrenghtMode
- ODE: PORT_HAL_SetOpenDrainCmd
- PFE: PORT_HAL_SetPassiveFilterCmd
- SER: PORT_HAL_SetSlewRateMode
- PE: PORT_HAL_SetPullCmd
- PS: PORT_HAL_SetPullMode
Então o código fica assim:
//Led Vermelho PORT_HAL_SetMuxMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortMuxAsGpio); PORT_HAL_SetDriveStrengthMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortLowDriveStrength); PORT_HAL_SetOpenDrainCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false); PORT_HAL_SetPassiveFilterCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false); PORT_HAL_SetSlewRateMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortSlowSlewRate); PORT_HAL_SetPullCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false); PORT_HAL_SetPullMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortPullDown); //Led Verde PORT_HAL_SetMuxMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortMuxAsGpio); PORT_HAL_SetDriveStrengthMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortLowDriveStrength); PORT_HAL_SetOpenDrainCmd(PORT_LED_VERDE,BIT_LED_VERDE,false); PORT_HAL_SetPassiveFilterCmd(PORT_LED_VERDE,BIT_LED_VERDE,false); PORT_HAL_SetSlewRateMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortSlowSlewRate); PORT_HAL_SetPullCmd(PORT_LED_VERDE,BIT_LED_VERDE,false); PORT_HAL_SetPullMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortPullDown); //Led Azul PORT_HAL_SetMuxMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortMuxAsGpio); PORT_HAL_SetDriveStrengthMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortLowDriveStrength); PORT_HAL_SetOpenDrainCmd(PORT_LED_AZUL,BIT_LED_AZUL,false); PORT_HAL_SetPassiveFilterCmd(PORT_LED_AZUL,BIT_LED_AZUL,false); PORT_HAL_SetSlewRateMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortSlowSlewRate); PORT_HAL_SetPullCmd(PORT_LED_AZUL,BIT_LED_AZUL,false); PORT_HAL_SetPullMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortPullDown);
Configurar a direção dos pinos:
Utilizar a função GPIO_HAL_SetPinDir():
//Trecho de código //Direção dos pinos dos Leds GPIO_HAL_SetPinDir(PT_LED_VERMELHO, BIT_LED_VERMELHO, kGpioDigitalOutput); GPIO_HAL_SetPinDir(PT_LED_VERDE, BIT_LED_VERDE, kGpioDigitalOutput); GPIO_HAL_SetPinDir(PT_LED_AZUL, BIT_LED_AZUL, kGpioDigitalOutput);
Operar no acionamento dos pinos:
- Para setar uma saída, usar a função: GPIO_HAL_SetPinOutput().
- Para o toggle de uma saída, usar a função: GPIO_HAL_TogglePinOutput().
//Trecho de código GPIO_HAL_SetPinOutput(PT_LED_VERMELHO, BIT_LED_VERMELHO); GPIO_HAL_SetPinOutput(PT_LED_VERDE, BIT_LED_VERDE); GPIO_HAL_SetPinOutput(PT_LED_AZUL, BIT_LED_AZUL);
A função de delay será usada uma variável com valor bem alto e decrementar até chegar a zero.
//Trecho de código uint32_t var_delay = VAL_DELAY; while(--var_delay); var_delay = VAL_DELAY;
Obs.: Da maneira que o projeto foi criado, a otimização de código pode alterar o funcionamento, então, é necessário não otimizar nada no código. E para fazer isso, entre nas propriedades do projeto:
Botão direito sobre o nome do projeto -> Properties -> C/C++ Build -> Settings -> Optimization -> Optimization Level -> None (-O0).
Habilite a impressão do tamanho do binário gerado. Para isso siga o caminho:
“Botão direito no nome do projeto -> Properties -> C/C++ Build -> Settings” -> “Aba Toolchains”. Marque o checkbox “Print size”.
Código completo:
#define VAL_DELAY 5000000
#define PORT_LED_VERMELHO PORTB
#define BIT_LED_VERMELHO 22
#define PT_LED_VERMELHO PTB
#define PORT_LED_VERDE PORTE
#define BIT_LED_VERDE 26
#define PT_LED_VERDE PTE
#define PORT_LED_AZUL PORTB
#define BIT_LED_AZUL 21
#define PT_LED_AZUL PTB
int main(void)
{
uint32_t var_delay = VAL_DELAY;
// Configure board specific pin muxing
hardware_init();
// Initialize UART terminal
dbg_uart_init();
PRINTF("\r\nRunning the PiscaLedComSuporteKSDK_b project.\n");
//Led Vermelho
PORT_HAL_SetMuxMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortMuxAsGpio);
PORT_HAL_SetDriveStrengthMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortLowDriveStrength);
PORT_HAL_SetOpenDrainCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false);
PORT_HAL_SetPassiveFilterCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false);
PORT_HAL_SetSlewRateMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortSlowSlewRate);
PORT_HAL_SetPullCmd(PORT_LED_VERMELHO,BIT_LED_VERMELHO,false);
PORT_HAL_SetPullMode(PORT_LED_VERMELHO,BIT_LED_VERMELHO,kPortPullDown);
//Led Verde
PORT_HAL_SetMuxMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortMuxAsGpio);
PORT_HAL_SetDriveStrengthMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortLowDriveStrength);
PORT_HAL_SetOpenDrainCmd(PORT_LED_VERDE,BIT_LED_VERDE,false);
PORT_HAL_SetPassiveFilterCmd(PORT_LED_VERDE,BIT_LED_VERDE,false);
PORT_HAL_SetSlewRateMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortSlowSlewRate);
PORT_HAL_SetPullCmd(PORT_LED_VERDE,BIT_LED_VERDE,false);
PORT_HAL_SetPullMode(PORT_LED_VERDE,BIT_LED_VERDE,kPortPullDown);
//Led Azul
PORT_HAL_SetMuxMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortMuxAsGpio);
PORT_HAL_SetDriveStrengthMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortLowDriveStrength);
PORT_HAL_SetOpenDrainCmd(PORT_LED_AZUL,BIT_LED_AZUL,false);
PORT_HAL_SetPassiveFilterCmd(PORT_LED_AZUL,BIT_LED_AZUL,false);
PORT_HAL_SetSlewRateMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortSlowSlewRate);
PORT_HAL_SetPullCmd(PORT_LED_AZUL,BIT_LED_AZUL,false);
PORT_HAL_SetPullMode(PORT_LED_AZUL,BIT_LED_AZUL,kPortPullDown);
//Direção dos pinos dos Leds
GPIO_HAL_SetPinDir(PT_LED_VERMELHO, BIT_LED_VERMELHO, kGpioDigitalOutput);
GPIO_HAL_SetPinDir(PT_LED_VERDE, BIT_LED_VERDE, kGpioDigitalOutput);
GPIO_HAL_SetPinDir(PT_LED_AZUL, BIT_LED_AZUL, kGpioDigitalOutput);
GPIO_HAL_SetPinOutput(PT_LED_VERMELHO, BIT_LED_VERMELHO);
GPIO_HAL_SetPinOutput(PT_LED_VERDE, BIT_LED_VERDE);
GPIO_HAL_SetPinOutput(PT_LED_AZUL, BIT_LED_AZUL);
while (1) // Forever loop
{
GPIO_HAL_TogglePinOutput(PT_LED_VERMELHO, BIT_LED_VERMELHO);
GPIO_HAL_TogglePinOutput(PT_LED_VERDE, BIT_LED_VERDE);
GPIO_HAL_TogglePinOutput(PT_LED_AZUL, BIT_LED_AZUL);
while(--var_delay);
var_delay = VAL_DELAY;
}
}
Conclusão
Para este processo foi necessário utilizar apenas o documento sobre as APIs do KSDK, mas mesmo assim, procurar por alguns detalhes bem específicos sobre o hardware. Um dos passos já foi executado automaticamente, e um brinde foi proporcionado, a porta serial para debug.
Teve uma diferença no tamanho de código, claro, mas pensando na facilidade de configurar os registradores, é de se pensar, não?
No próximo post, veremos mais uma maneira de se fazer projetos. Enquanto isso aproveite para explorar a documentação do KSDK, tem muita informação interessante lá.









