学习是一个漫长的过程,很早之前我们都是按照网络教程进行移植CONTIKI 2.7或CONTIKI 3.0,方法都是大同小意,最后的OS是被裁减只有CONTIKI内核调度了。
对此我就很不爽了,一个好好的OS怎么能移植成这样??于是我下载了最新的CONTIKI NG-DEVELOP,再一次在IAR进行NG的移植,要保留linux下全功能组件!!!
首先我不移植RF功能,和NET网络功能。并且让我高兴的是,把TICC2538的UARTprintf功能移植进OS里面,这个UARTprintf带环形缓冲功能。
发现明显提升了OS处理能力,从此printf信息不在影响OS效率。在IAR进行全功能的移植方法教程,不想去写教程了,挺麻烦又复杂,实不好意思!主要加深自己的记忆。
打开ng4.5-develop\arch\cpu\arm的arm-def.h,更改CLOCK_CONF_SECOND,使它为5MS一个tick.原来7.8ms太长了不喜欢
/** * \name Macros and typedefs * * Those values are not meant to be modified by the user * @{ */ #define CLOCK_CONF_SECOND 200 //128 高频测试性能,设为5MS一个tick /* Clock (time) comparison macro */ #define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) /* Platform typedefs */ typedef uint32_t clock_time_t; typedef uint32_t uip_stats_t;
在默认的SYSCLCK是16M的,我们改成32M的最高主频,发挥CPU最高性能
打开ng4.5-develop\examples\MYdemo\user\inc的cc2538-conf.h
/** * \name Security * * @{ */ #ifndef CRYPTO_CONF_INIT #define CRYPTO_CONF_INIT 1 /**< Whether to init cryptoprocessor */ #endif #ifndef AES_128_CONF #define AES_128_CONF cc2538_aes_128_driver /**< AES-128 driver */ #endif #ifndef CCM_STAR_CONF #define CCM_STAR_CONF cc2538_ccm_star_driver /**< AES-CCM* driver */ #endif //测试,将默认的16M系统时钟,改成32MHZ看看 ,20200913 #define SYS_CTRL_CONF_SYS_DIV SYS_CTRL_CLOCK_CTRL_SYS_DIV_32MHZ
好了,现在主频上升到了32MHZ,TICK也从7.8MS上升到了5MS,是更好的性能测试配置,如果是电池应用的产品话,请别这么做呀,电量耗不起的,因为要运行3年 5年的电池产品条件约束。
给出我的contiki-main.c
/*---------------------------------------------------------------------------*/ /* * \ addtogroup: Contiki NG操作系统,设计初心是注重【稳定】和【安全】。 * \ 它的前身是CONTIKI 3.0,官方表示NG是3.0的一个分支,是下一代IOT系统 * @{ */ /*---------------------------------------------------------------------------*/ /* * \file: 日期:2020-09-05 作者:李* * * Implementation of \os's main routine: * 原汁原味的CONTIKI NG系统,可能是首次在IAR移植成功、并拥有全功能的NG系统__Jian */ /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/leds.h" //测试1 #include "contiki-net.h" #include "sys/node-id.h" #include "sys/platform.h" #include "sys/energest.h" #include "nullmac.h " #include "dev/watchdog.h" #include "uart.h" #include "serial-line.h" #include "net/queuebuf.h" #include "net/app-layer/coap/coap-engine.h" #include "net/app-layer/snmp/snmp.h" #include "services/rpl-border-router/rpl-border-router.h" #include "services/orchestra/orchestra.h" #include "services/shell/serial-shell.h" #include "services/simple-energest/simple-energest.h" #include "services/tsch-cs/tsch-cs.h" #include <stdio.h> #include <stdint.h> /*---------------------------------------------------------------------------*/ /* Log configuration */ #include "sys/log.h" /* line:57用到cc2538-dev 的 sys_ctrl_get_sys_clock() 功能*/ #include "sys-ctrl.h" #define LOG_MODULE "Main" #define LOG_LEVEL LOG_LEVEL_MAIN /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void main(void) { TIprintf(); //标准库的移植UARTprintf, UARTprintf("....UARTprintf TEST\r\n"); //测试TIprintf(),可以在RA1看到打印信号 UARTprintf("0...UARTprintf TEST PASS\r\n"); //说明这个功能是OK的 UARTprintf("IAR8.40.2 AND WIN7 64bit FOR CONTIKI NG!!\r\n"); UARTprintf("SYSCLCK FOR cc2538:%dHz\r\n",sys_ctrl_get_sys_clock()); //开始CONTIKI NG platform_init_stage_one(); clock_init(); rtimer_init(); process_init(); process_start(&etimer_process, NULL); ctimer_init(); platform_init_stage_two(); //出错??void HardFault_Handler(void) 已经//掉了RF platform_init_stage_three(); /* 运行自启动模式的线程,AUTOSTART_ENABLE 1,一般在contiki-conf.h进行配置 */ autostart_start(autostart_processes); /* 手动开启进程 */ // process_start(&hello_world_process, NULL); UARTprintf("CONTIKI START!!\r\n"); //开始OS事件调度 while(1) { uint8_t r; do { r = process_run(); watchdog_periodic(); //喂狗 } while(r > 0); platform_idle(); //无事件时进入低功耗 } }
给出测试进程事件源码,在ng4.5-develop\examples\MYdemo\AUTO_processes的AUTO_processes.c,我自建的方便测试用
#include "contiki.h" #include "dev/leds.h" //测试1 #include <stdio.h> /* For printf() */ /***************************************************************************** hello-world.c 1--》从hello-world例程中移过来测试的。与GpioIputOutputTest共同测试PRINTF 打印缓冲的能力。 *******************************************************************************/ /*---------------------------------------------------------------------------*/ PROCESS(hello_process, "Hello process"); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(hello_process, ev, data) { static struct etimer timer; PROCESS_BEGIN(); /* Setup a periodic timer that expires after 10 seconds. */ etimer_set(&timer, CLOCK_SECOND*1); leds_on(LEDS_ALL); while(1) { /* Wait for the periodic timer to expire and then restart the timer. */ PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer)); UARTprintf(" hello-world!\r\n"); //约60字符一行,15行共约为900个字符 UARTprintf(" 1111111111111111111111111111111111111111111111111111111111\r\n \ 2222222222222222222222222222222222222222222222222222222222\r\n \ 3333333333333333333333333333333333333333333333333333333333\r\n \ 4444444444444444444444444444444444444444444444444444444444\r\n \ 5555555555555555555555555555555555555555555555555555555555\r\n \ 6666666666666666666666666666666666666666666666666666666666\r\n \ 7777777777777777777777777777777777777777777777777777777777\r\n \ 8888888888888888888888888888888888888888888888888888888888\r\n \ 9999999999999999999999999999999999999999999999999999999999\r\n \ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n \ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n \ cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\r\n \ dddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\r\n \ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\r\n \ 0123456789012345678901234567890123456789012345678901234567\r\n" ); etimer_reset(&timer); } PROCESS_END(); } /******************************************************************************* process1_GpioIputOutputTest 1--》主要是测试CC2538的PC3闪灯。 *******************************************************************************/ static struct etimer timeout1; //声明ETMIER事件 PROCESS(GpioIputOutputTest, "GpioIputOutputTest");//申请线程process1 PROCESS_THREAD(GpioIputOutputTest, ev, data)//进程1的功能体 { PROCESS_BEGIN();//开始 etimer_set(&timeout1,CLOCK_SECOND/200);//从当前时间起的,5MS极限测试 while(1) { PROCESS_WAIT_EVENT();//进行等待 if(ev == PROCESS_EVENT_TIMER) {//如果时间到了就打印信息,如果事件产生?? leds_toggle(LEDS_GREEN); //假设是一个固定时间的事件,5M一次取反一次LED灯, //使用示波器进行监测时间段 }//if etimer_reset(&timeout1);//复位时间,周而复始 }//while(1) PROCESS_END();//结束,与PROCESS_BEGIN()配对! }//PROCESS_THREAD /*--------取自\examples\platform-specific\cc2538-common的test-uart.c----------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ PROCESS(cc2538_uart_demo_process, "cc2538 uart demo"); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(cc2538_uart_demo_process, ev, data) { static uint16_t count=0; PROCESS_BEGIN(); etimer_set(&et, CLOCK_SECOND*1.2); while(1) { PROCESS_WAIT_UNTIL(etimer_expired(&et)); etimer_reset(&et); //UARTprintf("UART test:%d\r\n",count++); PROCESS_YIELD(); } PROCESS_END(); } //***********************************************************// /* 所有自启动模式的PROCESSES */ AUTOSTART_PROCESSES(&hello_process, &GpioIputOutputTest , &cc2538_uart_demo_process );
我们用示波器测试了反转的IO口电平,发现进行大量的UARTprintf打印,也不影响的GpioIputOutputTest时间参数,一直是稳定的5MS,这是很重要的测试结果。
因为之前测试NG系统自带的printf功能,发现严重影响其他任务的执行时间,可能变成100MS不等的延时,这个TI准标库uartstdio.c的UARTprintf移植到contiki NG相当麻烦,
看来还是TI才是行业的老大,技术的权威者。
经过测试,我们无意中,解决了printf性能低下的问题,提升了NG系统的性能!最后上个全家福
看视很顺利,但革命还未成功,还需续继努力!!