microkernel: Don't initialize packets in a command packet set
Reworks the internal design of a command packet set so that the command packet array is split out into a separate variable lying in uninitialized memory. This shrinks the command packet's data section footprint to almost nothing. Note: A side effect of this change is that it is no longer possible to define a command packet set as a "static" variable since the CMD_PKT_SET_INSTANCE() macro now generates two variables. Change-Id: I9c7ebe637edf879758589ff4a26ace1303790bf7 Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
This commit is contained in:
parent
7193a3e007
commit
f330d5adfe
5 changed files with 42 additions and 51 deletions
|
@ -28,8 +28,8 @@
|
||||||
* Each command packet set is created in global memory using ...
|
* Each command packet set is created in global memory using ...
|
||||||
* CMD_PKT_SET_INSTANCE(set variable name, # of command packets in the set);
|
* CMD_PKT_SET_INSTANCE(set variable name, # of command packets in the set);
|
||||||
*
|
*
|
||||||
* Once created, the command packet set is accessed using ...
|
* Once created, the command packet set is referenced as an ordinary structured
|
||||||
* CMD_PKT_SET(set variable name).<member field name>
|
* variable.
|
||||||
|
|
||||||
* A command packet set is a simple ring buffer. No error checking is performed
|
* A command packet set is a simple ring buffer. No error checking is performed
|
||||||
* when a command packet is retrieved from the set. Each obtained command packet
|
* when a command packet is retrieved from the set. Each obtained command packet
|
||||||
|
@ -52,47 +52,34 @@ extern "C" {
|
||||||
|
|
||||||
#define CMD_PKT_SIZE_IN_WORDS (19)
|
#define CMD_PKT_SIZE_IN_WORDS (19)
|
||||||
|
|
||||||
/**
|
/* define command packet set types */
|
||||||
* @brief Define a command packet set
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This macro is used to create a command packet set in the global namespace.
|
|
||||||
* Each packet set can have a different number of packets.
|
|
||||||
*
|
|
||||||
* @param name Name of command packet set
|
|
||||||
* @param num Number of packets in the set
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* It is critical that the word corresponding to the [alloc] field in the
|
|
||||||
* equivalent struct k_args command packet be zero so that the system knows that the
|
|
||||||
* command packet is not part of the free list.
|
|
||||||
* @endinternal
|
|
||||||
*/
|
|
||||||
#define CMD_PKT_SET_INSTANCE(name, num) \
|
|
||||||
uint32_t name[2 + CMD_PKT_SIZE_IN_WORDS * (num)] = {num, 0}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wrapper for accessing a command packet set
|
|
||||||
*
|
|
||||||
* A command packet set must be typecast to the cmd_pkt_set type
|
|
||||||
* when accessed, because it is instantiated as an array of uint32_t.
|
|
||||||
*
|
|
||||||
* @param name Name of command packet set
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define CMD_PKT_SET(name) (*(struct cmd_pkt_set *)(name))
|
|
||||||
|
|
||||||
typedef uint32_t cmdPkt_t[CMD_PKT_SIZE_IN_WORDS];
|
typedef uint32_t cmdPkt_t[CMD_PKT_SIZE_IN_WORDS];
|
||||||
|
|
||||||
struct cmd_pkt_set {
|
struct cmd_pkt_set {
|
||||||
uint32_t num_packets; /* number of command packets in set */
|
uint32_t num_packets; /* number of command packets in set */
|
||||||
uint32_t index; /* index into command packet array */
|
uint32_t index; /* index into command packet array */
|
||||||
cmdPkt_t command_packet[]; /* array of command packets */
|
cmdPkt_t *command_packet; /* pointer to array of command packets */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define a command packet set
|
||||||
|
*
|
||||||
|
* This macro is used to create a command packet set of the specified size.
|
||||||
|
*
|
||||||
|
* @param name Name of command packet set
|
||||||
|
* @param num Number of packets in the set
|
||||||
|
*
|
||||||
|
* @warning The command packet set exists in the global namespace,
|
||||||
|
* and cannot be hidden by prefixing the macro with "static".
|
||||||
|
*/
|
||||||
|
#define CMD_PKT_SET_INSTANCE(name, num) \
|
||||||
|
uint32_t __noinit (_k_cmd_pkts_ ## name)[CMD_PKT_SIZE_IN_WORDS * (num)]; \
|
||||||
|
struct cmd_pkt_set name = {(num), 0, (cmdPkt_t *)(_k_cmd_pkts_ ## name)}
|
||||||
|
|
||||||
/* externs */
|
/* externs */
|
||||||
|
|
||||||
extern cmdPkt_t *_cmd_pkt_get(struct cmd_pkt_set *pSet);
|
extern struct k_args *_cmd_pkt_get(struct cmd_pkt_set *pSet);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,17 @@ uint32_t _k_test_cmd_pkt_size
|
||||||
* @param pSet Pointer to set of command packets
|
* @param pSet Pointer to set of command packets
|
||||||
*
|
*
|
||||||
* @return pointer to the command packet
|
* @return pointer to the command packet
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* It is critical that the word corresponding to the [alloc] field in the
|
||||||
|
* equivalent struct k_args command packet be zero so that the system knows the
|
||||||
|
* command packet is not part of the free list.
|
||||||
|
* @endinternal
|
||||||
*/
|
*/
|
||||||
cmdPkt_t *_cmd_pkt_get(struct cmd_pkt_set *pSet)
|
struct k_args *_cmd_pkt_get(struct cmd_pkt_set *pSet)
|
||||||
{
|
{
|
||||||
uint32_t index; /* index into command packet array */
|
uint32_t index; /* index into command packet array */
|
||||||
|
struct k_args *cmd_pkt; /* pointer to command packet */
|
||||||
int key; /* interrupt lock level */
|
int key; /* interrupt lock level */
|
||||||
|
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
|
@ -53,7 +60,10 @@ cmdPkt_t *_cmd_pkt_get(struct cmd_pkt_set *pSet)
|
||||||
pSet->index = 0;
|
pSet->index = 0;
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
||||||
return &pSet->command_packet[index];
|
cmd_pkt = (struct k_args *)&pSet->command_packet[index];
|
||||||
|
cmd_pkt->alloc = false;
|
||||||
|
|
||||||
|
return cmd_pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -407,13 +407,7 @@ void isr_sem_give(ksem_t sema, struct cmd_pkt_set *pSet)
|
||||||
{
|
{
|
||||||
struct k_args *pCommand; /* ptr to command packet */
|
struct k_args *pCommand; /* ptr to command packet */
|
||||||
|
|
||||||
/*
|
pCommand = _cmd_pkt_get(pSet);
|
||||||
* The cmdPkt_t data structure was designed to work seamlessly with the
|
|
||||||
* struct k_args data structure and it is thus safe (and expected) to typecast
|
|
||||||
* the return value of _cmd_pkt_get() to "struct k_args *".
|
|
||||||
*/
|
|
||||||
|
|
||||||
pCommand = (struct k_args *)_cmd_pkt_get(pSet);
|
|
||||||
pCommand->Comm = _K_SVC_SEM_SIGNAL;
|
pCommand->Comm = _K_SVC_SEM_SIGNAL;
|
||||||
pCommand->args.s1.sema = sema;
|
pCommand->args.s1.sema = sema;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ extern struct nano_sem fiberSem; /* semaphore that allows test control the fiber
|
||||||
|
|
||||||
static ksem_t testIsrInfo;
|
static ksem_t testIsrInfo;
|
||||||
|
|
||||||
static CMD_PKT_SET_INSTANCE(cmdPktSet, 2);
|
CMD_PKT_SET_INSTANCE(cmdPktSetIsr, 2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that semaphore group entries are arranged so that resultSems[TC_PASS]
|
* Note that semaphore group entries are arranged so that resultSems[TC_PASS]
|
||||||
|
@ -167,7 +167,7 @@ void LowPriTaskEntry(void)
|
||||||
|
|
||||||
static void testIsrHandler(void *isrData)
|
static void testIsrHandler(void *isrData)
|
||||||
{
|
{
|
||||||
isr_sem_give(*(ksem_t *)isrData, &CMD_PKT_SET(cmdPktSet));
|
isr_sem_give(*(ksem_t *)isrData, &cmdPktSetIsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,8 +38,8 @@ extern ksem_t semList[];
|
||||||
|
|
||||||
static char __stack fiberStack[FIBER_STACK_SIZE]; /* test fiber stack size */
|
static char __stack fiberStack[FIBER_STACK_SIZE]; /* test fiber stack size */
|
||||||
|
|
||||||
/* array of command packets used by test fiber to signal semaphores */
|
/* command packet set used by test fiber to signal semaphores */
|
||||||
static CMD_PKT_SET_INSTANCE(cmdPktSet, N_TESTS + 1);
|
CMD_PKT_SET_INSTANCE(cmdPktSetFiber, N_TESTS + 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -59,18 +59,18 @@ static void testFiberEntry(void)
|
||||||
int i;
|
int i;
|
||||||
/* release semaphore test task is waiting for */
|
/* release semaphore test task is waiting for */
|
||||||
nano_fiber_sem_take_wait(&fiberSem);
|
nano_fiber_sem_take_wait(&fiberSem);
|
||||||
fiber_sem_give(simpleSem, &CMD_PKT_SET(cmdPktSet));
|
fiber_sem_give(simpleSem, &cmdPktSetFiber);
|
||||||
|
|
||||||
/* release the semaphore for N_TESTS times */
|
/* release the semaphore for N_TESTS times */
|
||||||
nano_fiber_sem_take_wait(&fiberSem);
|
nano_fiber_sem_take_wait(&fiberSem);
|
||||||
for (i = 0; i < N_TESTS; i++) {
|
for (i = 0; i < N_TESTS; i++) {
|
||||||
fiber_sem_give(simpleSem, &CMD_PKT_SET(cmdPktSet));
|
fiber_sem_give(simpleSem, &cmdPktSetFiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal each semaphore in the group */
|
/* signal each semaphore in the group */
|
||||||
for (i = 0; semList[i] != ENDLIST; i++) {
|
for (i = 0; semList[i] != ENDLIST; i++) {
|
||||||
nano_fiber_sem_take_wait(&fiberSem);
|
nano_fiber_sem_take_wait(&fiberSem);
|
||||||
fiber_sem_give(semList[i], &CMD_PKT_SET(cmdPktSet));
|
fiber_sem_give(semList[i], &cmdPktSetFiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue