秋月電子通商で販売しているAE-RX210ボードでリアルタイムOSのFreeRTOSを動かしてみました。 環境はe2 studio上でRXCです。
今回はOS部分をきれいに分離し新しプロジェクトに組み込み安くしました。ファイルとフォルダの構成を次に示します。
画面上ではこのようになります。
変更・新規作成したファイルを次に示します。
ApplicationHook.c(新規作成)
reset_program.c
main.c
今回はOS部分をきれいに分離し新しプロジェクトに組み込み安くしました。ファイルとフォルダの構成を次に示します。
[src] +---- iodefine.h <-- ウイザードで自動作成 +---- typedefine.h <-- ウイザードで自動作成 +---- dbsct.c <-- ウイザードで自動作成 +---- main.c <-- ウイザードで自動作成 | +-----[FreeRTOS] +------ croutine.h +------ deprecated_definitions.h +------ event_groups.h +------ FreeRTOS.h +------ list.h +------ mpu_wrappers.h +------ portable.h +------ projdefs.h +------ queue.h +------ semphr.h +------ StackMacros.h +------ task.h +------ timers.h +------ croutine.c +------ event_groups.c +------ list.c +------ queue.c +------ tasks.c +------ timers.c | +------ [portable] +------ FreeRTOSConfig.h +------ portmacro.h +------ stacksct.h <-- 移動 +------ vect.h <-- 移動 +------ ApplicationHook.c <-- 新規作成 +------ heap_2.c +------ hwsetup.c <-- 変更 +------ interrupt_handlers.c <-- 移動 +------ port.c +------ reset_program.c +------ vector_table.c
画面上ではこのようになります。
![](https://blogimg.goo.ne.jp/user_image/32/71/68f320881d5c3313dacef3dc7fe1a617.png)
変更・新規作成したファイルを次に示します。
ApplicationHook.c(新規作成)
/* * タスク切り替え用のタイマのスタートと各種フック関数 * * サンプルではmain関数と同じファイルに記述してあったがこのファイルに移動させた */ /* Hardware specific includes. */ #include "../../iodefine.h" /* Kernel includes. */ #include "../FreeRTOS.h" #include "../task.h" #include "../queue.h" /* This variable is not used by this simple Blinky example. It is defined purely to allow the project to link as it is used by the full build configuration. */ volatile unsigned long ulHighFrequencyTickCount = 0UL; /*-----------------------------------------------------------*/ /* A callback function named vApplicationSetupTimerInterrupt() must be defined to configure a tick interrupt source, and configTICK_VECTOR set in FreeRTOSConfig.h to install the tick interrupt handler in the correct position in the vector table. This example uses a compare match timer. It can be into any FreeRTOS project, provided the same compare match timer is available. */ void vApplicationSetupTimerInterrupt( void ) { /* Enable compare match timer 0. */ SYSTEM.PRCR.WORD = 0x0A502; MSTP( CMT0 ) = 0; SYSTEM.PRCR.WORD = 0x0A500; /* Interrupt on compare match. */ CMT0.CMCR.BIT.CMIE = 1; CMT0.CMCR.BIT.CKS = 0; // CLK = PCLK/8 /* Set the compare match value. */ CMT0.CMCOR = ( unsigned short ) ( ( ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) -1 ) / 8 ); /* Divide the PCLK by 8. */ CMT0.CMCR.BIT.CKS = 0; /* Enable the interrupt... */ _IEN( _CMT0_CMI0 ) = 1; ICU.IER[IER_CMT0_CMI0].BIT.IEN_CMT0_CMI0 = 1; //Enable CMIE /* ...and set its priority to the application defined kernel priority. */ _IPR( _CMT0_CMI0 ) = configKERNEL_INTERRUPT_PRIORITY; ICU.IPR[IPR_CMT0_CMI0].BYTE = configKERNEL_INTERRUPT_PRIORITY; // Set interrupt priority level /* Start the timer. */ CMT.CMSTR0.BIT.STR0 = 1; } /*-----------------------------------------------------------*/ /* If configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h, then this function will be called if pvPortMalloc() returns NULL because it has exhausted the available FreeRTOS heap space. See http://www.freertos.org/a00111.html. */ void vApplicationMallocFailedHook( void ) { for( ;; ); } /*-----------------------------------------------------------*/ /* If configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2 in FreeRTOSConfig.h, then this function will be called if a task overflows its stack space. See http://www.freertos.org/Stacks-and-stack-overflow-checking.html. */ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) { for( ;; ); } /*-----------------------------------------------------------*/ /* If configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h, then this function will be called on each iteration of the idle task. See http://www.freertos.org/a00016.html */ void vApplicationIdleHook( void ) { /* If this is being executed then the kernel has been started. Start the high frequency timer test as described at the top of this file. This is only included in the optimised build configuration - otherwise it takes up too much CPU time and can disrupt other tests. */ } /*-----------------------------------------------------------*/
reset_program.c
/***************************************************************/ /* */ /* PROJECT NAME : FreeRTOS02 */ /* FILE : reset_program.c */ /* DESCRIPTION : Reset program */ /* CPU SERIES : RX200 */ /* CPU TYPE : RX210 */ /* */ /* This file is generated by e2 studio. */ /* */ /***************************************************************/ /********************************************************************* * * Device : RX/RX200 * * File Name : resetprg.c * * Abstract : Reset Program. * * History : 1.00 (2010-12-17) * : 1.10 (2011-02-21) * : 1.11 (2011-06-20) * : 1.20 (2014-09-18) * : 1.21 (2014-10-22) * * NOTE : THIS IS A TYPICAL EXAMPLE. * * Copyright (C) 2010 (2011-2014) Renesas Electronics Corporation. and * Renesas Solutions Corp. All rights reserved. * *********************************************************************/ #include <machine.h> #include <_h_c_lib.h> //#include <stddef.h> // Remove the comment when you use errno //#include <stdlib.h> // Remove the comment when you use rand() #include "../../typedefine.h" // Define Types #include "stacksct.h" // Stack Sizes (Interrupt and User) extern void HardwareSetup( void ); #ifdef __cplusplus extern "C" { #endif void PowerON_Reset_PC(void); void main(void); #ifdef __cplusplus } #endif //#ifdef __cplusplus // Use SIM I/O //extern "C" { //#endif //extern void _INIT_IOLIB(void); //extern void _CLOSEALL(void); //#ifdef __cplusplus //} //#endif #define PSW_init 0x00010000 // PSW bit pattern #define FPSW_init 0x00000000 // FPSW bit base pattern //extern void srand(_UINT); // Remove the comment when you use rand() //extern _SBYTE *_s1ptr; // Remove the comment when you use strtok() //#ifdef __cplusplus // Use Hardware Setup //extern "C" { //#endif //extern void HardwareSetup(void); //#ifdef __cplusplus //} //#endif //#ifdef __cplusplus // Remove the comment when you use global class object //extern "C" { // Sections C$INIT and C$END will be generated //#endif //extern void _CALL_INIT(void); //extern void _CALL_END(void); //#ifdef __cplusplus //} //#endif #pragma section ResetPRG // output PowerON_Reset to PResetPRG section #pragma entry PowerON_Reset_PC void PowerON_Reset_PC(void) { #ifdef __RXV2 set_extb(__sectop("EXCEPTVECT")); #endif set_intb(__sectop("C$VECT")); #ifdef __FPU #ifdef __ROZ // Initialize FPSW #define _ROUND 0x00000001 // Let FPSW RMbits=01 (round to zero) #else #define _ROUND 0x00000000 // Let FPSW RMbits=00 (round to nearest) #endif #ifdef __DOFF #define _DENOM 0x00000100 // Let FPSW DNbit=1 (denormal as zero) #else #define _DENOM 0x00000000 // Let FPSW DNbit=0 (denormal as is) #endif set_fpsw(FPSW_init | _ROUND | _DENOM); #endif _INITSCT(); // _INIT_IOLIB(); // Use SIM I/O // errno=0; // Remove the comment when you use errno // srand((_UINT)1); // Remove the comment when you use rand() // _s1ptr=NULL; // Remove the comment when you use strtok() HardwareSetup(); // Use Hardware Setup nop(); // _CALL_INIT(); // Remove the comment when you use global class object set_psw(PSW_init); // Set Ubit & Ibit for PSW // chg_pmusr(); // Remove the comment when you need to change PSW PMbit (SuperVisor->User) main(); // _CLOSEALL(); // Use SIM I/O // _CALL_END(); // Remove the comment when you use global class object brk(); }
main.c
/* Hardware specific includes. */ #include "iodefine.h" /* Kernel includes. */ #include "FreeRTOS/FreeRTOS.h" #include "FreeRTOS/task.h" #include "FreeRTOS/queue.h" void vTask1(void *pvParameters) { while(1) { PORTC.PODR.BIT.B1 = ~PORTC.PODR.BIT.B1; vTaskDelay(100/portTICK_PERIOD_MS); } } void vTask2(void *pvParameters) { while(1) { PORTC.PODR.BIT.B2 = ~PORTC.PODR.BIT.B2; vTaskDelay(200/portTICK_PERIOD_MS); } } void vTask3(void *pvParameters) { while(1) { PORTC.PODR.BIT.B3 = ~PORTC.PODR.BIT.B3; vTaskDelay(300/portTICK_PERIOD_MS); } } void main(void) { /* Turn all LEDs off. */ PORTC.PDR.BYTE = 0xFF; //ポートC出力 PORTC.PODR.BYTE = 0xFF; //初期値 xTaskCreate(vTask1,"Task1",100,NULL,1,NULL); xTaskCreate(vTask2,"Task2",100,NULL,1,NULL); xTaskCreate(vTask3,"Task3",100,NULL,1,NULL); /* Create the queue. */ vTaskStartScheduler(); /* If all is well the next line of code will not be reached as the scheduler will be running. If the next line is reached then it is likely that there was insufficient heap available for the idle task to be created. */ for( ;; ); }