宏定义编写技巧__调试技巧【原创】

带颜色打印:

printk("\033[1;33;40m misc.c InterIoctl() action=%d\033[0m\r\n", action);

方法一、

 1 #ifndef _PMU_DUMMY_
 2
 3 #define _PMU_DUMMY_
 4
 5
 6
 7 #define PAX_PMU_DUMMY_DEBUG_ENABLE
 8
 9
10
11 #ifdef PAX_PMU_DUMMY_DEBUG_ENABLE
12
13 #define PAX_PMU_DUMMY_DEBUG(x...)   do{printk("\r\n");printk(x);printk("\r\n");}while(0)
14
15 #else
16
17 #define PAX_PMU_DUMMY_DEBUG(x...)
18
19 #endif
20
21
22
23 #define REGULATOR_DUMMY        "dummy_regulator"
24
25
26
27 #endif

 方法二、

 1 #define DEBUG_ENABLE   1
 2
 3
 4
 5 #if  DEBUG_ENABLE
 6
 7 #define PRINT(fmt, args...)  do{\
 8
 9         printf("<%s>【*%s()*】(%d):", __FILE__, __func__, __LINE__);\
10
11         printf(fmt, ##args);\
12
13 }while(0)
14
15 #else
16
17 #define PRINT(fmt, args...)
18
19 #endif

 

 

 

方法三、

 1 // 带格式的打印调试
 2 int Serial_Printf(char *fmt, ...)
 3 {
 4   va_list args;
 5   int printed = 0;
 6
 7   uint8 printf_buf[MAX_PRINTF_LEN];
 8
 9   va_start(args, fmt);
10   printed = vsprintf((char*)printf_buf, fmt, args);
11   va_end(args);
12
13   printf_buf[MAX_PRINTF_LEN-1] = '\0';
14   SerialPrintString(printf_buf);
15
16   return printed;
17 }
1 /*
2 打印一个字符串
3 str不可以包含0x00,除非结尾
4 */
5 void SerialPrintString(uint8 str[])
6 {
7   HalUARTWrite (SBP_UART_PORT, str, osal_strlen((char*)str));
8 }
 1 //#define DEBUG
 2
 3 #ifdef DEBUG
 4 #define DEBUG_PRINT(format, ...)            Serial_Printf(format, ##__VA_ARGS__)
 5 #define DEBUG_PRINT_BUFF(title, buff, len, display_char)  \
 6                                             Serial_PrintBuffer(title, buff, len, display_char)
 7 #else
 8 #define DEBUG_PRINT(format, ...)
 9 #define DEBUG_PRINT_BUFF(title, buff, len, display_char)
10 #endif  

 

 

方法四、
//console.c
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <pthread.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#include "Console.h"

/*----------------------------------------------------------*/
/*! \brief Structure which will be copied into shared memory, in order to synchronize console output from
 *         different processes and threads.
 */
/*----------------------------------------------------------*/
typedef struct {
    ///If set to true, there is an segmented print ongoing (Start, Continue, Exit).
    bool criticalSection;
    ///Handle of the shared mutex.
    pthread_mutex_t mutex;
} shared_data;

/*----------------------------------------------------------*/
/*! \brief Pointer to the shared memory instance.
 */
/*----------------------------------------------------------*/
static shared_data* data = NULL;

void show_read(unsigned char *str, unsigned char *buff, unsigned int len)
{
    ConsolePrintfStart("serial-RX: %s [", str);
    for (int i = 0; i < len; i++) {
        ConsolePrintfContinue("%02X ", buff[i]);
    }
    ConsolePrintfExit("]\r\n");
}

void ConsoleInit(void)
{
    pthread_mutexattr_t attr;
    int prot = PROT_READ | PROT_WRITE;
    int flags = MAP_SHARED | MAP_ANONYMOUS;
    data = (shared_data*)mmap(NULL, sizeof(shared_data), prot, flags, -1, 0);

    data->criticalSection = false;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&data->mutex, &attr);
}

void ConsoleDeinit(void)
{
    munmap(data, sizeof(data));
    data = NULL;
}

void ConsolePrintf(const char *statement, ...)
{
    int err;
    if (NULL == data) {
        printf("ConsolePrintf data was null\n");
        while (true);
    }
    if (0 != (err = pthread_mutex_lock(&data->mutex))) {
        printf("ConsolePrintf, pthread_mutex_lock error: %d\n", err);
    }
    if (NULL != statement) {
        va_list args;
        va_start(args, statement);
        vprintf(statement, args);
        va_end(args);
    }
    if (0 != (err = pthread_mutex_unlock(&data->mutex))) {
        printf("ConsolePrintf, pthread_mutex_unlock error: %d\n", err);
        while (true);
    }
}

void ConsolePrintfStart(const char *statement, ...)
{
    int err;
    if (NULL == data) {
        printf("ConsolePrintfStart data was null\n");
        while (true);
    }
    if (0 != (err = pthread_mutex_lock(&data->mutex))) {
        printf("ConsolePrintfStart, pthread_mutex_lock error: %d\n", err);
    }
    data->criticalSection = true;

    if (NULL != statement) {
        va_list args;
        va_start(args, statement);
        vprintf(statement, args);
        va_end(args);
    }
}

void ConsolePrintfContinue(const char *statement, ...)
{
    if (NULL == data) {
        printf("ConsolePrintfContinue data was null\n");
        while (true);
    }
    if (!data->criticalSection) {
        printf("ConsolePrintfContinue not in critical section\n");
        while (true);
    }

    if (NULL != statement) {
        va_list args;
        va_start(args, statement);
        vprintf(statement, args);
        va_end(args);
    }
}

void ConsolePrintfExit(const char *statement, ...)
{
    int err;
    if (NULL == data) {
        printf("ConsolePrintfExit data was null\n");
        while (true);
    }
    if (!data->criticalSection) {
        printf("ConsolePrintfExit not in critical section\n");
        while (true);
    }
    if (NULL != statement) {
        va_list args;
        va_start(args, statement);
        vprintf(statement, args);
        va_end(args);
    }
    data->criticalSection = false;
    if (0 != (err = pthread_mutex_unlock(&data->mutex))) {
        printf("ConsolePrintfExit, pthread_mutex_unlock error: %d\n", err);
        while (true);
    }
}
//console.h
/*----------------------------------------------------------*/
/*! \file
 *  \brief This file contains C-functions starting with "Console" to provide
 *         process and thread safe access to the console output.
 */
/*----------------------------------------------------------*/
#ifndef _CONSOLE_H_
#define _CONSOLE_H_

#define RESETCOLOR "\033[0m"
#define GREEN      "\033[0;32m"
#define RED        "\033[0;31m"
#define YELLOW     "\033[1;33m"
#define BLUE       "\033[0;34m"

#ifdef __cplusplus
extern "C"
{
#endif

    void show_read(unsigned char *str, unsigned char *buff, unsigned int len);
    /*----------------------------------------------------------*/
    /*! \brief Initializes the resources needed to synchronize between processes and threads.
     *  \note This function must be called before any other function of this component.
     *
     */
    /*----------------------------------------------------------*/
    void ConsoleInit(void);

    /*----------------------------------------------------------*/
    /*! \brief Destroys the resources needed to synchronize between processes and threads.
     *  \note After this function, any other function (except ConsoleInit) must not be called.
     *
     */
    /*----------------------------------------------------------*/
    void ConsoleDeinit(void);

    /*----------------------------------------------------------*/
    /*! \brief Uses the board specific PRINT mechanism and provides thread and process safety.
     *
     */
    /*----------------------------------------------------------*/
    void ConsolePrintf(const char *statement, ...);

    /*----------------------------------------------------------*/
    /*! \brief Starts to print and stay blocked after exit of this function
     *
     */
    /*----------------------------------------------------------*/
    void ConsolePrintfStart(const char *statement, ...);

    /*----------------------------------------------------------*/
    /*! \brief Continue to print and stay blocked after exit of this function
     *  \note ConsolePrintfStart must be called before and when finished ConsolePrintfExit must be called.
     *  \note This function may be called multiple times.
     */
    /*----------------------------------------------------------*/
    void ConsolePrintfContinue(const char *statement, ...);

    /*----------------------------------------------------------*/
    /*! \brief Continue to print and unblock after finishing.
     *  \note ConsolePrintfStart must be called before. ConsolePrintfContinue may have been called before multiple times.
     */
    /*----------------------------------------------------------*/
    void ConsolePrintfExit(const char *statement, ...);

#ifdef __cplusplus
}
#endif

#endif //_CONSOLE_H_
#ifndef _BASE_H_
#define _BASE_H_

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <setjmp.h>
#include <sys/mman.h>

#include "uart.h"
#include "Console.h"

//#define DEBUG

#ifdef DEBUG
    #define DEBUG_PRINT(format, ...)    ConsolePrintf(format, ##__VA_ARGS__);
    #define SHOW_READ(format, ...)    show_read(format, ##__VA_ARGS__);
#else
    #define DEBUG_PRINT(format, ...)
    #define SHOW_READ(format, ...)
#endif

#define     FALSE        0
#define     TRUE        1

typedef unsigned char   BYTE;           //  8-bit
typedef unsigned short  WORD;           // 16-bit
typedef unsigned long   DWORD;          // 32-bit
typedef unsigned char        u8;
typedef unsigned short        u16;
typedef unsigned int        u32;
typedef unsigned long long    u64;
typedef unsigned char        uint8;
typedef unsigned short        uint16;
typedef unsigned int        uint32;
typedef unsigned long long    uint64;

/* takes a byte out of a uint32 : var - uint32,  ByteNum - byte to take out (0 - 3) */
#define BREAK_UINT32( var, ByteNum ) \
          (uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF))

#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \
          ((uint32)((uint32)((Byte0) & 0x00FF) \
          + ((uint32)((Byte1) & 0x00FF) << 8) \
          + ((uint32)((Byte2) & 0x00FF) << 16) \
          + ((uint32)((Byte3) & 0x00FF) << 24)))

#define BUILD_UINT16(loByte, hiByte) \
          ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))

#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)

#define BUILD_UINT8(hiByte, loByte) \
          ((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4)))

#define HI_UINT8(a) (((a) >> 4) & 0x0F)
#define LO_UINT8(a) ((a) & 0x0F)

#endif

 

printk 调试方法

方法1:

//#define MY_DEBUG
#ifdef MY_DEBUG
#define MY_DBG(x...) do{printk(x);}while(0)
#else
#define MY_DBG(x...)
#endif

 

方法2:

驱动可以如下写:

#define MY_LEVEL1 (1 << 0)
#define MY_LEVEL2 (1 << 1)

unsigned int my_trace_param=0;
module_param_named(trace, my_trace_param, uint, S_IRUGO|S_IWUSR);

#define MY_DBG(flag, msg...) \
do { \
if (my_trace_param & flag) \
printk(KERN_ERR "zbh-debug: " msg); \
} while (0)

 

MY_DBG(MY_LEVEL1, "Goodbye module exit1.\r\n");
MY_DBG(MY_LEVEL2, "Goodbye module exit2.\r\n");
MY_DBG(MY_LEVEL2, "Goodbye module exit3.\r\n");

 

测试:

insmod my_printk_driver.ko 

echo 2 > /sys/module/my_printk_driver/parameters/trace 

这样就可以选择到底打印哪一条语句,用来动态调试开关,默认关打印

 

 

 

code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include<linux/slab.h>        //kmalloc
#include<asm/io.h>            //ioremap
#include<linux/device.h>    //class_create/device_create
#include <asm/uaccess.h>
#include <linux/pwm.h>
#include <linux/cdev.h>
#include <pax/gpio_cfg.h>
#include <pax/bcm5830x_gpio_def.h>
#include <mach/iproc_regs.h>
#include <mach/memory.h>
#include <mach/iomux.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>

#define PWM_IOC_MAGIC         'n'
#define PWM_CONFIG            _IOW(PWM_IOC_MAGIC, 1, int)
#define PWM_DISABLE            _IOW(PWM_IOC_MAGIC, 2, int)
#define ONE_PWM_CONFIG      _IOW(PWM_IOC_MAGIC, 3, int)
#define ONE_PWM_DISABLE     _IOW(PWM_IOC_MAGIC, 4, int)
#define ONE_PWM_WHILE_10000 _IOW(PWM_IOC_MAGIC, 5, int)
#define SET_PWM_GPIO        _IOW(PWM_IOC_MAGIC, 6, int)
#define SET_PWM_POLATIRY    _IOW(PWM_IOC_MAGIC, 7, int)
#define READ_ONEPLUSE_COUNTER  _IOW(PWM_IOC_MAGIC, 8, int)
#define SET_PWM_FUNC           _IOW(PWM_IOC_MAGIC, 9, int)
#define SET_PWM_WHILE           _IOW(PWM_IOC_MAGIC, 10, int)
#define ONE_PWM_DOORBELL           _IOW(PWM_IOC_MAGIC, 11, int)

#define MY_LEVEL1                    (1 << 0)
#define MY_LEVEL2                    (1 << 1)

unsigned int my_trace_param = 0;
module_param_named(trace, my_trace_param, uint, S_IRUGO|S_IWUSR);

#define MY_DBG(flag, msg...) \
    do { \
        if (my_trace_param & flag) \
            printk(KERN_ERR "zbh-bbl: " msg); \
    } while (0)

static int ttime = 0;
static int pmode = 0; // pmode=0 ----> asiu_pwmc , pmode=1 ----> onepluse

module_param(ttime, int, 0);
module_param(pmode, int, 0);

//module_param(period, int, 0);

#define HELLO_MAJOR 230
int hello_major = HELLO_MAJOR;

module_param(hello_major, int, 0);

static struct cdev *hello_cdev = NULL;
static struct class *dev_class = NULL;
static struct device *dev_device = NULL;

static int hello_open(struct inode *inode, struct file *filp);
static int hello_release(struct inode *inode, struct file *filp);

static int hello_open(struct inode *inode, struct file *filp)
{
    printk("hello_open is OK\r\n");
    return 0;
}

static int hello_release(struct inode *inode, struct file *filp)
{
    printk("hello_release is OK\r\n");

    printk("pwm disable and free\r\n");
    return 0;
}

struct file_operations hello_ops = {
    .owner    = THIS_MODULE,
    .open    = hello_open,
    .release     = hello_release,
    //.unlocked_ioctl = hello_ioctl,
};

static int __init hello_init(void)
{
    dev_t devno;
    int ret;

    devno = MKDEV(hello_major, 0);
    ret = register_chrdev_region(devno, 1, "zbh_hello");
    if (!ret) {
        printk("register dev OK.\r\n");
    }
    else {
        printk("register dev failed.\r\n");
    }

    hello_cdev = cdev_alloc();
    cdev_init(hello_cdev, &hello_ops);
    cdev_add(hello_cdev, devno, 1);
    hello_cdev->owner = THIS_MODULE;
    hello_cdev->ops = &hello_ops;

    dev_class = class_create(THIS_MODULE, "dev_class");
    if (IS_ERR(dev_class)) {
        printk(KERN_ERR "class_create() failed for dev_class\n");
        ret = -EINVAL;
        goto out_err_1;
    }

    dev_device = device_create(dev_class, NULL, devno, NULL, "zbh_hello");
    if (IS_ERR(dev_device)) {
        printk(KERN_ERR "device_create failed.\r\n");
        ret = -ENODEV;
        goto out_err_2;
    }

    printk("Hello module init OK.\r\n");

    return 0;

out_err_2:
    class_destroy(dev_class);

out_err_1:
    unregister_chrdev_region(MKDEV(hello_major, 0), 1);
    cdev_del(hello_cdev);
    return ret;
}

static void __exit hello_exit(void)
{
    cdev_del(hello_cdev);

    device_destroy(dev_class, MKDEV(hello_major, 0));
    class_destroy(dev_class);

    unregister_chrdev_region(MKDEV(hello_major, 0), 1);

    MY_DBG(MY_LEVEL1, "Goodbye module exit1.\r\n");
    MY_DBG(MY_LEVEL2, "Goodbye module exit2.\r\n");
    MY_DBG(MY_LEVEL2, "Goodbye module exit3.\r\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zhangbinghua");
MODULE_DESCRIPTION("zhangbh debug driver");

 

时间: 2024-10-27 01:59:58

宏定义编写技巧__调试技巧【原创】的相关文章

JavaScript的兼容性与调试技巧_javascript技巧

关于JavaSctipt的兼容性,最懒的办法就是用jQuery的工具函数.尽量不要用那些什么ECMAScript之类的函数,因为很多浏览器都会报找不到函数的错误.下面列出一些在开发过程中碰到过的javascript问题. 1.参数列表多个逗号. $.ajax({})方法,非常熟悉了吧,但是在IE中有个小地方要注意,如果你在拼接参数列表的时候最后一个也加了逗号,那么毫无疑问,IE下全部JS失效. 调试时报如下错误: 缺少标识符.字符串或数字 data: { S_Id: Subject_Id, le

C语言中的内联函数(inline)与宏定义(#define)详细解析_C 语言

先简明扼要,说下关键:1.内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快. 2.内联函数可以调试,而宏定义是不可以调试的.内联函数与宏本质上是两个不同的概念如果程序编写者对于既要求快速,又要求可读的情况下,则应该将函数冠以inline.下面详细介绍一下探讨一下内联函数与宏定义. 一.内联函数是什么?内联函数是代码被插入到调用者代码处的函数.如同 #define 宏(但并不等同,原因见下文),内联函数通过避免被调用的开销来提

C语言宏定义使用技巧

写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义-- 1,防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H //头文件内容 #endif 2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植. typedef unsigned char boolean: /* Boolean value type. */ typedef unsigned l

C++编程语言的四个调试技巧

1.调试标记 适用预处理#define定义一个或多个调试标记,在代码中把调试部分使用#ifdef和#endif进行管理.当程序最终调试完成后,只需要使用#undef标记,调试代码就会消失.常用的调试标记为DEBUG, 语句序列: #define DEBUG#ifdef DEBUG调试代码#endif 2.运行期间调试标记 在程序运行期间打开和关闭调试标记.通过设置一个调试bool标记可以实现.这对命令行运行的程序更为方便.例如下面代码: #include<iostream>#include &

[译] 前端调试技巧与诀窍

本文讲的是[译] 前端调试技巧与诀窍, 原文地址:Debugging Tips and Tricks 原文作者:SARAH DRASNER 译文出自:掘金翻译计划 译者:lsvih 校对者:loveky,ymz1124 前端调试技巧与诀窍 编写代码其实只是开发者的一小部分工作.为了让工作更有效率,我们还必须精通 debug.我发现,花一些时间学习新的调试技巧,往往能让我能更快地完成工作,对我的团队做出更大的贡献.关于调试这方面我有一些自己重度依赖的技巧与诀窍,同时我在 workshop 中经常建

VS2008调试技巧收集备用

VS2005调试技巧集合 http://blog.csdn.net/rainylin/archive/2007/09/06/1775125.aspx 下面有从浅入深的6个问题,您可以尝试回答一下 一个如下的语句for (int i = 0; i < 10; i++){if (i == 5)j = 5;},什么都写在一行,你怎么在j=5前面插入断点 在一个1000次的循环体内部设置断点,你希望当循环进行到900次后中断,怎么才能做到呢? 你有一个表达式在上面循环的某一次发生了变化,你想知道是哪一次

Visual Studio 原生开发的10个调试技巧(二)

原文:Visual Studio 原生开发的10个调试技巧(二) 我以前关于 Visual Studio 调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号).这些技巧可以应用在 VS2005 或者更新版本中(当然有一些可以适用于旧版本).如果你继续,你可以知道每个技巧的详细信息. 数据断点 线程重命名 特定进程中断 大概执行时间 数字格式化 内存数据格式化 系统DLL中断 装载符号表 MFC中内存泄露报告 调试A

10 个 Visual Studio 原生开发的调试技巧

我以前关于Visual Studio调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号).这些技巧可以应用在VS2005或者更新版本中(当然有一些可以适用于旧版本).如果你继续,你可以知道每个技巧的详细信息. 数据断点 线程重命名 特定进程中断 大概执行时间 数字格式化 内存数据格式化 系统DLL中断 装载符号表 MFC中内存泄露报告 调试ATL 提示11:数据断点 当数据所在内存位置变化时,调试器将会中断.然而,

Visual C++开发与调试技巧整理

Visual C++开发工具与调试技巧整理 自己总是用VC平台来开发东西,但是有时候总是出这样那样的问题,呵呵,总是需要上网查资料来解决,在这里把自己用到上网查的一些技巧摘录如下,希望对大家有用,省去大家再去搜索的烦恼. 1.如何在Release状态下进行调试 Project->Setting=>ProjectSetting对话框,选择Release状态.C/C++标签中的Category选General,Optimizations选Disable(Debug),Debut info选Prog