云海游戏(中国区)有限公司官网



  • example/cpp/candemo/candemo.cpp
    /*
    ** This software is furnished as Redistributable under the 云海游戏 Software Licence
    ** https://www.kvaser.com/canlib-webhelp/page_license_and_copyright.html
    **
    ** Description:
    ** Demo program for CANLIB.
    ** This program can send and receive CAN messages on all CAN channels installed
    ** in your computer. Start it, and press 'h' to get a list of available commands.
    ** ---------------------------------------------------------------------------
    */
    #include <canlib.h>
    #include "candemo.h"
    #include "stdio.h"
    // module globals
    unsigned int m_usedBaudRate = 0;
    canHandle m_usedChannel;
    unsigned int m_usedId;
    unsigned int m_usedFlags = 0;
    unsigned int m_Verbose = 1;
    driverData m_channelData;
    driverData *m_DriverConfig = &m_channelData;
    //Function that prints the "help- menu"
    void help(void)
    {
    printf("\n********************************************\n*\n");
    printf("* Keyboard commands:\n");
    printf("* t Transmit a Message\n");
    printf("* b Transmit a Message Burst\n");
    printf("* r Select Remote Message\n");
    printf("* S Request chip status\n");
    printf("* s Read chip status\n");
    printf("* o On/Off Bus\n");
    printf("* c/C/1-9 Select Channel\n");
    printf("* i/I Select Transmit Id (Up/Down)\n");
    printf("* x Select Extended Id\n");
    printf("* m Toggle Output Mode\n");
    printf("* v Toggle Logging to Screen\n");
    printf("* T Toggle transmission acknowledges for the current channel\n");
    printf("* k Read the clock (call kvReadTimer)\n");
    printf("* h Help\n");
    printf("* d Print Driver Configuration\n");
    printf("* e Clear Screen\n");
    printf("* y Clear Error Status and Counters\n");
    printf("* ESC Exit\n*\n*");
    printf("\n********************************************\n");
    }
    //Function that prints channel data
    void printDriverConfig( void )
    {
    unsigned int i;
    printf("\nDriver Configuration:\n ChannelCount=%u\n", m_DriverConfig->channelCount);
    for (i = 0; i < m_DriverConfig->channelCount; i++) {
    printf(" %s : Channel %d, isOnBus=%d, Baudrate=%u",
    m_DriverConfig->channel[i].name,
    m_DriverConfig->channel[i].channel,
    m_DriverConfig->channel[i].isOnBus,
    m_usedBaudRate);
    switch(m_usedBaudRate) {
    printf("canBITRATE_1M");
    break;
    printf("canBITRATE_500K");
    break;
    printf("canBITRATE_250K");
    break;
    printf("canBITRATE_125K");
    break;
    printf("canBITRATE_100K");
    break;
    printf("canBITRATE_62K");
    break;
    printf("canBITRATE_50K");
    break;
    default:
    printf("UNKNOWN");
    }
    printf("\n ");
    if (m_DriverConfig->channel[i].driverMode == canDRIVER_NORMAL) {
    printf("Drivermode=canDRIVER_NORMAL\n");
    } else {
    printf ("Drivermode=canDRIVER_SILENT\n");
    }
    }
    printf("\n\n");
    }
    // Open one handle to each channel present in the system.
    // Set bus parameters
    void InitDriver(void)
    {
    int i;
    canStatus stat;
    // Initialize ChannelData.
    memset(m_channelData.channel, 0, sizeof(m_channelData.channel));
    for (i = 0; i < MAX_CHANNELS; i++) {
    m_channelData.channel[i].isOnBus = 0;
    m_channelData.channel[i].driverMode = canDRIVER_NORMAL;
    m_channelData.channel[i].channel = -1;
    m_channelData.channel[i].hnd = canINVALID_HANDLE;
    m_channelData.channel[i].txAck = 0; // Default is TxAck off
    }
    m_channelData.channelCount = 0;
    //
    // Enumerate all installed channels in the system and obtain their names
    // and hardware types.
    //
    //initialize CANlib
    //get number of present channels
    stat = canGetNumberOfChannels((int*)&m_channelData.channelCount);
    for (i = 0; (unsigned int)i < m_channelData.channelCount; i++) {
    canHandle hnd;
    //obtain some hardware info from CANlib
    m_channelData.channel[i].channel = i;
    m_channelData.channel[i].name,
    sizeof(m_channelData.channel[i].name));
    &m_channelData.channel[i].hwType,
    sizeof(DWORD));
    //open CAN channel
    if (hnd < 0) {
    // error
    PRINTF_ERR(("ERROR canOpenChannel() in initDriver() FAILED Err= %d. <line: %d>\n",
    hnd, __LINE__));
    }
    else {
    m_channelData.channel[i].hnd = hnd;
    if ((stat = canIoCtl(hnd, canIOCTL_FLUSH_TX_BUFFER, NULL, NULL)) != canOK)
    PRINTF_ERR(("ERROR canIoCtl(canIOCTL_FLUSH_TX_BUFFER) FAILED, Err= %d <line: %d>\n",
    stat, __LINE__));
    }
    //set up the bus
    if (i == 0) {
    switch(m_usedBaudRate) {
    case 1000000:
    m_usedBaudRate = canBITRATE_1M;
    break;
    case 500000:
    m_usedBaudRate = canBITRATE_500K;
    break;
    case 250000:
    m_usedBaudRate = canBITRATE_250K;
    break;
    case 125000:
    m_usedBaudRate = canBITRATE_125K;
    break;
    case 100000:
    m_usedBaudRate = canBITRATE_100K;
    break;
    case 62500:
    m_usedBaudRate = canBITRATE_62K;
    break;
    case 50000:
    m_usedBaudRate = canBITRATE_50K;
    break;
    default:
    printf("Baudrate set to 125 kbit/s. \n");
    m_usedBaudRate = canBITRATE_125K;
    break;
    }
    }
    //set the channels busparameters
    stat = canSetBusParams(hnd, m_usedBaudRate, 0, 0, 0, 0, 0);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canSetBusParams() in InitDriver(). Err = %d <line: %d>\n",
    stat, __LINE__));
    }
    }
    printf("\n");
    }
    // Go off bus and close all open handles.
    void Cleanup(void)
    {
    unsigned int i;
    for (i = 0; i < m_channelData.channelCount; i++) {
    canStatus stat;
    if ((stat = canBusOff(m_channelData.channel[i].hnd)) != canOK)
    PRINTF_ERR(("ERROR canBusOff() FAILED Err= %d. <line: %d>\n", stat, __LINE__));
    if ((stat = canClose(m_channelData.channel[i].hnd)) != canOK) {
    PRINTF_ERR(("ERROR canClose() in Cleanup() FAILED Err= %d. <line: %d>\n",
    stat, __LINE__));
    }
    }
    }
    // CheckAbort()
    //
    // check at transmission of a message burst, if key pressed
    // if key pressed -> stop transmission
    int CheckAbort(void)
    {
    INPUT_RECORD ir;
    unsigned long n;
    GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &n);
    while (n > 0) {
    ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &n);
    if ((n == 1) && (ir.EventType == KEY_EVENT)) {
    if (ir.Event.KeyEvent.bKeyDown)
    return TRUE;
    }
    n--;
    }
    return FALSE;
    }
    // Transmit a message using channel, id and flags from the global variables
    // If print is TRUE the transmitted msg will be printed
    canStatus TransmitMessage(BOOL print)
    {
    unsigned char msg[8];
    int i;
    if (!m_Verbose) print = FALSE;
    if (print) {
    // The time stamp is not available when we call canWrite so it's
    // omitted here. (If we want to see when the message was sent, we
    // first need to enable transmission acknowledges with canIoCtl.
    // Then all sent messages will appear also as received messages,
    // but with the canMSG_TXACK flag set.
    printf("Ch:%u ID:%08x DLC:%zu Flg:%02x Data:",
    m_usedChannel, m_usedId, sizeof(msg), m_usedFlags);
    }
    for (i = 0; i < 8; i++) {
    msg[i] = (unsigned char) i;
    if (print) printf("%02x ", msg[i]);
    }
    if (print) printf("\n");
    return canWrite(m_DriverConfig->channel[m_usedChannel].hnd, m_usedId,
    msg, sizeof(msg), m_usedFlags);
    }
    /*************************************************************/
    /*************************************************************/
    // MAIN
    int main(int argc, char **argv)
    {
    HANDLE th[MAX_CHANNELS + 1];
    static int running = 1;
    DWORD active_handle;
    char c;
    canStatus stat;
    unsigned int i;
    m_usedId = 0;
    m_usedChannel = 0;
    system("cls");
    printf("\n\nWelcome to yet another CANLIB Test Application, compiled at " __DATE__ "\n"
    "(Check out http://www.kvaser.com for more info.)\n\n"
    "Usage:\n"
    " CANdemo [baudrate] [identifier]\n"
    "Press h for help\n\n\n -----------------------------------------------------------------\n\n");
    // Commandline can contain baudrate and an identifier, both optional.
    if (argc > 1) {
    m_usedBaudRate = atoi(argv[1]);
    if (m_usedBaudRate) {
    printf("Baudrate = %u\n\n", m_usedBaudRate);
    argc--;
    argv++;
    }
    }
    if (argc > 1) {
    sscanf (argv[1], "%x", &m_usedId );
    if (m_usedId) {
    printf("Identifier = 0x%x\n\n", m_usedId);
    }
    }
    // open channel and set busparams, etc...
    InitDriver();
    //get std_input event handle
    th[0] = GetStdHandle(STD_INPUT_HANDLE);
    if (th[0] == INVALID_HANDLE_VALUE)
    PRINTF_ERR(("ERROR inv handle (std_input). <line: %d>\n", __LINE__));
    for (i = 1; i < (m_channelData.channelCount + 1); i++) {
    HANDLE tmp;
    //go on bus (every channel)
    stat = canBusOn(m_channelData.channel[i-1].hnd);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    m_DriverConfig->channel[i-1].isOnBus = 1;
    }
    //get CAN - eventHandles
    stat = canIoCtl(m_channelData.channel[i-1].hnd,
    &tmp,
    sizeof(tmp));
    if (stat < 0) {
    PRINTF_ERR(("canIoCtl(canIOCTL_GET_EVENTHANDLE) FAILED. Err = %d <line: %d>\n",
    stat, __LINE__));
    }
    th[i] = tmp;
    }
    printDriverConfig();
    printf("\n");
    //Main LOOP
    while (running) {
    active_handle = WaitForMultipleObjects(m_channelData.channelCount + 1,
    th,
    FALSE /*any*/,
    INFINITE);
    //
    // CAN hardware event?
    //
    if (((active_handle - WAIT_OBJECT_0) > 0) &&
    ((active_handle - WAIT_OBJECT_0) <= m_channelData.channelCount))
    {
    unsigned int j;
    long id;
    unsigned char data[8];
    unsigned int dlc;
    unsigned int flags;
    DWORD time;
    int moreDataExist;
    do {
    moreDataExist = 0;
    for (i = 0; i < m_channelData.channelCount; i++) {
    stat = canRead(m_channelData.channel[i].hnd, &id, &data[0], &dlc, &flags, &time);
    switch (stat) {
    case canOK:
    if (m_Verbose) {
    printf("RxMsg: Ch:%d ID:%08lx DLC:%u Flg:%02x T:%08lx Data:",
    m_channelData.channel[i].channel, id, dlc, flags, time);
    if ((flags & canMSG_RTR) == 0) {
    for (j = 0; j < dlc; j++) {
    printf("%02x ", data[j]);
    }
    }
    printf("\n");
    }
    moreDataExist = 1;
    break;
    // No more data on this handle
    break;
    default:
    PRINTF_ERR(("ERROR canRead() FAILED, Err= %d <line: %d>\n", stat, __LINE__));
    break;
    }
    }
    } while (moreDataExist);
    }
    //STD_INPUT event
    else if (active_handle == WAIT_OBJECT_0)
    {
    unsigned long n;
    INPUT_RECORD ir;
    ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &n);
    if ((n == 1) && (ir.EventType == KEY_EVENT)) {
    if (ir.Event.KeyEvent.bKeyDown) {
    //pressed key switch
    switch ((c = ir.Event.KeyEvent.uChar.AsciiChar)) {
    //==================================================
    case 'V':
    case 'v':
    m_Verbose = !m_Verbose;
    if (m_Verbose) printf("Logging to screen ON. \n");
    else printf("Logging to screen OFF. \n");
    break;
    //==================================================
    case 't':
    {
    canStatus stat;
    if (m_Verbose) {
    printf("TxMsg: ");
    }
    if (m_DriverConfig->channel[m_usedChannel].isOnBus == 0) {
    printf("Cannot transmit message. \n");
    printf("Channel %d is OFF bus. \n", m_usedChannel);
    break;
    }
    stat = TransmitMessage(TRUE);
    if (stat < 0) {
    PRINTF_ERR(("ERROR TransmitMessage() FAILED Err= %d <line: %d>\n",
    stat, __LINE__));
    }
    }
    break;
    //==================================================
    case 'T':
    {
    canStatus stat;
    int tmp;
    if (m_Verbose) {
    printf("Toggling TxAcks on channel %d", m_usedChannel);
    }
    tmp = m_DriverConfig->channel[m_usedChannel].txAck? 0 : 1;
    stat = canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
    &tmp,
    sizeof(tmp));
    if (stat == canOK) {
    m_DriverConfig->channel[m_usedChannel].txAck = tmp;
    printf(" - now %s\n", tmp? "on" : "off");
    } else {
    printf(" failed with error %d on line %d\n", stat, __LINE__);
    }
    }
    break;
    //==================================================
    case 'k':
    {
    unsigned int can_time;
    stat = kvReadTimer(m_DriverConfig->channel[m_usedChannel].hnd, &can_time);
    if (stat == canOK) {
    printf("Time on channel %d: 0x%08x\n", m_usedChannel, can_time);
    } else {
    printf("kvReadTimer() failed with error %d on line %d\n", stat, __LINE__);
    }
    }
    break;
    //==================================================
    case 'B':
    case 'b':
    {
    if (m_Verbose) printf("Transmit message BURST. \n");
    // transmit a message burst
    unsigned char msg[8];
    int i;
    canStatus stat;
    if (m_DriverConfig->channel[m_usedChannel].isOnBus == 0) {
    printf("Cannot transmit burst. \n");
    printf("Channel %d is OFF bus. \n", m_usedChannel);
    break;
    }
    for (i = 0; i < 8; i++) {
    msg[i] = (unsigned char) i;
    }
    printf("Press any key to stop.\n");
    for (i = 0; ; i++) {
    //Send bursts of 250 messages
    for (int j = 0; j < 250; j++) {
    stat = TransmitMessage(FALSE);
    if (stat != canOK) {
    char err[100];
    canGetErrorText((canStatus)stat, err, 100);
    printf("ERROR: %s\n", err);
    break;
    }
    }
    if(stat != canOK)
    break;
    //Wait until all the messages are sent
    stat = canWriteSync(m_DriverConfig->channel[m_usedChannel].hnd, 2000);
    if (stat != canOK) {
    char err[100];
    canGetErrorText((canStatus)stat, err, 100);
    printf("ERROR: %s\n", err);
    break;
    }
    if ((i % 20) == 0) {
    printf("*");
    if (CheckAbort()) {
    printf("\nTransmission finished\n");
    break;
    }
    }
    }
    //flush transmit buffer
    stat = canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
    NULL,
    NULL);
    if (stat != canOK) {
    PRINTF_ERR(("ERROR canIoCtl() in 'b' FAILED. Err = %d <line: %d>\n", stat, __LINE__));
    }
    break;
    }
    //==================================================
    case 'R':
    case 'r':
    // Toggle sending of remote frames.
    m_usedFlags ^= canMSG_RTR;
    if (m_Verbose) {
    printf("Now sending %s frames.\n", (m_usedFlags & canMSG_RTR) ? "remote" : "data");
    }
    break;
    //==================================================
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    m_usedChannel = c - '1';
    goto select;
    //==================================================
    case 'C': // channel selection
    m_usedChannel--;
    if (m_usedChannel < 0)
    m_usedChannel = m_channelData.channelCount - 1;
    if (m_Verbose)
    printf("Current channel = %d \n", m_usedChannel);
    break;
    //==================================================
    case 'c': // channel selection
    m_usedChannel++;
    select:
    if (m_usedChannel >= (int)m_channelData.channelCount)
    m_usedChannel = 0;
    if (m_Verbose)
    printf("Current channel = %d \n", m_usedChannel);
    break;
    //==================================================
    case 'X': // id-type selection
    case 'x':
    // Toggle sending of extended frames.
    m_usedFlags ^= canMSG_EXT;
    if (m_Verbose) {
    printf("Now sending %s frames.\n",
    (m_usedFlags & canMSG_EXT) ? "extended" : "standard");
    }
    break;
    case 'i': // id selection
    m_usedId++;
    if (m_Verbose)
    printf("Id set to 0x%08x\n", m_usedId);
    break;
    //==================================================
    case 'I':
    if (m_usedId > 0) m_usedId--;
    if (m_Verbose)
    printf("Id set to 0x%08x\n", m_usedId);
    break;
    //==================================================
    case 'S':
    if ((stat = canRequestChipStatus(m_DriverConfig->channel[m_usedChannel].hnd)) != canOK) {
    PRINTF_ERR(("ERROR canRequestChipStatus() FAILED. Err= %d <line: %d>\n", stat, __LINE__));
    }
    break;
    //==================================================
    case 's':
    // print chip status here
    if (m_Verbose) {
    printf("Channel %d is ", m_usedChannel);
    if (m_DriverConfig->channel[m_usedChannel].isOnBus)
    printf("ON bus. \n");
    else printf("OFF bus. \n");
    }
    if (m_Verbose) {
    DWORD flags;
    if ((stat = canReadStatus(m_DriverConfig->channel[m_usedChannel].hnd, &flags)) != canOK) {
    PRINTF_ERR(("ERROR canReadStatus() FAILED. Err= %d <line: %d>\n", stat, __LINE__));
    }
    else {
    printf("Bus status : ");
    if (flags & canSTAT_ERROR_PASSIVE)
    printf("canSTAT_ERROR_PASSIVE ");
    if (flags & canSTAT_BUS_OFF)
    printf("canSTAT_BUS_OFF ");
    if (flags & canSTAT_ERROR_WARNING)
    printf("canSTAT_ERROR_WARNING ");
    if (flags & canSTAT_ERROR_ACTIVE)
    printf("canSTAT_ERROR_ACTIVE ");
    if (flags & canSTAT_TX_PENDING)
    printf("canSTAT_TX_PENDING ");
    if (flags & canSTAT_RX_PENDING)
    printf("canSTAT_RX_PENDING ");
    if (flags & canSTAT_TXERR)
    printf("canSTAT_TXERR ");
    if (flags & canSTAT_RXERR)
    printf("canSTAT_RXERR ");
    if (flags & canSTAT_HW_OVERRUN)
    printf("canSTAT_HW_OVERRUN ");
    if (flags & canSTAT_SW_OVERRUN)
    printf("canSTAT_SW_OVERRUN ");
    printf("\n");
    }
    }
    break;
    //==================================================
    case 'M':
    case 'm':
    // change output mode normal / silent
    {
    canStatus stat;
    if (m_DriverConfig->channel[m_usedChannel].driverMode == canDRIVER_NORMAL) {
    stat = canSetBusOutputControl(m_DriverConfig->channel[m_usedChannel].hnd, canDRIVER_SILENT);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canSetBusOutputControl(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    if (m_Verbose) printf("Channel %d Drivermode set to canDRIVER_SILENT. \n", m_usedChannel);
    m_DriverConfig->channel[m_usedChannel].driverMode = canDRIVER_SILENT;
    }
    }
    else {
    stat = canSetBusOutputControl(m_DriverConfig->channel[m_usedChannel].hnd, canDRIVER_NORMAL);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    if (m_Verbose) printf("Channel %d Drivermode set to canDRIVER_NORMAL. \n", m_usedChannel);
    m_DriverConfig->channel[m_usedChannel].driverMode = canDRIVER_NORMAL;
    }
    }
    }
    break;
    //==================================================
    case 'O':
    case 'o':
    {
    canStatus stat;
    // Go on bus/off bus here for currentChannel
    if (m_DriverConfig->channel[m_usedChannel].isOnBus) {
    stat = canBusOff(m_DriverConfig->channel[m_usedChannel].hnd);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canBusOff(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    if (m_Verbose) printf("Channel %d Off bus. \n", m_usedChannel);
    m_DriverConfig->channel[m_usedChannel].isOnBus = 0;
    }
    }
    else {
    stat = canBusOn(m_DriverConfig->channel[m_usedChannel].hnd);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    if (m_Verbose) printf("Channel %d On bus. \n", m_usedChannel);
    m_DriverConfig->channel[m_usedChannel].isOnBus = 1;
    }
    }
    }
    break;
    //==================================================
    case 27: // Esccape
    case 'q':
    case 'Q':
    running = FALSE;
    break;
    //==================================================
    case 'H':
    case 'h':
    help();
    break;
    //==================================================
    case 'E':
    case 'e':
    system("cls");
    break;
    //==================================================
    case 'D':
    case 'd':
    printDriverConfig();
    break;
    //==================================================
    case 'y':
    case 'Y':
    {
    canStatus stat;
    stat = canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
    NULL,
    NULL);
    if (stat < 0) {
    PRINTF_ERR(("ERROR canIoCtl(). Err = %d <line: %d>\n", stat, __LINE__));
    }
    else {
    printf("Error counters cleared successfully.\n");
    }
    }
    break;
    //==================================================
    default:
    break;
    } //switch
    }
    }
    } //event type
    } // while
    // Go off bus & close channels.
    Cleanup();
    return NULL;
    }
    【网站地图】【sitemap】