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
你这不好好的么,也没乱码,怎么没起作用。
gps基本没有发出来啊 你把SEMPEND,mutexpend,poST等的ERR用串口输出看看函数调用情况。
你这个timeout都设置为0会不会有问题,ucos我不太懂,瞎说勿怪。 两个任务在等一个信号量(UART1_Tx_FLAG),饿死优先级低的。PS:没用过uCOS ,猜想的不知道是不是这样? 墨非 发表于 2016-1-12 16:10
两个任务在等一个信号量(UART1_Tx_FLAG),饿死优先级低的。PS:没用过uCOS ,猜想的不知道是不是这样? ...
申请到互斥的话优先级就提高了 我知道问题所在了,是因为DMA的模式应该开normal,我开的是循环,但是开normal的话一开始只发送两次,不理解 问题解决了,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了 墨非 发表于 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了 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了 suebillt 发表于 2016-1-12 17:37
问题解决了,DMA的不定长发送应该是用normal模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
互斥是 ...
解决了就好。赞~
页:
[1]