添加信号量功能
1.修改os_cfg.h中的配置
#define OS_MAX_EVENTS 3 /* Max. number of event control blocks in your application */
#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_SEM_ACCEPT_EN 0 /* Include code for OSSemAccept() */
#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */
#define OS_SEM_QUERY_EN 0 /* Include code for OSSemQuery() */
2.在os_core.c添加事件的相关函数的实现
INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)
void OS_EventTaskWait (OS_EVENT *pevent)
void OS_EventTO (OS_EVENT *pevent)
void OS_EventWaitListInit (OS_EVENT *pevent)
static void OS_InitEventList (void)
在OSInit 中添加初始化事件控制块的OS_InitEventList
void OSInit (void)
{
OS_InitMisc(); /* Initialize miscellaneous variables */
OS_InitRdyList(); /* Initialize the Ready List */
OS_InitTCBList(); /* Initialize the free list of OS_TCBs */
OS_InitEventList(); //add by ljc
....
}
3.写信号量的测试代码
void main( void )
{
OSInit();
Sem1=OSSemCreate(0);
Sem2=OSSemCreate(0);
OSTaskCreate(AppTask1, /* Create an application task */
(void *)0,
&AppTask1Stk[APP_TASK1_STK_SIZE - 1],
1);
OSTaskCreate(AppTask2, /* Create a second application task */
(void *)0,
&AppTask2Stk[APP_TASK2_STK_SIZE - 1],
0);
OSStart();
}
/************************************************************************/
/* add by ljc */
/************************************************************************/
/* Arguments: Switch value, LED0: bit 0, LED1: bit 1. 0: dark, 1: lit */
void AppTask1 (void *parg)
{
INT8U err=0;
parg = parg; /* Prevent compiler warning */
OSSemPost(Sem1);
while(1){
OSSemPend(Sem1,0,&err);
//OSTimeDly(100);
led_out(0x1);
OSTimeDly(100);
led_out(0x2);
OSTimeDly(100);
OSSemPost(Sem2);
}
}
void AppTask2 (void *parg)
{
int i;
INT8U err;
parg = parg; /* Prevent compiler warning */
/* Initialize MCU functions */
init(); /* Initialize */
set_ccr( 0x00 ); /* Enable all interrupts */
/* Initialize micom car state */
handle( 0 );
speed( 0, 0 );
while( 1 ) {
OSSemPend(Sem2,0,&err);
led_out(0x3);
OSTimeDly(200);
OSSemPost(Sem1);
}
}
结果OSSemPend(Sem2,0,&err);能切换task2到task1,可是在task1中OSSemPost(Sem2); 却切换不到task2中。
后来发现在OSSemPost(Sem2)中Sem2怎么就变成了NULL,Sem2->OSEventType != OS_EVENT_TYPE_SEM,或者
Sem2->OSEventGrp == 0x00,是的OSSemPost执行不到OS_Sched()
调试了两天半,都快疯了,也没找到为什么这个样子。
今天修改了
#define OS_MAX_EVENTS 3 /* Max. number of event control blocks in your application */
把原来的2改成了3
把Sem1=OSSemCreate(1);改成了Sem1=OSSemCreate(0)加上OSSemPost(Sem1);测试成功了。
莫非是Sem2=OSSemCreate(0);失败了,可我明明只使用了两个信号量呀,怎么#define OS_MAX_EVENTS 2
第二个信号量怎么就失败了呢。不过改成3就成功了
另外
void AppTask1 (void *parg)
{
INT8U err=0;
parg = parg; /* Prevent compiler warning */
while(1){
//OSTimeDly(100);//如果没有这句代码,就造成了信号量失效的严重后果
led_out(0x1);//(一)
OSTimeDly(100);
led_out(0x2);
OSTimeDly(100);
OSSemPost(Sem2);
}
}
void AppTask2 (void *parg)
{
int i;
INT8U err;
parg = parg; /* Prevent compiler warning */
/* Initialize MCU functions */
init(); /* Initialize */
set_ccr( 0x00 ); /* Enable all interrupts */
/* Initialize micom car state */
handle( 0 );
speed( 0, 0 );
while( 1 ) {
OSSemPend(Sem2)
led_out(0x3);
OSTimeDly(200);//这句执行时,马上跳到了上面的(一)处
}
}
如果没有上面的蓝色代码,程序的显示结果是信号量无效,led_out(0x3);没有执行。原因是红色代码程序设计有问题,OSTimeDly(200);//这句执行时,马上跳到了上面的(一)处,结果led_out(0x1);//(一),led_out(0x3)虽然执行,可是看不出来。
现在找到主要原因了
OS_MAX_EVENTS和OS_MAX_QS的区别
OS_MAX_EVENTS
OS_MAX_EVENTS定义系统中最大的事件控制块的数量。系统中的每一个消息邮箱,消息队列,信号量都需要一个事件控制块。例如,系统中有10个消息邮箱,5个消息队列,3个信号量,则OS_MAX_EVENTS最小应该为18。只要程序中用到了消息邮箱,消息队列或是信号量,则OS_MAX_EVENTS最小应该设置为2。
OS_MAX_QS
OS_MAX_QS定义系统中最大的消息队列数。要使用消息队列,常量OS_Q_EN也要同时置1。如果要使用消息队列,OS_MAX_ QS最小应该设置为2。