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 ...
|
||||
* CMD_PKT_SET_INSTANCE(set variable name, # of command packets in the set);
|
||||
*
|
||||
* Once created, the command packet set is accessed using ...
|
||||
* CMD_PKT_SET(set variable name).<member field name>
|
||||
* Once created, the command packet set is referenced as an ordinary structured
|
||||
* variable.
|
||||
|
||||
* 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
|
||||
|
@ -52,47 +52,34 @@ extern "C" {
|
|||
|
||||
#define CMD_PKT_SIZE_IN_WORDS (19)
|
||||
|
||||
/**
|
||||
* @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))
|
||||
/* define command packet set types */
|
||||
|
||||
typedef uint32_t cmdPkt_t[CMD_PKT_SIZE_IN_WORDS];
|
||||
|
||||
struct cmd_pkt_set {
|
||||
uint32_t num_packets; /* number of command packets in set */
|
||||
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 */
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -40,10 +40,17 @@ uint32_t _k_test_cmd_pkt_size
|
|||
* @param pSet Pointer to set of command packets
|
||||
*
|
||||
* @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 */
|
||||
struct k_args *cmd_pkt; /* pointer to command packet */
|
||||
int key; /* interrupt lock level */
|
||||
|
||||
key = irq_lock();
|
||||
|
@ -53,7 +60,10 @@ cmdPkt_t *_cmd_pkt_get(struct cmd_pkt_set *pSet)
|
|||
pSet->index = 0;
|
||||
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 */
|
||||
|
||||
/*
|
||||
* 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 = _cmd_pkt_get(pSet);
|
||||
pCommand->Comm = _K_SVC_SEM_SIGNAL;
|
||||
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 CMD_PKT_SET_INSTANCE(cmdPktSet, 2);
|
||||
CMD_PKT_SET_INSTANCE(cmdPktSetIsr, 2);
|
||||
|
||||
/*
|
||||
* Note that semaphore group entries are arranged so that resultSems[TC_PASS]
|
||||
|
@ -167,7 +167,7 @@ void LowPriTaskEntry(void)
|
|||
|
||||
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 */
|
||||
|
||||
/* array of command packets used by test fiber to signal semaphores */
|
||||
static CMD_PKT_SET_INSTANCE(cmdPktSet, N_TESTS + 1);
|
||||
/* command packet set used by test fiber to signal semaphores */
|
||||
CMD_PKT_SET_INSTANCE(cmdPktSetFiber, N_TESTS + 1);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -59,18 +59,18 @@ static void testFiberEntry(void)
|
|||
int i;
|
||||
/* release semaphore test task is waiting for */
|
||||
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 */
|
||||
nano_fiber_sem_take_wait(&fiberSem);
|
||||
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 */
|
||||
for (i = 0; semList[i] != ENDLIST; i++) {
|
||||
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