1 Star 0 Fork 21

forest_555/raw-os

forked from jorya_txj/raw-os 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
raw_task.c 35.61 KB
一键复制 编辑 原始数据 按行查看 历史
jorya_txj 提交于 2016-07-20 20:16 +08:00 . tickless part 5
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622
/*
raw os - Copyright (C) Lingjun Chen(jorya_txj).
This file is part of raw os.
raw os is free software; you can redistribute it it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.
raw os is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. if not, write email to jorya.txj@gmail.com
---
A special exception to the LGPL can be applied should you wish to distribute
a combined work that includes raw os, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/* 2012-4 Created by jorya_txj
* xxxxxx please added here
*/
#include <raw_api.h>
/*
************************************************************************************************************************
* Create a task
*
* Description: This function is called to create a task.
*
* Arguments : task_obj is a pointer to the RAW_TASK_OBJ.
* ------
* task_name is a string name assigned to a task
* ------
* task_arg is an argument passing to task
* ------
* task_prio is a priority to task, smalled priority is higher priority
* -------
* time_slice is run time slice tick to task, assign to 0 means it will accept default slice time
* -------
* task_stack_base is a low address of memory
* ------
* stack_size is the number of stack elements of this task
* ------
* task_entry is the entry of this task
* ------
* auto_start is the flag to activate task:
* RAW_AUTO_START 1
* RAW_DONT_START 0
*
* Returns : RAW_IDLE_EXIT the idle priority should only be created once.
* -----
* RAW_OS_STOPPED raw os has not been started yet
* -----
* RAW_SUCCESS raw os return success.
*
* Note(s) :
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_task_create(RAW_TASK_OBJ *task_obj, RAW_U8 *task_name, void *task_arg,
RAW_U8 task_prio, RAW_U32 time_slice, PORT_STACK *task_stack_base,
RAW_U32 stack_size, RAW_TASK_ENTRY task_entry, RAW_U8 auto_start)
{
PORT_STACK *p_stack;
RAW_U32 i;
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_obj == 0) {
return RAW_NULL_OBJECT;
}
if (task_prio >= CONFIG_RAW_PRIO_MAX) {
return RAW_BYOND_MAX_PRIORITY;
}
if (task_stack_base == 0) {
return RAW_NULL_POINTER;
}
if (task_entry == 0) {
return RAW_NULL_POINTER;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
/*Idle task is only allowed to created once*/
if (task_prio == IDLE_PRIORITY) {
if (idle_task_exit) {
RAW_CRITICAL_EXIT();
return RAW_IDLE_EXIT;
}
idle_task_exit = 1u;
}
RAW_CRITICAL_EXIT();
raw_memset(task_obj, 0, sizeof(RAW_TASK_OBJ));
#if (CONFIG_SCHED_FIFO_RR > 0)
if (time_slice) {
task_obj->time_total = time_slice;
}
else {
task_obj->time_total = TIME_SLICE_DEFAULT;
}
task_obj->time_slice = task_obj->time_total;
task_obj->sched_way = SCHED_RR;
#endif
if (auto_start) {
task_obj->task_state = RAW_RDY;
}
else {
task_obj->task_state = RAW_SUSPENDED;
task_obj->suspend_count = 1u;
}
/*init all the stack element to 0*/
task_obj->task_stack_base = task_stack_base;
p_stack = task_stack_base;
for (i = 0; i < stack_size; i++) {
*p_stack++ = 0;
}
task_obj->task_name = task_name;
task_obj->priority = task_prio;
task_obj->bpriority = task_prio;
task_obj->stack_size = stack_size;
#if (RAW_CPU_STACK_DOWN > 0)
p_stack = task_obj->task_stack_base;
*p_stack = RAW_TASK_STACK_CHECK_WORD;
#else
p_stack = (PORT_STACK *)(task_obj->task_stack_base) + task_obj->stack_size - 1;
*p_stack = RAW_TASK_STACK_CHECK_WORD;
#endif
task_obj->task_stack = port_stack_init(task_stack_base, stack_size, task_arg, task_entry);
#if (CONFIG_RAW_USER_HOOK > 0)
task_create_hook(task_obj);
#endif
TRACE_TASK_CREATE(task_obj);
RAW_CRITICAL_ENTER();
list_insert(&(raw_task_debug.task_head), &task_obj->task_debug_list);
if (auto_start) {
add_ready_list_end(&raw_ready_queue, task_obj);
}
if (raw_os_active != RAW_OS_RUNNING) { /* Return if multitasking has not started */
RAW_CRITICAL_EXIT();
return RAW_OS_STOPPED;
}
RAW_CRITICAL_EXIT();
if (auto_start) {
raw_sched();
}
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Check Free elemenets of task stack
*
* Description: This function is called to check free stack elemenets of task stack
*
* Arguments :Free_stack is pointer to RAW_U32 and it will be filled later.It will be filled with free stack elements but not freebytes.
* -----
*
*
*
* Returns RAW_SUCCESS: raw os return success.
*
* Note(s) :Stack space probably be used more than this API get, so increase about 20% stack space!
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_STACK_CHECK > 0)
RAW_OS_ERROR raw_task_stack_check(RAW_TASK_OBJ *task_obj, RAW_U32 *free_stack)
{
PORT_STACK *task_stack;
RAW_U32 free_stk = 0;
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_obj == 0) {
return RAW_NULL_OBJECT;
}
if (free_stack == 0) {
return RAW_NULL_POINTER;
}
if (task_obj->task_state == RAW_DELETED) {
return RAW_INVALID_TASK_STATE;
}
#endif
#if (RAW_CPU_STACK_DOWN > 0)
task_stack = task_obj->task_stack_base + 1;
while (*task_stack++ == 0) {
free_stk++;
}
#else
task_stack = (PORT_STACK *)(task_obj->task_stack_base) + task_obj->stack_size - 2;
while (*task_stack-- == 0) {
free_stk++;
}
#endif
*free_stack = free_stk;
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Check Free elemenets of isr stack
*
* Description: This function is called to check free stack elemenets of isr stack
*
* Arguments :Free_stack is pointer to RAW_U32 and it will be filled later.It will be filled with free stack elements but not freebytes.
* -----
*
*
*
* Returns RAW_SUCCESS: raw os return success.
*
* Note(s) :ISR free stack need double or tripple because isr can be nested.
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_ISR_STACK_CHECK > 0)
RAW_OS_ERROR raw_isr_stack_check(RAW_U32 *free_stack)
{
RAW_U32 free_isr_stack;
free_isr_stack = port_isr_stack_free_check();
*free_stack = free_isr_stack;
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* disable the whole schedule
*
* Description: This function is called to disable the preempt of the raw os
*
* Arguments : None
*
*
*
*
* Returns RAW_SUCCESS raw os return success.
* RAW_NOT_CALLED_BY_ISR: can not call this API under ISR
* Note(s) :
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_disable_sche(void)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
if (raw_sched_lock >= 250u) {
return RAW_SCHED_OVERFLOW;
}
#endif
RAW_CPU_DISABLE();
#if (RAW_SCHE_LOCK_MEASURE_CHECK > 0)
sche_disable_measure_start();
#endif
raw_sched_lock++;
RAW_CPU_ENABLE();
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Enable the whole schedule
*
* Description: This function is called to enable the preempt of the raw os
*
* Arguments : NONE
*
*
*
*
* Returns RAW_SUCCESS raw os return success.
* RAW_NOT_CALLED_BY_ISR: can not call this API under ISR
* Note(s) :
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_enable_sche(void)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
if (raw_sched_lock == 0u) {
return RAW_SCHED_INVALID;
}
#endif
RAW_CPU_DISABLE();
raw_sched_lock--;
if (raw_sched_lock) {
RAW_CPU_ENABLE();
return RAW_SCHED_LOCKED;
}
#if (RAW_SCHE_LOCK_MEASURE_CHECK > 0)
sche_disable_measure_stop();
#endif
RAW_CPU_ENABLE();
raw_sched ();
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Task sleep
*
* Description: This function is called to cause the task to sleep
*
* Arguments : dly if dly bigged than zero than this task will go to sleep as specified ticks.
* if dly equals zero than this fucntion implement the relinquish function , put the task back
* to the same priority list.
*
*
*
*
*
* Returns RAW_SUCCESS: raw os return success.
* RAW_BLOCK_ABORT:Dly was aborted
* RAW_SCHED_DISABLE:system is locked so task can not sleep
* Note(s) :
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_SLEEP > 0)
RAW_OS_ERROR raw_sleep(RAW_TICK_TYPE dly)
{
RAW_OS_ERROR sleep_result;
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
if (dly == 0u) {
return RAW_INVALID_PARAMETER;
}
#endif
RAW_CRITICAL_ENTER();
/*system is locked so task can not sleep just return immediately*/
SYSTEM_LOCK_PROCESS();
raw_task_active->task_state = RAW_DLY;
#if (CONFIG_RAW_DYNAMIC_TICK > 0)
port_elapsed_ticks = port_elapsed_ticks_get();
tick_list_insert(raw_task_active, dly + port_elapsed_ticks);
#else
tick_list_insert(raw_task_active, dly);
#endif
remove_ready_list(&raw_ready_queue, raw_task_active);
RAW_CRITICAL_EXIT();
raw_sched();
USER_CPU_INT_DISABLE();
/*Is task timeout normally after sleep?*/
sleep_result = block_state_post_process(raw_task_active);
USER_CPU_INT_ENABLE();
return sleep_result;
}
RAW_OS_ERROR raw_task_yield(void)
{
if (raw_task_active == 0) {
return RAW_NULL_OBJECT;
}
if (raw_task_active->task_state == RAW_INVALID_STATE) {
return RAW_INVALID_TASK_STATE;
}
/*make current task to the end of ready list*/
move_to_ready_list_end(&raw_ready_queue, raw_task_active);
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Task sleep with specified time.
*
* Description: This function is called to cause the task to sleep with specified time.
*
* Arguments : hours: hours need to sleep, range from 0-999
* minutes:minutes need to sleep, range from 0-9999
* seconds:seconds need to sleep, range from 0-65535
* milli:mili seconds need to sleep, range from 0-4294967295.
*
* Returns RAW_SUCCESS: raw os return success.
* RAW_BLOCK_ABORT:Dly was aborted
* RAW_SCHED_DISABLE:system is locked so task can not sleep
* RAW_TIME_ZERO_SLEEP:zero ticks sleep is not allowed.
*
* Note(s) :you may still need to check parameters to avoid ticks overflow happen, if you sleep too long.
* this function is assumed RAW_TICKS_PER_SECOND is under 1000hz.
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_time_sleep(RAW_U16 hours, RAW_U16 minutes, RAW_U16 seconds, RAW_U32 milli)
{
RAW_TICK_TYPE tick_rate;
RAW_TICK_TYPE ticks;
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
if (minutes > 9999u) {
return RAW_INVALID_MINUTES;
}
if (hours > 999u) {
return RAW_INVALID_HOURS;
}
tick_rate = RAW_TICKS_PER_SECOND;
ticks = (hours * 3600u + minutes * 60u + seconds) * tick_rate
+ (tick_rate * (milli + 500u / tick_rate)) / 1000u;
if (ticks) {
return raw_sleep(ticks);
}
return RAW_TIME_ZERO_SLEEP;
}
#endif
/*
************************************************************************************************************************
* Suspend the specified task
*
* Description: This function is called to suspended the task specified by task_ptr
*
* Arguments :task_ptr is the address of task object
*
*
*
*
* Returns :RAW_SCHED_LOCKED loked task can not be suspended.
*
* Note(s) :RAW_INVALID_TASK_STATE wrong task state, probally sysytem error.
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_SUSPEND > 0)
RAW_OS_ERROR raw_task_suspend(RAW_TASK_OBJ *task_ptr)
{
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
#endif
if (task_ptr->priority == IDLE_PRIORITY) {
return RAW_SUSPEND_TASK_NOT_ALLOWED;
}
return task_suspend(task_ptr);
}
RAW_OS_ERROR task_suspend(RAW_TASK_OBJ *task_ptr)
{
RAW_SR_ALLOC();
RAW_CRITICAL_ENTER();
if (task_ptr == raw_task_active) {
SYSTEM_LOCK_PROCESS();
}
switch (task_ptr->task_state) {
case RAW_RDY:
task_ptr->suspend_count = 1;
task_ptr->task_state = RAW_SUSPENDED;
remove_ready_list(&raw_ready_queue, task_ptr);
break;
case RAW_DLY:
task_ptr->suspend_count = 1;
task_ptr->task_state = RAW_DLY_SUSPENDED;
break;
case RAW_PEND:
task_ptr->suspend_count = 1;
task_ptr->task_state = RAW_PEND_SUSPENDED;
break;
case RAW_PEND_TIMEOUT:
task_ptr->suspend_count = 1;
task_ptr->task_state = RAW_PEND_TIMEOUT_SUSPENDED;
break;
case RAW_SUSPENDED:
case RAW_DLY_SUSPENDED:
case RAW_PEND_SUSPENDED:
case RAW_PEND_TIMEOUT_SUSPENDED:
if (task_ptr->suspend_count == (RAW_SUSPEND_NESTED_TYPE) - 1) {
RAW_CRITICAL_EXIT();
return RAW_SUSPENDED_COUNT_OVERFLOWED;
}
task_ptr->suspend_count++;
break;
default:
RAW_CRITICAL_EXIT();
return RAW_INVALID_TASK_STATE;
}
RAW_CRITICAL_EXIT();
TRACE_TASK_SUSPEND(raw_task_active, task_ptr);
raw_sched();
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Resume the specified task
*
* Description: This function is called to resume the specified task.
*
* Arguments :task_ptr is the address of task object
* -----
*
*
*
* Returns RAW_SUCCESS raw os return success.
*
* Note(s) :
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_RESUME > 0)
RAW_OS_ERROR raw_task_resume(RAW_TASK_OBJ *task_ptr)
{
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
#endif
return task_resume(task_ptr);
}
RAW_OS_ERROR task_resume(RAW_TASK_OBJ *task_ptr)
{
RAW_SR_ALLOC();
RAW_CRITICAL_ENTER();
switch (task_ptr->task_state) {
case RAW_RDY:
case RAW_DLY:
case RAW_PEND:
case RAW_PEND_TIMEOUT:
RAW_CRITICAL_EXIT();
return HAS_NOT_SUSPENDED;
case RAW_SUSPENDED:
task_ptr->suspend_count--;
if (task_ptr->suspend_count == 0) {
/*Make task ready*/
task_ptr->task_state = RAW_RDY;
add_ready_list(&raw_ready_queue, task_ptr);
}
break;
case RAW_DLY_SUSPENDED:
task_ptr->suspend_count--;
if (task_ptr->suspend_count == 0) {
task_ptr->task_state = RAW_DLY;
}
break;
case RAW_PEND_SUSPENDED:
task_ptr->suspend_count--;
if (task_ptr->suspend_count == 0) {
task_ptr->task_state = RAW_PEND;
}
break;
case RAW_PEND_TIMEOUT_SUSPENDED:
task_ptr->suspend_count--;
if (task_ptr->suspend_count == 0) {
task_ptr->task_state = RAW_PEND_TIMEOUT;
}
break;
default:
RAW_CRITICAL_EXIT();
return RAW_INVALID_TASK_STATE;
}
RAW_CRITICAL_EXIT();
TRACE_TASK_RESUME(raw_task_active, task_ptr);
raw_sched();
return RAW_SUCCESS;
}
#endif
#if (CONFIG_RAW_TASK_PRIORITY_CHANGE > 0)
RAW_OS_ERROR change_internal_task_priority(RAW_TASK_OBJ *task_ptr, RAW_U8 new_priority)
{
RAW_U8 old_pri;
RAW_MUTEX *mtxcb;
RAW_TASK_OBJ *mtxtsk;
do {
if (task_ptr->priority != new_priority) {
switch (task_ptr->task_state) {
case RAW_RDY:
remove_ready_list(&raw_ready_queue, task_ptr);
task_ptr->priority = new_priority;
if (task_ptr == raw_task_active) {
add_ready_list_head(&raw_ready_queue, task_ptr);
}
else {
add_ready_list_end(&raw_ready_queue, task_ptr);
}
task_ptr = 0;
break;
case RAW_DLY:
case RAW_SUSPENDED:
case RAW_DLY_SUSPENDED:
/* Set new task priority*/
task_ptr->priority = new_priority;
task_ptr = 0;
break;
case RAW_PEND:
case RAW_PEND_TIMEOUT:
case RAW_PEND_SUSPENDED:
case RAW_PEND_TIMEOUT_SUSPENDED:
old_pri = task_ptr->priority;
task_ptr->priority = new_priority;
change_pend_list_priority(task_ptr);
if (task_ptr->block_obj->object_type == RAW_MUTEX_OBJ_TYPE) {
mtxcb = (RAW_MUTEX *)(task_ptr->block_obj);
mtxtsk = mtxcb->mtxtsk;
if (mtxtsk->priority > task_ptr->priority) {
/* Since the highest priority of the lock wait task
became higher, raise the lock get task priority
higher */
task_ptr = mtxtsk;
}
/*the highest priority task blocked on this mutex may decrease priority so reset the mutex task priority*/
else if (mtxtsk->priority == old_pri) {
/*find suitable tcb priority*/
new_priority = mutex_priority_look(mtxtsk, 0);
if (new_priority != mtxtsk->priority ) {
/* Change priority of lock get task */
task_ptr = mtxtsk;
}
else {
task_ptr = 0;
}
}
else {
/*tcb->priority<= mtxtsk->priority and mtxtsk->priority != oldpri*/
task_ptr = 0;
}
}
else {
task_ptr = 0;
}
break;
default:
port_system_error_process(RAW_INVALID_TASK_STATE, 0, 0, 0, 0, 0, 0);
return RAW_INVALID_TASK_STATE;
}
}
else {
task_ptr = 0;
}
} while (task_ptr != 0);
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Change the specified task priority
*
* Description: This function is called to change the specified task priority.
*
* Arguments :task_ptr is the address of task object
* -----
* new_priority is the new priority assigned to.
* -----
* old_priority will be filled with the orginal task priority if the task priority is changed success.
*
*
* Returns
* RAW_INVALID_TASK_STATE: Probablly system errors happens
* RAW_EXCEED_CEILING_PRIORITY: exceed mutex ceiling priority
* RAW_SUCCESS: raw os return success
*
* Note(s)
*l
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_task_priority_change(RAW_TASK_OBJ *task_ptr, RAW_U8 new_priority, RAW_U8 *old_priority)
{
RAW_U8 ret_pri = 0;
RAW_OS_ERROR error;
RAW_SR_ALLOC();
ret_pri = ret_pri;
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (old_priority == 0) {
return RAW_NULL_OBJECT;
}
#endif
/*Idle task is not allowed to change priority*/
if (task_ptr->priority >= IDLE_PRIORITY) {
return RAW_CHANGE_PRIORITY_NOT_ALLOWED;
}
/*Not allowed change to idle priority*/
if (new_priority == IDLE_PRIORITY) {
return RAW_CHANGE_PRIORITY_NOT_ALLOWED;
}
/*deleted task is not allowed to change priority*/
if (task_ptr->task_state == RAW_DELETED) {
return RAW_INVALID_TASK_STATE;
}
RAW_CRITICAL_ENTER();
/*Limit the priority change by mutex at task priority change*/
ret_pri = chg_pri_mutex(task_ptr, new_priority, &error);
if (error != RAW_SUCCESS) {
RAW_CRITICAL_EXIT();
return error;
}
task_ptr->bpriority = new_priority;
/*new pripority may change here!*/
new_priority = ret_pri;
*old_priority = task_ptr->priority;
error = change_internal_task_priority(task_ptr, new_priority);
if (error != RAW_SUCCESS) {
RAW_CRITICAL_EXIT();
return error;
}
RAW_CRITICAL_EXIT();
TRACE_TASK_PRIORITY_CHANGE(task_ptr, new_priority);
raw_sched();
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Delete the task
*
* Description: This function is called to delete the specified task and will cause reschdule
*
* Arguments : task_ptr is the address of task object
*
*
*
*
* Returns : RAW_INVALID_TASK_STATE: Probablly system errors happens
* RAW_SUCCESS: raw os return success
*
* Note(s) You can not delete a task which own a semphore or mutex.Highly recommended task to be deleted byself.
Task state will change to RAW_DELETED.
*
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_DELETE > 0)
RAW_OS_ERROR raw_task_delete(RAW_TASK_OBJ *task_ptr)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
if (task_ptr->priority == IDLE_PRIORITY) {
return RAW_DELETE_TASK_NOT_ALLOWED;
}
RAW_CRITICAL_ENTER();
if (task_ptr == raw_task_active) {
SYSTEM_LOCK_PROCESS();
}
/*free all the mutex which task_ptr hold!*/
raw_task_free_mutex(task_ptr);
switch (task_ptr->task_state) {
case RAW_RDY:
remove_ready_list(&raw_ready_queue, task_ptr);
task_ptr->task_state = RAW_DELETED;
break;
case RAW_SUSPENDED:
task_ptr->task_state = RAW_DELETED;
break;
case RAW_DLY:
case RAW_DLY_SUSPENDED:
tick_list_remove(task_ptr);
task_ptr->task_state = RAW_DELETED;
break;
case RAW_PEND:
case RAW_PEND_SUSPENDED:
case RAW_PEND_TIMEOUT:
case RAW_PEND_TIMEOUT_SUSPENDED:
tick_list_remove(task_ptr);
list_delete(&task_ptr->task_list);
task_ptr->task_state = RAW_DELETED;
mutex_state_change(task_ptr);
break;
default:
RAW_CRITICAL_EXIT();
return RAW_INVALID_TASK_STATE;
}
list_delete(&task_ptr->task_debug_list);
TRACE_TASK_DELETE(task_ptr);
#if (CONFIG_RAW_USER_HOOK > 0)
raw_task_delete_hook(task_ptr);
#endif
RAW_CRITICAL_EXIT();
raw_sched();
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Set the task user data pointer
*
* Description: This function is called to set the task user data pointer
*
* Arguments :task_ptr is the address of task object
* -----
* user_point is the n user data pointer
* ------
* point_position is the position of the user_data_pointer array, it starts from 0!
*
* Returns : point_position starts from 0.
*
*
*
************************************************************************************************************************
*/
#if (CONFIG_USER_DATA_POINTER > 0)
void raw_set_task_user_point(RAW_TASK_OBJ *task_ptr, void *user_point, RAW_U32 point_position)
{
RAW_SR_ALLOC();
RAW_CPU_DISABLE();
task_ptr->user_data_pointer[point_position] = user_point;
RAW_CPU_ENABLE();
}
void *raw_get_task_user_point(RAW_TASK_OBJ *task_ptr, RAW_U32 point_position)
{
return task_ptr->user_data_pointer[point_position];
}
#endif
/*
************************************************************************************************************************
* Change the specified task time slice
*
* Description: This function is called to change the specified task time slice
*
* Arguments :task_ptr is the address of task object
* -----
* new_time_slice is the new time slice assigned to task
*
*
* Returns RAW_SUCCESS: raw os return success
* Note(s) If new_time_slice is 0 then TIME_SLICE_DEFAULT will be the default time slice value
*
*
************************************************************************************************************************
*/
#if (CONFIG_SCHED_FIFO_RR > 0)
RAW_OS_ERROR raw_task_time_slice_change(RAW_TASK_OBJ *task_ptr, RAW_U32 new_time_slice)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
if (new_time_slice) {
/*assign the new time slice*/
task_ptr->time_total = new_time_slice;
}
else {
/*assign the default time slice*/
task_ptr->time_total = TIME_SLICE_DEFAULT;
}
task_ptr->time_slice = task_ptr->time_total;
RAW_CRITICAL_EXIT();
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Change the specified task sched way
*
* Description: This function is called to change the specified task sched way
*
* Arguments :task_ptr is the address of task object
* -----
* policy is the sched method assigned to task, sched method can be followings:
* SCHED_FIFO or SCHED_RR
* -----
* Returns RAW_SUCCESS: raw os return success
* RAW_INVALID_SCHED_WAY: No this sched method
* Note(s)
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_set_sched_way(RAW_TASK_OBJ *task_ptr, RAW_U8 policy)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if ((policy != SCHED_FIFO) && (policy != SCHED_RR)) {
return RAW_INVALID_SCHED_WAY;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
task_ptr->sched_way = policy;
RAW_CRITICAL_EXIT();
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Change the specified task sched way
*
* Description: This function is called to change the specified task sched way
*
* Arguments :task_ptr is the address of task object
* -----
* policy is the sched method of the task, and will be filled in later.
*
* Returns :RAW_SUCCESS: raw os return success
*
* Note(s)
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_get_sched_way(RAW_TASK_OBJ *task_ptr, RAW_U8 *policy_ptr)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (policy_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
*policy_ptr = task_ptr->sched_way;
RAW_CRITICAL_EXIT();
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Abort any dly and sunspension or and pend
*
* Description: This function is called to abort the specified task.
*
* Arguments :task_ptr is the address of task object
*
*
*
*
* Returns RAW_INVALID_TASK_STATE: Probablly system errors happens
* RAW_SUCCESS: raw os return success
*
* Note(s) Any aborted task will return a RAW_BLOCK_ABORT
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_TASK_WAIT_ABORT > 0)
RAW_OS_ERROR raw_task_wait_abort(RAW_TASK_OBJ *task_ptr)
{
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (task_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
switch (task_ptr->task_state) {
case RAW_RDY:
break;
case RAW_SUSPENDED:
/*change to ready state*/
task_ptr->task_state = RAW_RDY;
add_ready_list(&raw_ready_queue, task_ptr);
break;
case RAW_DLY:
case RAW_DLY_SUSPENDED:
/*change to ready state*/
tick_list_remove(task_ptr);
add_ready_list(&raw_ready_queue, task_ptr);
task_ptr->task_state = RAW_RDY;
task_ptr->block_status = RAW_B_ABORT;
break;
case RAW_PEND_SUSPENDED:
case RAW_PEND_TIMEOUT_SUSPENDED:
case RAW_PEND:
case RAW_PEND_TIMEOUT:
/*remove task on the tick list because task is waken up*/
tick_list_remove(task_ptr);
/*remove task on the block list because task is waken up*/
list_delete(&task_ptr->task_list);
/*add to the ready list again*/
add_ready_list(&raw_ready_queue, task_ptr);
task_ptr->task_state = RAW_RDY;
task_ptr->block_status = RAW_B_ABORT;
mutex_state_change(task_ptr);
task_ptr->block_obj = 0;
break;
default:
RAW_CRITICAL_EXIT();
return RAW_INVALID_TASK_STATE;
}
RAW_CRITICAL_EXIT();
#if (CONFIG_RAW_USER_HOOK > 0)
raw_task_abort_hook(task_ptr);
#endif
TRACE_TASK_WAIT_ABORT(task_ptr);
raw_sched();
return RAW_SUCCESS;
}
#endif
/*
************************************************************************************************************************
* Get the current active task object
*
* Description: This function is called to get the current task object.
*
* Arguments :None
*
*
*
*
* Returns current active task object.
*
* Note(s)
*
*
************************************************************************************************************************
*/
RAW_TASK_OBJ *raw_task_identify(void)
{
return raw_task_active;
}
/*
************************************************************************************************************************
* Debug blocked task on semphore, event, mutex,queue, block, byte memory
*
* Description: This function is called to debug blocked task on semphore, event, mutex,queue, block, byte memory
*
* Arguments :object_head can be and of semphore, event, mutex,queue.
* -----
* debug_function would be called for each blocked task on on semphore, event, mutex,queue.
* -----
* opt decide whether to wake up task or not.
* if opt > 0 then wake up all the blocked task.
* if opt = 0, just do nothing
*
* Returns
* Note(s) If no task blocked on these object then debug_function will not be called.
*
*
************************************************************************************************************************
*/
#if (CONFIG_RAW_DEBUG > 0)
RAW_OS_ERROR raw_iter_block_task(LIST *object_head, void (*debug_function)(RAW_TASK_OBJ *arg), RAW_U8 opt)
{
LIST *iter;
LIST *iter_temp;
RAW_SR_ALLOC();
#if (RAW_TASK_FUNCTION_CHECK > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif
RAW_CRITICAL_ENTER();
iter = object_head->next;
/*do it until list pointer is back to the original position*/
while (iter != object_head) {
iter_temp = iter->next;
if (debug_function) {
debug_function(raw_list_entry(iter, RAW_TASK_OBJ, task_list));
}
if (opt) {
raw_wake_object(raw_list_entry(object_head->next, RAW_TASK_OBJ, task_list));
}
/*move to list next*/
iter = iter_temp;
}
RAW_CRITICAL_EXIT();
raw_sched();
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Get raw os data and bss data space
* Description: This function is called to get raw os data and bss data space
*
* Arguments :None
*
* Returns raw os data plus bss data space
*
* Note(s)
*
*
************************************************************************************************************************
*/
RAW_U32 raw_get_system_global_space(void)
{
RAW_U32 data_space;
data_space = sizeof(raw_os_active) + sizeof(idle_task_exit) + sizeof(raw_ready_queue)
+ sizeof(raw_sched_lock) + sizeof(raw_int_nesting) + sizeof(high_ready_obj)
+ sizeof(raw_task_active) + sizeof(raw_idle_obj) + sizeof(idle_stack)
+ sizeof(tick_head) + sizeof(raw_idle_count) +sizeof(sys_time_tick);
#if (CONFIG_RAW_TIMER > 0)
data_space += sizeof(timer_head) + sizeof(raw_timer_count) + sizeof(raw_timer_ctrl)
+ sizeof(raw_timer_obj) + sizeof(timer_task_stack) + sizeof(timer_sem)
+ sizeof(timer_mutex);
#endif
#if (CONFIG_RAW_TICK_TASK > 0)
data_space += sizeof(tick_task_obj) + sizeof(tick_task_stack) + sizeof(tick_semaphore_obj);
#endif
data_space += sizeof(raw_task_debug);
#if (CONFIG_RAW_IDLE_EVENT > 0)
data_space += sizeof(STM_GLOBAL_EVENT) + sizeof(raw_idle_rdy_grp) + sizeof(raw_rdy_tbl)
+ sizeof(raw_idle_map_table);
#endif
return data_space;
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/forest555/raw-os.git
git@gitee.com:forest555/raw-os.git
forest555
raw-os
raw-os
master

搜索帮助