summaryrefslogtreecommitdiffstats
path: root/playground_05-25-2011.c
diff options
context:
space:
mode:
Diffstat (limited to 'playground_05-25-2011.c')
-rw-r--r--playground_05-25-2011.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/playground_05-25-2011.c b/playground_05-25-2011.c
new file mode 100644
index 0000000..20249a7
--- /dev/null
+++ b/playground_05-25-2011.c
@@ -0,0 +1,141 @@
+/*
+ * playground_05-25-2011.c
+ *
+ *
+ * Playing around with unions and macros, and how both
+ * of these things look in the memory
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define EXP(base, exp, ret) do { \
+ int i; \
+ int acc = 1; \
+ for (i = 0; i < exp; i++) \
+ acc *= base; \
+ ret = acc; \
+ } while(0) \
+
+#define MUL(base, mult, ret) do { \
+ int i; \
+ int acc = 0; \
+ for (i = 0; i < mult; i++) \
+ acc += base; \
+ ret = acc; \
+ } while(0) \
+
+/* trace a variable, requires ANSI compliant compiler */
+#define TRACE(var, fmt) \
+ printf("TRACE: " #var " = " #fmt ", %s:%d\n", var, __FILE__, __LINE__)
+
+#pragma pack(1)
+struct UART_tag
+{
+ union
+ {
+ struct
+ {
+ uint32_t baud_rate; /* bits [0:31] */
+
+ uint8_t tx_en : 1;
+ uint8_t rx_en : 1;
+ uint8_t parity : 1; /* bit [34], 35th */
+
+ uint32_t : 29;
+
+ } B;
+
+ uint64_t R;
+ } SET;
+
+};
+typedef struct UART_tag UART_t;
+
+void UART_info(UART_t *dev)
+{
+ printf("baud rate: %u\n"
+ "tx enabled: %s\n"
+ "rx enabled: %s\n"
+ "parity enabled: %s\n", dev->SET.B.baud_rate,
+ dev->SET.B.tx_en ? "yes" : "no",
+ dev->SET.B.rx_en ? "yes" : "no",
+ dev->SET.B.parity ? "yes" : "no");
+}
+
+void dumpHex(UART_t *p, unsigned int sz)
+{
+ int i;
+ for (i = 0; i < sz; i++)
+ {
+ if (i % 4 == 0)
+ printf("%s0x%08x: ", i == 0 ? "" : "\n", i);
+
+ printf(" 0x%02x", ((unsigned char *) p)[i] );
+ }
+ printf("\n\n");
+}
+
+int main(int argc, char **argv)
+{
+ /* assigning a struct within the union */
+ puts("\t assigning a struct within the union");
+ UART_t myUart;
+ myUart.SET.R = 0;
+ myUart.SET.B.baud_rate = 19200;
+ myUart.SET.B.tx_en = 1;
+ myUart.SET.B.rx_en = 1;
+ myUart.SET.B.parity = 0;
+
+ UART_info(&myUart);
+ puts("");
+
+ puts("\t this is how UART_t looks in the memory");
+ dumpHex(&myUart, sizeof(UART_t));
+
+ /* disable a flag within the struct */
+ puts("\t disable a flag within the struct");
+ myUart.SET.B.tx_en = 0;
+ UART_info(&myUart);
+ puts("");
+
+ /* modifying the whole structure at once */
+ puts("\t modifying the whole structure at once");
+ myUart.SET.R = 0;
+ UART_info(&myUart);
+ puts("");
+
+ /* enable the parity bit */
+ myUart.SET.R |= (uint64_t) \
+ ((uint64_t) 1 << (64 - 30)); /* this is inverted compared
+ * to how it would be done on
+ * a register */
+
+ puts("\t setting the parity bit to ON using logical OR operator");
+ UART_info(&myUart);
+ puts("");
+
+ printf("size of UART_t is: %lu bytes\n", sizeof(UART_t));
+ printf("size of UART_tag is: %lu bytes\n", sizeof(myUart.SET.B));
+
+ int x;
+ EXP(2, 20, x);
+ printf("a megabyte is %d bytes\n", x);
+
+ int y;
+ MUL(x, 4, y);
+ printf("4 megabytes is %d bytes\n", y);
+
+ /* endianess */
+ int z = 1;
+ if (*((unsigned char *) &z) == 1)
+ puts("machine has a little-endian byte ordering");
+ else
+ puts("machine has a big-endian byte ordering");
+
+ TRACE(y, %d);
+
+ return 0;
+}
+