سؤال

* تحديث *

هذا ما وجدته. كلما كان لديّ هذه الوظيفة هناك ، لن يجعل الرمز في الواقع قفلًا. من شأنه أن يجعل وظيفة RTC I²C بطيئة للغاية ، لكن الكود سيظل يعمل بشكل صحيح ، لكن كان علي الانتظار وقتًا طويلاً لتجاوز كل مرة أقرأ فيها RTC.

لذلك ، هناك مقاطعة إنذار لـ RTC ، وكان هذا يؤدي إلى تفاعلات أخرى I²C داخل ISR ، لذلك يبدو أنه كان يحاول القيام باتصالتين I²C في نفس الوقت ، وبالتالي إبطاء العملية. لقد أزلت الوظائف في ISR وهي تعمل الآن. سأستمر في التحقيق.


أواجه هذه المشكلة عند برمجة Microcontroller STM32F103 باستخدام IAR 5.40. لديّ هذه الوظيفة أنه إذا حاولت طباعة متغير محلي ، فإنه يتسبب في تجميد الكود في طريق آخر قبل أن يصل إلى هذه الوظيفة المعنية.

ماذا يمكن أن يسبب هذا؟

هذه هي الوظيفة:

u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
  char bTmpSms[3] = {0};

  itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string

  printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!

  GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
  return 1;
}

لقد جربت هذا أيضًا وهذا لا يتسبب في القفل الذي مررت به:

u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
  char bTmpSms[3] = {0};

  itoa(bSmsIndex, bTmpSms, 10);
  printf("index = 2\n");


  GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
  return 1;
}

لا يوجد أي تحسين على الإطلاق ويتعثر الرمز عند محاولة قراءة بايت من I²C RTC ، ولكن بمجرد إزالة هذا printf("index = %s\n", bTmpSms); أو استخدم هذا بدلاً من ذلك printf("index = 2\n"); ثم كل شيء سعيد. أيه أفكار؟

لن يكون BSMSINDEX أكثر من 30 عامًا في الواقع ، وحتى مع ذلك يحدث القفل Wayyyy قبل استدعاء هذه الوظيفة.

هل كانت مفيدة؟

المحلول 4

يبدو أنه إذا لم أهيئة BTMPSMS المتغير إلى شيء ما تحدث المشكلة.

أدركت أيضًا أن هذه هي المشكلة. إنها وظيفة ITOA. لقد جعلني أتحقق من أنه على الرغم من أنني لم أكن أعتقد أن هذه هي المشكلة ، عندما علقت وظيفة ITOA ، فقد عملت الرمز بأكمله.

لذلك انتهى بي الأمر:

u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
  char bTmpSms[4] = "aaa";    // I still need to find out why this is !!!

  itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string

  printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!

  GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
  return 1;
}

هذه هي وظيفة ITOA التي حصلت عليها:

char itoa(int value, char* result, int base)
{
  // Check that the base if valid
  if (base < 2 || base > 36) {
      *result = '\0';
      return 0;
  }

  char* ptr = result, *ptr1 = result, tmp_char;
  int tmp_value;

  do
  {
    tmp_value = value;
    value /= base;
    *ptr++ = "zyxwvutsr

qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz [35 + (tmp_value - value * base)] ؛} بينما (القيمة) ؛

  // Apply negative sign
  if (tmp_value < 0)
      *ptr++ = '-';
  *ptr-- = '\0';
  while(ptr1 < ptr)
  {
    tmp_char = *ptr;
    *ptr--= *ptr1;
    *ptr1++ = tmp_char;
  }
  return 1;
}

نصائح أخرى

char bTmpSms[3] فقط مساحة لـ "99". إذا كان BSMSIndex الخاص بك 100 أو أكثر ، فستحاول الكتابة إلى الذاكرة التي لا تنتمي إليك.


تحرير بعد التحديث

ليس لدي إشارة إلى itoa على الجهاز المحلي ، لكنني وجدت هذا ( http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ ). وفقا لهذه المرجع ، صفيف الوجهة يجب أن تكون طويلة بما يكفي لأي قيمة محتملة. تحقق من الوثائق الخاصة بك: الخاص بك itoa قد يكون مختلفا.

او استعمل sprintf, snprintf, ، أو بعض الوظائف الموصوفة بواسطة المعيار.

بعض الافكار:

إذا itoa() ليس بشكل صحيح-إنهاء السلسلة ، ثم قد تؤدي المكالمة إلى printf إلى الجهاز الذي يبحث عن NUL إلى الأبد.

PMG لديه نقطة جيدة جدا.

أيضا ، فكر في نوع الحجة الأولى ل itoa() هو. إذا تم توقيعه وكنت تمر في عدد صحيح غير موقّع ، فقد تحصل على علامة ناقص غير متوقعة في BTMPSMS. جرب استخدام sprintf() في حين أن.

التغيير في الكود يحرك بقية الكود الخاص بك في الذاكرة. أظن أن جزءًا آخر من الكود ، غير المدرج هنا ، هو ضرب بعض المواقع العشوائية ؛ في الحالة الأولى ، يحتوي هذا الموقع على شيء حرج ، في الحالة الثانية لا.

هذه هي أسوأ أنواع المشاكل لتعقب*. حظا طيبا وفقك الله.

*ربما ليس الأسوأ - قد يكون الأمر أسوأ لو كانت حالة سباق بين خيوط متعددة لم تتجلى إلا مرة واحدة في الأسبوع. ما زلت ليس نوعا المفضل من الأخطاء.

ما هي قيمة bSmsIndex هل تحاول الطباعة؟

إذا كان أكبر من 99 ، فأنت تتغلب على bTmpSms مجموعة مصفوفة.

إذا لم يساعد ذلك ، فاستخدم مصحح الأخطاء الجيدة لـ IAR - سأسقط في نافذة التجميع عند النقطة التي printf() يتم استدعاؤه وخطوة واحدة حتى ذهبت الأمور إلى الأعشاب الضارة. من المحتمل أن يوضح هذا المشكلة.

أو كإصلاح مستكشف سريع n-n-dirty ، حاول تحجيم الصفيف إلى شيء كبير (ربما 8) وشاهد ما يحدث.

ما هي قيمة BSMSINDEX؟

إذا كان أكثر من 99 سيكون ثلاثة أرقام عند تحويله إلى سلسلة. عند إنهاء الصفر ، سيكون أربعة أحرف ، لكنك خصصت ثلاثة فقط إلى BTMPSMS حتى يتم الكتابة الفارغة وسيحاول printf طباعة كل ما هو بعد BTMPSMS حتى الفارغ التالي. يمكن أن يصل إلى أي شيء ، حقا.

حاول تفكيك هذه المنطقة مع الفهرس = 2 مقابل الفهرس = %s.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top