# General porting procedures

**URL:** <https://forums.freertos.org/t/general-porting-procedures/16613>\
**Category:** Kernel\
**Created:** [January 24, 2023, 5:27pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613 "2023-01-24T17:27:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [January 24, 2023, 5:27pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/1 "2023-01-24T17:27:04Z")

</div>

Hello!

Can somebody to clarify me in general porting procedure?,please  
I still in progress of mips64 porting and I’ve already implemented basic concepts but to finish it I dont have complete picture

I based on PIC32MZ and used last version of FreeRTOS sources.  
As Ive understood I have to do changes according my MCU in the following files and with the following context:

1. port.c

- configure the tick interrupt() or interrtupt for regular tick;
- initinalize the stack for task(pxPortInitialiseStack) - but I dont understand from what I have to get values and ranges for - \*pxTopOfStack = (StackType\_t) 0xDEADBEEF; и \*pxTopOfStack = (StackType\_t) 0x12345678;
- setup the software interrupt(for switich context) in xPortStartScheduler

1. portmacro.h

- enable and disable interrupt including - software(for switch context)

1. port\_asm.s

- Save/Restore the stack pointer to the task to control pxCurrentTCB;

1. ISR\_support.h

- save SFR, EPC registers and control stack location and procuring interrupt nesting.

Ive tried to find out the verification about my assumptions in here

> **[FreeRTOS - Porting a FreeRTOS demo to a different hardware platform](https://www.freertos.org/porting-a-freertos-demo-to-different-hardware.html)**
>
> FreeRTOS is a portable, open source, mini Real Time kernel. A free RTOS for small embedded systems

But couldnt found for complete port

Thus, I asked to correct me, please

---

<div class="post-metadata">

**Author:** ![archigup](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/archigup/32/1418_2.png) [@archigup](https://forums.freertos.org/u/archigup)\
**Post date:** [January 25, 2023, 6:36pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/2 "2023-01-25T18:36:49Z")

</div>

Hey, we have a guiding on porting FreeRTOS here: [FreeRTOS Porting Guide](https://www.freertos.org/FreeRTOS-porting-guide.html)

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [January 26, 2023, 8:28am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/3 "2023-01-26T08:28:52Z")

</div>

Thanks! But this is exactly that I based on and itnt cover all about porting

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [January 26, 2023, 8:29am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/4 "2023-01-26T08:29:32Z")

</div>

Thats why I have got declared above questions

---

<div class="post-metadata">

**Author:** ![jasonpcarroll](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@jasonpcarroll](https://forums.freertos.org/u/jasonpcarroll)\
**Post date:** [January 27, 2023, 2:13am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/5 "2023-01-27T02:13:39Z")

</div>

Hi @addi,

There isn’t necessarily a more full porting picture - every architecture/compiler is different and thus will require you to do things specific for the architecture/compiler, depending on what hardware you want to utilize, and FreeRTOS features you want to support.

> Blockquote \* initinalize the stack for task(pxPortInitialiseStack) - but I dont understand from what I have to get values and ranges for - \*pxTopOfStack = (StackType\_t) 0xDEADBEEF; и \*pxTopOfStack = (StackType\_t) 0x12345678;

The pxPortInitialiseStack, portSAVE\_CONTEXT, and portRESTORE\_CONTEXT are closely tied together so will try to explain a bit on how these work. When a FreeRTOS task is not in a running state, the hardware context (like registers, stack pointer, etc.) needs to be stored within the stack of the task, so that portRESTORE\_CONTEXT will read the hardware context from the task’s stack, and restore the state of the hardware back to where it was when the task was last running. When a FreeRTOS task is first created, it is not in a running state, so when its eventually scheduled to start running, the call to portRESTORE\_CONTEXT is going to initialize the hardware context based on what is stored in its stack. This is the purpose of pxPortInitialiseStack. pxPortInitialiseStack initializes the part of the stack that will hold the initial value of hardware registers (i.e. the stack pointer, CPU registers, etc.) so that they are set properly when a context switch, which calls portRESTORE\_CONTEXT, starts running the newly created task. After a task is swapped off, then portSAVE\_CONTEXT should save the state of applicable hardware in the same place as expected by portRESTORE\_CONTEXT. Normally this is done by just appending this information to the current top of the stack when calling portSAVE\_CONTEXT, and and popping it off the stack when calling portRESTORE\_CONTEXT. How you choose to implement these functions is up to you and your hardware’s architecture.

---

<div class="post-metadata">

**Author:** ![jasonpcarroll](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@jasonpcarroll](https://forums.freertos.org/u/jasonpcarroll)\
**Post date:** [January 27, 2023, 2:16am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/6 "2023-01-27T02:16:57Z")

</div>

Im not sure why they store 0xDEADBEEF and 0x12345678 on the stack but I imagine it’s most likely used to detect stack corruption or overflow.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [January 27, 2023, 11:29pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/7 "2023-01-27T23:29:33Z")

</div>

As per Jason’s reply, those values form the context of a task when the task first starts as they get popped off the stack and into the CPU registers. Values that get popped into control registers are essential to be correct for the task’s wanted state because each bit has a specific meaning. Values that get popped into general purpose registers can normally take value, and often get set to something that helps with debugging. For example, you can set the value that should get popped into R0 to 0, and the value that should get popped into R1 to 1, etc. There can additionally be values like 0xdeadbeef (the actual number doesn’t matter) placed in positions that should not get popped into any register - if you see that value in a register when a task starts you know the code implementation is wrong. So - some values are critical and others just help debugging.

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [January 31, 2023, 6:42pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/8 "2023-01-31T18:42:14Z")

</div>

Thanks a lot!  
Сould you suggest in what case(in tickinterrupt or in software yeild interrupt) I must to store and restore shadow registers(of SFR)?, please.

Thanks and advance

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 1, 2023, 3:32pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/9 "2023-02-01T15:32:20Z")

</div>

and is it necessary to define PRIVILEGED\_FUNCTION(mpu\_wrappers.h) for do that?

---

<div class="post-metadata">

**Author:** ![jjulich](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/jjulich/32/3232_2.png) [@jjulich](https://forums.freertos.org/u/jjulich)\
**Post date:** [February 6, 2023, 4:31pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/10 "2023-02-06T16:31:04Z")

</div>

The PRIVILEGED\_FUNCTION macros are to decorate functions that must be placed in the privileged function memory region. This region is created in the linker script so it is possible to identify the small number of functions that would be allowed to raise privilege in the MPU port.

You will need to understand how shadow registers work in your architecture (when they are updated and restored to the primary registers) and use that information to ensure context saving/restoring works correctly.

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 7, 2023, 10:38am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/11 "2023-02-07T10:38:39Z")

</div>

The architecture is mip64, and I sure what shadow registers cover hardware interttups, but I didnt find any confirmation regarding software interrupts in open specifcations.  
And due to the fact that I have to port yield in my software interrupt, - I have to know that

---

<div class="post-metadata">

**Author:** ![jjulich](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/jjulich/32/3232_2.png) [@jjulich](https://forums.freertos.org/u/jjulich)\
**Post date:** [February 7, 2023, 2:08pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/12 "2023-02-07T14:08:17Z")

</div>

An application may need to port yield in a hardware interrupt as well. A common pattern is to use a semaphore or queue from an interrupt to inform a task of some external event. Many FreeRTOS API’s have a ‘fromISR’ version and these can cause a context switch.

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 7, 2023, 6:20pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/13 "2023-02-07T18:20:52Z")

</div>

Thank you for your replay!  
Maybe could you help me a little in my current porting problem then, please?

I have got problem in switching of 2 tasks  
After when scheduler staterd fill task started and then check task and its all, anothet switchin doesnt occure however fill trander data per queue in cycle, so check has to be also in cycle as its in pending receive

Thats my main:

```auto
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#include "iolib.h"
int var1_addr;// = 0x1503FF00;
int var2_addr;// = 0x1503FF01;
int var3_addr;// = 0x1503FF03;
	var1_addr = 0xFFFFFFFFB503FF00;//0x07FFFF00;//0x1503FF00;
	var2_addr = 0xFFFFFFFFB503FF08;//0x07FFFF08;//0x1503FF01;
	var3_addr = 0xFFFFFFFFB503FF0B;//0x07FFFF0B;
/* The rate at which data is sent to the queue, specified in milliseconds. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 10 )
#define IOP1_BASE 0xffffffffB610FF50

/* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find
the queue empty. */
#define mainQUEUE_LENGTH ( 16 )

/* Priorities at which the tasks are created. */
#define mainQUEUE_SEND_TASK_PRIORITY	( tskIDLE_PRIORITY + 1 )
#define mainQUEUE_RECEIVE_TASK_PRIORITY	( tskIDLE_PRIORITY + 2 )

 
static void CheckTask( void *pvParameters );
static void FillTask( void *pvParameters );
static void taskA( void* );
static void taskB( void* );

///-----------------------------------------------------------

// The queue used by both tasks. 
static xQueueHandle xQueue = NULL;

unsigned long ulTaskNumber[3];

uint8_t data[16];

//-----------------------------------------------------------
void main(void)
{

	*((volatile uint16_t* const)(IOP1_BASE )) = 0x0000;
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA55;

	xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
	if( xQueue != NULL )
	{
		 xTaskCreate( CheckTask, ( signed char * ) "CheckTask",	configMINIMAL_STACK_SIZE, NULL, ( tskIDLE_PRIORITY + 2 ), NULL ); // tskIDLE_PRIORITY + 2 , NULL );
		 xTaskCreate( FillTask, ( signed char * ) "FillTask", configMINIMAL_STACK_SIZE, NULL, ( tskIDLE_PRIORITY + 2 ), NULL ); //tskIDLE_PRIORITY + 1 , NULL );
					*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA50;
		vTaskStartScheduler();
	}

	for( ;; );
}

/*-----------------------------------------------------------*/

 void vApplicationTickHook( void )
 {
     for( ;; ){
         asm("nop");
     }
 }

/*-----------------------------------------------------------*/

static void FillTask( void *pvParameters )
{
	portTickType xNextWakeTime;
	const unsigned long ulValueToSend = 8;
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA54;
    for(int i = 0; i < 16; i++)
        data[i] = i + 5;

	
for( ;;)
{
	
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA54;
	if( xQueueSend( xQueue, &ulValueToSend, 0 ) != pdPASS )
	 
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA01;
	else
		*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA03;
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA00;
	
}
	
}
/*-----------------------------------------------------------*/

static void CheckTask( void *pvParameters )
{
unsigned long ulReceivedValue;

    for(;;){
		
	xQueueReceive( xQueue, &ulReceivedValue, 1000);///;portMAX_DELAY );
    	if( ulReceivedValue == 8 )
    	{*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0x55AA;
            for(int i = 0;i < 16;i++)
                if(data[i] != i + 5){
    
		}
		 
    }
}

/*-----------------------------------------------------------*/
///

void vAssertCalled( const char *pcFileName, unsigned long ulLine )
{
    asm("di");
		*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA56;
	*((volatile uint64_t* const)(var3_addr)) = 0x0000FFFF0000AA56;
	for (;;);
}

```

And thas my hardware ticktimer handler

```auto
_CP0_TIM_VEC4_handler:

		// Cause_DC = 1
		mfc0 a0, C0_CAUSE
		li a1, ~(1 << 27)
		and a0, a0, a1
		mtc0 a0, C0_CAUSE
		ehb

		di
		ehb
		ld sp, xISRStackTop 
		// LA sp, __stack

		LA gp, _gp
		/*.macro portSAVE_CONTEXT*/
		// Make room for the context. First save the current status so it can be
		//manipulated, and the cause and EPC registers so their original values are
		//captured. 
		ADDU sp, sp, -CTX_SIZE
		REG_S k1, CTX_K1(sp)

		// k1 is used as the frame pointer. 
		ADDU k1, zero, sp
		
		// Save the context into the space just created. 
		/*.macro _gpctx_save*/

		/*ld sp, xISRStackTop*/
  
		/* Save general registers. */
		/* $27/k1 must be saved prior to using this macro. */
		.irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 \
			20,21,22,23,24,25,26,28,29,30,31
		REG_S	$\num, CTX_REG(\num) (k1)
		.endr

		PTR_S $0, CTX_LINK(k1)	/* Clear the link field. */

		mfhi	$9
		REG_S	$9, CTX_HI0(k1)
		mflo	$10
		REG_S	$10, CTX_LO0(k1)

		/* Save CP0 registers. */
		PTR_MFC0 $31, C0_EPC
		ehb
		/* mfc0	$10, C0_STATUS */
		/* ehb */
		REG_S	$31, CTX_EPC(k1)
		ehb
		/* sw $10, CTX_STATUS(k1) */
		.endm

		// Save the stack pointer. 
		LA s6, uxSavedTaskStackPointer
		REG_S k1, (s6)
		REG_L k1, CTX_K1(sp)

		/*.endm*/ 
		jal vPortIncrementTick
		nop
		nop
		/*.macro portRESTORE_CONTEXT*/

		LA s6, uxSavedTaskStackPointer
		REG_L k0, (s6)

		// Restore the context. 
		/*.macro _gpctx_load*/
		REG_L	$9, CTX_HI0(k0)
		REG_L	$10, CTX_LO0(k0)
		mthi	$9
		mtlo	$10

		/* Restore the general registers. */
		.irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \
			20,21,22,23,24,25
		REG_L	$\num, CTX_REG(\num) (k0)
		.endr

		/* Restore CP0 registers, kernel registers and stack with
	   interrupts disabled. */
		/* di */
		/* lw k1, CTX_STATUS(k0) */
		/* mtc0	k1, C0_STATUS */
		REG_L	k1, CTX_EPC(k0)
		PTR_MTC0 k1, C0_EPC

		REG_L	$27, CTX_REG(27) (k0)
		REG_L	$28, CTX_REG(28) (k0)
		REG_L	$29, CTX_REG(29) (k0)
		REG_L	$30, CTX_REG(30) (k0)
		REG_L	$31, CTX_REG(31) (k0)

		/* Finally restore k0/$26. */
		REG_L	$26, CTX_REG(26)(k0)

		/*.endm*/

		LA sp, uxSavedTaskStackPointer
		REG_L sp, (sp)

		ADDU sp, sp, CTX_SIZE

		/*.endm*/
		// Count = 0
		mtc0	zero, C0_COUNT
		ehb

		mfc0 a0, C0_CAUSE
		li a1, (1 << 27)
		or a0, a0, a1
		mtc0 a0, C0_CAUSE
		ehb
		ei
		ehb

		eret
		.end _CP0_TIM_VEC4_handler

```

And thats my software interrupt handler to yield

```auto
SW_VEC1_handler:
	

	#mfc0 a0, C0_CAUSE
		
		di
		ehb

		ld sp, xISRStackTop
		LA gp, _gp
		/*portYIELD_SAVE*/
		// Make room for the context. First save the current status so it can be
		//manipulated. 
		daddiu sp, sp, -CTX_SIZE
		REG_S k1, CTX_K1(sp)

		// k0cd is used as the frame pointer. 
		move k1, sp

		// Save the context into the space just created. 
		/*_gpctx_save*/
		.irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 \
			20,21,22,23,24,25,27,28,29,30,31
        rdpgpr k1, $\num
		REG_S k1, CTX_REG(\num) (k0)
		.endr

		rdpgpr k1, $26
		nop
		nop
		REG_S k1, CTX_REG(26) (k0)

		mfhi	k1
		REG_S	k1, CTX_HI0(k0)
		mflo	k1
		REG_S	k1, CTX_LO0(k0)

		/* Save CP0 registers. */
		PTR_MFC0 k1, C0_EPC
		REG_S k1, CTX_EPC(k0)

		// Save the stack pointer to the task. 
		LA s7, pxCurrentTCB
		REG_L s7, (s7)
		REG_S k1, (s7) 
		
		jal vTaskSwitchContext
		nop
		nop

		/*portYIELD_RESTORE*/
		
		// Set the context restore register from the TCB. 
		LA s0, pxCurrentTCB
		REG_L s0, (s0)
		REG_L k0, (s0)

	
		// The _gpctx_load restore code just wholesale copies the
		// status register from the context back to the register loosing
		// any changes that may have occured, 'status' is really global state
		// You dont enable interrupts on one thread and not another...
		// So we just copy the current status value into the saved value
		// so nothing changes on the restore
		//
		/***/
		mfc0	k1, C0_STATUS
		sw k1, CTX_STATUS(k0)
		/***/
		/*_gpctx_load*/
		REG_L	$9, CTX_HI0(k0)
		REG_L	$10, CTX_LO0(k0)
		mthi	$9
		mtlo	$10

		/* Restore the general registers. */
		.irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \
			20,21,22,23,24,25
		REG_L	$\num, CTX_REG(\num) (k0)
		.endr

		/* Restore CP0 registers, kernel registers and stack with
	   interrupts disabled. */
		/* di */
		/* lw k1, CTX_STATUS(k0) */
		/* mtc0	k1, C0_STATUS */
		REG_L	k1, CTX_EPC(k0)
		PTR_MTC0 k1, C0_EPC

		REG_L	$27, CTX_REG(27) (k0)
		REG_L	$28, CTX_REG(28) (k0)
		REG_L	$29, CTX_REG(29) (k0)
		REG_L	$30, CTX_REG(30) (k0)
		REG_L	$31, CTX_REG(31) (k0)

		/* Finally restore k0/$26. */
		REG_L	$26, CTX_REG(26)(k0)

		// Restore the stack pointer from the TCB. 
		LA sp, pxCurrentTCB
		REG_L sp, (sp)
		REG_L sp, (sp)

		// Remove stack frame. 
		daddiu sp, sp, CTX_SIZE
	
		ei
		ehb
	        
		eret
		.end _SW_VEC1_handler

```

And I see that I have two consecutive triggers of software interrupt, - one that I do after increment tick and additional from FreeRTOS in portYIELD\_WITHIN\_API() of xQueueReceive when I stopped in fill task

Please help !

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [February 12, 2023, 5:57pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/14 "2023-02-12T17:57:13Z")

</div>

I am not familiar with this architecture so I can only provide general guidance. What is the definition of `vPortIncrementTick`? You need to call `xTaskIncrementTick` from the tick interrupt handler and do a context switch whenever it returns true. I do not see that in the code you shared above but do you do that elsewhere?

I’d suggest to do the following -

1. Verify that [the tick count](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L365) is incrementing.
2. Just have 2 periodic tasks and verify that those are being scheduled periodically.
3. Verify that an explicit yield causes the context switch.
4. Run all [these tests](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS/Demo/ThirdParty/Template).

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 13, 2023, 10:44am UTC](https://forums.freertos.org/t/general-porting-procedures/16613/15 "2023-02-13T10:44:19Z")

</div>

> [@aggarg](#):
>
> vPortIncrementTick

Thank you very much for detailed answer!!!  
I have got the following increment tick function:

```auto
void vPortIncrementTick( void )
{
   	if( xTaskIncrementTick() != pdFALSE )
	{
		/* Pend a context switch. */
		portYIELD();
	}
} 

```

Where, -

```auto
#define portYIELD() \
{ \
	mips_eic0_seticureq(1); \ // do software interrupt request
} 

```

I’ll try to verify tick incrementing and can replay about it, bit later  
Thanks again!

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 13, 2023, 12:58pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/16 "2023-02-13T12:58:48Z")

</div>

I checked tick incrementiation and got the following:

1. When I stayed in `“CheckTask” task I see incremeting up to 5 and then CPU stoped in:

```auto
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[tskIDLE_PRIORITY] ) ) > ( UBaseType_t ) 1 )
{
}

```

1. incremetation started during tick handler execution
2. in portYIELD() I entering during tick handler execution and before switching to “CheckTask” task but after first incerementing at first time and at the second time I see enterting after second incrementing and after switching in “CheckTask” task. The rest 3 times of incrementing(till 5) I see without portYIELD() entering
3. All incremeting have done in:

```auto
if( xConstTickCount >= xNextTaskUnblockTime )
{}

```

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [February 13, 2023, 2:46pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/17 "2023-02-13T14:46:04Z")

</div>

For now, remove all the tasks and get one (and then 2) very simple periodic tasks working which do something very minimal (like just incrementing a variable).

Have you correctly implemented critical section related macros in your port?

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 13, 2023, 4:39pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/18 "2023-02-13T16:39:48Z")

</div>

Thank you for your replay!!  
Ive done the following changes to simplify tasks interaction:

```auto
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#include "iolib.h"

/* The rate at which data is sent to the queue, specified in milliseconds. */
#define mainQUEUE_SEND_FREQUENCY_MS (1)///( 10 )
#define IOP1_BASE 0xffffffffB610FF50
static void CheckTask( void *pvParameters );
static void FillTask( void *pvParameters );
///-----------------------------------------------------------
int16_t temp=0;
//-----------------------------------------------------------
void main(void)
{
    *((volatile uint16_t* const)(IOP1_BASE )) = 0x0000;
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA55;

		 xTaskCreate( CheckTask, ( signed char * ) "CheckTask",	configMINIMAL_STACK_SIZE, NULL, ( tskIDLE_PRIORITY + 2 ), NULL ); // tskIDLE_PRIORITY + 2 , NULL );
		 xTaskCreate( FillTask, ( signed char * ) "FillTask", configMINIMAL_STACK_SIZE, NULL, ( tskIDLE_PRIORITY + 2 ), NULL ); //tskIDLE_PRIORITY + 1 , NULL );
     	vTaskStartScheduler();

	for( ;; );
}

/*-----------------------------------------------------------*/

static void FillTask( void *pvParameters )
{

for( ;;)
{
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA54;
	temp ++ ;
	*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = temp;///0xAA00;
}
	
}
/*-----------------------------------------------------------*/

static void CheckTask( void *pvParameters )
{
unsigned long ulReceivedValue;

    for(;;){
		
		*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0x55AA;
		if(temp)
		temp--;
		*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = temp;
		 
    }
}

/*-----------------------------------------------------------*/
///

void vAssertCalled( const char *pcFileName, unsigned long ulLine )
{
    asm("di");
		*((volatile uint16_t* const)(IOP1_BASE + 0x04)) = 0xAA56;
	*((volatile uint64_t* const)(var3_addr)) = 0x0000FFFF0000AA56;
	for (;;);
}
///

```

And now see the same problem, - absence of cyclic context switching, I still staying in  
“CheckTask” after only once switching from “FillTask” to “CheckTask” and no one backward

And can you direct me, please, in question about critical section and macros, - I didnt understand about what macros and maybe function in question

Another question in this regard appeared, - where return adress to “FillTask” is stored and how is possible to rewrite it by mistake?(now I see what EPC at the end do not consist of “FillTask” range, but dont understand what was the reason of changing)

Is it relates to task context and stack pointer location in prologue within tick incrementing handler pr to pxCurrentTCB saving/restoring whithin yield handler?

Or maybe it caused by absense of nesting interrupt processing in contex and yield switching?

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [February 15, 2023, 5:19pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/19 "2023-02-15T17:19:08Z")

</div>

> [@addi](#):
>
> And now see the same problem, - absence of cyclic context switching, I still staying in  
> “CheckTask” after only once switching from “FillTask” to “CheckTask” and no one backward

Is the tick interrupt firing and tick count incrementing? If yes, can you step through and check that you are calling `portYIELD();` in the `vPortIncrementTick`? And then you can trace from there why the context switch is not happening?

---

<div class="post-metadata">

**Author:** ![addi](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@addi](https://forums.freertos.org/u/addi)\
**Post date:** [February 15, 2023, 6:12pm UTC](https://forums.freertos.org/t/general-porting-procedures/16613/20 "2023-02-15T18:12:20Z")

</div>

> [@aggarg](#):
>
> Is the tick interrupt firing and tick count incrementing

yes it is, and only `vPortIncrementTick` call `portYIELD()`  
Ive noticed also what after switching in “CheckTask” a havnt got in r26 return address which would be “FillTask” address.  
Cause of what I dont understand where return address of previous existed task is locating

[Next page](https://forums.freertos.org/t/general-porting-procedures/16613.md?page=2)
