移植uC/OS-II到瑞萨的单片机,添加信号量功能

添加信号量功能
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。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值