原创 【博客大赛】【原创】Kinetis-K40FreeRTOS_V7.1.0移植学习记录

2012-3-22 16:30 2947 7 7 分类: MCU/ 嵌入式

 

Kinetis-K40 FreeRTOS_V7.1.0移植学习记录

 

tziang@hotmail.com

 

摘要:IAR, Source insight, J-LINK, FreeRTOS

 

2012-3-6

参照FreeRTOS_V7.1.0中的K60

1.

复制CORTEX_Kinetis_K60_Tower_IAR并改名为CORTEX_Kinetis_K40X256_IAR;

打开工程,编译提示找不到很多头文件

工程选项中添加头文件路径

C/C++ compile / Preprocessor 中添加

$PROJ_DIR$ 代表工程文件(后缀为.eww文件)的当前目录 

$PROJ_DIR$/../ 代表工程文件所在目录的上层目录,以此类推,增加相应的头文件路径即可

直到编译没有错误

Freescale_code/common/startup.c编译出错,在C/C++ compile / Preprocessor的Defined symbol

选项框中增加TWR_K60N512

最终Partest.c中的

GPIOA_PDDR=GPIO_PDDR_PDD( ulLEDs[ 0 ] | ulLEDs[ 1 ] | ulLEDs[ 2 ] | ulLEDs[ 3 ] );

编译不过,GPIOA_PDDR没定义,更新下,

增加\FreeRTOSV7.1.0\Demo\CORTEX_Kinetis_K40X256_IAR\Freescale_Code\cpu\headers

使用自己的头文件,而不是IAR系统自带的(\Freescale_Code\common\common.h中定义)

到此,官方发布的K60的模板没有问题了(或许官方的代码你直接编译就没有问题,可能是我的IAR6.10有问题,不过折腾下,也对IAR的使用有一些基本了解)

2.

开始修改为K40的模板

删除网络相关部分代码

修改\Freescale_Code\common\common.h,改成K40的配置

3.

将kinetis-K40的SLCD驱动增加到工程中

Main函数的prvSetupHardware()中增加SLCD的操作函数,试验OK.

到此,FreeRTOS的K40框架模板基本完成了。

 

下一步是将kinetis-K40 demo中的其它驱动移植过来,

在模板drivers目录下新建k40demodriver文件夹,将Freescale提供的Kwikstik_Demo驱动一一移植过来。

 

2012-3-7

1.

移植buzzer驱动,需要Driver_PIT.c中的中断使能和禁止函数,一并拷过来。

用到一个void _PIT0_Isr(void) 定时器0中断服务函数

在vectors.h中,增加对应的中断函数入口地址,默认的是default_isr,所以这边不改的话,会在vectors.c中的default_isr( )死循环;

Vectors.h中可以很清楚的看到只有几个用到的isr对应的中断向量入口函数,其余的都是default_isr,用户可以根据模板,在具体应用中增加相应的中断服务程序即可。

2.

移植ADC,DAC,FlexMem,FlexTimer,GPIO,SD,TSI,UART,

这几个驱动直接就可以编译通过了

3.

Electrodes,TSI移植也比较简单,增加Kwikstik_Demo中的另外一些头文件即可,

USB的比较麻烦,用到MXQ的一些库等等,暂时不搞;

 

到此,基本驱动差不多了。

 

现在来看一下整个系统从上电开始的运行过程

1.

ctr0.s  ;初始化ARM的寄存器,跳转到start.c中

2.

start.c   #禁止wdog,

#拷贝必要的中断向量或代码段到RAM中,这个函数跟具体的编译环境相关

#系统初始化,主要是初始化一些时钟,pll那边配置要根据实际的晶体修改下,

                     另外,这边还初始化了调试用的trace_clk_init(); fb_clk_init();以及调

                     试串口等,后面再确认能否省略。

#flash相关检查

#跳转到main函数

3.

main.c   #执行prvSetupHardware( ) 即具体平台的初始化工作,比如移植驱动时的驱动测试

         可以在这里进行;

#下面就是涉及FreeRTOS的创建一系列任务等操作。

# 最后是vTaskStartScheduler(),到此操作系统就已经跑起来了。

 

现在开始来驱动细化

SCLD里面有个_time_delay函数,应该是MXQ的,目前是改成减循环函数来替代的,准备增加个定时器1中断来实现延迟

参照Driver_buzzer.c的定时器0中断处理函数来写

增加Driver_delaymSec.c文件,vector.c vector.h中修改对应的PIT内容,Driver_PIT.c中PIT1开启,没有成功,可能是PIT1的设置和PIT0有细微差异,暂不搞吧,设置系统时钟为100MHz,重新定义个delayms函数给系统使用,明天开始看FreeRTOS的细节,先搞两个任务,SLCD显示和buzzer看能不能跑起来。

 

 

2012-3-12

关于source insight的一些设置

1.增加汇编语言的关键字彩色显示

Option->Document Options-> "C Source FIle"对应的File filter中加入 *.s

2.文件中高亮设置,关键字高亮设置便于后面查找

按SHIFT+F8

 

现在来整理一些FreeRTOS的基本知识,

1.目录结构

FreeRTOS 

    ¦

    +-Demo      

    ¦   ¦

    ¦   +-Common     各种体系共用的文件

    ¦   +-Dir x      体系x的范例程序文件

    ¦   +-Dir y      体系y的范例程序文件

    ¦

    +-Source    

        ¦

        +-Portable   特定处理器代码

+-include         头文件

 

2.命名规则

a.变量

char类型的变量以 c 为前缀

short类型的变量以 s 为前缀

long类型的变量以 l 为前缀

float类型的变量以 f 为前缀

double类型的变量以 d 为前缀

枚举变量以 e 为前缀

其他类型(如结构体)以 x 为前缀

指针有一个额外的前缀 p , 例如short类型的指针前缀为 ps

无符号类型的变量有一个额外的前缀 u , 例如无符号short类型的变量前缀为 us

 

b.函数

文件内部函数以prv为前缀

API函数以其返回值类型为前缀,按照前面对变量的定义

函数的名字以其所在的文件名开头。如vTaskDelete函数在Task.c文件中定义

 

c.数据类型

数据类型并不直接在RTOS内核内部引用。相反,每个平台都有其自身的定义方式。例如,char类型定义为portCHAR,short类型定义为portSHORT等。范例程序源代码使用的就是这种符号,但这并不是必须的,你可以在你的程序中使用任何你喜欢的符号。

此外,有两种额外的类型要为每种平台定义。分别是:

portTickType

可配置为16位的无符号类型或32位的无符号类型。参考API文档中的 定制部分获取详细信息。

portBASE_TYPE

为特定体系定义的最有效率的数据类型。

如果portBASE_TYPE定义为char则必须要特别小心的保证用来作为函数返回值的signed char可以为负数,用于指示错误。  

 

3.基本框架

在主函数中,内核启动前至少要穿件一个任务

然后执行vTaskStartScheduler( void ) ,开始任务调度,vTaskStartScheduler( )执行后空闲任务自动被创建 

 

在main.c中增加一个显示任务每隔1S显示一次

和uc/OS类似,简单步骤如下:

1.定义该任务的优先级;

2.main函数中增加任务

xTaskCreate( prvSLCDDisplayTask, #函数名

 ( signed char * ) "SLCD", #r任务名,便于调试

 configMINIMAL_STACK_SIZE,#栈大小,words为单位

 NULL, 

mainSLCD_DISPLAY_TASK_PRIORITY,#优先级

 NULL );

函数原型为

portBASE_TYPE xTaskCreate( pdTASK_CODE prvTaskCode, 

const portCHAR * const pcName, 

unsigned portSHORT usStackDepth, 

void *prvParameters, 

unsigned portBASE_TYPE uxPriority, 

xTaskHandle *prvCreatedTask ); 

参数说明:

prvTaskCode 

指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环).

pcName 

描述任务的名字。主要便于调试。最大长度由

configMAX_TASK_NAME_LEN.定义,包括'\0'结束符

usStackDepth 

指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数. 例如,如果堆栈为16位宽度,usStackDepth定义为 100, 200 字节,这些将分配给堆栈。堆栈嵌套深度(堆栈宽度)不能超多最大值——包含了size_t类型的变量

prvParameters 

指针用于作为一个参数传向创建的任务

uxPriority 

任务运行时的优先级

prvCreatedTask 

用于传递一个处理——引用创建的任务,比如删除,改变优先级等等,可以用vTaskDelete( xHandle ) 删除任务,比如

xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, 

tskIDLE_PRIORITY, &xHandle );

// 使用处理来删除任务.  vTaskDelete( xHandle );

vTaskDelete(NULL),为删除当前任务

 

返回值:

pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

 

 

3.定义prvSLCDDisplayTask函数

static void prvSLCDDisplayTask( void *pvParameters )

{

  portTickType xLastWakeTime;

  const portTickType xFrequency = 1000;   //定义需要的频率 

 xLastWakeTime = xTaskGetTickCount(); //使用当前Tick初始化xLastWakeTime

     for( ; ; )

     {

         vTaskDelayUntil( &xLastWakeTime, xFrequency );//精确延时

 LCD_GCR ^= LCD_GCR_LCDEN_MASK; //切换SLCD显示

     }

}

 

测试没有问题,可以正常运作,到此FreeRTOS V7.1.0在Kinetis-K40上移植的基本框架就此结束,可以此为模板进行进一步深入开发。

 

典型的任务函数结构

void ATaskFunction( void *pvParameters )

{

/* 可以像普通函数一样定义变量。用这个函数创建的每个任务实例都有一个属于自己的iVarialbleExample变量。但如果iVariableExample被定义为static,这一点则不成立 – 这种情况下只存在一个变量,所有的任务实例将会共享这个变量。 */

int iVariableExample = 0;

/* 任务通常实现在一个死循环中。 */

for( ;; )

{

/* 完成任务功能的代码将放在这里。 */

}

/* 如果任务的具体实现会跳出上面的死循环,则此任务必须在函数运行完之前删除。传入NULL参数表示删除的是当前任务 */

vTaskDelete( NULL );

}

 

2012-3-13

Acrobat 中F3快捷键为浏览下一个查找的字符串

 

参考资料:

1.K40P144M100SF2RM

2.http://www.freertos.org/

3.FreeRTOS中文资料;

4.KWIKSTIKDEMOSWLAB;

5.KWIKSTIK-K40-SCH_V4-原理图.

 

 

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条