微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > DSP学习交流 > 基础(十四):SYSBIOS-NDK(1)

基础(十四):SYSBIOS-NDK(1)

时间:10-02 整理:3721RD 点击:

由于要使用网络,NDK就是个很不错的选择,但自己也是刚开始对NDK的学习。帖子不免有些基础。

程序首先是使用PlatformInit函数对系统时钟,调试串口,初始化。


  1. Void PlatformInit()
  2. {
  3.         // 平台初始化
  4.         platform_init_flags  Flags;
  5.         platform_init_config Config;

  6.         memset((void *)&Flags,  0, sizeof(platform_init_flags));
  7.         memset((void *)&Config, 0, sizeof(platform_init_config));

  8.         Flags.pll  = 0;     // 锁相环
  9.         Flags.ddr  = 0;     // DDR3
  10.     Flags.tcsl = 0;     // 时间戳计数器
  11.     Flags.phy  = 1;     // 以太网
  12.           Flags.ecc  = 0;     // DDR3 ECC

  13.     Config.pllm = 0;

  14.         // 调试串口初始化
  15.         platform_uart_init(PLATFORM_UART0);
  16.         platform_uart_set_baudrate(PLATFORM_UART0, 115200);
  17.         // 调试信息同时输出到串口和 CCS Console
  18.         platform_write_configure(PLATFORM_WRITE_ALL);

  19.     int status;
  20.         status = platform_init(&Flags, &Config);
  21.         if(status != Platform_EOK)
  22.         {
  23.                 platform_write("Platform failed to initialize. Error code %d \n", status);
  24.                 platform_write("We will fall in an infinite loop... \n");

  25.                 while(1)
  26.                 {
  27.                         platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
  28.                         platform_delay(1000);
  29.                         platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
  30.                         platform_delay(1000);
  31.                 }
  32.         }
  33. }

复制代码


在网卡驱动支持函数中,有一些是对中断的配置,但有一些函数看上去没有意义。

如下:


  1. void Osal_emacBeginMemAccess(void *addr, uint32_t size)
  2. {
  3.     (void)addr;
  4.     (void)size;

  5.     return;
  6. }

复制代码


这个函数没有返回值,函数体中也没有什么有用的语句,不知道这个函数的意义是什么 ,但是没有这些函数是会有错误的,可以在库中这些函数在其他的工程中是有实际意义的,只是在这个工程中没有用,所以就写了个类似的空函数。不知道这么理解对不对,初次学习NDK。



void CacheInit()缓存配置中使用了Cache_Size结构体,而这个结构体最终的原型是如下结构体。就是对L1、L2缓存的配置。



新建Task函数Void TaskInit()中递增建了一个task,名字为NDKTask。

使用Task_Params_init()函数创建这个配置参数结构,这个函数的声明原型为Void Task_Params_init(Task_Params *params);

对于Task_Params结构体:


  1. typedef struct Task_Params {
  2. // Instance config-params structure
  3.     IInstance_Params *instance;
  4.     // Common per-instance configs
  5.     UInt affinity;
  6.     // The core which this task is to run on. Default is Task_AFFINITY_NONE
  7.     UArg arg0;
  8.     // Task function argument. Default is 0
  9.     UArg arg1;
  10.     // Task function argument. Default is 0
  11.     Ptr env;
  12.     // Environment data struct
  13.     Int priority;
  14.     // Task priority (0 to Task.numPriorities-1, or -1). Default is 1
  15.     Ptr stack;
  16.     // Task stack pointer. Default = null
  17.     IHeap_Handle stackHeap;
  18.     // Mem heap used for dynamically created task stack
  19.     SizeT stackSize;
  20.     // Task stack size in MAUs
  21.     Bool vitalTaskFlag;
  22.     // Exit system immediately when the last task with this flag set to TRUE has terminated
  23. } Task_Params;

复制代码


分配的stack的大小是512*1024

使用Task_create()函数创建这个任务。


  1.         Task_Handle NDKTaskHandle;
  2.         Task_Params TaskParams;

  3.         Task_Params_init(&TaskParams);
  4.         TaskParams.stackSize = 512 * 1024;

  5.         NDKTaskHandle = Task_create(NDKTask, &TaskParams, NULL);
  6.         if(NDKTaskHandle == NULL)
  7.         {
  8.                 platform_write("NDK Task create failed!\r\n");
  9.         }

复制代码


NDKTask线程无疑是程序的主要部分。

在NDKTask中,首先是初始化操作系统环境,必须在使用 NDK 之前最先调用,这里使用的是NC_SystemOpen()函数,该函数为所有网络应用程序建立堆栈和内存环境,它初始化堆栈的内存管理和操作系统。它还配置了网络事件调度程序的任务优先级和操作模式。

这个函数有两个参数,一个是NDK优先级,一个是操作模式。

优先级有两个定义一个是高一个是低:NC_PRIORITY_LOW  与  NC_PRIORITY_HIGH

操作模式也有两个定义,是个是轮询一个是中断:NC_OPMODE_POLLING 与NC_OPMODE_INTERRUPT

面这里选择的是高优先级与中断方式。


  1. Int rc;
  2. rc = NC_SystemOpen(NC_PRIORITY_HIGH, NC_OPMODE_INTERRUPT);
  3.     if(rc)
  4.     {
  5.             platform_write("NC_SystemOpen Failed (%d)\n", rc);

  6.         for(;;);
  7.     }

复制代码


CfgNew()函数会创建一个配置句柄,这个句柄的类型是HANDLE,HANDLE 实际上只是一个空指针,它的定义如下:

typedef void *         HANDLE;

而CfgNew()函数返回值赋给了这个句柄,使用方法如下程序:


  1.   HANDLE hCfg;
  2.     hCfg = CfgNew();
  3.     if(!hCfg)
  4.     {
  5.             platform_write("Unable to create configuration\n");

  6.         goto Exit;
  7.     }

复制代码


利用该句柄使用CfgAddEntry()函数可以添加DHCP、DNS、HTTP等服务和配置SOCKET缓冲区大小与ARP超时参数。


  1. CfgAddEntry(hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0, strlen(HostName), (UINT8 *)HostName, 0);

复制代码


如下是CfgAddEntry()函数的几个参数的含义:



由于接下来的几篇都是NDK的讲解与使用方法的说明,在NDK的最后一篇将把所有的源码与二进制文件上传。


zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top