Posix port compile issues

I have been using the old William Davy posix port in a linux FreeRTOS simulation and decided to try the newest posix port that is part of the FreeRTOS distribution.

I tried out the latest posix simulation files from the directory portable/ThirdParty/GCC/Posix.

I encountered a few compiler warnings about unused variables, but in my build warnings become errors so it prevents compilation. So I commented them out. Maybe the official posix port should delete the lines with unused variables?

Also when using the posix port with CMSIS, I got a linker error about undefined reference to v_ipsr. This variable used to be defined in the William Davy port that I was using from CMSIS-FreeRTOS-on-Posix-Linux github repo. Edit: Looks like this v_ipsr came from the cmsis_compiler.h file that I obtained from a similar place to the port.c that I obtained (canā€™t post the link, new users only allowed 2 links), so its probably better I remove this from my port.c and change it to 0 in the cmsis_compiler.h file. Not sure, Iā€™d have to study it more. I included this part in my patch.

Additionally the usage of xTaskGetIdleTaskHandle() was giving me a link error. In other FreeRTOS files its usage is wrapped with an ā€œ#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )ā€, so I added that too.

As I am a new user to this forum I am not allowed to upload the file. So I am pasting a patch here:

--- port_old.c	2020-12-10 23:03:06.136862300 -0500
+++ port_new.c	2020-12-10 22:58:54.384621600 -0500
@@ -198,8 +198,10 @@
 		sigwait( &xSignals, &iSignal );
 	}
 
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 	/* Cancel the Idle task and free its resources */
 	vPortCancelThread( xTaskGetIdleTaskHandle() );
+#endif
 #if ( configUSE_TIMERS == 1 )
 	/* Cancel the Timer task and free its resources */
 	vPortCancelThread( xTimerGetTimerDaemonTaskHandle() );
@@ -323,7 +325,7 @@
 }
 
 static uint64_t prvStartTimeNs;
-static uint64_t prvTickCount;
+//static uint64_t prvTickCount;
 
 /*
  * Setup the systick timer to generate the tick interrupts at the required
@@ -364,7 +366,7 @@
 {
 Thread_t *pxThreadToSuspend;
 Thread_t *pxThreadToResume;
-uint64_t xExpectedTicks;
+//uint64_t xExpectedTicks;
 
 	uxCriticalNesting++; /* Signals are blocked in this signal handler. */
 
@@ -471,7 +473,7 @@
 
 static void prvSuspendSelf( Thread_t *thread )
 {
-int iSig;
+//int iSig;
 
 	/*
 	 * Suspend this thread by waiting for a pthread_cond_signal event.
@@ -559,3 +561,7 @@
 }
 /*-----------------------------------------------------------*/
 
+
+#ifdef FREERTOS_CMSIS
+volatile uint32_t v_ipsr;
+#endif

I will let others reply to your specifics, but I am curious how you use the POSIX port with CMSIS as CMSIS is ARM cortex-M specific.

I am able to use the posix port with CMSIS by using a modified cmsis_os2.c file where I made 4 edits, which are basically:

  1. Add #include to portmacro.h
  2. #if 0 out the SysTick code due to link error
  3. Comment out call to _disable_irq
  4. Comment out call to _enable_irq

Iā€™m using a modified core_cm7.h file where I commented out the bodies of 3 NVIC functions.

Iā€™m using cmsis_compiler.h file from the CMSIS-FreeRTOS-on-Posix-Linux github repo.

Thanks Rob,

I will provide a patch upload a patch for the unused variables.

I wonā€™t be adding the following diff though, as it is specific to your use case

+#ifdef FREERTOS_CMSIS
+volatile uint32_t v_ipsr;
+#endif

I created a pull request at


Could you please give it a try?

Thanks @gedeonag. I have tried your change. I am getting a compilation error that I didnā€™t have before:

../../freertos_lib/posix_sim/port.c: In function ā€˜prvSetupSignalsAndSchedulerPolicyā€™:
/gitworkspace/rbresali/evmb/mc5u/MC5U/freertos_lib/posix_sim/port.c:528:28: error: incompatible type for argument 3 of ā€˜pthread_sigmaskā€™
  528 |                            *&xSchedulerOriginalSignalMask );
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                            |
      |                            sigset_t {aka struct <anonymous>}
In file included from /usr/include/signal.h:396,
                 from ../../freertos_lib/posix_sim/port.c:53:
/usr/include/bits/sigthread.h:32:31: note: expected ā€˜__sigset_t * restrictā€™ {aka ā€˜struct <anonymous> * restrictā€™} but argument is of type ā€˜sigset_tā€™ {aka ā€˜struct <anonymous>ā€™}
   32 |        __sigset_t *__restrict __oldmask)__THROW;
      |        ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~

My /usr/include/bits/sigthread.h line 396 has:

/* Modify the signal mask for the calling thread.  The arguments have
   the same meaning as for sigprocmask(2). */
extern int pthread_sigmask (int __how,
			    const __sigset_t *__restrict __newmask,
			    __sigset_t *__restrict __oldmask)__THROW;

I am using CentOS 7.2

Looks like there is an ā€˜*ā€™ character before the &xSchedulerOriginalSignalMask in your:

    (void)pthread_sigmask( SIG_SETMASK, &xAllSignals,
                           *&xSchedulerOriginalSignalMask );

When I remove that ā€˜*ā€™ it compiles fine:

    (void)pthread_sigmask( SIG_SETMASK, &xAllSignals,
                           &xSchedulerOriginalSignalMask );

I still have the remaining issue that is CMSIS related.

In CMSIS there is a macro ā€œIS_IRQ()ā€ that is used to determine if we are in an interrupt context. In CMSIS I find it used in osDelay() function as below:

osStatus_t osDelay (uint32_t ticks) {
  osStatus_t stat;

  if (IS_IRQ()) {
    stat = osErrorISR;
  }
  else {
    stat = osOK;

    if (ticks != 0U) {
      vTaskDelay(ticks);
    }
  }

  return (stat);
}

I think in the posix port the IS_IRQ() should return ā€˜trueā€™ if we are in an interrupt handler such as the tick handler

How to get this functionality into the posix port?

Is there already some macro available in the posix port to know if we are in an IRQ and I could make the IS_IRQ() in CMSIS utilize it?

For reference:

In the CMSIS-FreeRTOS-on-Posix-Linux github repo (the forum is not letting me post the link) this is solved as follows.

cmsis_os2.c:

#define IS_IRQ_MASKED()           (__get_PRIMASK() != 0U)
#define IS_IRQ_MODE()             (__get_IPSR() != 0U)

#define IS_IRQ()                  (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (KernelState == osKernelRunning)))

cmsis_compiler.h:

#define __get_IPSR()                           v_ipsr
#define __get_PRIMASK()                        (0U)

And in port.c it has:

volatile uint32_t v_ipsr;

portBASE_TYPE xPortInterruptsSet(portBASE_TYPE mask)
{
#ifdef FREERTOS_CMSIS
	volatile uint32_t temp;
	v_ipsr |= mask;
	temp = v_ipsr;
	return temp;
#endif
}
/*-----------------------------------------------------------*/

portBASE_TYPE xPortInterruptsClean(portBASE_TYPE mask)
{
#ifdef FREERTOS_CMSIS
	volatile uint32_t temp;
	v_ipsr &= ~mask;
	temp = v_ipsr;
	return temp;
#endif
}

// Tick handler
void vPortSystemTickHandler( int sig )
{
	portBASE_TYPE mask = TICKS_INTERRUPT;
	
	xPortInterruptsSet(mask);
...
	xPortInterruptsClean(mask);
}

void prvSuspendSignalHandler(int sig)
{
	portBASE_TYPE mask = SYSCALL_INTERRUPT;
	
	xPortInterruptsSet(mask);
...
	xPortInterruptsClean(mask);
}

void prvResumeSignalHandler(int sig)
{
	portBASE_TYPE mask = SYSCALL_INTERRUPT;
	
	xPortInterruptsSet(mask);
...
	xPortInterruptsClean(mask);
}


@rtel or moderators, my original posts are flagged as spam, probably because I have some links in them. I am unable to edit the posts to remove the links. Can you unhide the posts? You can see they are not spam, the links are relevant to the issue.

Can you also give me the ability to post links?

EDIT: I figured out how to edit my original posts, I removed the links so that they wonā€™t be marked as spam.
EDIT2: Looks like I was able to edit because moderators unignored the posts. I still have the links removed, too much time to put them back. Thanks moderators.

@rowbearto, Iā€™ve approved your posts and elevated your user privilege so you should be able to post links without getting put into a review queue. It was triggered because of multiple links to the same domain multiple times.

1 Like

Sounds like we are making progress. I would be very reluctant to add CMSIS specific features into the POSIX port code. I am not aware of something like IS_IRQ being part of the Posix standard, so if we refer to this in any of our code it would stop working on all other Posix platforms.

The whole benefit of using standard Posix only is that the code will be portable without having to resort to hundreds of #ifdef statements, so that should be avoided at all costs.

@cobusve: I am not asking for IS_IRQ() to be referred to in the posix port.

What I am asking for whether there is information from the posix port that I can use in the my definition of IS_IRQ() which is outside of the posix port.

I would like to be able to know if the port is currently running in an ISR, such as the tick handler. Many FreeRTOS functions canā€™t run from ISRs, that is why there are ā€œISRā€ versions of functions.

Specifically, the CMSIS code has a function ā€œosDelay()ā€ which should not run from an ISR because it is blocking. So it does a check if it is an ISR.

So it would be good if the posix port could set some flag to indicate it is in an ISR like the tick handler. Then if posix port provides this information I can use it in the definition of IS_IRQ().

In my previous post I show code from a port.c that was created that will set some flags upon entry/exit to tick handler, and other signal handlers that can be used for CMSIS to know that it is in an interrupt routine or not.

There is no such thing in the existing port, but I am trying to understand what you are trying to do here so that I can suggest a plan of action because I think this is actually simpler than it sounds unless I am missing something here.

The Posix port only has 1 pseudo-interrupt, it does not support any others, and that interrupt is the tick interrupt, which calls prvSetupTimerInterrupt found in port.c. This means that you could modify the port for your use case by setting a global variable when entering that function, and clearing it when you leave the function. I believe however that you do not need to do this.

The reason I am asking why you need this, is that no other code can run while this ISR is operational, which means that whenever you call IS_IRQ() the return would be 0 in 100% of possible cases in your own code. As a result you could just implement IS_IRQ() as follows and it should be fine

#define IS_IRQ() 0

Code in the Tick Hook function could need it, so there is a possibility, but that also gives you a good point to set/clear that flag.

Indeed I use the tick hook to invoke the ISRs that we have in real hardware in the posix simulation environment. So it could be very useful to know from the tick hook. I suppose I could add such a flag in my tick handler, but at the moment Iā€™m still using this other CMSIS/posix simulation where that is built in. So if I moved it into my application code in my tick hook then I would only want that in the new environment using the FreeRTOS official posix simulator, but Iā€™m not ready to make the full switch to the official one as I just learned about it. At this point I am in the exploring phase to switch to the official port.

As the CMSIS environment has this IS_IRQ(), I would like to provide it somehow. On the real hardware it looks at a register that says whether we are in an ISR or not, but that doesnā€™t exist on the posix sim.

For posix sim it seems that a pseudo-isr like the tick handler uses posix signals. I tried to look up how to test if we are in a signal handler but it seems there is no posix way to do that.

Happy New Year all!

I notice that the port.c file in the official repository still has a compile error with the extra asterisk ā€˜*ā€™ on line 528:

                           *&xSchedulerOriginalSignalMask );
---------------------------^
Remove this *

cc: @gedeonag

Happy New Year Rob,

Iā€™ll take a look and fix!

Thanks,


Pushed a fix

Thank you for pushing the fix. I noticed today that this error also exists in the 202012.00 LTS release, which we would like to switch to for our project. Will fixes like this be pushed to LTS in the future?

NP!
Yes we will include it in the LTS release.