suebillt 发表于 2016-1-12 15:28:49

ucos 互斥信号量不起作用,求思路

一个项目需要407不断串口发送数据,gps是从gps那边读取的,提取所需内容后再转发,ais数据目前是软件自身模拟的
gps数据的采集并且通过消息队列传给gps发送任务
ais数据模拟并且通过消息队列发送给ais发送任务
gps发送和ais的发送都是使用串口1,所以发送的时候需要互斥,并且发送之前需要确认上次发送的数据发送完了

创建串口发送的信号量和互斥信号量:
UART1_Tx_FLAG=OSSemCreate(0);//创建UART1_Tx信号量
Tx_Mkd_Mutex=OSMutexCreate(9,&err);//创建GPS和AIS上报数据的互斥信号量,使用时优先级为9

ais发送任务:
void ais_mkd_trans_task(void *pdata)
{
        INT8U err;
        uint8_t * pbuf;
        u16 length = 0;
        u16 i = 0;
        OS_CPU_SRcpu_sr;
        while(1)
        {
                pbuf = OSQPend(Q_mkd_ais,0,&err);//没有新消息,则一直等待
                //OS_ENTER_CRITICAL();
                length = pbuf * 255 + pbuf;
                printf("\r\nmsg length:%d",length);
               
                OSMutexPend(Tx_Mkd_Mutex,0,&err);
                OSSemPend(UART1_Tx_FLAG,0,&err);//在此等待上次发送完成。       
                for(i = 0; i < length; i ++)
                {
                        Uart1_Tx1=pbuf;//使用串口1将数据输出
                }                                       
                  DMA2_Stream7->NDTR = length;
                  DMA_Cmd(DMA2_Stream7,ENABLE);
                OSMutexPost(Tx_Mkd_Mutex);
                //OS_EXIT_CRITICAL();
                OSTimeDly(10);
        }
}

gps发送任务:
void gps_mkd_trans_task(void *pdata)
{
        INT8U err;
        uint8_t * pbuf;
        u16 length = 0;
        u16 i;
        while(1)
        {
                pbuf=OSQPend(Q_mkd_GPS,0,&err);//没有新消息,则一直等待
                length=pbuf*255+pbuf;
                printf("\r\ngps_length:%d",length);
               
                OSMutexPend(Tx_Mkd_Mutex,0,&err);
                OSSemPend(UART1_Tx_FLAG,0,&err);//在此等待上次发送完成。
                for(i = 0; i < length; i ++)
                {
                        Uart1_Tx1=pbuf;//使用串口1将数据输出
                }               
                  DMA2_Stream7->NDTR = length;
                  DMA_Cmd(DMA2_Stream7,ENABLE);
                OSMutexPost(Tx_Mkd_Mutex);
                //OS_EXIT_CRITICAL();
                OSTimeDly(10);
        }
}
串口DMA中断处理:
void DMA2_Stream7_IRQHandler(void)
{ u8 err;
        if(DMA_GetITStatus(DMA2_Stream7,DMA_IT_TCIF7) != RESET)
        {
               OSIntEnter();

       DMA_ClearITPendingBit(DMA2_Stream7,DMA_IT_TCIF7);
               DMA_Cmd(DMA2_Stream7,DISABLE);
               //OSFlagPost(UART1_TX_FLAG,0x01,OS_FLAG_SET,&err);
                OSSemPost(UART1_Tx_FLAG);
                OSIntExit();
        }
}

jzkn 发表于 2016-1-12 15:45:10

你这不好好的么,也没乱码,怎么没起作用。

suebillt 发表于 2016-1-12 15:46:05

jzkn 发表于 2016-1-12 15:45
你这不好好的么,也没乱码,怎么没起作用。

gps基本没有发出来啊

jzkn 发表于 2016-1-12 16:06:11

你把SEMPEND,mutexpend,poST等的ERR用串口输出看看函数调用情况。
你这个timeout都设置为0会不会有问题,ucos我不太懂,瞎说勿怪。

墨非 发表于 2016-1-12 16:10:24

两个任务在等一个信号量(UART1_Tx_FLAG),饿死优先级低的。PS:没用过uCOS ,猜想的不知道是不是这样?

suebillt 发表于 2016-1-12 16:13:45

墨非 发表于 2016-1-12 16:10
两个任务在等一个信号量(UART1_Tx_FLAG),饿死优先级低的。PS:没用过uCOS ,猜想的不知道是不是这样? ...

申请到互斥的话优先级就提高了

suebillt 发表于 2016-1-12 16:44:08

我知道问题所在了,是因为DMA的模式应该开normal,我开的是循环,但是开normal的话一开始只发送两次,不理解

suebillt 发表于 2016-1-12 17:37:03

问题解决了,DMA的不定长发送应该是用normal模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
互斥是可以用的没有问题
UART1_Tx_FLAG=OSSemCreate(1);//创建UART1_Tx信号量起始值是1,这样第一次任务里面才能pend到
由于可能消息队列中pend过来消息是0的,所以要判断下   
if(length!=0)
{
要不然打开DMA后没有发送数据,就不会进入中断,flag就不会置1就一直在pend   flag了

suebillt 发表于 2016-1-12 17:37:20

墨非 发表于 2016-1-12 16:10
两个任务在等一个信号量(UART1_Tx_FLAG),饿死优先级低的。PS:没用过uCOS ,猜想的不知道是不是这样? ...

问题解决了,DMA的不定长发送应该是用normal模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
互斥是可以用的没有问题
UART1_Tx_FLAG=OSSemCreate(1);//创建UART1_Tx信号量起始值是1,这样第一次任务里面才能pend到
由于可能消息队列中pend过来消息是0的,所以要判断下   
if(length!=0)
{
要不然打开DMA后没有发送数据,就不会进入中断,flag就不会置1就一直在pend   flag了

suebillt 发表于 2016-1-12 17:37:35

jzkn 发表于 2016-1-12 15:45
你这不好好的么,也没乱码,怎么没起作用。

问题解决了,DMA的不定长发送应该是用normal模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
互斥是可以用的没有问题
UART1_Tx_FLAG=OSSemCreate(1);//创建UART1_Tx信号量起始值是1,这样第一次任务里面才能pend到
由于可能消息队列中pend过来消息是0的,所以要判断下   
if(length!=0)
{
要不然打开DMA后没有发送数据,就不会进入中断,flag就不会置1就一直在pend   flag了

jzkn 发表于 2016-1-12 17:46:13

suebillt 发表于 2016-1-12 17:37
问题解决了,DMA的不定长发送应该是用normal模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
互斥是 ...

解决了就好。赞~
页: [1]
查看完整版本: ucos 互斥信号量不起作用,求思路