學習是一個漫長的過程,很早之前我們都是按照網絡教程進行移植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系統的性能!最后上個全家福
看視很順利,但革命還未成功,還需續繼努力!!