OpenEdv-开源电子网

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

关于UCOSIII中同时等待多个内核对象中OSPendMulti这个函数出了点问题

[复制链接]

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2017-3-29
在线时间
39 小时
发表于 2020-3-16 11:49:44 | 显示全部楼层 |阅读模式
1金钱
我配置的思路也是按照例子来的,但是最后编译的时候会提示下面一个警告和一个错误
main.c(216): warning:  #223-D: function "OSPendMulti" declared implicitly
                  index=OSPendMulti(
main.c: 1 warning, 0 errors

..\OBJ\Template.axf: Error: L6218E: Undefined symbol OSPendMulti (referred from main.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 1 error messages.


我UCOSIII的配置是按照书里和视频里来的,前面的例子使用的时候没有出现问题,但是这里出现了引用的问题,不知道是哪里配置出了问题
下面是配置代码:
  1. #include "stm32f4xx.h"
  2. #include "usart.h"
  3. #include "delay.h"
  4. #include "sys.h"

  5. #include "includes.h"

  6. #include "led.h"
  7. #include "LCD.h"
  8. #include "stdlib.h"
  9. #include <os_app_hooks.h>
  10. #include "key.h"
  11. #include "malloc.h"
  12. #include "SRAM.h"
  13. //任务优先级
  14. #define START_TASK_PRIO                3
  15. //任务堆栈大小
  16. #define START_STK_SIZE                128
  17. //任务控制块
  18. OS_TCB StartTaskTCB;
  19. //任务堆栈
  20. CPU_STK START_TASK_STK[START_STK_SIZE];
  21. //任务函数
  22. void start_task(void *p_arg);


  23. /*****************************************************************/
  24. #define UOSCIII_MultiCore

  25. int lcd_discolor[14]={
  26.         WHITE, BLACK, BLUE,  BRED,      
  27.         GRED,  GBLUE, RED,   MAGENTA,   
  28.         GREEN, CYAN,  YELLOW,BROWN,        
  29.         BRRED, GRAY
  30. };

  31. /*****************************************************************/

  32. #ifdef UOSCIII_MultiCore

  33. #define TASK1_TASK_PRIO                                4
  34. #define TASK1_STK_SIZE                                128
  35. OS_TCB TASK1_TaskTCB;
  36. CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
  37. void task1_task(void *p_arg);

  38. #define MULTI_TASK_PRIO                5
  39. #define MULTI_STK_SIZE                128
  40. OS_TCB MULTI_TaskTCB;
  41. CPU_STK MULTI_TASK_STK[MULTI_STK_SIZE];
  42. void multi_task(void *p_arg);

  43. OS_SEM Test_Sem1;//信息量
  44. OS_SEM Test_Sem2;//信息量
  45. OS_Q Test_Q;//消息队列
  46. #define QUEUE_NUM                10//消息队列长度
  47. #define CORE_OBJ_NUM        3//内核对象个数一共3个:2个信号量和1个消息队列

  48. int main(void){
  49.         OS_ERR err;
  50.         CPU_SR_ALLOC();
  51.        
  52.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  53.         INTX_DISABLE();
  54.         BSP_Init();
  55.        
  56.         POINT_COLOR=RED;
  57.         LCD_ShowString(30,10,200,16,16,"Explorer STM32F4");
  58.         LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 13-1");
  59.         LCD_ShowString(30,50,200,16,16,"Events Flags");
  60.         LCD_ShowString(30,70,220,16,16,"KEY_UP:LED1 KEY0:Refresh LCD");
  61.         LCD_ShowString(30,90,200,16,16,"KEY1:Tmr1 KEY2:BEEP");
  62.         POINT_COLOR=BLACK;
  63.         LCD_DrawRectangle(5,110,234,314);
  64.         LCD_DrawLine(5,130,234,130);
  65.         POINT_COLOR=RED;
  66.         LCD_ShowString(50,111,200,16,16,"ObjRdy_Num: 0");
  67.         POINT_COLOR=BLUE;
  68.        
  69.         INTX_ENABLE();
  70.        
  71.         OSInit(&err);
  72.         OS_CRITICAL_ENTER();
  73.         OSTaskCreate(
  74.                 (OS_TCB *)&StartTaskTCB,
  75.                 (CPU_CHAR *)"start task",
  76.                 (OS_TASK_PTR)start_task,
  77.                 (void *)0,
  78.                 (OS_PRIO)START_TASK_PRIO,
  79.                 (CPU_STK *)&START_TASK_STK[0],
  80.                 (CPU_STK_SIZE)START_STK_SIZE/10,
  81.                 (CPU_STK_SIZE)START_STK_SIZE,
  82.                 (OS_MSG_QTY)0,
  83.                 (OS_TICK)0,
  84.                 (void *)0,
  85.                 (OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  86.                 (OS_ERR *)&err
  87.         );
  88.         OS_CRITICAL_EXIT();
  89.         OSStart(&err);
  90. }

  91. void start_task(void *p_arg){
  92.         OS_ERR err;
  93.         CPU_SR_ALLOC();
  94.         p_arg=p_arg;
  95.        
  96.         CPU_Init();
  97. #if OS_CFG_STAT_TASK_EN > 0u
  98.    OSStatTaskCPUUsageInit(&err);          //统计任务               
  99. #endif
  100.        
  101. #ifdef CPU_CFG_INT_DIS_MEAS_EN                //如果使能了测量中断关闭时间
  102.     CPU_IntDisMeasMaxCurReset();       
  103. #endif
  104.        
  105. #if        OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
  106.          //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
  107.         OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
  108. #endif       
  109.        
  110.         OS_CRITICAL_ENTER();
  111.         OSSemCreate(
  112.                 (OS_SEM *)&Test_Sem1,
  113.                 (CPU_CHAR *)"Test Sem1",
  114.                 (OS_SEM_CTR)0,
  115.                 (OS_ERR *)&err
  116.         );
  117.         OSSemCreate(
  118.                 (OS_SEM *)&Test_Sem2,
  119.                 (CPU_CHAR *)"Test Sem2",
  120.                 (OS_SEM_CTR)0,
  121.                 (OS_ERR *)&err
  122.         );
  123.         OSQCreate(
  124.                 (OS_Q *)&Test_Q,
  125.                 (CPU_CHAR *)"KEY Msg",
  126.                 (OS_MSG_QTY)QUEUE_NUM,
  127.                 (OS_ERR *)&err
  128.         );
  129.         OSTaskCreate(
  130.                 (OS_TCB *)&TASK1_TaskTCB,
  131.                 (CPU_CHAR *)"task1 task",
  132.                 (OS_TASK_PTR)task1_task,
  133.                 (void *)0,
  134.                 (OS_PRIO)TASK1_TASK_PRIO,
  135.                 (CPU_STK *)&TASK1_TASK_STK[0],
  136.                 (CPU_STK_SIZE)TASK1_STK_SIZE/10,
  137.                 (CPU_STK_SIZE)TASK1_STK_SIZE,
  138.                 (OS_MSG_QTY)0,
  139.                 (OS_TICK)0,
  140.                 (void *)0,
  141.                 (OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  142.                 (OS_ERR *)&err
  143.         );
  144.         OSTaskCreate(
  145.                 (OS_TCB *)&MULTI_TaskTCB,
  146.                 (CPU_CHAR *)"multi task",
  147.                 (OS_TASK_PTR)multi_task,
  148.                 (void *)0,
  149.                 (OS_PRIO)MULTI_TASK_PRIO,
  150.                 (CPU_STK *)&MULTI_TASK_STK[0],
  151.                 (CPU_STK_SIZE)MULTI_STK_SIZE/10,
  152.                 (CPU_STK_SIZE)MULTI_STK_SIZE,
  153.                 (OS_MSG_QTY)0,
  154.                 (OS_TICK)0,
  155.                 (void *)0,
  156.                 (OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  157.                 (OS_ERR *)&err
  158.         );
  159.         OS_CRITICAL_EXIT();
  160.         OSTaskDel((OS_TCB *)0, &err);
  161. }

  162. void task1_task(void *p_arg){
  163.         u8 key;
  164.         OS_ERR err;
  165.         u8 num;
  166.         u8 *pbuf;
  167.         static u8 msg_num;
  168.         pbuf=mymalloc(SRAMIN,10);
  169.         while(1){
  170.                 key=KEY_Scan(0);
  171.                 switch(key){
  172.                         case KEY1_PRES:
  173.                                 //发送信号量Test_Sem1
  174.                                 OSSemPost(&Test_Sem1, OS_OPT_POST_1, &err);
  175.                         break;
  176.                         case KEY0_PRES:
  177.                                 //发送信号量Test_Sem2
  178.                                 OSSemPost(&Test_Sem2, OS_OPT_POST_1, &err);
  179.                         break;
  180.                         case WKUP_PRES:
  181.                                 msg_num++;
  182.                                 sprintf((char *)pbuf, "ALIENTEK %d",msg_num);
  183.                                 //将pbuf的值发送给消息队列Test_Q
  184.                                 OSQPost(
  185.                                         (OS_Q *)&Test_Q,
  186.                                         (void *)pbuf,
  187.                                         (OS_MSG_SIZE)10,
  188.                                         (OS_OPT)OS_OPT_POST_FIFO,
  189.                                         (OS_ERR *)&err
  190.                                 );
  191.                         break;
  192.                 }
  193.                 num++;
  194.                 if(num==50){
  195.                         num=0;
  196.                         LED0=~LED0;
  197.                 }
  198.                 OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC, &err);
  199.         }
  200. }

  201. void multi_task(void *p_arg){
  202.         u8 num;
  203.         OS_ERR err;
  204.         OS_OBJ_QTY index;
  205.         OS_PEND_DATA pend_multi_tbl[CORE_OBJ_NUM];//定义的OS_PEND_DATA类型数组来表示含有多少个内核对象
  206.        
  207.         pend_multi_tbl[0].PendObjPtr=(OS_PEND_OBJ *)&Test_Sem1;
  208.         pend_multi_tbl[1].PendObjPtr=(OS_PEND_OBJ *)&Test_Sem2;
  209.         pend_multi_tbl[2].PendObjPtr=(OS_PEND_OBJ *)&Test_Q;
  210.        
  211.         while(1){
  212.                 //OSPendMulti等待内核对象,如果对象中有多个可用,则所有可用的信号量和消息都将返回给调用者,如果没有任何对象可用,则挂起当前任务等待:
  213.                 //对象变为可用/达到设定的超时时间/一个或多个任务被删除或终止
  214.                 index=OSPendMulti(
  215.                         (OS_PEND_DATA *)pend_multi_tbl,//多内核对象定义
  216.                         (OS_OBJ_QTY)CORE_OBJ_NUM,//内核对象数量
  217.                         (OS_TICK)0,//等待对象反应时间,设置成0若没有对象则一直等待下去
  218.                         (OS_OPT)OS_OPT_PEND_BLOCKING,//阻塞模式确定是否在没有任务下进行等待,与OS_TICK一起使用
  219.                         (OS_ERR *)&err
  220.                 );
  221.                 LCD_ShowNum(147,111,index,1,16);
  222.                 num++;
  223.                 LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
  224.                 LED1=~LED1;
  225.                 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);
  226.         }
  227. }

  228. void BSP_Init(void){
  229.         uart_init(115200);
  230.         delay_init(168);
  231.         LED_Init();
  232.         LCD_Init();
  233.         KEY_Init();
  234.         FSMC_SRAM_Init();
  235.         my_mem_init(SRAMIN);
  236.        
  237. }
复制代码


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

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2020-3-16 13:35:46 | 显示全部楼层
有OSPendMulti这个函数?你从哪里知道有这个函数的
一分耕耘一分收获。
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2017-3-29
在线时间
39 小时
 楼主| 发表于 2020-3-16 13:51:45 | 显示全部楼层
yklstudent 发表于 2020-3-16 13:35
有OSPendMulti这个函数?你从哪里知道有这个函数的

UCOS开发手册上,UCOS的库文件里有定义,在os_pend_multi.c中

  1. OS_OBJ_QTY  OSPendMulti (OS_PEND_DATA  *p_pend_data_tbl,
  2.                          OS_OBJ_QTY     tbl_size,
  3.                          OS_TICK        timeout,
  4.                          OS_OPT         opt,
  5.                          OS_ERR        *p_err)
  6. {
  7.     CPU_BOOLEAN   valid;
  8.     OS_OBJ_QTY    nbr_obj_rdy;
  9.     CPU_SR_ALLOC();



  10. #ifdef OS_SAFETY_CRITICAL
  11.     if (p_err == (OS_ERR *)0) {
  12.         OS_SAFETY_CRITICAL_EXCEPTION();
  13.         return ((OS_OBJ_QTY)0);
  14.     }
  15. #endif

  16. #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
  17.     if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Can't pend from an ISR                                 */
  18.        *p_err = OS_ERR_PEND_ISR;
  19.         return ((OS_OBJ_QTY)0);
  20.     }
  21. #endif

  22. #if OS_CFG_ARG_CHK_EN > 0u
  23.     if (p_pend_data_tbl == (OS_PEND_DATA *)0) {             /* Validate 'p_pend_data_tbl'                             */
  24.        *p_err = OS_ERR_PTR_INVALID;
  25.         return ((OS_OBJ_QTY)0);
  26.     }
  27.     if (tbl_size == (OS_OBJ_QTY)0) {                        /* Array size must be > 0                                 */
  28.        *p_err = OS_ERR_PTR_INVALID;
  29.         return ((OS_OBJ_QTY)0);
  30.     }
  31.     switch (opt) {
  32.         case OS_OPT_PEND_BLOCKING:
  33.         case OS_OPT_PEND_NON_BLOCKING:
  34.              break;

  35.         default:
  36.             *p_err = OS_ERR_OPT_INVALID;
  37.              return ((OS_OBJ_QTY)0);
  38.     }
  39. #endif

  40.     valid = OS_PendMultiValidate(p_pend_data_tbl,           /* -------- Validate objects to be OS_SEM or OS_Q ------- */
  41.                                  tbl_size);
  42.     if (valid == DEF_FALSE) {
  43.        *p_err = OS_ERR_OBJ_TYPE;                            /* Invalid, not OS_SEM or OS_Q                            */
  44.         return ((OS_OBJ_QTY)0);
  45.     }


  46.     CPU_CRITICAL_ENTER();
  47.     nbr_obj_rdy = OS_PendMultiGetRdy(p_pend_data_tbl,       /* --------- SEE IF OBJECT(s) HAVE BEEN POSTED ---------- */
  48.                                      tbl_size);
  49.     if (nbr_obj_rdy > (OS_OBJ_QTY)0) {
  50.         CPU_CRITICAL_EXIT();
  51.        *p_err = OS_ERR_NONE;
  52.         return ((OS_OBJ_QTY)nbr_obj_rdy);
  53.     }

  54.     if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {    /* Caller wants to block if not available?                */
  55.         CPU_CRITICAL_EXIT();
  56.        *p_err = OS_ERR_PEND_WOULD_BLOCK;                    /* No                                                     */
  57.         return ((OS_OBJ_QTY)0);
  58.     } else {
  59.         if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /* Can't pend when the scheduler is locked                */
  60.             CPU_CRITICAL_EXIT();
  61.            *p_err = OS_ERR_SCHED_LOCKED;
  62.             return ((OS_OBJ_QTY)0);
  63.         }
  64.     }
  65.                                                             /* Lock the scheduler/re-enable interrupts                */
  66.     OS_CRITICAL_ENTER_CPU_EXIT();
  67.                                                             /* ------ NO OBJECT READY, PEND ON MULTIPLE OBJECTS ----- */
  68.     OS_PendMultiWait(p_pend_data_tbl,                       /* Suspend task until object posted or timeout occurs     */
  69.                      tbl_size,
  70.                      timeout);

  71.     OS_CRITICAL_EXIT_NO_SCHED();

  72.     OSSched();                                              /* Find next highest priority task ready                  */

  73.     CPU_CRITICAL_ENTER();
  74.     switch (OSTCBCurPtr->PendStatus) {
  75.         case OS_STATUS_PEND_OK:                             /* We got one of the objects posted to                    */
  76.             *p_err = OS_ERR_NONE;
  77.              break;

  78.         case OS_STATUS_PEND_ABORT:                          /* Indicate that the multi-pend was aborted               */
  79.             *p_err = OS_ERR_PEND_ABORT;
  80.              break;

  81.         case OS_STATUS_PEND_TIMEOUT:                        /* Indicate that we didn't get semaphore within timeout   */
  82.             *p_err = OS_ERR_TIMEOUT;
  83.              break;

  84.         case OS_STATUS_PEND_DEL:                            /* Indicate that an object pended on has been deleted     */
  85.             *p_err = OS_ERR_OBJ_DEL;
  86.             break;

  87.         default:
  88.             *p_err = OS_ERR_STATUS_INVALID;
  89.              break;
  90.     }

  91.     OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
  92.     CPU_CRITICAL_EXIT();

  93.     return ((OS_OBJ_QTY)1);
  94. }
复制代码
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2020-3-16 19:19:12 | 显示全部楼层
你ucosiii版本是多少,最新V3.08.00版本里没有这个功能函数
一分耕耘一分收获。
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2017-3-29
在线时间
39 小时
 楼主| 发表于 2020-3-18 09:00:22 | 显示全部楼层
yklstudent 发表于 2020-3-16 19:19
你ucosiii版本是多少,最新V3.08.00版本里没有这个功能函数

我又去重新确认了一下,用的是
Version : V3.04.04
是用micrium上对STM32F429II的配置工程 改成F407的我自己的工程,
这里面有这个文件
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2017-3-29
在线时间
39 小时
 楼主| 发表于 2020-3-18 10:00:52 | 显示全部楼层
yklstudent 发表于 2020-3-16 19:19
你ucosiii版本是多少,最新V3.08.00版本里没有这个功能函数

我没找到v3.08,我看了下v3.07版本下,确实没有了这个文件和函数;
同时我找到了原因,
要用这个文件的函数需要在os_cfg.h中开启PEND_MULTI的使能就是将下面这个宏定义置位
  1. #define OS_CFG_PEND_MULTI_EN            1u   /* Enable (1) or Disable (0) code generation for multi-pend feature      */
复制代码
回复

使用道具 举报

0

主题

18

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
311
金钱
311
注册时间
2021-1-11
在线时间
193 小时
发表于 2023-3-7 11:28:00 | 显示全部楼层
需注意 os_cfg.h 中  #define OS_CFG_PEND_MULTI_EN        1u
有些例程中 os_cfg.h 中  #define OS_CFG_PEND_MULTI_EN        0u
造成报警
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-24 17:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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