先簡單記錄下安裝:
1. 安裝 sourcery工具鏈或 keil都行
安裝python 和 scons:
配置這些工具路徑以及RT-Thread源碼路徑RTT_ROOT,添加到環境變量
2. 開始編譯 bsp\stm32f10x工程,在編譯以前需要稍微修改如下幾個文件
rtconfig.py 此文件必須修改
rtconfig.h 此文件用於裁剪rt-thread(根據需要修改)
比如使用 keil工具來編譯:
修改rtconfig.py,
CROSS_TOOL='keil'
EXEC_PATH='D:\Keil_v5'
cmd命令行 cd到bsp\stm32f10x:
D:\rt-thread\bsp\stm32f10x>scons
即可在 bsp\stm32f10x路徑下生成 axf文件和bin文件
scons -c 清除編譯出來的文件,如.o
scons -j4 多線程編譯,2個線程/每個CPU核
主要在 rt-thread-v2.0.0\bsp\stm32f10x\ 下的文件進行修改和添加:
drivers\SConscript 添加驅動文件,
# add the general drivers.
src = Split("""
board.c
stm32f10x_it.c
led.c
LCD5110.c
sys.c
ds18b20.c
usart.c
""")
這些基本的驅動文件里的延時需要調試下。
其他文件不用怎么改,接下來在 applications\application.c 中創建自己的線程函數了,實現相關功能。
/* application.c 2015.12.4 by Huangtao */ #include <board.h> #include <rtthread.h> #ifdef RT_USING_COMPONENTS_INIT #include <components.h> #endif /* RT_USING_COMPONENTS_INIT */ #ifdef RT_USING_DFS /* dfs filesystem:ELM filesystem init */ #include <dfs_elm.h> /* dfs Filesystem APIs */ #include <dfs_fs.h> #endif #ifdef RT_USING_RTGUI #include <rtgui/rtgui.h> #include <rtgui/rtgui_server.h> #include <rtgui/rtgui_system.h> #include <rtgui/driver.h> #include <rtgui/calibration.h> #endif #include "led.h" #include "LCD5110.h" #include "ds18b20.h" // Thread ID static rt_thread_t led_id = RT_NULL; static rt_thread_t lcd5110_id = RT_NULL; static rt_thread_t ds18b20_id = RT_NULL; #define CPU_USAGE_CALC_TICK 10 #define CPU_USAGE_LOOP 100 static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0; static rt_uint32_t total_count = 0; static void cpu_usage_idle_hook() { rt_tick_t tick; rt_uint32_t count; volatile rt_uint32_t loop; if (total_count == 0) { /* get total count */ rt_enter_critical(); tick = rt_tick_get(); while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { total_count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } rt_exit_critical(); } count = 0; /* get CPU usage */ tick = rt_tick_get(); while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } /* calculate major and minor */ if (count < total_count) { count = total_count - count; cpu_usage_major = (count * 100) / total_count; cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count; } else { total_count = count; /* no CPU usage */ cpu_usage_major = 0; cpu_usage_minor = 0; } } /*void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor) { RT_ASSERT(major != RT_NULL); RT_ASSERT(minor != RT_NULL); *major = cpu_usage_major; *minor = cpu_usage_minor; }*/ void cpu_usage_init() { /* set idle thread hook */ rt_thread_idle_sethook(cpu_usage_idle_hook); } /* // led ALIGN(RT_ALIGN_SIZE) static rt_uint8_t led_stack[ 512 ]; static struct rt_thread led_thread;*/ static void led_thread_entry(void* parameter) { rt_hw_led_init(); while (1) { /* led1 on */ rt_hw_led_on(0); // 順便清屏 ClearScreen(); rt_thread_delay( 100 ); /* sleep 1 second and switch to other thread */ /* led1 off */ rt_hw_led_off(0); // 順便清屏 //ClearScreen(); rt_thread_delay( 100 ); } } // lcd5110 static void lcd5110_thread_entry(void* parameter) { LcdInit(); while(1) { DispString(15,0,"RT-Thread"); DispString(0,1,"CPU:"); DispNum(30,1,cpu_usage_major); DispChar(45,1,'%'); rt_thread_delay( 5 ); } } // ds18b20 static void ds18b20_thread_entry(void* parameter) { short temperature = 0; while(DS18B20_Init()); while(1) { DispString(0,3,"Temp: "); temperature = DS18B20_Get_Temp(); if(temperature<0) { DispChar(40,3,'-'); temperature=-temperature; } else DispChar(40,3,' '); DispNum(48,3,((u16)temperature)/10); //顯示正數部分 DispChar(60,3,'.'); DispNum(67,3,((u16)temperature)%10); //顯示小數部分 rt_thread_delay( 5 ); } } void rt_init_thread_entry(void* parameter) { #ifdef RT_USING_COMPONENTS_INIT /* initialization RT-Thread Components */ rt_components_init(); #endif #ifdef RT_USING_FINSH finsh_set_device(RT_CONSOLE_DEVICE_NAME); #endif /* RT_USING_FINSH */ /* Filesystem Initialization */ #if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) /* mount sd card fat partition 1 as root directory */ if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) { rt_kprintf("File System initialized!\n"); } else rt_kprintf("File System initialzation failed!\n"); #endif /* RT_USING_DFS */ #ifdef RT_USING_RTGUI { extern void rt_hw_lcd_init(); extern void rtgui_touch_hw_init(void); rt_device_t lcd; /* init lcd */ rt_hw_lcd_init(); /* init touch panel */ rtgui_touch_hw_init(); /* find lcd device */ lcd = rt_device_find("lcd"); /* set lcd device as rtgui graphic driver */ rtgui_graphic_set_device(lcd); #ifndef RT_USING_COMPONENTS_INIT /* init rtgui system server */ rtgui_system_server_init(); #endif calibration_set_restore(cali_setup); calibration_set_after(cali_store); calibration_init(); } #endif /* #ifdef RT_USING_RTGUI */ } int rt_application_init(void) { rt_thread_t init_thread; /* rt_err_t result; // 靜態創建 led 線程 result = rt_thread_init(&led_thread, // 線程控制塊內存地址 "led", // 線程名稱 led_thread_entry, // 線程入口入口函數 RT_NULL, // 線程入口入口函數參數 (rt_uint8_t*)&led_stack[0], // 線程棧起始地址 sizeof(led_stack), // 線程棧大小 20, // 線程優先級 5); // 線程時間片大小 if (result == RT_EOK) { rt_thread_startup(&led_thread); } */ // 動態創建 led 線程 led_id = rt_thread_create("led", // 線程名稱 led_thread_entry, // 線程入口入口函數 RT_NULL, // 線程入口入口函數參數 512, // 線程棧大小 21, // 線程優先級 10); // 線程時間片大小 // 如果獲得線程控制塊,啟動這個線程 if (led_id != RT_NULL) rt_thread_startup(led_id); // 動態創建 lcd5110 線程 lcd5110_id = rt_thread_create("lcd5110", // 線程名稱 lcd5110_thread_entry, // 線程入口入口函數 RT_NULL, // 線程入口入口函數參數 2048, // 線程棧大小 20, // 線程優先級 20); // 線程時間片大小 if (lcd5110_id != RT_NULL) rt_thread_startup(lcd5110_id); // 動態創建 ds18b20 線程 ds18b20_id = rt_thread_create("ds18b20", // 線程名稱 ds18b20_thread_entry, // 線程入口入口函數 RT_NULL, // 線程入口入口函數參數 2048, // 線程棧大小 19, // 線程優先級 20); // 線程時間片大小 if (ds18b20_id != RT_NULL) rt_thread_startup(ds18b20_id); // CPU % cpu_usage_init(); #if (RT_THREAD_PRIORITY_MAX == 32) init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 8, 20); #else init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 80, 20); #endif if (init_thread != RT_NULL) rt_thread_startup(init_thread); return 0; } /*@}*/
這些線程時間片和每個線程中的延時根據需要調整,不然出現屏幕顯示異常。^_^
下面放張效果圖: