Contiki操作系统移植STM32F103基于Keil编程软件

来源:互联网 发布:电脑连不上有线网络 编辑:程序博客网 时间:2024/06/07 09:36
Tips:实现了contiki移植到stm32f103上,并实现了流水灯

一、contiki简介

  刚开始当然是先简单介绍下contiki了。Contiki 是一个小型的,开源的,极易移植的多任务操作系统。它专门设计以适用于一系列的内存优先的网络系统,包括从8位电脑到微型控制器的嵌入系统。它的名字来自于托尔·海尔达尔的康提基号。Contiki只需几kilobyte的代码和几百字节的内存就能提供多任务环境和内建TCP/IP支持——维基百科。

二、移植前准备

  • 基础stm32f103的开发板、下载器等。我用的是原子的stm32f103的开发板。
  • keil软件。我的是mdk5。
  • contiki源码。我用的版本是3.0。github上直接克隆就好了,地址我就不放了,相信都能找到。

三、开始移植

首先自己建立一个stm32f103的基本模板,要确保能够正常使用。
先上我自己的工程模板的图
工程模板
我的keil打开文件放在USER中。

  • 工程根目录新建文件夹contiki用于存放contiki移植相关源码
  • contiki文件夹下新建文件夹core、cpu
  • contiki源码文件夹下core所有文件copy到工程目录/contiki/core
  • contiki源码文件夹下cpu/arm/stm32f103所有文件copy到工程目录/contiki/cpu下
  • contiki源码文件夹下platform/stm32test文件下下的contiki-conf.h、contiki-main.c文件copy到工程目录/USER,将原本的main.c删除,相当于替换
  • 打开工程,添加相应文件和include路径。
    contiki_cpu的文件在cpu文件夹下
    contiki_core的文件在contiki/core/sys下
    我自己的目录和路径如下图
    这里写图片描述
    这里写图片描述

按照常规,移植需要修改相应的时钟文件和中断服务,contiki相对简单一点,需要把clock.c修改一下,先在clock源文件中添加头文件

include “stm32f10x.h”
include “stm32f10x_it.h”
删除原来的
include<stm32f10x_map.h>
include <nvic.h>
把systick初始化改成

voidclock_init(){    if (SysTick_Config(SystemCoreClock / CLOCK_SECOND))    {        while(1);    }//    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;}

把systick中断改为

voidSysTick_Handler(void){    current_clock++;    if(etimer_pending()&& etimer_next_expiration_time()<= current_clock) {        etimer_request_poll();        // printf("%d,%d\n",clock_time(),etimer_next_expiration_time     ());    }    if (--second_countdown== 0) {        current_seconds++;        second_countdown = CLOCK_SECOND;    }}

最后,把stm32f10x_it.c的void SysTick_Handler(void){}删除
clock.c就变成了这样

#include "stm32f10x.h"#include "stm32f10x_it.h"#include <sys/clock.h>#include <sys/cc.h>#include <sys/etimer.h>static volatile clock_time_t current_clock = 0;static volatile unsigned long current_seconds = 0;static unsigned int second_countdown = CLOCK_SECOND;//void//SysTick_handler(void) __attribute__ ((interrupt));voidSysTick_Handler(void){    current_clock++;    if(etimer_pending()&& etimer_next_expiration_time()<= current_clock) {        etimer_request_poll();        // printf("%d,%d\n",clock_time(),etimer_next_expiration_time     ());    }    if (--second_countdown== 0) {        current_seconds++;        second_countdown = CLOCK_SECOND;    }}voidclock_init(){    if (SysTick_Config(SystemCoreClock / CLOCK_SECOND))    {        while(1);    }//    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;}clock_time_tclock_time(void){  return current_clock;}#if 0/* The inner loop takes 4 cycles. The outer 5+SPIN_COUNT*4. */#define SPIN_TIME 2 /* us */#define SPIN_COUNT (((MCK*SPIN_TIME/1000000)-5)/4)#ifndef __MAKING_DEPS__voidclock_delay(unsigned int t){#ifdef __THUMBEL__   asm volatile("1: mov r1,%2\n2:\tsub r1,#1\n\tbne 2b\n\tsub %0,#1\n\tbne 1b\n":"=l"(t):"0"(t),"l"(SPIN_COUNT));#else#error Must be compiled in thumb mode#endif}#endif#endif /* __MAKING_DEPS__ */unsigned longclock_seconds(void){  return current_seconds;}

观察contiki-main.c的源码。发现头件#include<stm32f10x_map.h>、#include <gpio.h>、include<nvic.h>,替换成#include <stm32f10x.h>,如果使用debug-uart.c就把头文件一样替换掉,不使用直接删除debug-uart.c即可。我没有使用它的DMA方式,所以直接重写了debug文件。但是串口还没使用,所以不知道对不对。

//#include <stm32f10x_map.h>#include <stm32f10x.h>//#include <stm32f10x_dma.h>//#include <gpio.h>//#include <nvic.h>#include <stdint.h>#include <stdio.h>#include <debug-uart.h>#include <sys/process.h>#include <sys/procinit.h>#include <etimer.h>#include <sys/autostart.h>#include <clock.h>unsigned int idle_count = 0;intmain(){  dbg_setup_uart();  printf("Initialising\n");  clock_init();  process_init();  process_start(&etimer_process, NULL);  autostart_start(autostart_processes);  printf("Processes running\n");  while(1) {    do {    } while(process_run() > 0);    idle_count++;    /* Idle! */    /* Stop processor clock */    /* asm("wfi"::); */   }  return 0;}
#include <debug-uart.h>#include <string.h>#include <stm32f10x.h>#include <stm32f10x_it.h>#include <stdint.h>#include <stdio.h>void  dbg_setup_uart(void)  {      USART_InitTypeDef USART_InitStructure;      GPIO_InitTypeDef GPIO_InitStructure;      //使能GPIOA时钟      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA                          | RCC_APB2Periph_USART1 ,ENABLE);        //PA9 TX1 复用推挽输出      GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;      GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;      GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;      GPIO_Init(GPIOA,&GPIO_InitStructure);      //PA10 RX1 浮动输入      GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;      GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;      GPIO_Init(GPIOA,&GPIO_InitStructure);      USART_InitStructure.USART_BaudRate= 9600;      USART_InitStructure.USART_WordLength= USART_WordLength_8b;      USART_InitStructure.USART_StopBits= USART_StopBits_1;      USART_InitStructure.USART_Parity= USART_Parity_No;      USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;      USART_InitStructure.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;      USART_Init(USART1,&USART_InitStructure);      //使能USART1      USART_Cmd(USART1,ENABLE);    }  int fputc(int ch, FILE* f)  {    USART_SendData(USART1,(uint8_t)ch);      while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET );      return ch;  }  

完成后发现编译有错误
编译错误
从contiki-main.c头文件进入autostart.h文件,添加#define AUTOSTART_ENABLE 1 ,宏定义。修改procinit.c,extern const struct process *procinit[];修改为const struct process *procinit[];
编译后发现还有autostart错误,暂时先不管,先编写自己的led功能,经过编写后contiki-main.c文件如下:

#include <stm32f10x.h>#include <stm32f10x_dma.h>#include <stdint.h>#include <stdio.h>#include <debug-uart.h>#include <sys/process.h>#include <sys/procinit.h>#include <etimer.h>#include <sys/autostart.h>#include <clock.h>#define Contiki_etimer_DelayMS(MS) \    etimer_set(&et, MS/(1000/CLOCK_SECOND)); \    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et))unsigned int idle_count = 0;static void led_init(void);PROCESS(led_blink_process, "Led");PROCESS_THREAD(led_blink_process, ev, data);AUTOSTART_PROCESSES(&led_blink_process);int main(){    dbg_setup_uart();    led_init();    clock_init();    process_init();    process_start(&etimer_process, NULL);    autostart_start(autostart_processes);    process_start(&led_blink_process, NULL);    while(1) {        do {        } while(process_run() > 0);        idle_count++;        /* Idle! */        /* Stop processor clock */        /* asm("wfi"::); */    }    return 0;}void led_init(void){    GPIO_InitTypeDef GPIO_Initstructure;    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_8;    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOA, &GPIO_Initstructure);    GPIO_SetBits(GPIOA, GPIO_Pin_8);    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_2;    GPIO_Init(GPIOD, &GPIO_Initstructure);    GPIO_SetBits(GPIOD, GPIO_Pin_2);}PROCESS_THREAD(led_blink_process, ev, data){    static struct etimer et;    PROCESS_BEGIN();    while(1)    {        GPIO_ResetBits(GPIOA, GPIO_Pin_8);        GPIO_SetBits(GPIOD, GPIO_Pin_2);        Contiki_etimer_DelayMS(500);        GPIO_SetBits(GPIOA, GPIO_Pin_8);        GPIO_ResetBits(GPIOD, GPIO_Pin_2);        Contiki_etimer_DelayMS(500);    }    PROCESS_END();}

编译后发现没错,下载到单片机,led成功点亮并跑马灯了!!! 移植还是很简单的吧?!!!

阅读全文
0 0
原创粉丝点击