学习RT-thread记录
我2011.11.02才开始收集关于RT-thread的资料,到今天已经11天了,其中有两天到济南出差,严格里来说只有9天的时间。用了7天看编程指南,2天时间看例程。感觉很好,在这里记录一下(可能比较乱),有不对的地方还请见谅!
RT-thread官网: http://www.rt-thread.org/
我是使用版本: RT-Thread 0.4.0 RC1 1.finsh的所使用
在RT-Thread 0.4.0 RC1里的stm32f10x工程里已经有示例的代码了,只需要重新编译下载到开发板。在串口会有
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 11 2011
2006 - 2011 Copyright by rt-thread team
finsh>>
使用串口输入“list()”发送到串口去,会返回一些函数和变量
--Function List:
set_date -- set date. e.g: set_date(2010,2,28)
set_time -- set time. e.g: set_time(23,59,59)
list_date -- show date and time.
list_mem -- list memory usage information
hello -- say hello world
version -- show RT-Thread version information
list_thread -- list thread
list_sem -- list semaphone in system
list_event -- list event in system
list_mutex -- list mutex in system
list_mailbox -- list mail box in system
list_msgqueue -- list message queue in system
list_mempool -- list memory pool in system
list_timer -- list timer in system
list_device -- list device in system
list -- list all symbol in system
led -- set led on or off.
--Variable List:
dummy -- dummy variable for finsh
0, 0x00000000
finsh>>
可以根据提示输入,例如set_date(2011,11,13) 设置日期
这就是finsh的感性认识了 1.2怎么映finsh射到串口2呢(我的串口1需要他用)
参见http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=5191294&bbs_page_no=1&search_mode=3&search_text=lindabell&bbs_id=9999
在board.c修改如下
// <o> Console on USART: <0=> no console <1=>USART 1 <2=>USART 2 <3=> USART 3
// <i>Default: 1
#define STM32_CONSOLE_USART 2 //原来是1
在rtconfig.c修改如下
/* SECTION: Device System */
/* Using Device System */
#define RT_USING_DEVICE
#define RT_USING_UART2 //原来是#define RT_USING_UART1
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
finsh_set_device("uart1");
#endif
改为
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
finsh_set_device("uart2"); //原来是uart1
#endif
好了,这就完成从串口1到串口2了 2.finsh的底层暂时不理它,它的实现还是比较麻烦的。咱先感受一下hello word 吧
led的移植
我们的应用程序都是从rt_application_init开始的,就像我们变成纯C的main函数一样的。
看看rt_application_init有什么
int rt_application_init() //应用程序初始化
{
rt_thread_t init_thread;
rt_err_t result;
/* init led thread */
result = rt_thread_init(&led_thread, //led线程
"led", //线程名称
led_thread_entry, RT_NULL, //led线程入口 、无参数
(rt_uint8_t*)&led_stack, sizeof(led_stack), //线程堆栈地址 和 堆栈大小
20, 5); //优先级时间片
if (result == RT_EOK) //判断是否初始化成功
{
rt_thread_startup(&led_thread); //线程初始化成功了启动线程
}
result=rt_thread_init(&my_thread,
"my_thread",
my_thread_entery,RT_NULL,
(rt_uint8_t*)my_stack,sizeof(my_stack),
20,5);
if(result==RT_EOK)
{
rt_thread_startup(&my_thread);
}
#if (RT_THREAD_PRIORITY_MAX == 32) //在RT-thread中优先级有256 和 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;
}
创建了3个线程led、my_thread、init(其中my_thread是我自己创建的)
找到led的入口函数led_thread_entry,发现里面有一个初始化函数的调用rt_hw_led_init();
在找到rt_hw_led_init的实现部分
void rt_hw_led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(led1_rcc|led2_rcc,ENABLE);
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = led1_pin;
GPIO_Init(led1_gpio, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = led2_pin;
GPIO_Init(led2_gpio, &GPIO_InitStructure);
}
到这里了不用说都知道这么改了,改完编译下载到板子,使用串口调用led函数就会有反应了 最近在看ucos,不过RTT最近听到好多人在说 呵呵 回复【4楼】tyqhaha
最近在看ucos,不过rtt最近听到好多人在说 呵呵
-----------------------------------------------------------------------
我以前也看过ucos ii,感觉RTT比较好一点 3创建线程,在例程中只有一个线程,不容易学习线程间的通信
线程有静态和动态之分的
通过rt thread init创建静态线程,使用rt_thread_create创建动态线程
以为我的板子有4个led,所以我创建了4个动态线程
led_tid=rt_thread_create("led1",
led1_thread_entery,RT_NULL,
2000,30,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led2",
led2_thread_entery,RT_NULL,
2000,29,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led3",
led3_thread_entery,RT_NULL,
2000,28,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led4",
led4_thread_entery,RT_NULL,
2000,27,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
static void led4_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t e;
while(1)
{
rt_event_recv(pEvent,1<<5,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&e);
rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_hw_led_on(4);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_mutex_release(pMutex);
rt_hw_led_off(4);
rt_thread_delay( RT_TICK_PER_SECOND );
}
}
线程入口分别为
static void led1_thread_entery(void* parameter)
{
rt_hw_led_init();//初始化io口
while(1)
{
rt_hw_led_on(1);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(1);
rt_thread_delay( RT_TICK_PER_SECOND );
}
}
static void led2_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
while(1)
{
rt_hw_led_on(2);
//rt_thread_delay( RT_TICK_PER_SECOND);
//rt_hw_led_off(2);
//rt_thread_delay( RT_TICK_PER_SECOND );
}
}
static void led3_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
while(1)
{
rt_hw_led_on(3);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(3);
rt_thread_delay( RT_TICK_PER_SECOND );
}
}
static void led4_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t e;
while(1)
{
rt_hw_led_on(4);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(4);
rt_thread_delay( RT_TICK_PER_SECOND );
}
}
怎样就建立好了4个线程
编译下到板子看看有没有这4个线程
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 13 2011
2006 - 2011 Copyright by rt-thread team
finsh>>list_thread()
threadpristatus sp stack size max used left tickerror
-------- ---- ------- ---------- ---------- ---------- ---------- ---
led4 0x1b suspend 0x00000078 0x000007d0 0x00000078 0x00000005 000
led3 0x1c suspend 0x00000078 0x000007d0 0x00000078 0x00000005 000
led2 0x1d ready 0x00000058 0x000007d0 0x00000058 0x00000003 000
led1 0x1e ready 0x00000040 0x000007d0 0x00000040 0x00000005 000
tidle 0x1f ready 0x00000040 0x00000100 0x00000040 0x00000020 000
tshell 0x14 ready 0x00000088 0x00000800 0x000001b0 0x00000006 000
init 0x08 0x00000068 0x00000800 0x000000c0 0x00000013 000
0, 0x00000000
finsh>>
finsh>>
可以看见led1~4的线程了,说明创建成功了 4线程间通信
4.1信号量
信号量是用来解决线程同步和互斥的通用工具,和互斥量类似,信号量也可用作资源互斥访问,但
信号量没有所有者的概念,在应用上比互斥量更广泛。信号量比较简单,不能解决优先级翻转问
题,但信号量是一种轻量级的对象,比互斥量小巧、灵活。因此在很多对互斥要求不严格的系统
中(或者不会造成优先级翻转的情况下),经常使用信号量来管理互斥资源
信号量我认为就是一个数值,当其为0时表示资源不可用,但不为0时表示资源可以使用。在初始化信号量是要初始化信号量的值。每当一个线程取得信号量时信号量的数值——,当释放信号量时期数值++。所以假如你初始化为1时,说明在同一时间只能一个线程会得到这个信号量。假如2时最多可以被线程获取2次。
首先说明一个信号量
static rt_sem_t pSem=RT_NULL; //信号量
再在创建线程之前初始化信号量,名为sem,数值为1,基于先进先出模式
pSem=rt_sem_create("sem",1,RT_IPC_FLAG_FIFO);
这样我们就有一个信号量了,下面就该使用了
修改led1和led2
static void led1_thread_entery(void* parameter)
{
rt_hw_led_init();//初始化io口
while(1)
{
rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(1);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(1);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_sem_release(pSem);
}
}
static void led2_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
while(1)
{
rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(2);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(2);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_sem_release(pSem);
}
}
预期的现象是led1亮灭-led2亮灭-led1亮灭 循环的
list_sem()
semaphore v suspend thread
----------- --------------
sem 000 1:led1
shrx 001 0
heap 001 0
0, 0x00000000
finsh>>
finsh>>list_sem()
semaphore v suspend thread
----------- --------------
sem 000 1:led2
shrx 001 0
heap 001 0
0, 0x00000000
finsh>>
finsh>>
从finsh中看可以看出了led1和led2,间隔持有信号量sem 4.2互斥量
其实互斥量和信号量的建立差不多的,同样邮箱、事件也多差不多
建立互斥量
static rt_mutex_t pMutex; //互斥量
初始化互斥量
pMutex=rt_mutex_create("mutex",RT_IPC_FLAG_FIFO);
修改代码
static void led3_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
while(1)
{
rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_hw_led_on(3);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(3);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_mutex_release(pMutex);
}
}
static void led4_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t e;
while(1)
{
rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_hw_led_on(4);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(4);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_mutex_release(pMutex);
}
}
效果和使用信号量一样的(led3,led4)
从finsh看
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 13 2011
2006 - 2011 Copyright by rt-thread team
finsh>>list_mutex()
mutex owner hold suspend thread
-------- -------- ---- --------------
mutex led3 0001 1
0, 0x00000000
finsh>>
finsh>>list_mutex()
mutex owner hold suspend thread
-------- -------- ---- --------------
mutex led3 0001 1
0, 0x00000000
finsh>>
finsh>>list_mutex()
mutex owner hold suspend thread
-------- -------- ---- --------------
mutex led3 0001 1
0, 0x00000000
finsh>>
finsh>>list_mutex()
mutex owner hold suspend thread
-------- -------- ---- --------------
mutex led4 0001 1
0, 0x00000000
finsh>>
finsh>>list_mutex()
mutex owner hold suspend thread
-------- -------- ---- --------------
mutex led4 0001 1
0, 0x00000000
finsh>>
finsh>> 4.3事件
事件看可以多个触发一个,即发生几件事才会触发或其中一件事发生也可以触发
建立事件
static rt_event_t pEvent; //事件
事件初始化
pEvent=rt_event_create("event",RT_IPC_FLAG_FIFO);
修改代码
Led1发送1<<5
Led2发送1<<6
Led3接收 1<<5 |1<<6
Led3接收 1<<5 &1<<6
static void led1_thread_entery(void* parameter)
{
rt_hw_led_init();//初始化io口
while(1)
{
rt_event_send(pEvent,1<<5);
//rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(1);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(1);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_sem_release(pSem);
}
}
static void led2_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
while(1)
{
rt_event_send(pEvent,1<<6);
//rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(2);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(2);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_sem_release(pSem);
}
}
static void led3_thread_entery(void* parameter)
{
rt_uint32_t Temp;
//rt_hw_led_init();//初始化io口
while(1)
{
rt_event_recv(pEvent,1<<5|1<<6,RT_EVENT_FLAG_OR,RT_WAITING_FOREVER,&Temp);
//rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_hw_led_on(3);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(3);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_mutex_release(pMutex);
}
}
static void led4_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t e;
while(1)
{
rt_event_recv(pEvent,1<<5|1<<6,RT_EVENT_FLAG_AND,RT_WAITING_FOREVER,&e);
//rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_hw_led_on(4);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(4);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_mutex_release(pMutex);
}
}
Led3,led4能够一闪一闪就说明收到事件了
从finsh看
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 13 2011
2006 - 2011 Copyright by rt-thread team
finsh>>list_event()
event set suspend thread
-------- ---------- --------------
event 0x00000060 0
0, 0x00000000
finsh>> 4.3邮箱
一个邮箱里可以放4个字节的数据(最好是指针了),同理
static rt_mailbox_t pMailbox; //邮箱
pMailbox=rt_mb_create("mailbox",5,RT_IPC_FLAG_FIFO);
static void led1_thread_entery(void* parameter)
{
rt_hw_led_init();//初始化io口
while(1)
{
rt_mb_send(pMailbox,0xAABBCCDD);//发送一个邮箱数据
rt_event_send(pEvent,1<<5);
//rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(1);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(1);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_sem_release(pSem);
}
}
static void led2_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t temp=0;
while(1)
{
rt_mb_recv(pMailbox,&temp,RT_WAITING_FOREVER);
if(temp==0XAABBCCDD)
{
rt_event_send(pEvent,1<<6);
//rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_hw_led_on(2);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(2);
rt_thread_delay( RT_TICK_PER_SECOND );
//rt_sem_release(pSem);
}
}
}
现象led2一闪一闪说明收到了正确的数据了
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 13 2011
2006 - 2011 Copyright by rt-thread team
finsh>>list_mailbox()
mailboxentry size suspend thread
-------- -------- --------------
mailbox00000005 0
0, 0x00000000
finsh>>
finsh>> 队列,比较费资源。没有仔细看。就算了 谢谢楼主的分享,我也正在准备学习。 楼上看得很快呀,相比之下我就慢了很多。刚刚弄到信号量那部分。感觉和ucos非常类似,如果有ucos的基础,这个概念基本上就不用看了,不过也可能因为太相似了,有一些函数的功能还是有区别的,这点对于有ucos基础的人反而是一个障碍。
楼主弄到了信号量部分,你创建的是一个FIFO模式的信号量,我想了解一下FIFO模式和优先级模式个什么区别?为自己做了一个例子实验了一下,发现并没有什么区别,都是优先级不同的话,最高优先级的任务获得信号量,优先级相同的,先申请信号量的任务获得信号量,这个不知道楼主研究过没有? 我移植到lpc1752上经常出现硬件异常,找原因中! 马甲 mark 回复【13楼】tiancaigao7天才杨威利
-----------------------------------------------------------------------
我也没有什么ucos ii的经验了,只是上学时看过一遍而已。
看看你是不是这种情况:
假设A优先级比B的优先级高。
1.但是B申请信号量时,A其实没有申请;那么信号量当然给B了。
2.假如C已经占有信号量了,还没有释放;AB又同时申请该信号量了;那么在C释放了该信号量之后
1)如果使用FIFO的话就给先申请的
2)如果是基于优先级的则给A 楼主一定要继出下部,支持. 回复【17楼】lindabell 欧海
回复【13楼】tiancaigao7天才杨威利
-----------------------------------------------------------------------
我也没有什么ucos ii的经验了,只是上学时看过一遍而已。
看看你是不是这种情况:
假设a优先级比b的优先级高。
1.但是b申请信号量时,a其实没有申请;那么信号量当然给b了。
2.假如c已经占有信号量了,还没有释放;ab又同时申请该信号量了;那么在c释放了该信号量之后
1)如果使用fifo的话就给先申请的
2)如果是基于优先级的则给a
-----------------------------------------------------------------------
回复楼主,我实验室这样进行的,信号量FIFO模式下,AB两个任务中分别申请信号量,AB两个任务优先级相同,任务C发送信号量(一次)。在启动任务的时候,按照顺序启动任务A B,之后在启动任务C(任务C启动的时候,任务AB都因为没有信号量而挂起)。分别在任务AB中获取信号量函数后面设定断点。发现这种情况下A任务进入断点。如果我在创建让任务的时候让B任务优先级比A任务高,那么会进入到B任务的断点中。当然在PRIO模式下也是一样。不知道楼主是否遇到过这方面的问题。
另外,我现在似乎用的是3.3.0版,听说4.0版的RTT中不再有start_rvds.s这个启动文件,而是直接利用STM32对应的启动文件,是不是这样?打算下载一个4.0版看看,不知道是否稳定。 回复【19楼】tiancaigao7天才杨威利
-----------------------------------------------------------------------
“任务C发送信号量(一次)”信号量能发送吗??
贴一下我的代码
线程入口
static void led1_thread_entery(void* parameter)
{
rt_device_t Wrdevice;
rt_hw_led_init();//初始化io口
Wrdevice=rt_device_find("uart1");
rt_device_open(Wrdevice,RT_DEVICE_FLAG_DMA_TX);
while(1)
{
// rt_device_write(Wrdevice,0,Str,sizeof(Str)-1);
// rt_mb_send(pMailbox,0xAABBCCDD);//发送一个邮箱数据
// rt_event_send(pEvent,1<<5);
rt_thread_delay( RT_TICK_PER_SECOND/2);
rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_kprintf("led1\r\n");
rt_hw_led_on(1);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(1);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_sem_release(pSem);
}
}
static void led2_thread_entery(void* parameter)
{
//rt_hw_led_init();//初始化io口
rt_uint32_t temp=0;
while(1)
{
//rt_mb_recv(pMailbox,&temp,RT_WAITING_FOREVER);
//if(temp==0XAABBCCDD)
//{
//rt_event_send(pEvent,1<<6);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_kprintf("led2\r\n");
rt_hw_led_on(2);
rt_thread_delay( RT_TICK_PER_SECOND);
rt_hw_led_off(2);
rt_thread_delay( RT_TICK_PER_SECOND );
rt_sem_release(pSem);
//}
}
}
static void led3_thread_entery(void* parameter)
{
rt_uint32_t Temp;
//rt_hw_led_init();//初始化io口
while(1)
{
//rt_event_recv(pEvent,1<<5|1<<6,RT_EVENT_FLAG_OR,RT_WAITING_FOREVER,&Temp);
//rt_mutex_take(pMutex,RT_WAITING_FOREVER);
rt_sem_take(pSem,RT_WAITING_FOREVER);
rt_kprintf("led3\r\n");
rt_hw_led_on(3);
rt_thread_delay( 5*RT_TICK_PER_SECOND);
rt_hw_led_off(3);
rt_thread_delay(5* RT_TICK_PER_SECOND );
//rt_mutex_release(pMutex);
rt_sem_release(pSem);
}
}
创建线程
void rt_led_init(void)
{
rt_thread_t led_tid;
pSem=rt_sem_create("sem",1,RT_IPC_FLAG_PRIO);
pMutex=rt_mutex_create("mutex",RT_IPC_FLAG_FIFO);
pEvent=rt_event_create("event",RT_IPC_FLAG_FIFO);
pMailbox=rt_mb_create("mailbox",5,RT_IPC_FLAG_FIFO);
led_tid=rt_thread_create("led1",
led1_thread_entery,RT_NULL,
2000,30,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led2",
led2_thread_entery,RT_NULL,
2000,29,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led3",
led3_thread_entery,RT_NULL,
2000,28,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
led_tid=rt_thread_create("led4",
led4_thread_entery,RT_NULL,
2000,27,5
);
if(led_tid!=RT_NULL) rt_thread_startup(led_tid);
}
当基于FIFo时led3->led2->led1
基于优先级时led3->led2->led3->led2 唉,就是对LM3S的的支持太弱了 不错。mark! 楼主写得不错 RTT的IO设备复杂的,看了2遍没怎么看懂 关注中 mark... 今天弄了SRAM
参见http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=5197842&bbs_page_no=1&search_mode=3&search_text=lindabell&bbs_id=9999
在board.h中修改成(我的SRAM是1M的)
/* whether use board external SRAM memory */
// <e>Use external SRAM memory on the board
// <i>Enable External SRAM memory
#define STM32_EXT_SRAM 1
// <o>Begin Address of External SRAM
// <i>Default: 0x68000000
#define STM32_EXT_SRAM_BEGIN 0x68000000 /* the begining address of external SRAM */
// <o>End Address of External SRAM
// <i>Default: 0x68080000
#define STM32_EXT_SRAM_END 0x68100000 /* the end address of external SRAM */
为了看出动态分配的情况在rtdebug.h中
/* Turn on some of these (set to non-zero) to debug kernel */
#ifndef RT_DEBUG_MEM
#define RT_DEBUG_MEM 0
#endif
改成
/* Turn on some of these (set to non-zero) to debug kernel */
#ifndef RT_DEBUG_MEM
#define RT_DEBUG_MEM 1
#endif
初始化FSMC,在board.c中修改EXT_SRAM_Configuration使符合你的板子,下面是我的
void EXT_SRAM_Configuration(void)
{
FSMC_NORSRAMInitTypeDefFSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDefp;
GPIO_InitTypeDef GPIO_InitStructure;
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF
| RCC_APB2Periph_GPIOG, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*
FSMC_D0 ~ FSMC_D3
PD14 FSMC_D0
PD15 FSMC_D1
PD0 FSMC_D2
PD1 FSMC_D3
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*
FSMC_D4 ~ FSMC_D12
PE7 ~ PE15FSMC_D4 ~ FSMC_D12
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10
| GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOE,&GPIO_InitStructure);
/* FSMC_D13 ~ FSMC_D15 PD8 ~ PD10 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*
FSMC_A0 ~ FSMC_A5 FSMC_A6 ~ FSMC_A9
PF0 ~ PF5 PF12 ~ PF15
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF,&GPIO_InitStructure);
/* FSMC_A10 ~ FSMC_A15
PG0 ~ PG5 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOG,&GPIO_InitStructure);
/* FSMC_A16 ~ FSMC_A18
PD11 ~ PD13 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*FSMC_A19 ~ FSMC_A21
PE3 ~ PE6 */
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3 | GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOE,&GPIO_InitStructure);
/* RD-PD4
WR-PD5 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/* NBL0-PE0
NBL1-PE1 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOE,&GPIO_InitStructure);
// /* NE1/NCE2 */
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; ///????????????????????????????/
// GPIO_Init(GPIOD,&GPIO_InitStructure);
// /* NE2 */
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
// GPIO_Init(GPIOG,&GPIO_InitStructure);
/* NE3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOG,&GPIO_InitStructure);
/* NE4 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOG,&GPIO_InitStructure);
}
/* FSMC GPIO configure */
/*-- FSMC Configuration ------------------------------------------------------*/
p.FSMC_AddressSetupTime = 0;
p.FSMC_AddressHoldTime = 0;
p.FSMC_DataSetupTime = 2;
p.FSMC_BusTurnAroundDuration = 0;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
// FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* Enable FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
}
从finsh看看,有什么变化
\ | /
- RT - Thread Operating System
/ | \ 0.4.0 build Nov 14 2011
2006 - 2011 Copyright by rt-thread team
mem init, heap begin address 0x68000000, size 1048552
malloc size 152
allocate memory at 0x6800000c, size: 164
malloc size 2048
allocate memory at 0x680000b0, size: 2060
malloc size 696
allocate memory at 0x680008bc, size: 708
malloc size 44
allocate memory at 0x68000b80, size: 56
malloc size 48
allocate memory at 0x68000bb8, size: 60
malloc size 44
allocate memory at 0x68000bf4, size: 56
malloc size 60
allocate memory at 0x68000c2c, size: 72
malloc size 20
allocate memory at 0x68000c74, size: 32
malloc size 152
allocate memory at 0x68000c94, size: 164
malloc size 2000
allocate memory at 0x68000d38, size: 2012
malloc size 152
allocate memory at 0x68001514, size: 164
malloc size 2000
allocate memory at 0x680015b8, size: 2012
malloc size 152
allocate memory at 0x68001d94, size: 164
malloc size 2000
allocate memory at 0x68001e38, size: 2012
malloc size 152
allocate memory at 0x68002614, size: 164
malloc size 2000
allocate memory at 0x680026b8, size: 2012
finsh>>led3
release memory 0x680000b0, size: 2060
release memory 0x6800000c, size: 164 RTT的IO设备居然这么复杂,总是理不清思路 回复【2楼】lindabell欧海
1.2怎么映finsh射到串口2呢(我的串口1需要他用)
参见http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=5191294&bbs_page_no=1&search_mode=3&search_text=lindabell&bbs_id=9999
在board.c修改如下
// <o> console on usart: <0=> no console <1=>usart 1 <2=>usart 2 <3=> usart 3
// <i>default: 1
#define stm32_console_usart 2 //原来是1
在rtconfig.c修改如下
/* section: device system */......
-----------------------------------------------------------------------
貌似这里你提到的board.c和rtconfig.c在0.40RC1中应该是board.h和startup.c
郁闷了。。。。 回复【29楼】chewy
-----------------------------------------------------------------------
更正这些配置分别在下面3个文件中(看来真的累了)
board.h
rtconfig.h
startup.c 回复【30楼】lindabell欧海
回复【29楼】chewy
-----------------------------------------------------------------------
更正这些配置分别在下面3个文件中(看来真的累了)
board.h
rtconfig.h
startup.c
-----------------------------------------------------------------------
呵呵 直接把你帖子里的改了吧 不然有人会跟错~ 回复【31楼】chewy
-----------------------------------------------------------------------
我也想改啊,你不知道贴发出24小时就不能改了吗
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_695807XO5TIY.png
(原文件名:err.png) 回复【32楼】lindabell欧海
-----------------------------------------------------------------------
额 还真不知道。。。囧 IO 设备
弄了3天的时间,现在感觉才明白一点
1.初始化硬件
2.注_册到RTT
3.查找io设备
4.调用io设备的相关函数
感觉还是表达不清楚,直接上文件
点击此处下载 ourdev_696154PZJAVT.rar(文件大小:2K) (原文件名:USART1.rar) 关注! 非常感谢楼主的分享!我正在寻找像你这样的帖子! 楼主是个好人......... 回复【28楼】lindabell 欧海
rtt的io设备居然这么复杂,总是理不清思路
-----------------------------------------------------------------------
确实 RTT的IO设备感觉太复杂了,不过很大程度上是因为RTT的编程指南写的不清楚,也不太专业。很多应该说的话没有说到。IO设备部分是后面使用GUI,FS LWIP等等外设的基础,因此虽然现在我不太明白,但是也要保证大体上知道如何修改。
另外不知道楼主是不是发现了,RTT的线程完成同样的任务要比ucos多占用很多线程栈?而且使用它内置的文件系统的代码要比我移植FATFS大很多,因此现在我还是用RTT+FATFS来做的。 good!!!!!!! 楼主用的自己的开发板? 感谢楼主的分享! 回复【38楼】tiancaigao7天才杨威利
-----------------------------------------------------------------------
这个倒是不清楚
补充;打错字 好东西,顶下,支持下,要是能出个PDF版本的就更好了,谢谢楼主 学习学习了。 我的串口回去怎么输出乱码,用串口助手。 我现在还没入门,随便看看 mark 支持lz继续下去 回复【8楼】lindabell欧海
-----------------------------------------------------------------------
我现在每天都在学习楼主的教程。现在学到了信号量,
写了如下代码:
static rt_sem_t pSem=RT_NULL; //信号量
pSem=rt_sem_create("sem",1,RT_IPC_FLAG_FIFO);
static void rt_thread_entry_led1(void* parameter)
{
/* init led configuration */
rt_hw_led_init();
while (1)
{
rt_sem_take(pSem,RT_WAITING_FOREVER);
/* led on */
rt_kprintf("led1 on\r\n");
rt_hw_led_on(0);
rt_thread_delay(50); /* sleep 0.5 second and switch to other thread */
/* led off */
rt_kprintf("led1 off\r\n");
rt_hw_led_off(0);
rt_thread_delay(50);
rt_sem_release(pSem);
}
}
结果,编译不通过:
application.c(168): error:#77-D: this declaration has no storage class or type specifier
请问是啥原因? 回复【4楼】tyqhaha
最近在看ucos,不过rtt最近听到好多人在说 呵呵
-----------------------------------------------------------------------
ucos这种东西不算什么操作系统,它不支持多线程,实时性不高。 回复【49楼】cnsxgh
-----------------------------------------------------------------------
提示说你这里没有存储类型,是不是忘记int 、char什么的了 向楼主学习,可怜我还在等待审核,不能请教各位了 楼主太有才了,对我等初哥帮助很大,期待精彩下文 楼主能否描述一上用一个邮箱方式来通知 线程上的调用. 学习了。。。 顶一个!!!!现在开始学习,先MARK
页:
[1]