⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 platform.c

📁 uclinux线程的创建、消息队列的创建、信号量、互斥信号量、信号等的创建
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <signal.h>#include <stdio.h>#include <stdarg.h>#include <fcntl.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <termios.h>#include <pthread.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/types.h>#include <asm/ioctl.h>
#include <errno.h>#include <sys/msg.h>
#include <asm/param.h>#include <semaphore.h>
#include <sys/sem.h>#include <sys/ipc.h>#include <sys/time.h>#include "platform.h"

#ifndef __TASK__
/************************************************************************************
                                    发 起 任 务
函数名: taskSpawn()

功能:   发起一个任务

参数:   name        指针类型,任务的名称,仅作为创建任务出错时打印使用

        priority    实时任务的优先级,linux下实时任务的优先级范围为1-99,其中99
                    为最高优先级,但为了适应vxworks及其他实时操作系统的概念,本函数
                    使用1为最高优先级,99为最低优先级。
                    
        options     未使用

        stackSize   指定任务堆栈的大小,且该值必须大于16384Byte

        entryPt     任务的入口函数

        arg1        任务函数的入参, 指针强制转换成的整型值

        arg2        发起任务的类型,可选参数为:
                    SCHED_FIFO  :发起一个先进先出的实时任务,实时系统需要的正是这一类
                                 任务,FIFO任务根据优先级调度,如果没有高优先级任务到
                                 达,则该任务将一直占用cpu,直到主动放弃。
                    SCHED_RR    :发起一个时间片轮转实时任务,是FIFO类型任务的一个补充,
                                 为了保证多个具有相同优先级的实时任务任务具有基本相等
                                 的使用cpu的机会,应将这几个任务设置为本类型。
                    SCHED_OTHER :发起一个分时调度的任务,该任务不具有实时性,优先级也
                                 是最低的,始终给实时任务让道。
    
        arg3-10     未使用
        
返回值: OK          创建任务成功
        ERROR       创建失败
*************************************************************************************/
int taskSpawn    (    USE char *  name,      /* 任务的名称 */
    USE int     priority,  /* 实时任务的优先级 1-99,1为高优先级 */    NO int     options,   /* 选项 */    USE int     stackSize, /* 任务堆栈的大小 必须大于16384字节*/
    USE void * (*entryPt)(void *),   /* 任务的函数入口 */    USE int     arg1,      /* 这是一个指针值,任务入口函数的入参 */    NO int     arg2,    /*任务类型,实时任务可使用SCHED_FIFO和和SCHED_RR*/
    NO int     arg3,   /*下面的参数不使用*/
    NO int     arg4,    NO int     arg5,    NO int     arg6,    NO int     arg7,    NO int     arg8,    NO int     arg9,
    NO int     arg10 
    ){
    int nRet = 0;
    struct sched_param tSchParam;	    pthread_attr_t tThreadAttr;    pthread_t thread_id;    
    /*判断静态优先级的正确性*/
    if (priority > sched_get_priority_max(SCHED_FIFO)
        ||priority < sched_get_priority_min(SCHED_FIFO))
    {        pl(); print("priority must be between %d and %d\n", 
                    sched_get_priority_min(SCHED_FIFO),
                    sched_get_priority_max(SCHED_FIFO));
        return ERROR;    }        /*初始化线程参数*/    pthread_attr_init(&tThreadAttr);    /*设置使用tThreadAttr指定的参数,而不是从调用任务那继承*/    tThreadAttr.__inheritsched = PTHREAD_EXPLICIT_SCHED;        /*设置调度策略    pthread_attr_getschedpolicy(&tThreadAttr, &nSchPolicy);*/    /*nSchPolicy = arg9;创建的所有任务都将是实时任务    pthread_attr_setschedpolicy(&tThreadAttr, nSchPolicy);*/    /*设置进程为分离状态,任务分离后将不需要用pthread_join()等待*/    //pthread_attr_setdetachstate(&tThreadAttr, PTHREAD_CREATE_DETACHED);


    /*设置堆栈的大小*/
    if (pthread_attr_setstacksize(&tThreadAttr, stackSize) != OK)
    {
        print("pthread_attr_setstacksize false,stackSize must > 16k Byte\n");
        return ERROR;
    }
        
    nRet = pthread_create(&thread_id, &tThreadAttr, entryPt, (void *)arg1);
    if(nRet != OK)    {      perror(NULL); print(name);
      return ERROR;    }    if (arg2 == SCHED_FIFO || arg2 == SCHED_RR)
    {        /* 设置实时任务的优先级*/        tSchParam.sched_priority = 100 - priority;//ucliunx优先级和vxworks相反,0为最低静态优先级        if (pthread_setschedparam(thread_id, SCHED_FIFO, &tSchParam) != OK)        {            print("set task %s priority false\n", name);            perror(0);        }    }    else    {            }        return thread_id;
}

/********************************************************************************
                                    删除一个任务
函数名  : taskDelete()

功能    : 删除一个已经存在的任务

参数    : tid       被删除任务的id

返回值  : OK        成功删除任务
          ERROR     删除失败
                                    
*********************************************************************************/
int taskDelete    (    int tid /* task ID of task to delete */    ){    if (pthread_cancel(tid) != OK)
    {        perror(NULL); pl();print("taskDelete\n");
        return ERROR;    }        return OK;}

/********************************************************************************
                                    当前任务的id
函数名  : taskIdSelf()

功能    : 查询当前任务的id

参数    : 无

返回值  : 当前任务id        成功
          ERROR             查询失败
                                    
*********************************************************************************/
int taskIdSelf()
{
    return pthread_self();
}
/*对linux线程进行的操作,线程创建好后即是可取消状态,但需等到取消点才能真正退出*/
void initLinuxTask(){    /*设置进程可被其他线程杀死,具体可通过在linux下    执行man pthread_setcancelstate来获得帮助*/    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);    /*设置线程收到中止信号后立即中止, 不需要等执行到到取消点*/    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);}
/*******************************************************************************
                                     任务延时
函数名  :   taskDelay()

功能    :   任务延时

参数    :   ticks       任务延迟的tick数,arm下如果宏CLOCKS_PER_SECOND设置为100,
                        则每个tick的时长为10ms
                        
返回值  :   OK          设置成功
            ERROR       设置失败
********************************************************************************/
int taskDelay
    (    int ticks /* number of ticks to delay task */    ){    return usleep(TICK_INTEVAL_us*ticks); 
}
/*用来锁定线程的互斥信号量*/SEM_ID taskLockMutexSem;
static void initTaskLockMutextSem()
{    taskLockMutexSem = semMCreate(0);
    if (taskLockMutexSem == NULL)
    {
        pl();print("initTaskLockMutextSem error,kill main()\n");
        exit(0);
    }
}
/**********************************************************************
注意,linux下无锁定任务切换的函数,只能通过线程互斥方法来实现,即所有 "用户任务" 在执行前都需要取得该信号量,如果取不到则永远等待,从而实现让取得信号量的任务一直执行到释放信号量的地方。***********************************************************************/
#define taskLock ()\{\    semTake(taskLockMutexSem, WAIT_FOREVER);\}\#define taskUnLock (void)\{\    semGive(taskLockMutexSem);\}/*该功能经测试没有达到预期效果,不能使用*/
int taskSafe( ){    /*防止本线程程被其他线程杀死,具体可通过在linux下    执行man pthread_setcancelstate来获得帮助*/
    int old=2;
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);
    
    print("oldstate = %d\n", old);

    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);
    
    print("newstate = %d\n", old);
    
    return OK;
}
/*该功能经测试没有达到预期效果,不能使用*/
int taskUnSafe( ){    /*设置进程可被其他线程杀死,具体可通过在linux下    执行man pthread_setcancelstate来获得帮助*/    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);    /*设置线程收到中止信号后立即中止, 不需要等执行到到取消点*/    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);    return OK;}

/*主进程函数,该函数不能返回*/
int main()
{    initSemList();
    initTaskLockMutextSem();
    userApp();    for(;;)
    {        sleep(2000);    }    return OK;//永远不会执行到这个地方
}/*用户应用程序入口*/
void userApp(){    //testSemM();    testTaskDel();
    //testPrio();
    //SemM();
}
#endif


#ifndef __MSG_Q__
/*****************************************************************************
                                删除一个消息队列
函数名   : msgQDelete()
  
功能     : 删除linux消息队列
  
参数     : msgQId      需要删除的消息队列的id
    
返回值:    OK(0)       成功返回
            ERROR(-1)   调用失败
******************************************************************************/
int  msgQDelete    (    USE MSG_Q_ID  msgQId /* message queue to delete */
    ){    return msgctl(msgQId, IPC_RMID, NULL);}/****************************************************************************
                                创建一个消息队列
函数名   : msgQCreate()
  
功能     : 创建一个linux消息队列
  
参数     : maxMsgs      消息队列可容纳的消息个数
            maxMsgLength 单个消息的最大长度
            options      未使用
            
返回值   : 消息队列的id(大于0)       成功返回
            NULL(0)                   调用失败
******************************************************************************/
MSG_Q_ID msgQCreate
    (       USE int maxMsgs, /*最大消息个数*/      USE int maxMsgLength,/*单个消息最大长度*/      NO int options/*选项,linux未使用*/    ){    int msgQid = 0;    struct msqid_ds msg_info;    /*创建了一个消息队列,0666指定了访问权限,所有进程都可以访问*/    msgQid = msgget(IPC_PRIVATE, IPC_CREAT|IPC_EXCL|0666);    if(msgQid == -1)    {    	return NULL;    }        /*获取消息队列的属性*/    if (msgctl(msgQid,IPC_STAT,&msg_info) == ERROR)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -