FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to 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.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [August 2012 Threads] FreeRTOS on TI 28335Posted by taoxia on August 14, 2012 I'm trying to run FreeRTOS on TI DSP28335. There is a tranplant version developed by CodeSkin and is working well for most of the time. But I've found that there is something wrong with the pxPortInitialiseStack() function, and parameter (void *pvParameters) is disabled as a result . the code of pxPortInitialiseStack() is like this: portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ){
/* FIRST we need to emulate automatic context save assumed by the IRET function */ /* ============================================================================ */
/* see "TMS320C28x CPU and Instruction Set Reference Guide", page 3-14 * on how stack is populated by automatic context save */
// we even-align stack (details of automatic context save depend on alignment if(((unsigned long)pxTopOfStack & 1) != 0){ pxTopOfStack++; }
// ST0: for C runtime environment, it is presumed that OVM=0, PM=0 *pxTopOfStack = 0x0000; pxTopOfStack++; // T - upper 16-bit of Multiplicand Register, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // AL - Accumulator, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // AH - Accumulator, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PL - Product Register, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PH - Product Register, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // AR0 - Aux Register 0, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // AR1 - Aux Register 0, nothing presumed *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++;
// ST1: ARP(15-13) XF(12) M0M1MAP(11) Reserved(10) OBJMODE(9) AMODE(8) IDLESTAT(7) // EALLOW(6) LOOP(5) SPA(4) VMAP(3) PAGE0(2) DBGM(1) INTM(0) // presumed is PAGE0=0 // 1: M0 and M1 mapping mode bit. The M0M1MAP bit should always remain set to 1 in the C28x object mode. // 0: Reserved // 1: C28x object mode (OBJMODE == 1) // 0: AMODE This bit is set to 0 on reset. // 0: IDLESTAT is not restored from the stack. // 0: When the CPU services an interrupt, the current value of EALLOW is saved on the // stack (when ST1 is saved on the stack), and then EALLOW is cleared. Therefore, at the // start of an interrupt service routine (ISR), access to protected registers is disabled. If the // ISR must access protected registers, it must include an EALLOW instruction. At the end // of the ISR, EALLOW can be restored by the IRET instruction. // 0: Upon return from the interrupt, LOOP is not restored from the stack. // 0: SPA = 0 The stack pointer has not been aligned to an even address. // 1: VMAP = For normal operation leave this bit set. // 0: PAGE0 = presumed at 0 by C compiler // 0: DBGM: 0 = Debug events are enabled. // 0: INTM: 0 Maskable interrupts are globally enabled. // ST1 B: 0000 1010 0000 1000 *pxTopOfStack = ( portSTACK_TYPE ) 0x8A08; pxTopOfStack++; // DP - no assumptions made *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // IER - interrupt enable register - probably needs to be passed as a parameter! *pxTopOfStack = ( portSTACK_TYPE ) configTICK_IER_MASK; pxTopOfStack++; // DBGSTAT, emulation info - NOT SURE *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PCL *pxTopOfStack = ( portSTACK_TYPE ) ((unsigned long)pxCode & 0xFFFF); pxTopOfStack++; // PCH *pxTopOfStack = ( portSTACK_TYPE ) (((unsigned long)pxCode >> 16) & 0xFFFF); pxTopOfStack++; // unused location (per automatic context save) *pxTopOfStack = ( portSTACK_TYPE )0xbea1; pxTopOfStack++;
/* SECOND, we need to emulate portSAVE_CONTEXT in portext.asm */ /* ========================================================== */ /* A variable is used to keep track of the critical section nesting. This variable has to be stored as part of the task context and is initially set to zero. */ *pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING; pxTopOfStack++;
/* alignment of stack (required by C environment) */ if(((unsigned long)pxTopOfStack & 1) == 0){ // stack already aligned, save SPA = 0 *pxTopOfStack = ( portSTACK_TYPE ) 0x8A08; // ST1 B: 0000 1010 0000 1000 pxTopOfStack++; } else { // align stack, save SPA = 1 pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x8A18; // ST1 B: 0000 1010 0001 1000 pxTopOfStack++; } // now DP again, for emulating complete PUSH DP:ST1 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; // DP - no assumptions made pxTopOfStack++;
// RPC needs to be saved when stack switching (value does not matter initially) *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; // RPC L pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; // RPC H pxTopOfStack++; // PUSH AR1H:AR0H *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PUSH *SP++,XAR4 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PUSH *SP++,XAR5 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PUSH *SP++,XAR6 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; //PUSH *SP++,XAR7 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; // PUSH XT *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++; *pxTopOfStack = ( portSTACK_TYPE ) 0x0000; pxTopOfStack++;
/* Return a pointer to the top of the stack we have generated so this can be stored in the task control block for the task. */ return pxTopOfStack; } We can see that parameter void *pvParameters is simply skipped in the function, thus one cannot utilise this parameter afterwards. How can I properly correct this? Thanks! Xiatao
RE: FreeRTOS on TI 28335Posted by Richard on August 14, 2012 There is no official port to that device, and I am not familiar with the architecture at all, but I can't help noticing that pvParameters does not appear in your code snippet at all.
pvParameters is passed into pxPortInitialiseStack(), and should be assigned to a register on the stack frame being created such that, when the task is started, the parameter value is popped into the register your compiler expects to find it in. As pvParameters is not loaded into any register, it is no wonder it is not being passed into the task. If you know which register (or otherwise which stack position, if parameters are passed on the stack) it should be in you could edit the code to ensure it works as the compiler expects.
Regards.
RE: FreeRTOS on TI 28335Posted by Richard on August 14, 2012 By the way - please let me know where this port is on the internet, or who is maintaining it, so it or a link to it can be added to the FreeRTOS Interactive site for the benefit of the whole community. I didn't even know it existed.
Regards.
RE: FreeRTOS on TI 28335Posted by taoxia on August 14, 2012 Thank you for the prompt reply. The link to this port has been posted on the FreeRTOS Interactive site http://www.freertos.org/Interactive_Frames/Open_Frames.html?http://interactive.freertos.org/forums/135229-texas-instruments, but the source code seems to have been removed...
RE: FreeRTOS on TI 28335Posted by taoxia on August 14, 2012 I've just solved this problem with your help. I've checked the assembly code and found that the parameter *pvParameters is passed through register XAR4. So I stacked that in function pxPortInitialiseStack() and it seems to work~Thanks once again!
RE: FreeRTOS on TI 28335Posted by Westmoreland Engineering on August 16, 2012 I tried to do this for the 'C551X family but had some difficulty with an internal system stack that is on the processor - maybe I can revisit this soon.
Glad to see someone has seemingly got this working on a TI DSP.
FreeRTOS on TI 28335Posted by jaysfk on June 20, 2016 do you have this port by chance?
Best
FreeRTOS on TI 28335Posted by jaysfk on June 20, 2016 do you have port by chance?
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|