Fixed bug in daemon kill and updated k2k RM server source
authorJustin Sobota <jsobota@ti.com>
Sun, 9 Mar 2014 00:17:00 +0000 (19:17 -0500)
committerJustin Sobota <jsobota@ti.com>
Sun, 9 Mar 2014 00:17:00 +0000 (19:17 -0500)
test/k2h/armv7/linux/rm_server.c
test/k2k/armv7/linux/build/makefile
test/k2k/armv7/linux/rm_server.c
test/k2k/armv7/linux/rm_server_osal.c [new file with mode: 0644]
test/k2k/armv7/linux/serverlogutil.h [new file with mode: 0644]

index fca88ee5211e1fc13c5fca6168f333ed16a1be48..450cdf44d9c79e08d23c035ca67058dda2e985b7 100644 (file)
@@ -510,8 +510,9 @@ int main(int argc, char *argv[])
         if (kill) {
             if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
                 printf("Failed to kill daemon: %s\n", strerror(errno));
-                exit(EXIT_SUCCESS);
+                exit(EXIT_FAILURE);
             }
+            exit(EXIT_SUCCESS);
         }
 
         /* Single instance */
index c115f9ef2e60d5c433a1d00149ede4146ff7b308..04e57bcc58d58fe0a07ee30f242170d7f84b587b 100644 (file)
@@ -43,16 +43,17 @@ INCDIR := $(PDK_INSTALL_PATH);$(RM_INC_DIR);$(RM_ARM_LIN_TEST_DIR);$(IPC_DEVKIT_
 
 # Libraries
 RM_LIB = -lrm
+DAEMON_LIB = -ldaemon
 IPC_LIBS = -ltiipc -ltiipcutils
 
 ifeq ($(USEDYNAMIC_LIB), yes)
 #presuming ARM executable would depend on dynamic library dependency
 EXE_EXTN = _so
-LIBS     = $(RM_LIB)
+LIBS     = $(RM_LIB) $(DAEMON_LIB)
 else
 #forcing ARM executable to depend on static LLD libraries
 EXE_EXTN =
-LIBS     = -static $(RM_LIB) -Wl,-Bdynamic
+LIBS     = -static $(RM_LIB) -Wl,-Bdynamic $(DAEMON_LIB)
 endif
 
 # Compiler options
@@ -77,7 +78,7 @@ VPATH=$(SRCDIR)
 #List the Source Files
 RM_SERVER_SRC =     \
     rm_server.c     \
-    rm_linux_osal.c \
+    rm_server_osal.c \
     sockutils.c
     
 RM_LINUX_CLIENT_TEST_SRC = \
index 1b7a31c448dfa1f7e7491b7cbd336e1ea26980d3..450cdf44d9c79e08d23c035ca67058dda2e985b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com/
  *
  *
  *  Redistribution and use in source and binary forms, with or without
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <signal.h>
 #include <fcntl.h>
-#include <time.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <libdaemon/daemon.h>
 
 /* Socket Includes */
+#include "serverlogutil.h"
 #include "sockutils.h"
 #include "sockrmmsg.h"
 
 #include <ti/drv/rm/rm.h>
 #include <ti/drv/rm/rm_transport.h>
 
-#define error_msg printf
-#define info_msg  printf
+#define RMSERVER_DAEMON_PID_FILE_NAME "/var/run/rmServer/pid"
+#define RMSERVER_DAEMON_LOG_FILE_NAME "/var/log/rmServer.log"
 
 /* Socket timeout */
 #define SERVER_SOCK_TIMEOUT_USEC     (500)
 
-/* Seconds since last request to print resources */
-#define SECONDS_SINCE_LAST_REQUEST   (5)
-
 /* Error checking macro */
 #define ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg)            \
     if (resultVal != checkVal) {                                          \
         char errorMsgToPrint[] = printMsg;                                \
-        printf("%s : ", rmInstName);                                      \
-        printf("%s with error code : %d\n", errorMsgToPrint, resultVal);  \
+        error_msg("%s : ", rmInstName);                                      \
+        error_msg("%s with error code : %d\n", errorMsgToPrint, resultVal);  \
         exit(EXIT_FAILURE);                                               \
     }
 
+/* logging errors */
+#define error_msg(...) rmsrv_log(LOG_ERR, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging warnings */
+#define warning_msg(...) rmsrv_log(LOG_WARNING, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging information */
+#define info_msg(...) rmsrv_log(LOG_INFO, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging debug information */
+#define debug_msg(...) rmsrv_log(LOG_DEBUG, __func__, __FILE__, __LINE__, __VA_ARGS__);
+
+#define LOG_APPEND(x)                              \
+    do {                                           \
+        int len;                                   \
+        len = MAX_LOG_LEN - strlen(rmsrv_log_buf); \
+        if (len > 0) {                             \
+            strncat(rmsrv_log_buf, x, len);        \
+        }                                          \
+        else {                                     \
+            return;                                \
+        }                                          \
+    } while(0)
+
 /* RM registered transport mapping structure */
 typedef struct trans_map_entry_s {
     /* Registered RM transport handle */
@@ -80,22 +103,67 @@ typedef struct trans_map_entry_s {
 /**********************************************************************
  ********************** Global Variables ******************************
  **********************************************************************/
+
 /* RM Server instance name (must match with RM Global Resource List (GRL) and policies */
-char   server_name[RM_NAME_MAX_CHARS] = "RM_Server";
+char           server_name[RM_NAME_MAX_CHARS] = "RM_Server";
+
+Rm_Handle      server_h;
+
+sock_h         server_sock = NULL;
+
+rmserver_cfg_t rmsrv_cfg;
+
+char           rmsrv_log_buf[MAX_LOG_LEN];
+
+/**********************************************************************
+ ********************** External Variables ****************************
+ **********************************************************************/
 
-sock_h server_sock = NULL;
+extern int   optind;
+extern char *optarg;
 
 /**********************************************************************
  ************************** Server Functions **************************
  **********************************************************************/
+
+/* RM Server logging utility (need to move it to another file) */
+void rmsrv_log(const int loglevel, const char* functionName, const char* fileName, const int lineNo, const char* format, ...)
+{
+    int len;
+    char lineno_a[32];
+    va_list args;
+
+    sprintf(lineno_a, "%d", lineNo);
+
+    rmsrv_log_buf[0] = 0;
+
+    LOG_APPEND(fileName);
+    LOG_APPEND(":");
+    LOG_APPEND(lineno_a);
+    LOG_APPEND(":");
+    LOG_APPEND(functionName);
+    LOG_APPEND(":");
+
+    len = MAX_LOG_LEN - strlen(rmsrv_log_buf);
+    if (len <= 0) {
+        return;
+    }
+
+    va_start(args, format);
+    vsnprintf(&rmsrv_log_buf[strlen(rmsrv_log_buf)], len, format, args);
+    va_end(args);
+
+    fprintf(rmsrv_cfg.logfile_p, "%s", rmsrv_log_buf);
+    fflush(rmsrv_cfg.logfile_p);
+}
+
 Rm_Packet *transportAlloc(Rm_AppTransportHandle appTransport, uint32_t pktSize, Rm_PacketHandle *pktHandle)
 {
     Rm_Packet *rm_pkt = NULL;
 
     rm_pkt = calloc(1, sizeof(*rm_pkt));
     if (!rm_pkt) {
-        error_msg("can't malloc for RM send message (err: %s)\n",
+        error_msg("Failed to malloc RM packet (err: %s)\n",
                   strerror(errno));
         return (NULL);
     }
@@ -107,8 +175,7 @@ Rm_Packet *transportAlloc(Rm_AppTransportHandle appTransport, uint32_t pktSize,
 
 void transportFree (Rm_Packet *rm_pkt)
 {
-    uint32_t pkt_size = rm_pkt->pktLenBytes;
-    int32_t  status;
+    int32_t status;
 
     if (rm_pkt) {
         free (rm_pkt);
@@ -121,21 +188,19 @@ int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHa
     Rm_Packet   *rm_pkt = (Rm_Packet *)pktHandle;
     
     if (sock_send(server_sock, (char *)rm_pkt, (int) rm_pkt->pktLenBytes, client_sock_name)) {
-        error_msg("send data failed\n");
+        error_msg("Failed to send RM packet\n");
+    }
+    else {
+        /* Print resources after sending response */
+        Rm_resourceStatus(server_h, 1);
     }
+
+    transportFree(rm_pkt);
     return (0);
 }
 
-int main(int argc, char *argv[])
+int rm_server_run(void *grl, void *policy, void *lin_dtb, int is_daemon)
 {
-    int                 fd;
-    time_t              old_time;
-    struct stat         file_stat;
-    char               *grl_addr;
-    char               *linux_dtb_addr;
-    char               *policy_addr;
-    Rm_Handle           server_h;
     Rm_InitCfg          rm_init_cfg;
     Rm_TransportCfg     rm_trans_cfg;
     int32_t             rm_result;
@@ -147,102 +212,48 @@ int main(int argc, char *argv[])
     sock_name_t         serv_sock_name;
     sock_name_t         client_sock_addr;
     Rm_Packet          *rm_pkt = NULL;
-    struct sockaddr_un  client_addr;
-    struct timeval      tv = {0, SERVER_SOCK_TIMEOUT_USEC};    
+    char                pkt_src[RM_NAME_MAX_CHARS];
+    struct sockaddr_un  client_addr; 
+    int                 signal_fd = -1;
     char                rm_socket_name[] = RM_SERVER_SOCKET_NAME;
 
-    if ((argc < 3) || (argc > 4))
-    {
-        error_msg("Invalid number of input arguments\n");
-        exit(EXIT_FAILURE);        
-    }
-
-    /* mmap the GRL */
-    fd = open(argv[1], O_RDONLY);
-    if (fd == -1) {
-        error_msg("Error opening GRL\n");
-        exit(EXIT_FAILURE);
-    }
-    /* Obtain file size */
-    if (fstat(fd, &file_stat) == -1) {
-        error_msg("Error getting GRL size\n");
-        exit(EXIT_FAILURE);
-    }
-    grl_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (grl_addr == MAP_FAILED) {
-        error_msg("mmap of GRL failed\n");
-        exit(EXIT_FAILURE);
-    }
-
-    /* mmap the Global Policy */
-    fd = open(argv[2], O_RDONLY);
-    if (fd == -1) {
-        error_msg("Error opening Global Policy\n");
-        exit(EXIT_FAILURE);
-    }
-    /* Obtain file size */
-    if (fstat(fd, &file_stat) == -1) {
-        error_msg("Error getting Global Policy size\n");
-        exit(EXIT_FAILURE);
-    }
-    policy_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (policy_addr == MAP_FAILED) {
-        error_msg("mmap of Global Policy failed\n");
-        exit(EXIT_FAILURE);
-    }
-
-    if (argc == 4){
-        /* mmap (Example) Linux DTB */
-        fd = open(argv[3], O_RDONLY);
-        if (fd == -1) {
-            error_msg("Error opening Linux DTB\n");
-            exit(EXIT_FAILURE);
-        }
-        /* Obtain file size */
-        if (fstat(fd, &file_stat) == -1) {
-            error_msg("Error getting Linux DTB size\n");
-            exit(EXIT_FAILURE);
-        }
-        linux_dtb_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-        if (linux_dtb_addr == MAP_FAILED) {
-            error_msg("mmap of Linux DTB failed\n");
-            exit(EXIT_FAILURE);
-        }
+    rmsrv_cfg.logfile_p = fopen(RMSERVER_DAEMON_LOG_FILE_NAME, "w+");
+    if (!rmsrv_cfg.logfile_p) {
+        printf("Error in opening log file %s (%s)", RMSERVER_DAEMON_LOG_FILE_NAME, strerror(errno));
     }
 
+    debug_msg("Starting RM server");
+    
     /* Create the Server instance */
     memset(&rm_init_cfg, 0, sizeof(rm_init_cfg));
     rm_init_cfg.instName = server_name;
     rm_init_cfg.instType = Rm_instType_SERVER;
-    rm_init_cfg.instCfg.serverCfg.globalResourceList = (void *)grl_addr;
-    rm_init_cfg.instCfg.serverCfg.linuxDtb = (void *)linux_dtb_addr;
-    rm_init_cfg.instCfg.serverCfg.globalPolicy = (void *)policy_addr;
+    rm_init_cfg.instCfg.serverCfg.globalResourceList = grl;
+    rm_init_cfg.instCfg.serverCfg.linuxDtb = lin_dtb;
+    rm_init_cfg.instCfg.serverCfg.globalPolicy = policy;
     server_h = Rm_init(&rm_init_cfg, &rm_result);
     ERROR_CHECK(RM_OK, rm_result, server_name, "Initialization failed\n");
 
-    printf("\n\nInitialized %s\n\n", server_name);
+    debug_msg("RM Server initialized with name: %s", server_name);
 
     Rm_resourceStatus(server_h, 1);
     
     serv_sock_name.type = sock_name_e;
     serv_sock_name.s.name = rm_socket_name;
     server_sock = sock_open (&serv_sock_name);
+    if (!server_sock) {
+        error_msg("Error when opening socket %s", rm_socket_name);
+        return -1;
+    }
 
-    old_time = time(NULL);
-    info_msg("Begin waiting for messages from Clients\n");
+    if (is_daemon){
+        signal_fd = daemon_signal_fd();
+    }
 
     while(1) {
-
-        if ((time(NULL) - old_time) > SECONDS_SINCE_LAST_REQUEST) {
-            Rm_resourceStatus(server_h, 1);
-            old_time = time(NULL);
-        }
-
-        retval = sock_wait(server_sock, &length, &tv, -1);
-        if (retval == -2) {
-            goto loop_continue;
-        }
-        else if (retval < 0) {
+        info_msg("Waiting for messages from Clients\n");
+        retval = sock_wait(server_sock, &length, NULL, signal_fd);
+        if (retval < 0) {
             error_msg("Error in reading from socket\n");
             goto loop_continue;
         }
@@ -267,7 +278,13 @@ int main(int argc, char *argv[])
             goto loop_continue;
         }
 
-        info_msg("received RM pkt of size %d bytes from %s\n", length, client_sock_addr.s.addr->sun_path);
+        info_msg("Received RM pkt of size %d bytes from socket %s\n", length, client_sock_addr.s.addr->sun_path);
+        if (Rm_receiveGetPktSrcName(rm_pkt, &pkt_src[0], RM_NAME_MAX_CHARS) == RM_OK) {
+            info_msg("    RM pkt originated from %s instance\n", &pkt_src[0]);
+        }
+        if (Rm_receiveGetPktServiceSrcName(rm_pkt, &pkt_src[0], RM_NAME_MAX_CHARS) == RM_OK) {
+            info_msg("    Service request within RM pkt originated from %s instance\n", &pkt_src[0]);
+        }
 
         map_index = trans_map;
         while(map_index != NULL) {
@@ -313,15 +330,256 @@ int main(int argc, char *argv[])
 
         /* Provide packet to RM Server for processing */       
         if (rm_result = Rm_receivePacket(map_index->trans_handle, rm_pkt)) {
-            printf("RM failed to process received packet: %d\n", rm_result);
+            error_msg("RM failed to process received packet: %d\n", rm_result);
         }
-        transportFree(rm_pkt);
-        old_time = time(NULL);
+        
 loop_continue:
         /* Cleanups */
-        length = 0;    
+        length = 0;
+        transportFree(rm_pkt);
         memset(&client_sock_addr, 0, sizeof(sock_name_t));
         memset(&client_addr, 0, sizeof(struct sockaddr_un));
+    }   
+}
+
+char *get_pid_file_name(void) {
+       static char pid_file_name[] = RMSERVER_DAEMON_PID_FILE_NAME;
+
+       return pid_file_name;
+}
+
+static void print_usage(char *appname)
+{
+    printf ("Usage: %s [OPTION]... [GRL] [POLICY]\n", appname);
+    printf ("Run a resource manager server with the specified [GRL] and [POLICY]\n"
+            "[GRL] and [POLICY] must be device tree blob (DTB) files\n"
+            "Example: rmserver grl.dtb policy.dtb\n\n"
+            "Optional Input:\n"
+            "  -l, --lindtb [LINUX_DTB]  Optionally, provide a Linux DTB file\n"
+            "                            that RM will use to reserve resources\n"
+            "                            for Linux.  The GRL must have the\n"
+            "                            proper Linux DTB resource mappings\n"
+            "                            for this feature to work\n"
+            "Miscellaneous:\n"
+            "  -n, --nodaemon            do not daemonize, run in foreground\n"
+            "  -k, --kill                kill the existing daemon\n"
+            "  -h, --help                print this message\n"
+            "\n"
+            "rmserver will run as a daemon by default.\n\n");
+}
+
+int main(int argc, char *argv[])
+{
+    int          opt;
+    int          daemonize = 1, kill = 0;
+    int          fd;
+    struct stat  file_stat;
+    pid_t        pid;
+    char        *grl_file;
+    char        *policy_file;
+    char        *lin_dtb_file = NULL;
+    void        *grl;
+    void        *policy;
+    void        *lin_dtb = NULL;
+    
+
+    const struct option longopts[] =
+    {
+        {"nodaemon", no_argument,       0, 'n'},
+        {"kill",        no_argument,       0, 'k'},
+        {"help",     no_argument,       0, 'h'},
+        {"lindtb",   required_argument, 0, 'l'},
+        {0,          0,                 0,   0},
+    };
+
+    while((opt = getopt_long(argc, argv, "nkhl:", longopts, NULL)) != -1) {
+        switch (opt) {
+            case 'n':
+                daemonize = 0;
+                break;
+            case 'k':
+                kill = 1;
+                break;
+            case 'l':
+                lin_dtb_file = optarg;
+                break;
+            case 'h':
+            default:
+                print_usage(argv[0]);
+                exit(EXIT_SUCCESS);
+        }
+    }
+
+    if (!kill) {
+        /* GRL and Policy must always be provided */
+        if (optind == (argc - 2)) {
+            /* First must be GRL */
+            grl_file = argv[optind++];
+            /* Second must be policy */
+            policy_file = argv[optind++];  
+        }
+        else {
+            printf("GRL or policy not provided\n\n");
+            print_usage(argv[0]);
+            exit(EXIT_FAILURE);
+        }
+
+        /* mmap the GRL */
+        fd = open(grl_file, O_RDONLY);
+        if (fd == -1) {
+            printf("Error opening GRL: %s\n", strerror(errno));
+            exit(EXIT_FAILURE);
+        }
+        /* Obtain file size */
+        if (fstat(fd, &file_stat) == -1) {
+            printf("Error getting GRL size\n");
+            exit(EXIT_FAILURE);
+        }
+        grl = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+        if (grl == MAP_FAILED) {
+            printf("mmap of GRL failed\n");
+            exit(EXIT_FAILURE);
+        }
+
+        /* mmap the Global Policy */
+        fd = open(policy_file, O_RDONLY);
+        if (fd == -1) {
+            printf("Error opening Global Policy: %s\n", strerror(errno));
+            exit(EXIT_FAILURE);
+        }
+        /* Obtain file size */
+        if (fstat(fd, &file_stat) == -1) {
+            printf("Error getting Global Policy size\n");
+            exit(EXIT_FAILURE);
+        }
+        policy = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+        if (policy == MAP_FAILED) {
+            printf("mmap of Global Policy failed\n");
+            exit(EXIT_FAILURE);
+        }
+
+        if (lin_dtb_file) {
+            /* mmap the Linux DTB if it was provided */
+            fd = open(lin_dtb_file, O_RDONLY);
+            if (fd == -1) {
+                printf("Error opening Linux DTB: %s\n", strerror(errno));
+                exit(EXIT_FAILURE);
+            }
+            /* Obtain file size */
+            if (fstat(fd, &file_stat) == -1) {
+                printf("Error getting Linux DTB size\n");
+                exit(EXIT_FAILURE);
+            }
+            lin_dtb = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+            if (lin_dtb == MAP_FAILED) {
+                printf("mmap of Linux DTB failed\n");
+                exit(EXIT_FAILURE);
+            }
+        }        
+    }
+
+    if (daemonize) {
+        if (kill) {
+            printf("Killing %s\n", argv[0]);
+        }
+        else {
+            printf("Starting %s\n", argv[0]);
+        }
+
+        /* Reset signal handlers */
+        if (daemon_reset_sigs(-1) < 0) {
+            printf("Failed to reset all signal handlers: %s\n", strerror(errno));
+            exit(EXIT_FAILURE);
+        }
+
+        /* Unblock signals */
+        if (daemon_unblock_sigs(-1) < 0) {
+            printf("Failed to unblock all signals: %s\n", strerror(errno));
+            exit(EXIT_FAILURE);
+        }
+
+        if (check_and_create_path (get_pid_file_name()) < 0) {
+            printf("Failed to create pid file path: %s\n", get_pid_file_name());
+            exit(EXIT_FAILURE);
+        }
+
+        /* set daemon id string */
+        daemon_log_ident = daemon_ident_from_argv0(argv[0]);
+        daemon_pid_file_proc = (daemon_pid_file_proc_t) get_pid_file_name;
+
+        if (kill) {
+            if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
+                printf("Failed to kill daemon: %s\n", strerror(errno));
+                exit(EXIT_FAILURE);
+            }
+            exit(EXIT_SUCCESS);
+        }
+
+        /* Single instance */
+        if ((pid = daemon_pid_file_is_running()) >= 0) {
+            printf("Daemon already running on PID file %u\n", pid);
+            exit(EXIT_FAILURE);
+        }
+
+        if (daemon_retval_init() < 0) {
+            printf("Failed to create pipe.\n");
+            exit(EXIT_FAILURE);
+        }
+
+        /* Do the fork */
+        if ((pid = daemon_fork()) < 0) {
+            daemon_retval_done();
+            printf("Error in daemon fork %s\n", strerror(errno));
+            exit(EXIT_FAILURE);
+        } 
+        else if (pid) { /* The parent */
+            int ret;
+
+            /* Wait for 20 seconds for the return value passed from the daemon process */
+            if ((ret = daemon_retval_wait(20)) < 0) {
+                printf("Could not receive return value from daemon process: %s\n", strerror(errno));
+                return -1;
+            }
+
+            printf("Daemon returned %i as return value.\n", ret);
+            return ret;
+        }
+
+        /* Close FDs */
+        if (daemon_close_all(-1) < 0) {
+            printf("Failed to close all file descriptors: %s\n", strerror(errno));
+
+            /* Send the error condition to the parent process */
+            daemon_retval_send(1);
+            goto close_n_exit;
+        }
+
+        /* Create the PID file */
+        if (daemon_pid_file_create() < 0) {
+            printf("Could not create PID file (%s).\n", strerror(errno));
+            daemon_retval_send(2);
+            goto close_n_exit;
+        }
+
+        /* Initialize signal handling */
+        if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
+            printf("Could not register signal handlers (%s).\n", strerror(errno));
+            daemon_retval_send(3);
+            goto close_n_exit;
+        }
+
+        /* Send OK to parent process */
+        daemon_retval_send(0);
     }
+
+    rm_server_run(grl, policy, lin_dtb, daemonize);
+
+close_n_exit:
+    printf("Exiting %s daemon\n", argv[0]);
+    if (daemonize) {
+        daemon_retval_send(255);
+        daemon_signal_done();
+        daemon_pid_file_remove();
+    }    
 }
 
diff --git a/test/k2k/armv7/linux/rm_server_osal.c b/test/k2k/armv7/linux/rm_server_osal.c
new file mode 100644 (file)
index 0000000..8a4ae07
--- /dev/null
@@ -0,0 +1,209 @@
+/**
+ *   @file  rm_server_osal.c
+ *
+ *   @brief
+ *      This is the OS abstraction layer used by the RM Server in Linux.
+ *
+ *  \par
+ *  ============================================================================
+ *  @n   (C) Copyright 2012-2014, Texas Instruments, Inc.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  \par
+*/
+
+/* Standard Includes */
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "serverlogutil.h"
+
+/**********************************************************************
+ ****************************** Defines *******************************
+ **********************************************************************/
+
+/**********************************************************************
+ ************************** Global Variables **************************
+ **********************************************************************/
+uint32_t rmMallocCounter = 0;
+uint32_t rmFreeCounter   = 0;
+
+/**********************************************************************
+ ********************** External Variables ****************************
+ **********************************************************************/
+
+extern char rmsrv_log_buf[MAX_LOG_LEN];
+extern rmserver_cfg_t rmsrv_cfg;
+
+/**********************************************************************
+ *************************** OSAL Functions **************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Allocates memory
+ ***********************************************************************
+ * DESCRIPTION: The function is used to allocate a memory block of the
+ *              specified size.
+ */
+void *Osal_rmMalloc (uint32_t num_bytes)
+{
+    /* Increment the allocation counter. */
+    rmMallocCounter++;
+
+       /* Allocate memory. */
+       return calloc(1, num_bytes);
+}
+
+/* FUNCTION PURPOSE: Frees memory
+ ***********************************************************************
+ * DESCRIPTION: The function is used to free a memory block of the
+ *              specified size.
+ */ 
+void Osal_rmFree (void *ptr, uint32_t size)
+{
+    /* Increment the free counter. */
+    rmFreeCounter++;
+       free(ptr);
+}
+
+/* FUNCTION PURPOSE: Critical section enter
+ ***********************************************************************
+ * DESCRIPTION: The function is used to enter a critical section.
+ *              Function protects against 
+ *      
+ *              access from multiple cores 
+ *              and 
+ *              access from multiple threads on single core
+ */  
+void *Osal_rmCsEnter(void)
+{
+    return NULL;
+}
+
+/* FUNCTION PURPOSE: Critical section exit
+ ***********************************************************************
+ * DESCRIPTION: The function is used to exit a critical section 
+ *              protected using Osal_cppiCsEnter() API.
+ */  
+void Osal_rmCsExit(void *CsHandle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Cache invalidate
+ ***********************************************************************
+ * DESCRIPTION: The function is used to indicate that a block of memory is 
+ *              about to be accessed. If the memory block is cached then this 
+ *              indicates that the application would need to ensure that the 
+ *              cache is updated with the data from the actual memory.
+ */  
+void Osal_rmBeginMemAccess(void *ptr, uint32_t size)
+{
+    return;
+}
+
+/* FUNCTION PURPOSE: Cache writeback
+ ***********************************************************************
+ * DESCRIPTION: The function is used to indicate that the block of memory has 
+ *              finished being accessed. If the memory block is cached then the 
+ *              application would need to ensure that the contents of the cache 
+ *              are updated immediately to the actual memory. 
+ */  
+void Osal_rmEndMemAccess(void *ptr, uint32_t size)
+{
+    return;
+}
+
+/* FUNCTION PURPOSE: Creates a task blocking object
+ ***********************************************************************
+ * DESCRIPTION: The function is used to create a task blocking object
+ *              capable of blocking the task a RM instance is running
+ *              within
+ */
+void *Osal_rmTaskBlockCreate(void)
+{
+    return(NULL);
+}
+
+/* FUNCTION PURPOSE: Blocks a RM instance
+ ***********************************************************************
+ * DESCRIPTION: The function is used to block a task whose context a
+ *              RM instance is running within.
+ */
+void Osal_rmTaskBlock(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: unBlocks a RM instance
+ ***********************************************************************
+ * DESCRIPTION: The function is used to unblock a task whose context a
+ *              RM instance is running within.
+ */
+void Osal_rmTaskUnblock(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Deletes a task blocking object
+ ***********************************************************************
+ * DESCRIPTION: The function is used to delete a task blocking object
+ *              provided to a RM instance
+ */
+void Osal_rmTaskBlockDelete(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Prints a variable list
+ ***********************************************************************
+ * DESCRIPTION: The function is used to print a string to the console
+ */
+void Osal_rmLog (char *fmt, ... )
+{
+    va_list ap;
+    int     len;
+
+    rmsrv_log_buf[0] = 0;
+
+    len = MAX_LOG_LEN - strlen(rmsrv_log_buf);
+    if (len <= 0) {
+        return;
+    }
+
+    va_start(ap, fmt);
+    vsnprintf(&rmsrv_log_buf[strlen(rmsrv_log_buf)], len, fmt, ap);
+    va_end(ap);
+
+    fprintf(rmsrv_cfg.logfile_p, "%s", rmsrv_log_buf);
+    fflush(rmsrv_cfg.logfile_p);
+}
+
diff --git a/test/k2k/armv7/linux/serverlogutil.h b/test/k2k/armv7/linux/serverlogutil.h
new file mode 100644 (file)
index 0000000..d0a1009
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SERVERLOGUTIL_H__
+#define __SERVERLOGUTIL_H__
+
+#include <stdio.h>
+
+#define MAX_LOG_LEN (65536)
+
+typedef struct rmserver_cfg_tag {
+       FILE *logfile_p;
+} rmserver_cfg_t;
+
+#endif /* __SERVERLOGUTIL_H__ */