Tutorial ARM
Tutorial ARM
Tutorial ARM
CPGEI
NIKOLAS LIBERT
CURITIBA
2012
LISTA DE FIGURAS
SUMRIO
1 INTRODUO ....................................................................................................6
2 CONFIGURAO DO ECLIPSE ........................................................................8
2.1 INSTALANDO O COMPILADOR ...................................................................8
2.2 INSTALANDO AS BIBLIOTECAS DO MICROCONTROLADOR ................9
2.3 INSTALANDO O ECLIPSE .............................................................................10
2.4 INSTALANDO O PLUG-IN GNU ARM ..........................................................10
2.5 INSTALANDO O PLUG-IN DO DEPURADOR..............................................13
2.6 PROGRAMA PARA PISCAR LED .................................................................14
2.6.1 Criando um projeto .........................................................................................15
2.6.2 Configurando o plug-in GNU ARM .................................................................17
2.6.3 Importando o arquivo de inicializao .............................................................23
2.6.4 Escrevendo o programa ...................................................................................25
2.6.5 Configurando o OpenOCD ..............................................................................27
2.6.6 Configurando o depurador...............................................................................31
2.7 PROGRAMA PARA ACESSAR A INTERFACE SERIAL .............................39
2.7.1 Criando o projeto ............................................................................................40
2.7.2 Escrevendo o programa ...................................................................................40
2.7.3 Criando pasta virtual e adicionando atalho para arquivo................................42
3 INSTALAO DO RTOS ....................................................................................45
3.1 ADICIONANDO O FREERTOS A UM PROJETO .....................................45
3.2 ESCREVENDO PROGRAMA DE TESTE COM O FREERTOS ................50
4 INSTALAO DA PILHA TCP/IP ....................................................................55
4.1 INSTALANDO E CRIANDO UM PROJETO DE EXEMPLO ........................55
REFERNCIAS ......................................................................................................69
APNDICE A - Listagem de cdigo do arquivo main.c criado no exemplo do
FreeRTOS .........................................................................................................70
1 INTRODUO
2 CONFIGURAO DO ECLIPSE
C/C++ para ARM, que inclui um maker e um linker, assim como as bibliotecas
padres de C/C++. Foi utilizada a verso 2011.09-69 lite, que pode ser obtida
gratuitamente do site da mentor.
de bibliotecas com funes para acesso aos perifricos do kit de desenvolvimento EKLM3S8962. Pode ser obtido no site da texas instruments.
10
e das bibliotecas do
11
12
13
14
15
16
17
18
Figura 12 Configurao do GNU ARM. Definio do caminho dos arquivos de cabealho utilizados.
19
No item Additional Tools, existem opes para que seja gerada a imagem
que ser gravada na memria Flash e para a exibio de uma mensagem informando
o tamanho do cdigo gerado. Tambm no sero feitas alteraes neste item.
O item ARM Sourcery Windows GCC Assembler e seus subitens ficaro
como esto, uma vez que no ser programado em assembly.
Conforme mostrado na Figura 12, no subitem Directories da categoria
ARM Sourcery Windows GCC C Compiler, devem ser inseridos os caminhos para
os locais onde esto os arquivos de cabealho das bibliotecas que sero utilizadas. Isso
pode ser feito clicando-se sobre o smbolo que est marcado com um circulo vermelho
na Figura 12. Neste caso, ser necessrio adicionar apenas a pasta raiz da biblioteca
do pacote StellarisWare, j que nenhuma outra biblioteca ser utilizada.
20
21
Por fim, deve ser feita uma alterao no subitem Output da seo ARM
Sourcery Windows GNU Create Flash Image. O campo Output file format deve
ser alterado para binary, como demonstrado na Figura 15. Clique em Apply para
salvar as alteraes.
Na Figura 16, pode ser vista a janela de configurao dos smbolos e
caminhos de arquivos utilizados pelo projeto do Eclipse. Caso o item GNU C seja
selecionado na lista Languages, o item C:\Dev\StellarisWare poder ser visto na
lista Include directories. Nenhuma alterao precisa ser feita.
22
23
24
25
Finalmente, o programa de teste pode ser escrito. Um novo arquivo deve ser
criado, clicando-se com o boto direito sobre o nome do projeto e selecionando-se
New -> Source File. Isso pode ser visto na Figura 20. Na janela que se abrir,
nomeie o arquivo como main.c e clique em Finish.
Abra o arquivo criado e escreva o seguinte cdigo:
main.c
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
int main(){
unsigned char flagLEDLigado = false;
unsigned long contador;
/* Configura Clock para 50 MHz. */
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_8MHZ);
26
27
${workspace_loc:}/../OpenOCD/bin/openocd-0.5.0.exe,
onde
28
a pasta raiz dos projetos. Em Working Directory deve ser inserido o caminho para
o diretrio base do OpenOCD, que neste caso ${workspace_loc:}/../OpenOCD/.
O texto contido no campo Arguments ser adicionado como parmetro na chamada
do OpenOCD pelo Eclipse e deve ser igual a -f .\board\ek-lm3s8962.cfg -c "init" -c
"reset
halt"
-c
"stellaris
mass_erase
0"
-c
"flash
write_bank
../Eclipse/${project_name}/Debug/${project_name}.hex 0" .
29
algumas
alteraes
precisam
ser
feitas.
parmetro
30
31
32
nova configurao para Servidor GDB. Alm disso, remova alguns parmetros da
caixa de texto Arguments at que seu contedo fique igual a -f .\board\eklm3s8962.cfg -c "init . O resultado final est mostrado na Figura 25. No se
esquea de clicar em Apply.
Agora devem ser feitas as configuraes do GDB Debugger. Para tanto, entre
em Run -> Debug Configurations.... Na janela da Figura 26, clique com o boto
direito sobre GDB Hardware Debugging e selecione a opo New. Posteriormente,
abra a aba Debugger e faa as modificaes da Figura 27. Altere o texto do campo
GDB Command para arm-none-eabi-gdb e o texto do campo Port number para
3333.
33
34
35
36
sobre a seta ao lado do cone com aparncia de computador aparecer uma lista com
os programas externos abertos. Caso haja algum item do OpenOCD ou do GDB,
clique sobre ele e encerre-o. Para encerrar a execuo, basta clicar sobre o quadrado
vermelho mostrado na Figura 30. Aps encerrar a execuo do programa externo, o
console do mesmo pode ser fechado clicando-se sobre o X ao lado do quadrado.
37
38
meio do menu no canto superior direito da janela principal, que est destacado na
Figura 35.
39
40
adicionados arquivos de cdigo fonte externos ao projeto. Isso no havia sido feito na
outra seo, onde haviam sido utilizados apenas arquivos de cabealho externos e
bibliotecas pr-compiladas.
41
main.c
#include
#include
#include
#include
#include
"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"utils/uartstdio.h"
int main(){
unsigned char flagLEDLigado = false;
unsigned long contador;
/* Configura Clock para 50 MHz. */
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_8MHZ);
/* Habilita drivers do GPIO F. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
/* Configura o port F0 como sada para o LED. */
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0);
/* Habilita drivers do GPIO A (utilizado pela serial). */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
/* Configura ports F0 e F1 para uso com a serial. */
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
/* Inicializa a serial que ligada ao controlador USB. */
UARTStdioInit(0);
/* Lao infinito. */
while(1){
if (flagLEDLigado == false){
/* Liga LED. */
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 1);
UARTwrite("LED Ligado\n", 11);
flagLEDLigado = true;
} else {
/* Desliga LED. */
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0);
UARTwrite("LED Desligado\n", 14);
flagLEDLigado = false;
}
/* Gera Atraso. */
for (contador=0; contador<5000000; contador++);
}
}
Este programa far com que toda vez que o estado do LED se altere, seja
transmitida uma mensagem pela interface serial. Neste exemplo foram utilizadas as
funes UARTStdioInit e UARTwrite, que esto declaradas no arquivo
uartstdio.c da pasta utils do pacote StellarisWare. A funo UARTStdioInit
42
43
digite o nome desejado. Para este exemplo, escolhi o nome utils. Estas
configuraes esto ilustradas na Figura 40.
Agora um atalho para o cdigo fonte precisa ser adicionado. Como mostrado
na Figura 41, clique com o boto direito sobre a pasta criada e selecione New ->
File. Na janela aberta, que est representada na Figura 42, clique em Advanced e
selecione a opo Link to file in the file system. Ento clique em Browse e
selecione o arquivo \StellarisWare\utils\uartstdio.c. Agora que o atalho foi
adicionado, o arquivo ser includo no processo de compilao pelo plug-in GNU
ARM. Caso se deseje excluir temporariamente algum arquivo do processo de
compilao, pode-se clicar com o boto direito sobre o mesmo e selecionar Resource
44
Configurations
->
Exclude
from
Build....
Compile
projeto,
grave-o
no
45
3 INSTALAO DO RTOS
Inicialmente deve ser criado um novo projeto para este exemplo. Faa uma
cpia do projeto Teste da seo Programa para piscar LED. Nomeie o projeto
como RTOS.
O ncleo do FreeRTOS encontra-se basicamente nos seguintes arquivos:
list.c, queue.c e tasks.c, que esto no diretrio FreeRTOS\Source\. No
entanto para que o sistema operacional funcione, tambm necessrio um arquivo de
interface que especfico para cada famlia de microcontrolador. O arquivo de
interface utilizado com o ARM Cortex M3 est no diretrio FreeRTOS\Source\
portable\GCC\ARM_CM3\ e se chama port.c. Ainda necessrio um arquivo de
46
selecione
47
ao
projeto.
Eu
criei
atalho
dentro
das
pastas
virtuais
do
ncleo
do
sistema
operacional.
Outro
para
diretrio
48
cabealho de interface, e o ltimo para a pasta base do projeto, onde est o arquivo
de configurao que foi importado.
49
sizeof(pulStack)),
The initial stack pointer
The reset handler
Reserved
SVCall handler
Debug monitor handler
Reserved
The PendSV handler
The SysTick handler
GPIO Port A
Hibernate
50
Para testar o FreeRTOS ser escrito um programa que ter uma tarefa e
uma interrupo. A interrupo ser gerada por um timer, a cada segundo. A rotina
51
Esta varivel representa uma fila que ser usada para comunicao entre a
rotina de interrupo e a tarefa da serial. Para o uso de filas, o arquivo de cabealho
queue.h tambm deve ser includo.
Declare a funo ISRTimer adicionando o cdigo abaixo.
void ISRTimer(void){
/* Varivel para contagem dos segundos decorridos */
static unsigned long segundos=0;
/* Tarefa de prioridade mais alta foi desbloqueada? */
long tarefaPrioritariaDespertada;
/* Apaga interrupo do timer. Deve ser a primeira coisa a ser feita.*/
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
segundos++; /* Incrementa tempo */
/* Envia mensagem, informando tarefa da serial que se passou um segundo. */
xQueueSendToBackFromISR(filaInterfaceSerial, &segundos,
&tarefaPrioritariaDespertada);
}
52
53
funo
xQueueReceive.
Caso
haja
algum
elemento
na
fila
pasta
virtual
adicionando
atalho
para
arquivo.
cabealho
54
Como pode ser visto, inicialmente o timer configurado para uma frequncia
de 1 Hz e so habilitadas suas interrupes. muito importante que a prioridade da
interrupo do timer seja inferior ou igual (de nmero maior ou igual) a constante
configMAX_SYSCALL_INTERRUPT_PRIORITY, que est definida no arquivo
de configurao do FreeRTOS. Para que uma interrupo possa ter prioridade
maior, ela no deve utilizar as funes do sistema operacional. Para as funes de
configurao das interrupes so necessrios os cabealhos inc/hw_ints.h e
driverlib/interrupt.h.
Aps as configuraes do timer, inicializada a fila da interface serial, com
espao para no mximo dois elementos de tamanho unsigned long. A seguir criada
a
tarefa
da
interface
serial,
com
uma
pilha
de
tamanho
55
56
leituras/escritas nos registradores do mesmo. Por sorte, este arquivo fornecido pelo
pacote StellarisWare e no precisa ser alterado. J os outros arquivos, embora
presentes no pacote StellarisWare, necessitaro de alteraes.
Aps extrair os arquivos do LwIP, copie a pasta ports (presente no
diretrio \Dev\StellarisWare\thir_party\lwip-1.3.2\) para a pasta do LwIP
(\Dev\LWIP). A estrutura do novo diretrio criado dever ficar assim:
-> \LWIP\ports\stellaris
* perf.c
* sys_arch.c
-> include\
-> arch\
* bpstruct.h
* cc.h
* epstruct.h
* perf.h
* sys_arch.h
-> netif\
* stellarisif.h
-> netif\
* stellarisif.c
57
as
pastas
Ethernet\LWIP\src\core\ipv6
Ethernet\LWIP\src\
include\ipv6.
Agora podem ser feitas as alteraes nos arquivos de interface sys_arch.c,
sys_arch.h e cc.h. Abra-os pelo Eclipse e substitua seus contedos pelos cdigos
58
/Ethernet/LWIP/src/include
seguindo
procedimento
da
e
seo
59
StellarisWare
(no
diretrio
\Dev\StellarisWare\boards\ek-lm3s8962\
041:
054:
138:
160:
161:
163:
291:
376:
378: #endif
397: #define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE...
220:
268:
269:
270:
280:
281:
282:
283:
323:
#define
#define
#define
#define
#define
#define
#define
#define
#define
TCP_SND_QUEUELEN (4 * (TCP_SND_BUF/TCP_MSS))
TCPIP_THREAD_STACKSIZE 1024
TCPIP_THREAD_PRIO 3
TCPIP_MBOX_SIZE 6
DEFAULT_RAW_RECVMBOX_SIZE 6
DEFAULT_UDP_RECVMBOX_SIZE 6
DEFAULT_TCP_RECVMBOX_SIZE 6
DEFAULT_ACCEPTMBOX_SIZE 6
SYS_STATS 0
padres,
podem
ser
vistas
no
arquivo
de
cabealho
\Dev\LWIP\src\include\lwip\opt.h.
Agora, crie dois novos arquivos de cdigo fonte e seus respectivos cabealhos
na pasta Ethernet. Nomeie-os como Ethernet.c, Ethernet.h, Servidor.c e
Servidor.h. Todos os arquivos esto anexados ao PDF.
60
61
xSemaphoreGiveFromISR(EthernetISRSemaphore, &higherPriorityTaskWoken);
/* Desabilita temporariamente as interrupes da ethernet. Quando
* dados forem passados adiante pela tarefa de interrupo, as
* interrupes sero rehabilitadas. */
EthernetIntDisable(ETH_BASE, ETH_INT_RX | ETH_INT_TX);
/* Caso alguma tarefa tenha acordado com a liberao do semforo,
* executa chaveamento de tarefas. */
if (higherPriorityTaskWoken) vPortYieldFromISR();
}
/*
* Inicializa interface ethernet.
*/
void EthernetInicializa(void){
unsigned long UserRegister0, UserRegister1;
unsigned char MACAddress[8];
// Habilita e reseta o controlador Ethernet.
SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
// Habilita LEDs para ETHERNET.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3);
// Endeo MAC obtido do registrador do usurio.
FlashUserGet(&UserRegister0, &UserRegister1);
MACAddress[0] = ((UserRegister0 >> 0) & 0xff);
MACAddress[1] = ((UserRegister0 >> 8) & 0xff);
MACAddress[2] = ((UserRegister0 >> 16) & 0xff);
MACAddress[3] = ((UserRegister1 >> 0) & 0xff);
MACAddress[4] = ((UserRegister1 >> 8) & 0xff);
MACAddress[5] = ((UserRegister1 >> 16) & 0xff);
// Grava o endereo MAC no controlador Ethernet.
EthernetMACAddrSet(ETH_BASE, (unsigned char *)MACAddress);
/* Inicializa a pilha TCP, cria tarefa que gerencia a pilha e define
* callback para finalizao da inicializao da interface Ethernet.
* A funo de callback ser chamada de dentro do contexto da tarefa
* do LwIP quando o escalonador estiver rodando. */
tcpip_init(EthernetInitCallback, NULL);
/* Cria a tarefa que controlar o servidor TCP */
xTaskCreate(ServidorTask, ( signed portCHAR * ) "ServidorTCP",
SERVIDOR_STACK_SIZE, NULL, SERVIDOR_TASK_PRIORITY, NULL);
}
/*
* Termina a inicializao da interface Ethernet.
*/
static void EthernetInitCallback(void * param) {
struct ip_addr IPAddress, NetMask, GatewayAddress;
static struct netif NetworkInterfaceDescriptor;
extern err_t stellarisif_init(struct netif *netif);
/* Cria semforo para sincronismo do acesso ao controlador ethernet. */
62
sys_sem_new(&EthernetISRSemaphore, 1);
/* Cria tarefa que trata as interrupes da interface ethernet.
* Essa tarefa armazena os dados recebidos e os transmite para a
* tarefa que gerencia a pilha. */
xTaskCreate(EthernetInterruptTask, (signed portCHAR *)"eth_int",
ETHERNET_ISRTHREAD_STACKSIZE, &NetworkInterfaceDescriptor,
ETHERNET_ISRTHREAD_PRIO, 0);
/* Inicializa structs de endereo IP, Mscara de sub-rede e Gateway. */
IP4_ADDR(&IPAddress, ETHERNET_IPADDR0, ETHERNET_IPADDR1, ETHERNET_IPADDR2,
ETHERNET_IPADDR3);
IP4_ADDR(&GatewayAddress, ETHERNET_GATEWAY_ADDR0, ETHERNET_GATEWAY_ADDR1,
ETHERNET_GATEWAY_ADDR2, ETHERNET_GATEWAY_ADDR3);
IP4_ADDR(&NetMask, ETHERNET_NET_MASK0, ETHERNET_NET_MASK1,
ETHERNET_NET_MASK2, ETHERNET_NET_MASK3);
/* Inicializa interface de rede. */
netif_add(&NetworkInterfaceDescriptor, &IPAddress, &NetMask,
&GatewayAddress, NULL, stellarisif_init, tcpip_input);
/* Configura interface como padro. */
netif_set_default(&NetworkInterfaceDescriptor);
/* Inicia interface. */
netif_set_up(&NetworkInterfaceDescriptor);
}
63
contexto da tarefa tcpip. Na ltima linha da funo criada a tarefa que controla o
servidor, onde deve estar o cdigo do usurio, que efetivamente utilizar a interface
ethernet.
EthernetInitCallback(): Funo que ser chamada de dentro da tarefa principal
da pilha tcpip para finalizao das configuraes. Aqui ser criada a tarefa de
interrupo da ethernet, bem como o semforo utilizado nas interrupes.
No arquivo Ethernet.h, insira as seguintes definies:
Ethernet.h
Este arquivo tambm foi includo como anexo no documento em PDF.
/* Tamanho da pilha da tarefa que recebe os
* dados da ISR. */
#define ETHERNET_ISRTHREAD_STACKSIZE 256
/* Prioridade da tarefa que recebe os dados
* da ISR. */
#define ETHERNET_ISRTHREAD_PRIO 3
/* The IP address being used. */
#define ETHERNET_IPADDR0
#define ETHERNET_IPADDR1
#define ETHERNET_IPADDR2
#define ETHERNET_IPADDR3
172
17
5
150
172
17
5
194
255
255
255
0
void EthernetInicializa(void);
64
65
66
Servidor.h
Este arquivo tambm foi includo como anexo no documento em PDF.
/* Tamanho da pilha da tarefa que controla o servidor TCP */
#define SERVIDOR_STACK_SIZE 256
/* Prioridade da tarefa que controla o servidor TCP */
#define SERVIDOR_TASK_PRIORITY 2
/* Porta utilizada pelo servidor TCP */
#define SERVIDOR_PORTA 80
/* Prottipos de funes. */
void ServidorTask(void* Parametros);
varivel
global
xQueueHandle
filaInterfaceSerial
as
funes
no
incio
do
arquivo
adicione
diretiva
#include
67
Esta funo far com que o estado do LED se altere a cada trs segundos.
Assim, caso exista algum problema no programa e o sistema venha a travar, isso
ficar evidente para o usurio. Tanto a funo vApplicationTickHook() quanto a
funo de tratamento de conexes do servidor utilizam a varivel global ledLigado
para identificar o estado atual do LED. Isso no recomendado, pois as operaes
que acessam esta varivel, no servidor ethernet, no so atmicas. O ideal seria
proteger o acesso a varivel por meio de um semforo, o que no foi feito para
simplificar o cdigo.
A verso final do arquivo main.c se encontra no APNDICE E e tambm
foi includo como anexo a este PDF.
68
69
REFERNCIAS
70
71
main.c
Este arquivo tambm foi includo como anexo no documento em PDF com o nome
FreeRTOSmain.c.
/*
* main.c
*
* Created on: 06/06/2012
*
Author: Mr. Burns
*/
/* Stellaris Includes */
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "utils/uartstdio.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "task.h"
#include "queue.h"
xQueueHandle filaInterfaceSerial;
void ISRTimer(void){
/* Varivel para contagem dos segundos decorridos */
static unsigned long segundos=0;
/* Flag que informa se alguma tarefa de prioridade mais alta que aguardava
mensagens
* foi desbloqueada com o envio da mensagem. Neste caso, esta varivel no
ser
* utilizada, mas poderia ser til para execuo de um chaveamento de
tarefas. */
long tarefaPrioritariaDespertada;
/* Apaga interrupo do timer. O ideal que isso seja a primeira coisa a
ser feita.*/
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
segundos++; /* Incrementa tempo */
/* Envia mensagem, informando tarefa da serial que se passou um segundo. */
xQueueSendToBackFromISR(filaInterfaceSerial, &segundos,
&tarefaPrioritariaDespertada);
}
void TarefaSerial(void *pvParameters)
{
unsigned short segundos;
unsigned char flagLEDLigado = false;
/* Habilita drivers do GPIO F (utilizado pelo LED). */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
72
73
while(1);
}
void vApplicationTickHook( void )
{
}
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR
*pcTaskName )
{
for( ;; );
}
74
75
sys_arch.c
Este arquivo tambm foi includo como anexo no documento em PDF.
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Modifications Copyright (c) 2006 Christian Walter <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
*
this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*
this list of conditions and the following disclaimer in the documentation
*
and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
*
derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <[email protected]>
*
*/
/**
* This file is derived from the file provided by the FreeRTOS lwip_MCF5235_GCC
demo.
*/
/* Standart includes */
#include <stdio.h>
/* lwIP includes. */
#include "lwip/opt.h"
#include "lwip/sys.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Structure needed for the creation of a linked list that
* holds the handles for all the tasks created by LwIP. */
typedef struct sys_tcb {
76
77
78
79
80
81
/* We disable the FreeRTOS scheduler because it might be the case that the new
* tasks gets scheduled inside the xTaskCreate function. To prevent this we
* disable the scheduling. Note that this can happen although we have
interrupts
* disabled because xTaskCreate contains a call to taskYIELD( ).
*/
vPortEnterCritical();
p = tasks;
i = 0;
/* We are called the first time. Initialize it. */
if( p == NULL ){
p = pvPortMalloc( sizeof( sys_tcb_t ) );
if( p != NULL ){
tasks = p;
}
} else {
/* First task already counter. */
i++;
/* Cycle to the end of the list. */
while( p->next != NULL ){
i++;
p = p->next;
}
p->next = pvPortMalloc( sizeof( sys_tcb_t ) );
p = p->next;
}
if( p != NULL ){
/* Memory allocated. Initialize the data structure. */
p->next = NULL;
p->pid = ( xTaskHandle )0;
( void )snprintf( thread_name, configMAX_TASK_NAME_LEN, "lwIP%d", i );
/* Now q points to a free element in the list. */
if( xTaskCreate(thread, (signed char*)thread_name, stacksize, arg, prio,
&p->pid ) == pdPASS ){
thread_hdl = p;
}else{
vPortFree( p );
}
}
vPortExitCritical(
return thread_hdl;
);
}
/**
* Removes a thread.
*
* @param hdl is a handle for the thread to be removed.
*/
void sys_arch_thread_remove( sys_thread_t hdl ) {
sys_tcb_t
*current = tasks, *prev;
sys_tcb_t
*toremove = hdl;
xTaskHandle
pid = ( xTaskHandle ) 0;
82
83
84
sys_arch.h
Este arquivo tambm foi includo como anexo no documento em PDF.
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
*
this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*
this list of conditions and the following disclaimer in the documentation
*
and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
*
derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <[email protected]>
*
*/
#ifndef __ARCH_SYS_ARCH_H__
#define __ARCH_SYS_ARCH_H__
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* NULL
#define
#define
#define
Handles. */
SYS_MBOX_NULL
SYS_THREAD_NULL
SYS_SEM_NULL
( xQueueHandle )0
NULL
( xSemaphoreHandle )0
85
86
87
cc.h
Este arquivo tambm foi includo como anexo no documento em PDF.
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
*
this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*
this list of conditions and the following disclaimer in the documentation
*
and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
*
derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <[email protected]>
*
*/
#ifndef __CC_H__
#define __CC_H__
#ifdef DEBUG
#define U8_F "c"
#define S8_F "c"
#define X8_F "x"
#define U16_F "u"
#define S16_F "d"
#define X16_F "x"
#define U32_F "u"
#define S32_F "d"
#define X32_F "x"
#define STZ_F "uz"
#endif
typedef
typedef
typedef
typedef
typedef
typedef
typedef
unsigned
signed
unsigned
signed
unsigned
signed
u32_t
char
char
short
short
long
long
u8_t;
s8_t;
u16_t;
s16_t;
u32_t;
s32_t;
mem_ptr_t;
88
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
/* Macro to display debug and trace messages. */
#ifndef LWIP_PLATFORM_DIAG
#include "utils/uartstdio.h"
#define LWIP_PLATFORM_DIAG(msg) UARTprintf msg;
#endif
/* Macro to display error message and call the error handler function. */
#ifndef LWIP_PLATFORM_ASSERT
#ifdef DEBUG
extern void __error__(char *pcFilename, unsigned long ulLine);
#define LWIP_PLATFORM_ASSERT(msg)
\
{
\
UARTprintf(msg);
\
__error__(__FILE__, __LINE__);
\
}
#else
#define LWIP_PLATFORM_ASSERT(msg)
#endif
#endif
#include <stdlib.h>
#define LWIP_RAND() ((u32_t)rand())
#endif /* __CC_H__ */
89
90
main.c
Este arquivo tambm foi includo como anexo no documento em PDF com o nome
LwIPmain.c.
/*
* main.c
*
* Created on: 06/06/2012
*
Author: Mr. Burns
*/
/* Stellaris Includes */
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "utils/uartstdio.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "task.h"
#include "queue.h"
/* User includes. */
#include "Ethernet/Ethernet.h"
unsigned char ledLigado = true;
int main(){
/* Configura Clock para 50 MHz. */
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_8MHZ);
/* Configura LED */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 1);
/* Inicializa a interface ethernet e cria tarefas da pilha TCP/IP.
* Sero criadas trs tarefas:
*
- tcpip_thread: Tarefa que controla a pilha TCP/IP.
*
- eth_int: Tarefa que recebe os dados e os envia para a
*
tarefa principal quando ocorrem interrupes da ethernet.
*
- ServidorTCP: Tarefa que atualiza os LEDs quando algum
*
cliente se conecta. */
EthernetInicializa();
/* Inicia escalonador do FreeRTOS. */
vTaskStartScheduler();
/* No deve chegar aqui. */
while(1);
}
void vApplicationTickHook( void )
{
static unsigned long Contador=0;
91
Contador++;
if(Contador == 3000){
if (ledLigado){
/* Desliga LED. */
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0);
ledLigado = false;
} else {
/* Liga LED. */
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 1);
ledLigado = true;
}
Contador = 0;
}
}
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR
*pcTaskName )
{
for( ;; );
}