|
NOTE:This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
FreeRTOS Support Archive
The FreeRTOS support forum can be used for active support both from Amazon Web Services and the community. In return for using our software for free, we request you play fair and do your bit to help others! Sign up for an account and receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
[FreeRTOS Home]
[Live FreeRTOS Forum]
[FAQ]
[Archive Top]
[September 2013 Threads]
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on September 24, 2013 I am portin the FreeRTOS onto ARM926 platform.
My processor gets resetting when i am creating the Task.
actually this is happening in the below code.
define portENTER_CRITICAL() vPortEnterCritical()
define portEXIT_CRITICAL() vPortExitCritical()
define portDISABLE_INTERRUPTS() __disable_irq()
define portENABLE_INTERRUPTS() __enable_irq()
void disableirq (void)
{
unsigned long old,temp;
serialputc(‘I’);
__asm volatile(“mrs %0, cpsrn”
“orr %1, %0, #0xc0n”
“msr cpsr_c, %1”
: “=r” (old), “=r” (temp)
:
: “memory”);
serial_putc('J');
// return (old & 0x80) == 0;
}
Please suggest me the correct procedure.
Thanks & Regards,
Nagaraju
FreeRTOS porting to ARM926ejsPosted by davedoors on September 24, 2013 It should be the same code as the ARM7 port.
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS()
__asm volatile (
"STMDB SP!, {R0} nt" /* Push R0. */
"MRS R0, CPSR nt" /* Get CPSR. */
"ORR R0, R0, #0xC0 nt" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 nt" /* Write back modified value. */
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS()
__asm volatile (
"STMDB SP!, {R0} nt" /* Push R0. */
"MRS R0, CPSR nt" /* Get CPSR. */
"BIC R0, R0, #0xC0 nt" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 nt" /* Write back modified value. */
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 1, 2013 Hi,
I ported the basic startup code, timer and interrupt is generating at given
period of time and serial port is working.
I have created the two tasks and started the scheduler, at this time i observed that only one task is running, both the tasks have the same priority.
If i assign one task priority is high at this time only high priority task is running i am unable to see any console messages from the task2..
I initialized one hardware timer and which is generating interrupt at 5 ms.In my timer interrupt handler i am calling the vTaskIncrementTick().
Please suggest me how do i make my scheduler has to the schedule the created tasks to make sure multitasking is happening.
Thanks,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 1, 2013 Assuming the interrupt handler is formed correctly, as a naked function or as an assembly file, then it should contain the code:
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
xTaskIncrementTick() being the function that might unblock a task, and vTaskSwitchContext() being the function that selects the highest priority task to run.
This is correct for FreeRTOS V7.5.0 onwards, anyway.
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 2, 2013 Thank you, Ricahrd.
Currently my timer handler code consists of the below.
void OSTimeTick( void )
{
/* Increment the tick counter. */
vTaskIncrementTick();
#if configUSE_PREEMPTION == 1
{
/* The new tick value might unblock a task. Ensure the highest task that
is ready to execute is the task that will execute when the tick ISR
exits. */
vTaskSwitchContext();
}
#endif
}
configUSE_PREEMPTION flag is enable.I am using the FreeRTOS version 7.5.2
Thanks,
FreeRTOS porting to ARM926ejsPosted by edwards3 on October 2, 2013 vTaskSwitchContext() does not exist in FreeRTOS V7.5.2? It is called xTaskSwitchContext().
Is your OSTimeTick() function called after the task context is stored? It should be something like this:
void OSTimeTick( void ) __attribute__((naked));
void OSTimeTick( void )
{
/* Save the context of the current task. */
portSAVE_CONTEXT();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
portRESTORE_CONTEXT();
}
The yield function should also be naked.
I'm using FreeRTOSSourceportableGCCARM7_AT91SAM7SportISR.c as a reference.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 3, 2013 Hi,
My Code looks to be same as you suggested.
Only i observed that the prints are coming from my ISR at peroidically.
But my taks have to through some chars on to the console when they run.
Please find my attached console log.
in this chars are ‘M’ ‘N’ ‘O’ ‘P’are i am printing through the ISR routine of the timer.
Please suggest me which part of code making wrong me.
Thanks
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 3, 2013 Please find the attached file that explains my portSAVECONTEXT() and portRESTORECONTEXT().
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 3, 2013 Are you 100% sure the interrupt is actually being entered and executed, and that the tick count is being incremented (the tick count is held in the xTickCount variable that is accessible from inside tasks.c).
Only i observed that the prints are coming from my ISR at peroidically.
Are you printing to a console from an interrupt? If so, then that is highly likely to cause you problems.
Trying to rapidly print from tasks can also cause problems, depending on how characters are actually being output. Anything that uses semihosting on an ARM9 will cause all sorts of issues as it will probably try and use the same interrupts as FreeRTOS.
I would recommend just starting with two tasks, of the form:
volatile unsigned long ul1 = 0, ul2 = 0;
void vTask1( void *pvParameters )
{
for( ;; )
{
ul1++;
}
}
void vTask2( void *pvParameters )
{
for( ;; )
{
ul2++;
}
}
Let that run for a while then check both ul1 and ul2 are being incremented at roughly the same rate.
Regards.
FreeRTOS porting to ARM926ejsPosted by berni8k on October 3, 2013 Another thing to make sure is that you have your config file contains sets configUSE_PREEMPTION to 1 and make sure it does indeed get included in all the code correctly.
I created my port for a ARM9 by sticking the ARM7 context save routines in to a ARM Cortex R4 port of it. Only had a slight snag with interrupt enables.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 3, 2013 I am 100% sure that interrupt is firing and ISR routine is executing.
The xTickCount variable is getting incrementing this i have tested like in tasks.c file i am cheking this variable for a value of 1000 at that time i am entering into infinite loop and serial_put(‘D’) which coming here and contineously printing D like below.
xTaskIncrementTick()
++xTickCount
if(xTickCount == 1000)
while(1){
serial_putc(‘D’);
}
in case of ARM 9 the interrupt code like below.
void do_irq (void)
{
ifdef CONFIG_MCS8140
if ((__read_irq_status) & (1<<IRQ_TIMER))
{
__clear_irq(IRQ_TIMER);
if(rd_b(TIMERS_INTERRUPT_STATUS_REG)&2)
{
bit16_timer_interrupt_occured = 1;
/* serial putc(‘M’);
serialputc(‘N’);
serial putc(‘O’);
serialputc(‘P’);
serial_putc(‘@’);*/
OSTimeTick();
}
}
/ ———————————————————–/
void OSTimeTick( void ) attribute((naked));
void OSTimeTick( void )
{
//portSAVE_CONTEXT();
/* Increment the tick counter. */
if( xTaskIncrementTick() != pdFALSE );
// #if configUSE_PREEMPTION == 1
{
/* The new tick value might unblock a task. Ensure the highest task that
is ready to execute is the task that will execute when the tick ISR
exits. */
serial_putc('W');
serial_putc('W');
serial_putc('W');
serial_putc('W');
serial_putc('W');
vTaskSwitchContext();
}
// #endif
//portRESTORE_CONTEXT();
}
I don’t have flexibility to run the suggested program to watch the values. Instead that when my count value equal to some 100 then i am going to infinite loop but i have not observed that.
Apart from that is there any program to check the my FreeRTOS up and running.
Here i observed that only one task is continuously running.When i change the priority of another task at that time only high priority task is runing.
Please guide me how do i make sure that my both the tasks are running simultaneously.
Thanks,
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 3, 2013 In vTaskSwitchContext() function i am entering in to the else part in this i have not seen the defination for the below
traceTASKSWITCHEDOUT();
and the configGENERATERUNTIME_STATS is not defined not entering in to this condition.
traceTASKSWITCHEDIN(); is also not defined and configUSENEWLIBREENTRANT is defined as 0.
Please suggest me how to overcome the problem.
Regards,
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 4, 2013 Hi, I have run the below code by placing the break points in task 1 and task2.Every time task2 break point and only the varible inside the ul2 is getting updated.
volatile unsigned long ul1 = 0, ul2 = 0;
void vTask1( void *pvParameters )
{
for( ;; )
{
ul1++;
}
}
void vTask2( void *pvParameters )
{
for( ;; )
{
ul2++;
}
}
Please could you point out me why the scheduler is not scheduling my task1.
Which part of the code needs to be modified.
Regards,
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 4, 2013 Every time the break point inside the task2 is hitting and the value inside task2 getting incremented but ihave not observed that the task 1 break point is not hitting and the variable inside the task2 is not getting updated.
Please could you update me on the same, i am using FreeRTOS version 7.5.2.
Regards,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 4, 2013
serialputc(‘W’);
serialputc(‘W’);
serialputc(‘W’);
serialputc(‘W’);
serial_putc(‘W’);
vTaskSwitchContext();
I think I already mentioned that sending serial characters from the interrupt is really not a good idea – sending 5 from the tick interrupt is positively a bad idea!
Have you removed that code?
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 4, 2013 Hi,
I observed that my code gets hanging in portSAVE_CONTEXT() function.
Regards
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 9, 2013 Hi,
I have configured my interrupt handler like below.
irq:
get irqstack
bl portSAVE CONTEXT
bl doirq
bl portRESTORE_CONTEXT
my do_irq function is like below.
void do_irq (void)
{
if ((__read_irq_status) & (1<<IRQ_TIMER))
{
__clear_irq(IRQ_TIMER);
if(rd_b(TIMERS_INTERRUPT_STATUS_REG)&2)
{
OSTimeTick();
}
}
void OSTimeTick( void ) attribute((naked));
void OSTimeTick( void )
{
/* Increment the tick counter. */
if( xTaskIncrementTick() != pdFALSE );
{
/* The new tick value might unblock a task. Ensure the highest task that is ready to execute is the task that will execute when the tick ISR
exits. */
vTaskSwitchContext();
}
}
I have configured the timer interrupt to generate at every 5ms and i called this in my vTaskStartScheduler() function just before calling the
if( xPortStartScheduler() != pdFALSE ) with the function name
prvSetupTimerInterrupt();
Initially my processor is in SVC mode and interrupts are enabled and IRQ interrupt is firing and entering into the IRQ mode and IRQ interrupts are disabled.We dont get any further interrupts that means no further do_irq gets called.
Then entering into portSAVE_CONTEXT and hanging at the below stmfd instruction.
@ Push all the system mode registers onto the task stack.
stmfd LR, {R0-LR}^
NOP
SUB LR, LR, #60
In my main routine i have created the two tasks of both having the same priority and both the tasks are created successfully and i have started the scheduler.
my code looks like below
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the first task. */
serial_putc('K');
vPortStartFirstTask();
serial_putc('N');
/* Should not get here! */
return 0;
}
my vPortStartFirstTask(); calls the bl portRESTORE_CONTEXT.
First time my task2 gets scheduling and only that task running contineously but the task1 never get a chance to schedule and it is not running.
But some times at the end of instruction portRESTORE CONTEXT bl which is jumping to the OSTimeTick function but my tasks are not gets scheduled and which is hanging at the portSAVECONTEXT as i mentioned above.
Please could you provide me the tips to overcome my hang issue and to scheduler to schedule my two tasks symultaneously.
Thanks
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 9, 2013 Ok – I’m loosing the thread here. Lets go back to the beginning and go through this step by step.
irq:
getirqstack
bl portSAVECONTEXT
bl doirq
bl portRESTORE_CONTEXT
Broadly speaking, there are two ways the interrupt controller can work on ARM9 devices.
1) Single vector interrupt.
In this scheme there is only one entry point into any interrupt. That single entry point performs some stack management, then looks to see what caused the interrupt, then calls the appropriate handler. The handler is just a standard C function that returns back to the single interrupt handler, which then cleans up the stack and returns back to non interrupt code.
From the code quoted above, it looks like that is the scheme you are using. Although I’m not sure what the line “get irqstack” is doing, as the processor should automatically switch to the IRQ stack for you.
2) Auto vectoring
In auto vectoring the interrupt controller is clever enough to know the cause of the interrupt and jumps directly to a handler for that interrupt. In this scheme there are multiple interrupt entry points – one for each interrupt source.
The discussion in this thread so far has assumed scheme 2 was being used – auto vectoring, but the code you have just posted (and quoted in this thread) makes me think you are actually using scheme 1 – single vector interrupt.
Can you confirm which you are using. Then we can move onto the next step.
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 9, 2013 Thank you for your posting.
Yes i am using the scheme1 single vector interrupt, and getirqstack does the STACK pointer point to particular location address.
Regards,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 9, 2013 Ok – I’m going to ignore the get irqstack call as I’m not sure what it is doing. It is however very important that, whatever it is doing, it does not change the value of any registers before they have been saved as part of the task context (the IRQ stack pointer can be changed, as that is not used by tasks).
The other thing about your interrupt code I note is that you are branching to the save and restore context macros – these should be inline macros, not functions.
One of the STR9 demos in the FreeRTOS download uses the single vector method. Take a look at the file:
FreeRTOSDemoARM9 STR91XIAR91x_vect.s
in that file find the IRQHandler assembly function. You will see the first thing it does is call portSAVE CONTEXT, but portSAVECONTEXT is a macro – it is inlined – the CPU does not branch to it. The implementation of the macro is part of the FreeRTOS port layer (for IAR in this case) and is defined in:
FreeRTOSSourceportableIARSTR91xISR_Support.h.
IRQHandler likewise ends in the inline portRESTORE_CONTEXT macro.
The code between portSAVE CONTEXT and portRESTORECONTEXT is specific to the chip – so ignore that.
Once your vector is set up like this then the individual functions that service peripherals become standard C functions – you don’t need the naked attribute or to do any further saving or restoring of context.
While you are in the 91x_vect.s file also take a look at the vector table. vPortYieldProcessor is installed as the SWI handler:
LDR PC, Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
NOP ; Reserved vector
LDR PC, IRQ_Addr
Reset_Addr DCD __iar_program_start
Undefined_Addr DCD UndefinedHandler
SWI_Addr DCD vPortYieldProcessor ; <<<<<<<<<<<<<<<<
Prefetch_Addr DCD PrefetchAbortHandler
Abort_Addr DCD DataAbortHandler
DCD 0 ; Reserved vector
IRQ_Addr DCD IRQHandler
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 9, 2013 Thank you for your reply.
By doing the below changes i am able to run the multiple tasks.
I have created the three tasks in my main programme and started the scheduler.
In my each task entry i am enabling my IRQ interrupts and before exiting task disbaling the irq interrupts.
Why i enabled the interrupts:
I observed that once entering into the task interrupts are disabling and i am not getting the IRQ interrupts and contineously only that task is running.
Once i enabled the interrupts i am getting the interrupt and next task getting the cpu time slice and it is running. But these tasks are running in ARM IRQ mode.
my code looks like below.
void OSTimeTick( void )
{
if( xTaskIncrementTick() != pdFALSE );
{
vTaskSwitchContext();
}
portRESTORE_CONTEXT();
}
I have removed my portSAVE_CONTEXT code as i mentioned in my previous message.
Please correct me if i am wrong.
I will try now with suggested inputs.
Regards,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 9, 2013 Are your clearing the timer interrupt anywhere? When a timer generates an interrupt it is normal for the interrupt handler to clear the interrupt in the peripheral. It is often additionally necessary to clear the interrupt in the interrupt controller too. How that is done is chip specific, and not FreeRTOS related, but it sounds like you might be missing that step somewhere.
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 9, 2013 Thank you for your reply,
Yes i am clearing the my timer interrupt in my interrupt handler.
Once interrupt comes i am checking that this is timer interrupt, if it is timer interrupt then i am clearing the timer interrupt in my simple interrupt controller.
code looks like below.
void do_irq (void)
{
if ((__read_irq_status) & (1<<IRQ_TIMER))
{
__clear_irq(IRQ_TIMER);
if(rd_b(TIMERS_INTERRUPT_STATUS_REG)&2)
{
OSTimeTick();
}
}
}
As you have stated that it is chip specific.
Please could you guide me how to do the missing step (as present in FreeRTOS).
Regards,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 9, 2013 I'm afraid without having the project and hardware in front of me I don't know what the missing step is. OSTimeTick() should now just be a standard C function (not naked).
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 10, 2013 Please could you elaborate me on what is naked ? If OSTimeTick function is not naked how do i make it as naked?
Regards,
FreeRTOS porting to ARM926ejsPosted by xz8987f on October 10, 2013 for ARM gcc:
attribute ((naked)) void vPortTickHandler(void) ...
...
Erich
FreeRTOS porting to ARM926ejsPosted by xz8987f on October 10, 2013 needs to have double underscore around attribute:
__attribute__ ((naked)) void vPortTickHandler(void) ...
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 10, 2013 is it true for arm-none-eabi-gcc ?
In case od ARM will jump into the generic handler called do_irq() inside this handlwe will check for which peripheral has raised the interrupt then will call the OSTimeTick().
Please could you suggest me now i have to made OSTimeTick() as naked or do_irq() naked?
Regards ,
FreeRTOS porting to ARM926ejsPosted by richardbarry on October 10, 2013 As already said - if you are using a single interrupt entry point that is saving the task context, then determining the interrupt source, then calling the appropriate C function to handle the interrupt source....the C function that is called should be a standard C function - not a naked function.
All the stack manipulation and context saving and restoring is performed in just on place - the IRQ entry point. After that everything is just C code managed by the compiler.
Regards.
FreeRTOS porting to ARM926ejsPosted by nagarajukarre on October 10, 2013 Thank you for your reply.
I observed the code for Cortex-M3 and i found the below observations.
void xPortSysTickHandler( void ) and
void xPortPendSVHandler( void ) inside this handler we are getting the current TCB and saving all the processor registers and calling
bl vTaskSwitchContext and restoring the context.
Whenever the timer gets expired xPortSysTickHandler() function will be called and timer tick count gets incremented.
Please could you clarify me the below.When the below handlers are going to be called and where we are registering thse handlers.
vPortSVCHandler() and void xPortPendSVHandler( void )
Regards,
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|
|