这段时间稍微折腾了一下stm32,稍微知道了一点stm32程序的编写方法,所以再次拿起了rtt,因为这个东西确实很强大。
随手记录一下rtt的一些知识:
1、关于finsh
这是一个命令行系统,很好玩,开始不知道怎么用的,输入help之类的毫无用处,后来发现按tab键就能出现帮助。命令格式不是一般想象中那样,而是类似于C语言函数,比如:显示进程,得这样写list_thread(),再比如控制LED亮灭,得这样写led(1,0),这样第2个led就灭了。当时确实折腾了我好一整子。另外,还可以将自己写的函数可以在finsh中调用,参考led.c的最后部分,用FINSH_FUNCTION_EXPORT宏,第一个参数是函数名,第二个参数是描述文字,不用双引号。
2、关于用Eclipse开发
官方wiki有篇用Eclipse开发的教程,说得很详细了。不过我试验了一下,最先的感觉是直接新成工程后会有一大堆的动态错误检测,编译却能通过,确实得关掉。另外,用jlink debug不是很方便,不过没关系,基本上用j-flash arm下载就行了。
3、关于线程的堆栈空间
为了多线程能够顺利执行,必须得为每个线程分配一定的堆栈空间,用于储存进程切换时的操作数据。至于空间得分配多少,据一篇文章介绍说,可以先分配高一点,然后用finsh再list_thread,即可看到"max used“使用了多少堆栈。当然,如果ram充足,多分配点也无妨。
4、RTT最简单应用
最简单应用莫过于创建一个新的线程了。参照led线程创建一个新的进程。
1、定义线程堆栈、结构体、入口函数
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t led_stack[ 512 ];
static struct rt_thread led_thread;
static void led_thread_entry(void* parameter){
/*TODO:*/
}
2、在rt_application_init函数中初始化
按照led线程的写法是在rt_init_thread_entry进程前面,应该也可以写在后面,毕竟两者初始化后多直接启动了,时间上应该差别不大。
led的线程初始化函数是:
rt_err_t result;
result = rt_thread_init(&led_thread,
"led",
led_thread_entry, RT_NULL,
(rt_uint8_t*)&led_stack[0], sizeof(led_stack), 20, 5);第1个参数:线程结构体
第2个参数: 线程名称(?能用中文否?)
第3个参数:线程入口函数
第4个参数:线程入口函数的参数
第5个参数:堆栈空间起始地址
第6个参数:堆栈空间大小
第7个参数:线程优先级(0最高?)
第8个参数:如果有相同的优先级,进程静默时间
3、启动进程
rt_thread_startup(init_thread);