From a71694a20b36f4ccab329802c8de336b73dab2c5 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 15 Apr 2013 14:31:46 -0400 Subject: [PATCH] revamped printk system Changed ioctl to allow for variable amount of debug printing at cc2520.ko runtime. This way applications can completely turn off debug output, or enable full debug output without having to recompile the module. Defaults to INFO level printing, as before. --- csma.c | 11 +++++---- debug.h | 23 ++++++++++++++++++ interface.c | 50 +++++++++++++++++++-------------------- interface.h | 4 ++-- ioctl.h | 4 ++-- lpl.c | 7 +++--- module.c | 20 ++++++++++------ packet.c | 7 +++--- platform.c | 67 ++++++++++++++++++++++++++++------------------------- radio.c | 4 +++- sack.c | 10 ++++---- unique.c | 5 ++-- 12 files changed, 125 insertions(+), 87 deletions(-) create mode 100644 debug.h diff --git a/csma.c b/csma.c index ea5e316..f703cf9 100644 --- a/csma.c +++ b/csma.c @@ -8,6 +8,7 @@ #include "csma.h" #include "cc2520.h" #include "radio.h" +#include "debug.h" struct cc2520_interface *csma_top; struct cc2520_interface *csma_bottom; @@ -128,12 +129,12 @@ static enum hrtimer_restart cc2520_csma_timer_cb(struct hrtimer *timer) // interrupt context, there's a few places // where we spin lock and assume we can be // preempted. If we're running in atomic mode - // that promise is broken. We use a work queue. + // that promise is broken. We use a work queue. - // The workqueue adds about 30uS of latency. + // The workqueue adds about 30uS of latency. INIT_WORK(&work, cc2520_csma_wq); queue_work(wq, &work); - return HRTIMER_NORESTART; + return HRTIMER_NORESTART; } else { spin_lock_irqsave(&state_sl, flags); @@ -141,7 +142,7 @@ static enum hrtimer_restart cc2520_csma_timer_cb(struct hrtimer *timer) csma_state = CC2520_CSMA_CONG; spin_unlock_irqrestore(&state_sl, flags); - new_backoff = + new_backoff = cc2520_csma_get_backoff(backoff_min, backoff_max_cong); INFO((KERN_INFO "[cc2520] - channel still busy, waiting %d uS\n", new_backoff)); @@ -228,4 +229,4 @@ void cc2520_csma_set_init_backoff(int backoff) void cc2520_csma_set_cong_backoff(int backoff) { backoff_max_cong = backoff; -} \ No newline at end of file +} diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..3743a20 --- /dev/null +++ b/debug.h @@ -0,0 +1,23 @@ +#ifndef DEBUG_H +#define DEBUG_H + +// Define different levels of debug printing + +// print nothing +#define DEBUG_PRINT_OFF 0 +// print only when something goes wrong +#define DEBUG_PRINT_ERR 1 +// print occasional messages about interesting things +#define DEBUG_PRINT_INFO 2 +// print a good amount of debuging output +#define DEBUG_PRINT_DBG 3 + +// Defines the level of debug output +extern uint8_t debug_print; + +// Define the printk macros. +#define ERR(x) do {if (debug_print >= DEBUG_PRINT_ERR) { printk x; }} while (0) +#define INFO(x) do {if (debug_print >= DEBUG_PRINT_INFO) { printk x; }} while (0) +#define DBG(x) do {if (debug_print >= DEBUG_PRINT_DBG) { printk x; }} while (0) + +#endif diff --git a/interface.c b/interface.c index 75058fb..7dcf712 100644 --- a/interface.c +++ b/interface.c @@ -17,6 +17,7 @@ #include "sack.h" #include "csma.h" #include "lpl.h" +#include "debug.h" struct cc2520_interface *interface_bottom; @@ -45,8 +46,6 @@ static struct semaphore rx_done_sem; // Results, stored by the callbacks static int tx_result; -static bool print_messages = false; - DECLARE_WAIT_QUEUE_HEAD(cc2520_interface_read_queue); static void cc2520_interface_tx_done(u8 status); @@ -135,7 +134,7 @@ static ssize_t interface_write( } tx_pkt_len = pkt_len; - if (print_messages) { + if (debug_print >= DEBUG_PRINT_DBG) { interface_print_to_log(tx_buf_c, pkt_len, true); } @@ -163,7 +162,7 @@ static ssize_t interface_read(struct file *filp, char __user *buf, size_t count, if (copy_to_user(buf, rx_buf_c, rx_pkt_len)) return -EFAULT; - if (print_messages) { + if (debug_print >= DEBUG_PRINT_DBG) { interface_print_to_log(rx_buf_c, rx_pkt_len, false); } @@ -176,15 +175,15 @@ static long interface_ioctl(struct file *file, { switch (ioctl_num) { case CC2520_IO_RADIO_INIT: - printk(KERN_INFO "[cc2520] - radio starting\n"); + INFO((KERN_INFO "[cc2520] - radio starting\n")); cc2520_radio_start(); break; case CC2520_IO_RADIO_ON: - printk(KERN_INFO "[cc2520] - radio turning on\n"); + INFO((KERN_INFO "[cc2520] - radio turning on\n")); cc2520_radio_on(); break; case CC2520_IO_RADIO_OFF: - printk(KERN_INFO "[cc2520] - radio turning off\n"); + INFO((KERN_INFO "[cc2520] - radio turning off\n")); cc2520_radio_off(); break; case CC2520_IO_RADIO_SET_CHANNEL: @@ -236,10 +235,11 @@ static void interface_ioctl_set_print(struct cc2520_set_print_messages_data *dat return; } - INFO((KERN_INFO "[cc2520] - setting debug message print: %d", ldata.enabled)); + INFO((KERN_INFO "[cc2520] - setting debug message print: %i", ldata.debug_level)); - print_messages = ldata.enabled; + debug_print = ldata.debug_level; } + static void interface_ioctl_set_channel(struct cc2520_set_channel_data *data) { int result; @@ -248,11 +248,11 @@ static void interface_ioctl_set_channel(struct cc2520_set_channel_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_channel_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the channel\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the channel\n")); return; } - printk(KERN_INFO "[cc2520] - Setting channel to %d\n", ldata.channel); + INFO((KERN_INFO "[cc2520] - Setting channel to %d\n", ldata.channel)); cc2520_radio_set_channel(ldata.channel); } @@ -263,12 +263,12 @@ static void interface_ioctl_set_address(struct cc2520_set_address_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_address_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the address\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the address\n")); return; } - printk(KERN_INFO "[cc2520] - setting addr: %d ext_addr: %lld pan_id: %d\n", - ldata.short_addr, ldata.extended_addr, ldata.pan_id); + INFO((KERN_INFO "[cc2520] - setting addr: %d ext_addr: %lld pan_id: %d\n", + ldata.short_addr, ldata.extended_addr, ldata.pan_id)); cc2520_radio_set_address(ldata.short_addr, ldata.extended_addr, ldata.pan_id); } @@ -279,11 +279,11 @@ static void interface_ioctl_set_txpower(struct cc2520_set_txpower_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_txpower_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the txpower\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the txpower\n")); return; } - printk(KERN_INFO "[cc2520] - setting txpower: %d\n", ldata.txpower); + INFO((KERN_INFO "[cc2520] - setting txpower: %d\n", ldata.txpower)); cc2520_radio_set_txpower(ldata.txpower); } @@ -371,7 +371,7 @@ int cc2520_interface_init() // Allocate a major number for this device result = alloc_chrdev_region(&char_d_mm, 0, 1, cc2520_name); if (result < 0) { - printk(KERN_INFO "[cc2520] - Could not allocate a major number\n"); + ERR((KERN_INFO "[cc2520] - Could not allocate a major number\n")); goto error; } major = MAJOR(char_d_mm); @@ -381,21 +381,21 @@ int cc2520_interface_init() char_d_cdev.owner = THIS_MODULE; result = cdev_add(&char_d_cdev, char_d_mm, 1); if (result < 0) { - printk(KERN_INFO "[cc2520] - Unable to register char dev\n"); + ERR((KERN_INFO "[cc2520] - Unable to register char dev\n")); goto error; } - printk(KERN_INFO "[cc2520] - Char interface registered on %d\n", major); + INFO((KERN_INFO "[cc2520] - Char interface registered on %d\n", major)); cl = class_create(THIS_MODULE, "cc2520"); if (cl == NULL) { - printk(KERN_INFO "[cc2520] - Could not create device class\n"); + ERR((KERN_INFO "[cc2520] - Could not create device class\n")); goto error; } // Create the device in /dev/radio de = device_create(cl, NULL, char_d_mm, NULL, "radio"); if (de == NULL) { - printk(KERN_INFO "[cc2520] - Could not create device\n"); + ERR((KERN_INFO "[cc2520] - Could not create device\n")); goto error; } @@ -422,12 +422,12 @@ void cc2520_interface_free() result = down_interruptible(&tx_sem); if (result) { - printk("[cc2520] - critical error occurred on free."); + ERR(("[cc2520] - critical error occurred on free.")); } result = down_interruptible(&rx_sem); if (result) { - printk("[cc2520] - critical error occurred on free."); + ERR(("[cc2520] - critical error occurred on free.")); } cdev_del(&char_d_cdev); @@ -436,7 +436,7 @@ void cc2520_interface_free() class_destroy(cl); - printk(KERN_INFO "[cc2520] - Removed character device\n"); + INFO((KERN_INFO "[cc2520] - Removed character device\n")); if (rx_buf_c) { kfree(rx_buf_c); @@ -447,4 +447,4 @@ void cc2520_interface_free() kfree(tx_buf_c); tx_buf_c = 0; } -} \ No newline at end of file +} diff --git a/interface.h b/interface.h index 1c52574..2e115db 100644 --- a/interface.h +++ b/interface.h @@ -1,5 +1,5 @@ #ifndef INTERFACE_H -#define iNTERFACE_H +#define INTERFACE_H // Interface int cc2520_interface_init(void); @@ -7,4 +7,4 @@ void cc2520_interface_free(void); extern struct cc2520_interface *interface_bottom; -#endif \ No newline at end of file +#endif diff --git a/ioctl.h b/ioctl.h index e2042b5..d75c4f3 100644 --- a/ioctl.h +++ b/ioctl.h @@ -39,7 +39,7 @@ struct cc2520_set_csma_data { }; struct cc2520_set_print_messages_data { - bool enabled; + u8 debug_level; }; // Possible TX Powers: @@ -66,4 +66,4 @@ struct cc2520_set_txpower_data { #define CC2520_IO_RADIO_SET_ACK _IOW(BASE, 6, struct cc2520_set_ack_data) #define CC2520_IO_RADIO_SET_LPL _IOW(BASE, 7, struct cc2520_set_lpl_data) #define CC2520_IO_RADIO_SET_CSMA _IOW(BASE, 8, struct cc2520_set_csma_data) -#define CC2520_IO_RADIO_SET_PRINT _IOW(BASE, 9, struct cc2520_set_print_messages_data) \ No newline at end of file +#define CC2520_IO_RADIO_SET_PRINT _IOW(BASE, 9, struct cc2520_set_print_messages_data) diff --git a/lpl.c b/lpl.c index 334e5ff..c25d364 100644 --- a/lpl.c +++ b/lpl.c @@ -6,6 +6,7 @@ #include "lpl.h" #include "packet.h" #include "cc2520.h" +#include "debug.h" struct cc2520_interface *lpl_top; struct cc2520_interface *lpl_bottom; @@ -125,7 +126,7 @@ static void cc2520_lpl_tx_done(u8 status) } else { spin_unlock_irqrestore(&state_sl, flags); - //printk(KERN_INFO "[cc2520] - lpl retransmit.\n"); + DBG((KERN_INFO "[cc2520] - lpl retransmit.\n")); lpl_bottom->tx(cur_tx_buf, cur_tx_len); } } @@ -138,7 +139,7 @@ static void cc2520_lpl_tx_done(u8 status) else { spin_unlock_irqrestore(&state_sl, flags); lpl_bottom->tx(cur_tx_buf, cur_tx_len); - } + } } } else { @@ -190,4 +191,4 @@ void cc2520_lpl_set_listen_length(int length) void cc2520_lpl_set_wakeup_interval(int interval) { lpl_interval = interval; -} \ No newline at end of file +} diff --git a/module.c b/module.c index b0e9223..69f8f03 100644 --- a/module.c +++ b/module.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -17,9 +17,13 @@ #include "sack.h" #include "csma.h" #include "unique.h" +#include "debug.h" -#define DRIVER_AUTHOR "Andrew Robinson " -#define DRIVER_DESC "A driver for the CC2520 radio. Be afraid." +#define DRIVER_AUTHOR "Andrew Robinson " +#define DRIVER_DESC "A driver for the CC2520 radio. Be afraid." +#define DRIVER_VERSION "0.5" + +uint8_t debug_print; struct cc2520_state state; const char cc2520_name[] = "cc2520"; @@ -48,11 +52,13 @@ int init_module() { int err = 0; + debug_print = DEBUG_PRINT_INFO; + setup_bindings(); memset(&state, 0, sizeof(struct cc2520_state)); - - INFO((KERN_INFO "loading CC2520 Kernel Module v0.01...\n")); + + INFO((KERN_INFO "loading CC2520 Kernel Module v%s...\n", DRIVER_VERSION)); err = cc2520_plat_gpio_init(); if (err) { @@ -69,7 +75,7 @@ int init_module() err = cc2520_interface_init(); if (err) { ERR((KERN_ALERT "[cc2520] - char driver error. aborting.\n")); - goto error5; + goto error5; } err = cc2520_radio_init(); @@ -135,4 +141,4 @@ void cleanup_module() MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); \ No newline at end of file +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/packet.c b/packet.c index e32f337..405eca9 100644 --- a/packet.c +++ b/packet.c @@ -2,6 +2,7 @@ #include #include "packet.h" #include "cc2520.h" +#include "debug.h" bool cc2520_packet_requires_ack_reply(u8 *buf) { @@ -89,8 +90,8 @@ u64 cc2520_packet_get_src(u8 *buf) src_addr_offset += 10; } // WARNING: this is a weird edge case from the - // 802.15.4 spec. - // NOTE: Assuming we're on LE arch. + // 802.15.4 spec. + // NOTE: Assuming we're on LE arch. else if (pan_compression) { src_addr_offset += 2; } @@ -108,7 +109,7 @@ u64 cc2520_packet_get_src(u8 *buf) memcpy(&ret, buf + src_addr_offset, 8); } - INFO((KERN_INFO "[cc2520] - src_mode: %d dest_mode: %d pan_comp: %d src_addr_offset: %d\n", + DBG((KERN_INFO "[cc2520] - src_mode: %d dest_mode: %d pan_comp: %d src_addr_offset: %d\n", src_addr_mode, dest_addr_mode, pan_compression, src_addr_offset)); return ret; diff --git a/platform.c b/platform.c index 309d8a1..a9d45b8 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -13,6 +13,7 @@ #include "cc2520.h" #include "radio.h" #include "platform.h" +#include "debug.h" ////////////////////////// // SPI Stuff @@ -28,23 +29,23 @@ static int cc2520_spi_add_to_bus(void) spi_master = spi_busnum_to_master(SPI_BUS); if (!spi_master) { - printk(KERN_ALERT "[cc2520] - spi_busnum_to_master(%d) returned NULL\n", - SPI_BUS); - printk(KERN_ALERT "[cc2520] - Missing modprobe spi-bcm2708?\n"); + ERR((KERN_ALERT "[cc2520] - spi_busnum_to_master(%d) returned NULL\n", + SPI_BUS)); + ERR((KERN_ALERT "[cc2520] - Missing modprobe spi-bcm2708?\n")); return -1; } spi_device = spi_alloc_device(spi_master); if (!spi_device) { put_device(&spi_master->dev); - printk(KERN_ALERT "[cc2520] - spi_alloc_device() failed\n"); + ERR((KERN_ALERT "[cc2520] - spi_alloc_device() failed\n")); return -1; } spi_device->chip_select = SPI_BUS_CS0; /* Check whether this SPI bus.cs is already claimed */ - snprintf(buff, sizeof(buff), "%s.%u", + snprintf(buff, sizeof(buff), "%s.%u", dev_name(&spi_device->master->dev), spi_device->chip_select); @@ -52,13 +53,15 @@ static int cc2520_spi_add_to_bus(void) if (pdev) { if (pdev->driver != NULL) { - printk(KERN_INFO - "[cc2520] - Driver [%s] already registered for %s. Nuking from orbit.\n", - pdev->driver->name, buff); + ERR((KERN_INFO + "[cc2520] - Driver [%s] already registered for %s. \ +Nuking from orbit.\n", + pdev->driver->name, buff)); } else { - printk(KERN_INFO - "[cc2520] - Previous driver registered with no loaded module. Nuking from orbit.\n"); + ERR((KERN_INFO + "[cc2520] - Previous driver registered with no loaded module. \ +Nuking from orbit.\n")); } device_unregister(pdev); @@ -73,12 +76,12 @@ static int cc2520_spi_add_to_bus(void) spi_device->controller_data = NULL; strlcpy(spi_device->modalias, cc2520_name, SPI_NAME_SIZE); - status = spi_add_device(spi_device); - if (status < 0) { + status = spi_add_device(spi_device); + if (status < 0) { spi_dev_put(spi_device); - printk(KERN_ALERT "[cc2520] - spi_add_device() failed: %d\n", - status); - } + ERR((KERN_ALERT "[cc2520] - spi_add_device() failed: %d\n", + status)); + } put_device(&spi_master->dev); return status; @@ -86,14 +89,14 @@ static int cc2520_spi_add_to_bus(void) static int cc2520_spi_probe(struct spi_device *spi_device) { - printk(KERN_INFO "[cc2520] - Inserting SPI protocol driver.\n"); + ERR((KERN_INFO "[cc2520] - Inserting SPI protocol driver.\n")); state.spi_device = spi_device; return 0; } static int cc2520_spi_remove(struct spi_device *spi_device) { - printk(KERN_INFO "[cc2520] - Removing SPI protocol driver."); + ERR((KERN_INFO "[cc2520] - Removing SPI protocol driver.")); state.spi_device = NULL; return 0; } @@ -118,7 +121,7 @@ int cc2520_plat_spi_init() result = spi_register_driver(&cc2520_spi_driver); if (result < 0) goto error; - + return 0; error: @@ -138,7 +141,7 @@ void cc2520_plat_spi_free() // Interrupt Handles ///////////////////////// -static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) +static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) { int gpio_val; struct timespec ts; @@ -157,11 +160,11 @@ static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t cc2520_fifop_handler(int irq, void *dev_id) +static irqreturn_t cc2520_fifop_handler(int irq, void *dev_id) { if (gpio_get_value(CC2520_FIFOP) == 1) { DBG((KERN_INFO "[cc2520] - fifop interrupt occurred\n")); - cc2520_radio_fifop_occurred(); + cc2520_radio_fifop_occurred(); } return IRQ_HANDLED; } @@ -216,10 +219,10 @@ int cc2520_plat_gpio_init() } err = request_irq( - irq, - cc2520_fifop_handler, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "fifopHandler", + irq, + cc2520_fifop_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "fifopHandler", NULL ); if (err) @@ -234,10 +237,10 @@ int cc2520_plat_gpio_init() } err = request_irq( - irq, - cc2520_sfd_handler, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "sfdHandler", + irq, + cc2520_sfd_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "sfdHandler", NULL ); if (err) @@ -247,7 +250,7 @@ int cc2520_plat_gpio_init() return err; fail: - printk(KERN_ALERT "[cc2520] - failed to init GPIOs\n"); + ERR((KERN_ALERT "[cc2520] - failed to init GPIOs\n")); cc2520_plat_gpio_free(); return err; } @@ -266,4 +269,4 @@ void cc2520_plat_gpio_free() free_irq(state.gpios.fifop_irq, NULL); free_irq(state.gpios.sfd_irq, NULL); -} \ No newline at end of file +} diff --git a/radio.c b/radio.c index d5dba6f..87f39ee 100644 --- a/radio.c +++ b/radio.c @@ -17,6 +17,8 @@ #include "cc2520.h" #include "radio.h" #include "radio_config.h" +#include "interface.h" +#include "debug.h" static u16 short_addr; static u64 extended_addr; @@ -790,4 +792,4 @@ static cc2520_status_t cc2520_radio_strobe(u8 cmd) ret.value = rx_buf[0]; return ret; -} \ No newline at end of file +} diff --git a/sack.c b/sack.c index acd037d..683e70b 100644 --- a/sack.c +++ b/sack.c @@ -6,8 +6,8 @@ #include "sack.h" #include "cc2520.h" #include "packet.h" - #include "radio.h" +#include "debug.h" struct cc2520_interface *sack_top; struct cc2520_interface *sack_bottom; @@ -76,7 +76,7 @@ int cc2520_sack_init() hrtimer_init(&timeout_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timeout_timer.function = &cc2520_sack_timer_cb; - + spin_lock_init(&sack_sl); sack_state = CC2520_SACK_IDLE; @@ -126,7 +126,7 @@ static void cc2520_sack_start_timer() static int cc2520_sack_tx(u8 * buf, u8 len) { spin_lock_irqsave(&sack_sl, flags); - + if (sack_state != CC2520_SACK_IDLE) { INFO((KERN_INFO "[cc2520] - Ut oh! Tx spinlocking.\n")); } @@ -182,13 +182,13 @@ static void cc2520_sack_rx_done(u8 *buf, u8 len) // release the buffer. When I was troubleshooting // a terrible concurrency bug I added this // as a possible solution, but I don't - // think it's needed anymore. + // think it's needed anymore. cc2520_radio_release_rx(); spin_lock_irqsave(&sack_sl, flags); if (cc2520_packet_is_ack(cur_rx_buf)) { - if (sack_state == CC2520_SACK_TX_WAIT && + if (sack_state == CC2520_SACK_TX_WAIT && cc2520_packet_is_ack_to(cur_rx_buf, cur_tx_buf)) { sack_state = CC2520_SACK_IDLE; spin_unlock_irqrestore(&sack_sl, flags); diff --git a/unique.c b/unique.c index 5889955..58b764b 100644 --- a/unique.c +++ b/unique.c @@ -7,6 +7,7 @@ #include "unique.h" #include "packet.h" #include "cc2520.h" +#include "debug.h" struct node_list{ struct list_head list; @@ -66,7 +67,7 @@ static void cc2520_unique_rx_done(u8 *buf, u8 len) dsn = cc2520_packet_get_header(buf)->dsn; src = cc2520_packet_get_src(buf); - + found = false; drop = false; @@ -98,4 +99,4 @@ static void cc2520_unique_rx_done(u8 *buf, u8 len) if (!drop) unique_top->rx_done(buf, len); -} \ No newline at end of file +}