OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4847|回复: 4

FreeRTOS互斥信号量操作实验的疑问

[复制链接]

44

主题

225

帖子

0

精华

高级会员

Rank: 4

积分
658
金钱
658
注册时间
2013-11-22
在线时间
131 小时
发表于 2019-3-15 11:23:34 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 zhp 于 2019-3-15 11:29 编辑

首先我在一个STM32F103RCT6的最小系统板上跑原子哥的“FreeRTOS实验14-4 FreeRTOS互斥信号量操作实验”例程(把STM32F103ZET6换成了STM32F103RCT6),良好运行,但是我把printf函数换成串口1的输出函数,结果是只看到高优先级任务在运行,中等优先级和低优先级的输出都没了?

原始printf输出结果

原始printf输出结果
           

更改为串口1输出

更改为串口1输出

    原始printf输出结果                                            将printf更改为uart1_send_buf输出结果

附件里有程序源码,我的问题是,为什么将printf改成 uart1 输出后,结果会这样?串口1的输出函数为:
[mw_shl_code=applescript,true]void uart1_send_buf(u8 *data, u16 len)
{
    u16 i = 0;
   
    for(i=0; i<len; i++)
    {
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
        USART_SendData(USART1, *(data + i));               
    }
}[/mw_shl_code]



FreeRTOS实验14-4 FreeRTOS互斥信号量操作实验(更换printf为uart1_send_buf).rar

643.52 KB, 下载次数: 10

更改后工程代码

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1906

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4100
金钱
4100
注册时间
2018-8-14
在线时间
695 小时
发表于 2019-3-15 11:55:36 | 显示全部楼层
把高优先级任务, 贴出来吧
回复

使用道具 举报

44

主题

225

帖子

0

精华

高级会员

Rank: 4

积分
658
金钱
658
注册时间
2013-11-22
在线时间
131 小时
 楼主| 发表于 2019-3-16 10:11:10 | 显示全部楼层
本帖最后由 zhp 于 2019-3-16 10:18 编辑
edmund1234 发表于 2019-3-15 11:55
把高优先级任务, 贴出来吧

好的,为了方便不用下载工程就可以看到代码,我把主要代码贴上来,由于KEIL把代码粘过来中文显示会乱码,所以干脆截图给大家看,下面是mian.c的代码
main.c
1.png 2.png 3.png 4.png 5.png


mian.c的代码也贴出来吧,程序中只是将printf输出换成了uart1输出,printf函数其实也是从uart1输出的
[mw_shl_code=cpp,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "beep.h"
#include "malloc.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/************************************************
ALIENTEK &#213;&#189;&#189;¢STM32F103&#191;a·¢°&#229; FreeRTOSêμ&#209;é14-4
FreeRTOS&#187;¥3aD&#197;o&#197;á&#191;2ù×÷êμ&#209;é-&#191;aoˉêy°&#230;±&#190;
&#188;&#188;ê&#245;&#214;§3&#214;£owww.openedv.com
ì&#212;±|μê&#198;ì£ohttp://eboard.taobao.com
1&#216;×¢&#206;¢D&#197;1&#171;&#214;ú&#198;&#189;ì¨&#206;¢D&#197;o&#197;£o"&#213;yμ&#227;&#212;-×ó"£&#172;&#195;a·&#209;&#187;&#241;è&#161;STM32×êá&#207;&#161;£
1&#227;&#214;YêDD&#199;òíμ&#231;×ó&#191;&#198;&#188;&#188;óD&#207;T1&#171;&#203;&#190;  
×÷&#213;&#223;£o&#213;yμ&#227;&#212;-×ó @ALIENTEK
************************************************/

//è&#206;&#206;&#241;ó&#197;&#207;è&#188;&#182;
#define START_TASK_PRIO                        1
//è&#206;&#206;&#241;&#182;&#209;&#213;&#187;′óD&#161;        
#define START_STK_SIZE                         256  
//è&#206;&#206;&#241;&#190;&#228;±ú
TaskHandle_t StartTask_Handler;
//è&#206;&#206;&#241;oˉêy
void start_task(void *pvParameters);

//è&#206;&#206;&#241;ó&#197;&#207;è&#188;&#182;
#define LOW_TASK_PRIO                        2
//è&#206;&#206;&#241;&#182;&#209;&#213;&#187;′óD&#161;        
#define LOW_STK_SIZE                         256  
//è&#206;&#206;&#241;&#190;&#228;±ú
TaskHandle_t LowTask_Handler;
//è&#206;&#206;&#241;oˉêy
void low_task(void *pvParameters);

//è&#206;&#206;&#241;ó&#197;&#207;è&#188;&#182;
#define MIDDLE_TASK_PRIO                 3
//è&#206;&#206;&#241;&#182;&#209;&#213;&#187;′óD&#161;        
#define MIDDLE_STK_SIZE                  256
//è&#206;&#206;&#241;&#190;&#228;±ú
TaskHandle_t MiddleTask_Handler;
//è&#206;&#206;&#241;oˉêy
void middle_task(void *pvParameters);

//è&#206;&#206;&#241;ó&#197;&#207;è&#188;&#182;
#define HIGH_TASK_PRIO                         4
//è&#206;&#206;&#241;&#182;&#209;&#213;&#187;′óD&#161;        
#define HIGH_STK_SIZE                          256
//è&#206;&#206;&#241;&#190;&#228;±ú
TaskHandle_t HighTask_Handler;
//è&#206;&#206;&#241;oˉêy
void high_task(void *pvParameters);

//&#187;¥3aD&#197;o&#197;á&#191;&#190;&#228;±ú
SemaphoreHandle_t MutexSemaphore;        //&#187;¥3aD&#197;o&#197;á&#191;

//LCD&#203;¢&#198;áê±ê1ó&#195;μ&#196;&#209;&#213;é&#171;
int lcd_discolor[14]={        WHITE, BLACK, BLUE,  BRED,      
                                                GRED,  GBLUE, RED,   MAGENTA,               
                                                GREEN, CYAN,  YELLOW,BROWN,                        
                                                BRRED, GRAY };

int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//éè&#214;&#195;&#207;μí3&#214;D&#182;&#207;ó&#197;&#207;è&#188;&#182;·&#214;×é4         
        delay_init();                                            //&#209;óê±oˉêy3&#245;ê&#188;&#187;ˉ         
        uart_init(115200);                                        //3&#245;ê&#188;&#187;ˉ′&#174;&#191;ú
        LED_Init();                                                          //3&#245;ê&#188;&#187;ˉLED
        KEY_Init();                                                        //3&#245;ê&#188;&#187;ˉ°′&#188;ü
        BEEP_Init();                                                //3&#245;ê&#188;&#187;ˉ·&#228;&#195;ù&#198;÷
        LCD_Init();                                                        //3&#245;ê&#188;&#187;ˉLCD
        my_mem_init(SRAMIN);                    //3&#245;ê&#188;&#187;ˉ&#196;ú2&#191;&#196;ú′&#230;3&#216;

    POINT_COLOR = RED;
        LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");        
        LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 14-3");
        LCD_ShowString(30,50,200,16,16,"Priority Overturn");
        LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,90,200,16,16,"2016/11/25");
        
        //′′&#189;¨&#191;aê&#188;è&#206;&#206;&#241;
    xTaskCreate((TaskFunction_t )start_task,            //è&#206;&#206;&#241;oˉêy
                (const char*    )"start_task",          //è&#206;&#206;&#241;&#195;&#251;3&#198;
                (uint16_t       )START_STK_SIZE,        //è&#206;&#206;&#241;&#182;&#209;&#213;&#187;′óD&#161;
                (void*          )NULL,                  //′&#171;μY&#184;&#248;è&#206;&#206;&#241;oˉêyμ&#196;2&#206;êy
                (UBaseType_t    )START_TASK_PRIO,       //è&#206;&#206;&#241;ó&#197;&#207;è&#188;&#182;
                (TaskHandle_t*  )&StartTask_Handler);   //è&#206;&#206;&#241;&#190;&#228;±ú              
    vTaskStartScheduler();          //&#191;a&#198;&#244;è&#206;&#206;&#241;μ÷&#182;è
}

//&#191;aê&#188;è&#206;&#206;&#241;è&#206;&#206;&#241;oˉêy
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //&#189;&#248;è&#235;áù&#189;&#231;&#199;&#248;
        
        //′′&#189;¨&#187;¥3aD&#197;o&#197;á&#191;
        MutexSemaphore=xSemaphoreCreateMutex();
        
    //′′&#189;¨&#184;&#223;ó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;
    xTaskCreate((TaskFunction_t )high_task,            
                (const char*    )"high_task",           
                (uint16_t       )HIGH_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )HIGH_TASK_PRIO,        
                (TaskHandle_t*  )&HighTask_Handler);   
    //′′&#189;¨&#214;Dμèó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;
    xTaskCreate((TaskFunction_t )middle_task,     
                (const char*    )"middle_task",   
                (uint16_t       )MIDDLE_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )MIDDLE_TASK_PRIO,
                (TaskHandle_t*  )&MiddleTask_Handler);
        //′′&#189;¨μíó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;
    xTaskCreate((TaskFunction_t )low_task,     
                (const char*    )"low_task",   
                (uint16_t       )LOW_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LOW_TASK_PRIO,
                (TaskHandle_t*  )&LowTask_Handler);
    vTaskDelete(StartTask_Handler); //é&#190;3y&#191;aê&#188;è&#206;&#206;&#241;
    taskEXIT_CRITICAL();            //í&#203;3&#246;áù&#189;&#231;&#199;&#248;
}

//&#184;&#223;ó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;μ&#196;è&#206;&#206;&#241;oˉêy
void high_task(void *pvParameters)
{
        u8 num;
    u8 bufpend[]="high task Pend Sem\r\n";
    u8 bufrunn[]="high task Running!\r\n";
        
        POINT_COLOR = BLACK;
        LCD_DrawRectangle(5,110,115,314);         //&#187;-ò&#187;&#184;&#246;&#190;&#216;D&#206;        
        LCD_DrawLine(5,130,115,130);                //&#187;-&#207;&#223;
        POINT_COLOR = BLUE;
        LCD_ShowString(6,111,110,16,16,"High Task");
        

        while(1)
        {
                vTaskDelay(500);        //&#209;óê±500ms£&#172;ò2&#190;íê&#199;500&#184;&#246;ê±&#214;ó&#189;ú&#197;&#196;        
                num++;
                //printf("high task Pend Sem\r\n");
        uart1_send_buf(bufpend, sizeof(bufpend));
                xSemaphoreTake(MutexSemaphore,portMAX_DELAY);        //&#187;&#241;è&#161;&#187;¥3aD&#197;o&#197;á&#191;
                //printf("high task Running!\r\n");
        uart1_send_buf(bufrunn, sizeof(bufrunn));
                LCD_Fill(6,131,114,313,lcd_discolor[num%14]);         //ì&#238;3&#228;&#199;&#248;óò
                LED1=!LED1;
                xSemaphoreGive(MutexSemaphore);                                        //êí·&#197;D&#197;o&#197;á&#191;
                vTaskDelay(500);        //&#209;óê±500ms£&#172;ò2&#190;íê&#199;500&#184;&#246;ê±&#214;ó&#189;ú&#197;&#196;  
        }
}

//&#214;Dμèó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;μ&#196;è&#206;&#206;&#241;oˉêy
void middle_task(void *pvParameters)
{
        u8 num;
        u8 buf[]="middle task Running!\r\n";
        POINT_COLOR = BLACK;
        LCD_DrawRectangle(125,110,234,314); //&#187;-ò&#187;&#184;&#246;&#190;&#216;D&#206;        
        LCD_DrawLine(125,130,234,130);                //&#187;-&#207;&#223;
        POINT_COLOR = BLUE;
        LCD_ShowString(126,111,110,16,16,"Middle Task");
   
        while(1)
        {
                num++;
                //printf("middle task Running!\r\n");
        uart1_send_buf(buf, sizeof(buf));
                LCD_Fill(126,131,233,313,lcd_discolor[13-num%14]); //ì&#238;3&#228;&#199;&#248;óò
                LED0=!LED0;
        vTaskDelay(1000);        //&#209;óê±1s£&#172;ò2&#190;íê&#199;1000&#184;&#246;ê±&#214;ó&#189;ú&#197;&#196;        
        }
}

//μíó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;μ&#196;è&#206;&#206;&#241;oˉêy
void low_task(void *pvParameters)
{
        static u32 times;

    u8 buf[]="low task Running!\r\n";
        while(1)
        {
                xSemaphoreTake(MutexSemaphore,portMAX_DELAY);        //&#187;&#241;è&#161;&#187;¥3aD&#197;o&#197;á&#191;
                //printf("low task Running!\r\n");
        uart1_send_buf(buf, sizeof(buf));
                for(times=0;times<5000000;times++)                                //&#196;£&#196;aμíó&#197;&#207;è&#188;&#182;è&#206;&#206;&#241;&#213;&#188;ó&#195;&#187;¥3aD&#197;o&#197;á&#191;
                {
                        taskYIELD();                                                                //·¢&#198;eè&#206;&#206;&#241;μ÷&#182;è
                }
                xSemaphoreGive(MutexSemaphore);                                        //êí·&#197;&#187;¥3aD&#197;o&#197;á&#191;
                vTaskDelay(1000);        //&#209;óê±1s£&#172;ò2&#190;íê&#199;1000&#184;&#246;ê±&#214;ó&#189;ú&#197;&#196;        
        }
}




[/mw_shl_code]
回复

使用道具 举报

3

主题

1906

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4100
金钱
4100
注册时间
2018-8-14
在线时间
695 小时
发表于 2019-3-16 12:09:40 | 显示全部楼层
我为什么只让你贴最优先级别的任务呢, 因为问题在它哪儿
你用到的usart1_send_buf函数就是问题所在, 因为大部分时间都在轮询等待, 但它在等的时候又不会让低优先级别的任务做事。
我猜LCD_Fill也是这类型的函数。
非要用这类型函数的话, 也只可以把它放低优先级别的任务去
其实有很多方法可以用, DMA, 中断, 状态机。。都可以解决这些本来不是问题的问题
回复

使用道具 举报

44

主题

225

帖子

0

精华

高级会员

Rank: 4

积分
658
金钱
658
注册时间
2013-11-22
在线时间
131 小时
 楼主| 发表于 2019-3-18 10:19:51 | 显示全部楼层
edmund1234 发表于 2019-3-16 12:09
我为什么只让你贴最优先级别的任务呢, 因为问题在它哪儿
你用到的usart1_send_buf函数就是问题所在, 因 ...

uart1_send_buf的确是在轮询等待发送,不过程序中3个任务中都有vTaskDelay 做系统延时,调度器在这个延时中应该可以做任务切换的呀?   其实我的本意是在做互斥量操作时,本来就不希望调度,期望互斥操作的内部尽可能的快;另外从发送时间来看,我个人认为DMA并没有比轮询更快,DMA只是暂时释放CPU,可以转去做其它事情,但DMA无法减少发送数据本事的时间吧?因为比如同样发送100个字节,同样的波特率,物理特性就决定了最少需要的时间,不管轮询还是DMA,都得花费同样的发送时间吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 23:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表