Ai-Thinker-Open / GPRS_C_SDK

Ai-Thinker A9/A9G GPRS (with GPS(A9G)) module C development SDK
https://ai-thinker-open.github.io/GPRS_C_SDK_DOC
MIT License
448 stars 234 forks source link

Crash when using CriticalSection #261

Open mkeevy opened 5 years ago

mkeevy commented 5 years ago

1. SDK version(SDK 版本)

{ SW_V2125_csdk }


2. In what kind of operation problems appear, and how to reproduce the problem ?(什么样的操作步骤问题会出现,是否是稳定复现,如何复现问题?)

{ I am trying to read data from a DHT22 with code taken from the adafruit Arduino library. The code tries to time the pulse lengths coming from the DHT. When I don't using CriticalSections the timing occasionally fails. The Arduino library disables interrupts to enhance timing, but I could not find an interrupt disable call for the A9G, and presumed that CriticalSections would work similarly.

Here is the code I am trying.

define MAX_CYCLES 3373

define DHT_PIN GPIO_PIN25

static uint8_t data[5];

uint32_t expectPulse(GPIO_LEVEL level){ volatile uint32_t count = 0; GPIO_LEVEL pinState;

GPIO_Get(DHT_PIN, &pinState);
while (pinState == level){
    if (count++ > MAX_CYCLES){
        return 0;
    }
    GPIO_Get(DHT_PIN, &pinState);
}

return count;

}

bool readDht(){ uint32_t cycles[80]; GPIO_config_t ioPin = { .mode = GPIO_MODE_OUTPUT, .pin = DHT_PIN, .defaultLevel = GPIO_LEVEL_HIGH }; uint32_t status;

// Start reading process
GPIO_Init(ioPin);
GPIO_Set(DHT_PIN, GPIO_LEVEL_HIGH);
OS_Sleep(250);

// Set data line low and wait for 20 msec
GPIO_Set(DHT_PIN, GPIO_LEVEL_LOW);
OS_Sleep(20);

// End start signal GPIO_Set(DHT_PIN, GPIO_LEVEL_HIGH); OS_SleepUs(40);

// Change pin
ioPin.mode = GPIO_MODE_INPUT;
GPIO_Init(ioPin);

// Start timing critical section
status = SYS_EnterCriticalSection();

// First expect a low signal f0r 80 us
if (expectPulse(GPIO_LEVEL_LOW) == 0){
    SYS_ExitCriticalSection(status);    
    Trace(2, "Timeout waiting for start signal low pulse");
    return false;
}
if (expectPulse(GPIO_LEVEL_HIGH) == 0){
    SYS_ExitCriticalSection(status);    
    Trace(2, "Timeout waiting for start signal high pulse");
    return false;
}

// Now read the 40 bits sent by the sensor. Each bit is sent as a 50 // microsecond low pulse followed by a variable length high pulse. If the // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds // then it's a 1. We measure the cycle count of the initial 50us low pulse // and use that to compare to the cycle count of the high pulse to determine // if the bit is a 0 (high state cycle count < low state cycle count), or a // 1 (high state cycle count > low state cycle count). Note that for speed all // the pulses are read into a array and then examined in a later step. for (int i = 0; i < 80; i += 2) { cycles[i] = expectPulse(GPIO_LEVEL_LOW); cycles[i + 1] = expectPulse(GPIO_LEVEL_HIGH); }

// End time critical
SYS_ExitCriticalSection(status);    

// Inspect pulses and determine which ones are 0 (high state cycle count < low
// state cycle count), or 1 (high state cycle count > low state cycle count).
for (int i = 0; i < 40; ++i) {
    uint32_t lowCycles = cycles[2 * i];
    uint32_t highCycles = cycles[2 * i + 1];
    if ((lowCycles == 0) || (highCycles == 0)) {
        Trace(2, "Timeout waiting for pulse (%d).", i);
        return false;
    }
    data[i/8] <<= 1;
    // Now compare the low and high cycle times to see if the bit is a 0 or 1.
    if (highCycles > lowCycles) {
        // High cycles are greater than 50us low cycle count, must be a 1.
        data[i/8] |= 1;
    }
    // Else high cycles are less than (or equal to, a weird case) the 50us low
    // cycle count so this must be a zero.  Nothing needs to be changed in the
    // stored data.
}

return true; }

Here is the coolwatcher output. Assert received!! Reading detail... ASSERT DETAIL : FrameStart: got 2nd FrameStart without FrameEnd Detected BCPU in the GDB loop (0x9db10000), connect GDB debugger for more info. Detected XCPU in the GDB loop (0x9db00000), connect GDB debugger for more info.

Here is the Tracer output snippet. ##############################################

FATAL assert

--> FrameStart: got 2nd FrameStart without FrameEnd

############################################## [08:27:25.190] SXR 01 : Stack owner not found 0x81c0fdac\n [08:27:25.190] SXR 01 : BitMapReady 0x0 [08:27:25.190] SXR 01 : Job Monitoring A job (0, 0x15) [08:27:25.190] SXR 01 : wait event 14.\n [08:27:25.190] SXR 01 : Stack: 672/1000 Top 0x82273640 <- 0x82273a28 Data 0x0\n [08:27:25.190] SXR 01 : Job Monitoring B job (1, 0x16) [08:27:25.190] SXR 01 : is stopped.\n [08:27:25.190] SXR 01 : Stack: 996/1000 Top 0x82272e40 <- 0x82273228 Data 0x0\n [08:27:25.190] SXR 01 : Job Near job (2, 0x3) [08:27:25.190] SXR 01 : wait event 15.\n [08:27:25.190] SXR 01 : Stack: 408/1000 Top 0x82273240 <- 0x82273628 Data 0x0\n [08:27:25.190] SXR 01 : Job Cch control job (3, 0x12) [08:27:25.190] SXR 01 : is stopped.\n [08:27:25.190] SXR 01 : Stack: 460/1000 Top 0x82273a40 <- 0x82273e28 Data 0x0\n [08:27:25.190] SXR 01 : Job CchA job (6, 0x13) [08:27:25.190] SXR 01 : wait event 0.\n [08:27:25.190] SXR 01 : Stack: 616/1000 Top 0x822771f4 <- 0x822775dc Data 0x0\n [08:27:25.190] SXR 01 : Back trace\n [08:27:25.190] SXR 01 : 82005a25y\n [08:27:25.190] SXR 01 : 8200594cy\n [08:27:25.190] SXR 01 : 81c04e75y\n [08:27:25.190] SXR 01 : 82009180y\n [08:27:25.190] SXR 01 : 82005a25y\n [08:27:25.190] SXR 01 : 82005a05y\n [08:27:25.190] SXR 01 : 81c07cbdy\n [08:27:25.190] SXR 01 : 880aa9cby\n [08:27:25.190] SXR 01 : 88071aedy\n [08:27:25.190] SXR 01 : 81c053ddy\n [08:27:25.190] SXR 01 : 82005da8y\n [08:27:25.190] SXR 01 : 88071aedy\n [08:27:25.190] SXR 01 : 81c04e75y\n [08:27:25.190] SXR 01 : 81c02657y\n [08:27:25.190] SXR 01 : 88071ab5y\n [08:27:25.190] SXR 01 : 81c07c57y\n [08:27:25.190] SXR 01 : 88071acby\n [08:27:25.190] SXR 01 : 81c0648fy\n [08:27:25.190] SXR 01 : 81c061e9y\n [08:27:25.190] SXR 01 : 88071aedy\n [08:27:25.359] SXR 01 : 81c07f61y\n

Sorry for posting so much detail, but I wanted it to be clear so that someone could help me, or suggest a better route. If anymore information is needs please don't hesitate to comment.

Many thanks, Matthew. }


vbtaneja commented 5 years ago

I am also trying to connect a DHT22 but I am still struggling with Hardware connections. I have some questions. At what voltage are you running the DHT22? Which IO Pin are you using? [2.8V Or Lower] Are you using VIO? Are the A9G IO Pins 5V Tolerant? Is a Pull up Resistance required on the Data Line? Can we connect the Pull up to 2.8V and use it with DHT Running on 5V?

win32cpp commented 5 years ago

Hi No solution has been found yet to solve this problem?

mkeevy commented 5 years ago

@vbtaneja yes I used VIO which seems to work fine with the DHT22. I did use a pull-up resistor between the data line and VIO. I used IO25 for data. I used a calibrated delay loop to time the returned pulse. It works well enough, but you do miss data at which point you just try again.

vbtaneja commented 5 years ago

Thanks for reply.I have powered DHT using 5V Supply. I have added extra circuit to ensure Drive Out voltage of 5v and input voltage of 3v. I have used 2 GPIO pins. Since I have not used critical sections, I get a data error about 10% of the time.VinayTaneja 

Sent from my Samsung Galaxy smartphone. -------- Original message --------From: mkeevy notifications@github.com Date: 23/02/2019 2:15 p.m. (GMT+05:30) To: Ai-Thinker-Open/GPRS_C_SDK GPRS_C_SDK@noreply.github.com Cc: vbtaneja vbtaneja@gmail.com, Mention mention@noreply.github.com Subject: Re: [Ai-Thinker-Open/GPRS_C_SDK] Crash when using CriticalSection (#261) @vbtaneja yes I used VIO which seems to work fine with the DHT22. I did use a pull-up resistor between the data line and VIO. I used IO25 for data.

I used a calibrated delay loop to time the returned pulse. It works well enough, but you do miss data at which point you just try again.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread. {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/Ai-Thinker-Open/GPRS_C_SDK","title":"Ai-Thinker-Open/GPRS_C_SDK","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/Ai-Thinker-Open/GPRS_C_SDK"}},"updates":{"snippets":[{"icon":"PERSON","message":"@mkeevy in #261: @vbtaneja yes I used VIO which seems to work fine with the DHT22. I did use a pull-up resistor between the data line and VIO. I used IO25 for data.\r\nI used a calibrated delay loop to time the returned pulse. It works well enough, but you do miss data at which point you just try again."}],"action":{"name":"View Issue","url":"https://github.com/Ai-Thinker-Open/GPRS_C_SDK/issues/261#issuecomment-466630194"}}} [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/Ai-Thinker-Open/GPRS_C_SDK/issues/261#issuecomment-466630194", "url": "https://github.com/Ai-Thinker-Open/GPRS_C_SDK/issues/261#issuecomment-466630194", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]