单片机
返回首页

MSP430G2553 移植 Contiki RTOS 实时操作系统

2022-07-20 来源:csdn

平台:Code Composer Studio 10.4.0

MSP-EXP430G2 LaunchPad 试验板

MSP430G2553 LaunchPad™ Development Kit (MSP‑EXP430G2ET)


contiki下载:contiki-os Github

本文参考自二、Contiki移植 —— 一根线


本工程示例


新建工程

在这里插入图片描述


移植过程

新建contiki文件夹

在这里插入图片描述

添加core、cpu文件夹

在这里插入图片描述

将Github下载的contiki/core内如下文件复制进刚建好的core文件夹

在这里插入图片描述

dev内仅保留watchdog.h

lib内仅保留list.c、list.h

在这里插入图片描述

把建好的core文件夹加入路径

在这里插入图片描述

core内新建contiki-conf.h

在这里插入图片描述

其内容为


#ifndef CONTIKI_CONF_H_

#define CONTIKI_CONF_H_


#include


#define CCIF

#define CLIF


#define NETSTACK_CONF_WITH_IPV4 1

#define WITH_ASCII 1


#define CLOCK_CONF_SECOND 100


/* These names are deprecated, use C99 names. */

typedef uint8_t u8_t;

typedef uint16_t u16_t;

typedef uint32_t u32_t;

typedef int8_t s8_t;

typedef int16_t s16_t;

typedef int32_t s32_t;


typedef unsigned int clock_time_t;

typedef unsigned int uip_stats_t;


#ifndef BV

#define BV(x) (1<<(x))

#endif


/* uIP configuration */

#define UIP_CONF_LLH_LEN         0

#define UIP_CONF_BROADCAST       1

#define UIP_CONF_LOGGING 1

#define UIP_CONF_BUFFER_SIZE 116


#define UIP_CONF_TCP_FORWARD 1


/* Prefix for relocation sections in ELF files */

#define REL_SECT_PREFIX '.rel'


#define CC_BYTE_ALIGNED __attribute__ ((packed, aligned(1)))


#define USB_EP1_SIZE 64

#define USB_EP2_SIZE 64


#define RAND_MAX 0x7fff

#endif /* CONTIKI_CONF_H_ */


contiki.h 中加入


#include


#define  dint() __disable_interrupt()

#define  eint() __enable_interrupt()

在这里插入图片描述

cpu文件夹内新建msp430文件夹

在这里插入图片描述

将Github下载的contiki/cpu/msp430内如下文件复制进刚建好的msp430文件夹

在这里插入图片描述

将Github下载的contiki/cpu/msp430/f1xxx内如下文件复制进刚建好的msp430文件夹

在这里插入图片描述

将刚建好的msp430文件夹加入路径

在这里插入图片描述

按下小锤子编译,此时有这些错误

在这里插入图片描述

将中断服务函数修改为CCS的风格:

watchdog.c中

修改前

在这里插入图片描述

修改后

在这里插入图片描述

rtimer-arch.c中

修改前

在这里插入图片描述

修改后

在这里插入图片描述

clock.c中:

修改前

在这里插入图片描述

修改后

在这里插入图片描述

clock.c中此处提到CLOCK_CONF_SECOND需为2的整数幂

在这里插入图片描述

到contiki-conf.h中修改后屏蔽掉#error语句

在这里插入图片描述
在这里插入图片描述

再次编译,此时仅剩compower.c内有错误

在这里插入图片描述

将compower.c、compower.h(暂时用不到)删除后再编译,此时已经没有错误了

在这里插入图片描述

关于时间

因我的开发板未焊上外部晶振,故ACLK时钟源只能选为内部低频振荡器 VLO,其标称值是 12kHz, 受温度和供电电压影响(范围 4kHz~20kHz)

本移植案例中,Contiki的时基由定时器A0的中断控制。

本示例中,将TA0的时钟源设为ACLK,将P1.0复用输出测得ACLK频率约为16k:


//-----在P1.0上输出ACLK----

P1SEL |= BIT0;

P1DIR |= BIT0;

在这里插入图片描述

将rtimer-arch.h中的RTIMER_ARCH_SECOND设为16000U

在这里插入图片描述

修改clock.c的条件编译语句,注释掉#error语句

在这里插入图片描述

void

clock_init(void)

{

  dint();


  /* Select SMCLK (2.4576MHz), clear TAR */

  /* TACTL = TASSEL1 | TACLR | ID_3; */


  /* Select ACLK 32768Hz clock, divide by 2 */

  /*  TACTL = TASSEL0 | TACLR | ID_1;*/


  /* Select ACLK 32768Hz clock */

  /* TACTL = TASSEL0 | TACLR; */


#if INTERVAL==32768/CLOCK_SECOND

  TACTL = TASSEL0 | TACLR;

#elif INTERVAL==16384/CLOCK_SECOND

  TACTL = TASSEL0 | TACLR | ID_1;

#else

  TACTL = TASSEL_1 | TACLR | ID_0; //TA0时钟源设为ACLK,不分频

  TACCR0 = RTIMER_ARCH_SECOND;

//#error NEED TO UPDATE clock.c to match interval!

#endif


  /* Initialize ccr1 to create the X ms interval. */

  /* CCR1 interrupt enabled, interrupt occurs when timer equals CCR. */

  TACCTL1 = CCIE;


  /* Interrupt after X ms. */

  TACCR1 = INTERVAL;


  /* Start Timer_A in continuous mode. */

  TACTL |= MC1;


  count = 0;


  /* Enable interrupts. */

  eint();


}


多任务示例

两个任务分别反转LED1、LED2,它们延时的时间互不相同,LED1为1s,LED2为0.5s。


main.c

#include  


#include

#include

#include

#include

#include


unsigned int idle_count = 0;


#define Contiki_etimer_DelayMS(MS)

    etimer_set(&et, MS/(1000/CLOCK_SECOND));

    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et))


PROCESS(led1_blink_process, 'Led1');

AUTOSTART_PROCESSES(&led1_blink_process);


PROCESS_THREAD(led1_blink_process, ev, data)

{

    static struct etimer et;

    PROCESS_BEGIN();

    while(1)

    {

    P1OUT |= BIT0; // set P1.0

        Contiki_etimer_DelayMS(1000);

        P1OUT &= ~BIT0; // reset

        Contiki_etimer_DelayMS(1000);

    }

    PROCESS_END();

}


PROCESS(led2_blink_process, 'Led2');

AUTOSTART_PROCESSES(&led2_blink_process);


PROCESS_THREAD(led2_blink_process, ev, data)

{

    static struct etimer et;

    PROCESS_BEGIN();

    while(1)

    {

    P1OUT |= BIT6; // set P1.6

        Contiki_etimer_DelayMS(500);

        P1OUT &= ~BIT6; // reset

        Contiki_etimer_DelayMS(500);

    }

    PROCESS_END();

}


/**

 * main.c

 */

int main(void)

{

WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer


//16Mhz

if (CALBC1_16MHZ==0xFF) // If calibration constant erased

{

while(1); // do not load, trap CPU!!

}

DCOCTL = CALDCO_16MHZ; // 调取出厂校准后存储在Flash中的参数

BCSCTL1 = CALBC1_16MHZ; // 将DCO设为16MHz

BCSCTL2 |= DIVM_0 | DIVS_0; // MCLK、SMCLK均不分频

BCSCTL3 |= LFXT1S1; // 将ACLK时钟源设为内部低频振荡器, 其标称值是 12kHz, 受温度和供电电压影响(范围 4kHz~20kHz)


// //-----在P1.0上输出ACLK----

// P1SEL |= BIT0;

// P1DIR |= BIT0;


//-----在P1.4上输出SMCLK----

P1SEL |= BIT4;

P1DIR |= BIT4;


P1DIR |= BIT0;              // Set P1.0 to output direction

P1DIR |= BIT6;              // Set P1.6 to output direction


clock_init();

process_init();

process_start(&etimer_process, NULL);

// autostart_start(autostart_processes);


process_start(&led1_blink_process, NULL);

process_start(&led2_blink_process, NULL);


while(1)

{

    do

    {


    } while(process_run() > 0);

    idle_count++;

    /* Idle! */

    /* Stop processor clock */

    /* asm('wfi'::); */

  }

return 0;

}


内存使用情况

在这里插入图片描述

效果

LED1:理论1s 实测1.097s 误差9.7%

在这里插入图片描述

LED2:理论0.5s 实测0.547s 误差9.4%

在这里插入图片描述

在这里插入图片描述


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章