📄 platform.c
字号:
#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 + -