Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Pic32 port: some general and some specific Qs

Posted by Erupter on October 1, 2011
Hello.
1st) thank you for FreeRTOS, it's amazing!

2nd) thanks to Joao Melo for his demo configured to run on the Pic32 Ethernet Starter Kit (link here

3rd)
I would like to see some stats, and have been reading the defines I have to make, which are missing in the Pic32 port.
But I'm not clear on what the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() should do.
Should I configure the first to setup a free timer on the micro, possibly running 100x faster then the main timer?
And then what value should the second macro report? I don't think the raw timer value would be sufficient, even if it were a 16bit timer. But it would roll over very quickly.
Can you please clarify it a bit?

4th)
I'm (slowly) working on getting the Microchip USB stack working in a task.
Right now the CDC part is working.
But I would really like to use some printf style functions, is there a way I can point the default printf to use a function of mine to output the final chars? I've had a look at fprintf and the likes but I'm not sure on how to *create* another stream.

5th)
If I get the custom putc/getc functions, they would be executed in the task stack space.
That means that should a semaphore variable exist, the code could check (for security of concurrence) that the calling task had the semaphore before attempting to send data.
But I haven't found a way to check who's got possesion of the token in binary semaphores. There are only give and take funcs, but it should be possible (in my opinion) to know if I have it or not. How could I do it?

6th) much more general: in a preemptive env, why aren't there signals to send to the tasks?
Tasks can block on sempahores and queues but it seems to me that a signal would really simplify things in some cases.
For example in higher level tasks (say app layer) you could wait for a lower level task to get a complete message for you (like a tcpip stack) but then how would the lower level task notify you? putting the message in a queue?
In a tcp style case, it would be very inefficient: what size would you allow for each queue memeber?
Also how could all the higher level tasks check if the message is for them or not?
It seems to me that a signaling system could really simplify such occasions.

RE: Pic32 port: some general and some specific Qs

Posted by Erupter on October 1, 2011
7th) how can I use all the tracing features with microchip's IDE?
I'm tempted to say I can't...
Have been reading all the wonderful things about tracing, stats, kernel debugging and so on.
Hooking breakpoints here and there doesn't seem that good anymore.

RE: Pic32 port: some general and some specific Qs

Posted by Richard Damon on October 1, 2011
3rd)
portCONFIGURE_TIMER_FOR_RUN_TIME_STATES should set up a timer for use in the generation of run time states. This timer should be running fairly fast, as that controls the precision that the states are measured at. FreeRTOS also expects it to be a "unsigned long" (i.e. 32 bit) counter, to reduce problems with overflow. Many Pics have the ability to combine two 16 bit counters into a 32 bit counter, and reading in a certain sequence allows you to avoid the roll over issues

portGET_RUN_TIME_COUNTER returns that counter.

4th) Most imbedded libraries have a way to override the routine used to output to "the console". I am not familiar with doing this on the PIC32, but it should be in the documentation. I tend to avoid printfs in embedded code.

5th) Semaphores are not "owned" by a task, as one common use of them is one task (or interrupt routine) will be just raising the semaphore, marking that something is available, while another task will be waiting on and taking the semaphore to do the processing. The structure for mutual exclusion is a MUTEX, and it sounds like in your application a recursive mutex is called for, as this allows a routine to take the mutex, and if a different task own it, it will wait, while if the mutex is free or already owned by the task it proceeds, and the mutex isn't free until it has been given as many times as it has been taken.

6th) How are you expecting this "signal" to work. Do you mean jumping into a typical "signal handler" ala signs()?, if so there is so little you are allowed to do in such a handler. Typically a task that is looking for notifications like this would be sitting waiting on an queue which holds messages for it to process. For a TCP/IP message, I wouldn't put the TCP/IP message itself in the message, but a pointer to it.

Another method would be to register a call back function (that is run in the context of the low level routine) to signal this, and it files the data (possibly by putting info about it in a queue as above),

RE: Pic32 port: some general and some specific Qs

Posted by Richard on October 2, 2011
Not much to add to richard_damon's previous answer.


3rd)

I think some of the original PIC32 demos used a separate timer to measure interrupt jitter, might I might be wrong. If so, you could dig those out to see how it can be done (don't ask me to do it though, as it would involve some mining).

I presume you have seen http://www.freertos.org/rtos-run-time-stats.html

It is also possible to use the same timer that generates the tick interrupt to generate run time stats, but that can take a bit of maths, and so might not always be efficient enough. For example, on a Cortex-M3 I sometimes use the following code (which might not be 100% correct, but good enough for not safety related work):

void vMainConfigureTimerForRunTimeStats( void )
{
/* How many clocks are there per tenth of a millisecond? */
ulClocksPer10thOfAMilliSecond = configCPU_CLOCK_HZ / 10000UL;
}


unsigned long ulMainGetRunTimeCounterValue( void )
{
unsigned long ulSysTickCounts, ulTickCount, ulReturn;
const unsigned long ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
volatile unsigned long * const pulCurrentSysTickCount = ( ( volatile unsigned long *) 0xe000e018 );
volatile unsigned long * const pulInterruptCTRLState = ( ( volatile unsigned long *) 0xe000ed04 );
const unsigned long ulSysTickPendingBit = 0x04000000UL;

/* NOTE: There are potentially race conditions here. However, it is used
anyway to keep the examples simple, and to avoid reliance on a separate
timer peripheral. */


/* The SysTick is a down counter. How many clocks have passed since it was
last reloaded? */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;

/* How many times has it overflowed? */
ulTickCount = xTaskGetTickCountFromISR();

/* Is there a SysTick interrupt pending? */
if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL )
{
/* There is a SysTick interrupt pending, so the SysTick has overflowed
but the tick count not yet incremented. */
ulTickCount++;

/* Read the SysTick again, as the overflow might have occurred since
it was read last. */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;
}

/* Convert the tick count into tenths of a millisecond. THIS ASSUMES
configTICK_RATE_HZ is 1000! */
ulReturn = ( ulTickCount * 10UL ) ;

/* Add on the number of tenths of a millisecond that have passed since the
tick count last got updated. */
ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond );

return ulReturn;
}



4th)

Have you seen
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en544728

If you are using the PIC32 starter kit then you can print directly to the MPLAB IDE - but it is slow - this is example what I do in the examples that come with the PIC32 edition of the FreeRTOS tutorial book. Some compilers versions will default to character by character Tx, which is *very* slow, and you have to manually tell it to switch to line buffering mode. Others will use line buffering mode by default.

You used to have to call DBINIT() in order for the print statements to get directed to the IDE. I don't know if that is still the case. After that you could just use printf() and fflush().

Regards.

RE: Pic32 port: some general and some specific Qs

Posted by Erupter on October 2, 2011
3rd)
I'll have a look at the current port tick implementation to see what timers are used and how.
Looks like if I do all the daisy-chaining and adding in an ISR and store the 32 bit in a variable, the GET_RUN_TIME_COUNTER could go read that value. Or are finer values required? like inter-interrupt timer values?

4th)
i was looking for a generalized approach as I'm not familiar with the matter of overridind these routines in general

5th and 6th)
The USB stack works in packets, those exchanged at the peripheral endpoints.
So a poller gets called fairly frequently and does the "dirty" work on the bus.

One very comfy way of using the USB capabilities (during debug) is to have the device appear as a comport, and route messages on this virtual com port. Now that would require putc/getc/printf to send chars on this channel.
BUT... this channel is packetized, while the usual stdout stream is not.
Also the bus poller is (quite naturally) at a higher priority then the tasks using its services.
So we have an anti-symmetrical setup for input and output.
OUTPUT: putc and its cousins should write on a buffer until it reaches some predefined quantity of data, then signal the stack to send the packet.
INPUT: incoming data gets placed in another buffer, and a signal has to be raised that data is available.

Then, to guard from access concurrence and guarantee coherence, a mutex or semaphore should be used in protecting putc/printf access, as to guarantee that an application finishes sending whatever it is it's sending, and another doesn't start putting data in the middle of its stream.
Also another mutex/semaphore could be used to block getc access if the app using the link knows it's expecting data.

Right now I have implemented this doulbe data exchange (from app to stack, from stack to bus) with queues.
There are in/out queues on which single chars are loaded, the stack and the app then gets feed one char at a time.
This works for very slow speeds, up to 100 chars per second, but starts loosing chars after that.
I suspect because of the queues AND the fact that I'm effectively sending out 1byte packets on the usb bus.

So I think that a time guard is necessary at the stack level. After some time that data is not eighter received or sent, the buffers get flushed. But it's much easier on the TX side as when the mutex/semaphore gets released, you know an app has finished sending so you can send all you have.
Much more difficult for RX... any proposals on how should I do it?

RE: Pic32 port: some general and some specific Qs

Posted by Erupter on October 2, 2011
Hello Richard,
I'll have a look at those implementations.

As for the debug printf: yes I know there is that possibility but as you said it's painfully slow, and I haven't found a way to enable buffering, and it's not portable. I need the IDE running. Plus the program stops complitely when using debug output.
Having a virtual com port enables all sorts of things, including mixed devices with a debug/config line available at any moment.

I'm much more interested in getting microchip's stack to run decently in freertos.
So I'm investigating how to wrap around it to most effectively use its potential.
I've started with the cdc because it gives me a nice and easy comlink, but I plan to expand to the MSD at least and possibly more.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS