Quality RTOS & Embedded Software

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




Loading

Porting HCS12 for GCC

Posted by Jeff Smith on July 1, 2005
I'm going to try to get FreeRTOS running on my C32 DIP module starting from

HCS12 -> MC9S12C32 (small)
http://www.freertos.org/porthcs12.html

The problem is that I am using GCC instead of CodeWarrior. It's just more available.

Although I feel qualified to port the source for GCC, I wonder if anyone else is working or planning to make an official port to GCC.

Some related links
http://www.technologicalarts.ca/catalog/index.php/cPath/50_36
http://m68hc11.serveftp.org/


RE: Porting HCS12 for GCC

Posted by Richard on July 1, 2005
I have not used GCC with this device, but I think the translation should be fairly straight forward. GCC is a very flexible compiler in general and tends to make life easy.

I think the original (unsupported) HCS12 port was configured so it could be built with either CodeWarrior or GCC. It is still available here:

http://www.realtimeengineers.com/hcs12.zip

I should copy the code from the supported port rather than this, but it might be useful for reference to the needed GCC syntax. It assumes the banked memory model.

I have just taken a look at the HCS12 GCC manual. One place to take care is interrupt function prologue and epilogue, and trap (SWI) function prologue and epilogue. They are not the same. Although the processor saves the registers it seems that GCC requires more data to be saved (soft registers). All required data needs saving and restoring in both interrupt and SWI cases.


As a tip to start I suggest setting the scheduler to use cooperative mode as this makes debugging much easier. Then just create a single task that runs at the idle priority and calls portYIELD(). You should then get simply switching between that task and the idle task. When you have that running you can try something more adventurous.

Let us know how you get on.

Regards.

RE: Porting HCS12 for GCC

Posted by Jeff Smith on July 1, 2005
I didn't mention before that I was working on the unsupported version before the supported version appeared. I realized that the supported version would be the better base, although I figure it will take some getting used to since 3.0 had significant changes. I will include the patch below (sorry if it's not very readable).

I felt like my work was ready for a first test, but didn't test it. Here are some issues with portability:

I addressed some interrupt details as you mentioned. I found that the gcc-m68hc1x port does not support the "naked" attribute, so I can't tell it not to generate it's own interrupt code. Also the code would need changed if the number of software registers (such as "._d0") changed

The example is changed for no longer for CodeWarrior. The leftovers might make it hard to read. I tried to keep the port files switchable, but not sure since it's not tested.

The method of addressing IO ports is from the Ipac port in GEL examples. The file there is "gel-1.6.1/include/asm-m68hc12/arch-Ipac/arch/iodg256b.h". I added some defines to it for some popular bits used.


======== patch =========
Only in FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources: Makefile
diff -r -u FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/port.c FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/port.c
--- FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/port.c2005-07-01 13:37:45.587354171 -0600
+++ FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/port.c2005-04-08 14:48:51.000000000 -0600
@@ -1,5 +1,7 @@
/* This file is part of an "unsupported" FreeRTOS port distribution for
* Freescale MC9S12DP256B CPU.
+ *
+ * 2004-04-06 imajeff: modify to work with GCC
*/

/* Scheduler include files. */
@@ -14,7 +16,7 @@
#pragma MESSAGE DISABLE C12053
#include "6812dp256b.h"
#else
- #include "port.h"
+ #include <arch/iodg256b.h>
#endif

volatile unsigned char vPortSchRunning = 0;
@@ -231,7 +233,7 @@
CRGINT = (unsigned char) 0x80;

/* clear overflow interrupt flag */
-CRGFLG_RTIF = 1;
+CRGFLG = RTIF;
}

/*-----------------------------------------------------------*/
diff -r -u FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/portmacro.h FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/portmacro.h
--- FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/portmacro.h2005-07-01 13:37:45.584354465 -0600
+++ FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/portmacro.h2005-04-19 09:44:36.000000000 -0600
@@ -1,5 +1,7 @@
/* This file is part of an "unsupported" FreeRTOS port distribution for
* Freescale MC9S12DP256B CPU.
+ *
+ * 2005-04-06 gcc fixes, imajeff
*/

#ifndef PORTMACRO_H
@@ -42,7 +44,7 @@
* or a 32 bit value. See documentation on http://www.FreeRTOS.org to decide
* which to use.
*/
-#define USE_16_BIT_TICKS0
+#define USE_16_BIT_TICKS1


/*-----------------------------------------------------------
@@ -72,8 +74,13 @@
#endif

/*-----------------------------------------------------------*/
+#ifdef __HIWARE__
#define portDISABLE_RTI_INTERRUPT() CRGINT_RTIE = 0
#define portENABLE_RTI_INTERRUPT() CRGINT_RTIE = 1
+#else
+#define portDISABLE_RTI_INTERRUPT() CRGINT &= ~RTIE
+#define portENABLE_RTI_INTERRUPT() CRGINT |= RTIE
+#endif
/*-----------------------------------------------------------*/
void vPortEnterCritical(void);
void vPortExitCritical(void);
@@ -118,7 +125,7 @@
#define vPortIsrTail() \
{ \
/* reset pending RTI interrupt */ \
- CRGFLG_RTIF = 1; \
+ CRGFLG = RTIF; \
__asm__("rti"); \
}

@@ -126,6 +133,7 @@

/* hardware interrupt handler saves CCR, A, B, X, Y, so there's no need to save
* them one more time */
+#ifdef __HIWARE__
#define portSAVE_CONTEXT() \
{ \
extern volatile void * pxCurrentTCB; \
@@ -144,5 +152,34 @@
__asm__("stab 0x30"); \
}

+#else /* GNUC */
+#define portSAVE_CONTEXT()\
+{\
+__asm__("\n\
+.globl pxCurrentTCB\n\
+movw _.frame, 2,-sp\n\
+movw _.tmp, 2,-sp\n\
+movw _.xy, 2,-sp\n\
+movw _.z, 2,-sp\n\
+movb 0x30, 1,-sp ; PPAGE\n\
+sts pxCurrentTCB\n\
+");\
+}
+
+#define portRESTORE_CONTEXT()\
+{\
+__asm__("\n\
+.globl pxCurrentTCB\n\
+lds pxCurrentTCB\n\
+movb 1,+sp, 0x30 ; PPAGE\n\
+movw _.z, 2,+sp\n\
+movw _.xy, 2,+sp\n\
+movw _.tmp, 2,+sp\n\
+movw _.frame, 2,+sp\n\
+");\
+}
+#endif
+
+
#endif /* PORTMACRO_H */

diff -r -u FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/queue.c FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/queue.c
--- FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/queue.c2005-07-01 13:37:45.594353485 -0600
+++ FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/queue.c2005-04-14 12:22:08.000000000 -0600
@@ -109,6 +109,7 @@
void vQueueDelete( xQueueHandle xQueue );
signed portCHAR cQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portCHAR cTaskPreviouslyWoken );
signed portCHAR cQueueReceive( xQueueHandle pxQueue, void *pcBuffer, portTickType xTicksToWait );
+signed portCHAR cQueueReceiveFromISR( xQueueHandle pxQueue, void *pcBuffer, signed portCHAR *pcTaskWoken );

/*
* Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
diff -r -u FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/test.c FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/test.c
--- FreeRTOS-2.6.1/Source/portable/CodeWarrior/HCS12/sources/test.c2005-07-01 13:37:45.589353975 -0600
+++ FreeRTOS-2.6.1-m/Source/portable/CodeWarrior/HCS12/sources/test.c2005-04-18 17:22:43.000000000 -0600
@@ -1,36 +1,37 @@
-#include <6812dp256b.h> /* derivative information */
+/*
+ * 2004-04-06 imajeff: modifying to test FreeRTOS with HC12/GCC
+ */
+
+#include <arch/iodg256b.h> /* derivative information */

#include <stddef.h>
#include <stdio.h>
+#include <string.h>

#include "task.h"
#include "semphr.h"

-#pragma MESSAGE DISABLE C4002
-
-const char message[] = "This is a FreeRTOS test program. ";
-const char message2[] = "Semaphore work demonstration. ";
-const char charTable[] = "0123456789abcdef";
+void isrDefault7 (void);
+void testTask (void *);
+void testTask2 (void *);
+void pllConfig (void);
+
+const portCHAR message[] = "This is a FreeRTOS test program. ";
+const portCHAR message2[] = "Semaphore work demonstration. ";
+const portCHAR charTable[] = "0123456789abcdef";
xSemaphoreHandle xSemaphore;

-#pragma CODE_SEG NON_BANKED
-#pragma MESSAGE DISABLE C12053
-/* pay attention to _VECTOR section in PRM file */

-#pragma NO_EXIT
-__interrupt void isrDefault7(void)
+void isrDefault7 (void)
{
vPortIsrHead();
-
+
/* do interrupt stuff... */

-vPortIsrTail();
+ vPortIsrTail();
}
-#pragma MESSAGE DEFAULT C12053
-#pragma CODE_SEG DEFAULT
-

-void testTask(void * p)
+void testTask (void * p)
{
static const char * strMsg = message;
static unsigned int count = 0;
@@ -38,11 +39,6 @@

(void) p;

- /* initialize SCI: baud rate = 115200 with bus clock 16MHz */
- SCI1CR1 = 0x00;
- SCI1CR2 = 0x0c;
- SCI1BD = 0x09;
-
while (cSemaphoreTake(xSemaphore, 100) != pdTRUE)
{
portYIELD();
@@ -50,8 +46,9 @@

for (;;)
{
- while (!SCI1SR1_TDRE)
+ while (!SCI1SR1 & TDRE)
{
+ // waiting for byte on SCI
portYIELD();
}
SCI1DRL = *strMsg;
@@ -60,10 +57,11 @@
if (*strMsg == '\0')
{

- sprintf(msg, "0x%04x\r", count);
+ strcpy(msg, ", So ha\r");
+// sprintf(msg, "0x%04x\r", count);
for (strMsg = msg; *strMsg > 0; strMsg++)
{
- while (!SCI1SR1_TDRE)
+ while (!SCI1SR1 & TDRE)
{
portYIELD();
}
@@ -83,7 +81,7 @@
}
}

-void testTask2(void * p)
+void testTask2 (void * p)
{
static const char * strMsg = message2;
static unsigned int count;
@@ -91,11 +89,6 @@

(void) p;

- /* initialize SCI: baud rate = 115200 with bus clock 16MHz */
- SCI1CR1 = 0x00;
- SCI1CR2 = 0x0c;
- SCI1BD = 0x09;
-
while (cSemaphoreTake(xSemaphore, 100) != pdTRUE)
{
portYIELD();
@@ -103,7 +96,7 @@

for (;;)
{
- while (!SCI1SR1_TDRE)
+ while (!SCI1SR1 & TDRE)
{
portYIELD();
}
@@ -112,10 +105,11 @@
strMsg++;
if (*strMsg == '\0')
{
- sprintf(msg, "0x%04x\r", count);
+ strcpy(msg, ", So there\r");
+// sprintf(msg, "0x%04x\r", count);
for (strMsg = msg; *strMsg > 0; strMsg++)
{
- while (!SCI1SR1_TDRE)
+ while (!SCI1SR1 & TDRE)
{
portYIELD();
}
@@ -135,24 +129,26 @@
}
}

-void pllConfig(void)
+void sciConfig ()
{
- SYNR = 0x07;
- REFDV = 0x01;
- while (!CRGFLG_LOCK);
- PLLCTL_AUTO = 1;
- CLKSEL_PLLSEL = 1;
+ /* initialize SCI1: baud rate = 9615 with bus clock 24MHz */
+ SCI1CR1 = 0x00;
+ SCI1CR2 = 0x0c;
+ SCI1BD = 0x009c;
+
}

-void main(void)
+int main (void)
{
xTaskHandle xHandle;

- pllConfig();
+ sciConfig();

vSemaphoreCreateBinary(xSemaphore);

(void) sTaskCreate(testTask, "test", 100, NULL, tskIDLE_PRIORITY, &xHandle);
(void) sTaskCreate(testTask2, "test2", 100, NULL, tskIDLE_PRIORITY, &xHandle);
vTaskStartScheduler(portUSE_PREEMPTION);
+
+ return 0; // never does
}

RE: Porting HCS12 for GCC

Posted by Jeff Smith on July 7, 2005
In studying the port, I found this initial value

volatile unsigned portBASE_TYPE uxCriticalNesting = 0xff;

I am puzzled. It seems it should have been initialized to 0, according to how it is being handled. --jeffs

RE: Porting HCS12 for GCC

Posted by Richard on July 7, 2005
This is to prevent interrupts being enabled before the scheduler has been initialised.

Interrupts being enabled prior to the scheduler being initialised is only a problem if the interrupt service routine expects to be able to use the scheduler. The demo applications install ISR's that will attempt a context switch, so it is important that the ISR's are not enabled prior to the scheduler being started.

Creating a task will cause calls to portENTER_CRITICAL() and portEXIT_CRITICAL(). The portEXIT_CRITICAL() macro will enable interrupts if it finds uxCriticalNesting to be 0. Initialising it to 0xff ensures this will never happen. [In fact 0xff is a bad initial value if portBASE_TYPE is set to be a char as overflows will occur, 10 would be better.].


RE: Porting HCS12 for GCC

Posted by Marcel van Lieshout on July 7, 2005
I can answer this one because it tricked me during my port of FreeRTOS to
PIC18/wizC

During normal processing you are correct. However, to avoid interrupts from
being enabled during taskcreations BEFORE the scheduler has started, this
initial value is chosen. In "my" port portBASE_TYPE is a char and
uxCriticalNesting is initialized to 0x7F. By setting it to a value
"halfway", it can be incremented and decremented without risking it to reach
zero.

When the scheduler is started, this situation must end. This is done by
initializing uxCriticalNesting to zero on the initial stack.
This sets uxCriticalNesting to zero for every task when this task is
switched in for the first time.

HTH

Marcel

RE: Porting HCS12 for GCC

Posted by Jeff Smith on July 7, 2005
I finally found what you described, in pxPortInitialiseStack(). So I see what you mean about the overflow problem with 0xff. I'll try changing it to 10 or even half-way between. Also thank you Marcel for your explanation.

I haven't got anything ready to compile yet, but I'm making progress on the port.
--jeffs

RE: Porting HCS12 for GCC

Posted by Jeff Smith on July 15, 2005
I'm having some trouble finding how malloc functions (i.e. pvPortMalloc() ) are defined in the CodeWarrior version.

Maybe it won't help me port to GCC anyway, since GCC-m68hc1x doesn't come with an efficient malloc yet.

RE: Porting HCS12 for GCC

Posted by Nobody/Anonymous on July 15, 2005
Just include either heap_1.c or heap_2.c in your project as described on the WEB site under Configuration->Memory Management.

The files are in FreeRTOS/portable/MemMang.


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists