en
Feedback
Amin'sTechLab

Amin'sTechLab

Open in Telegram

🔬 Embedded Systems | AI | FPGA | PCB Design 🚀 Exploring tech at the edge of innovation 🧠 Founder of AminTechLab 📍Engineering the future – one bit at a time

Show more
2 030
Subscribers
+124 hours
+27 days
+4830 days
Attracting Subscribers
September '26
September '26
+3
in 0 channels
August '26
+68
in 0 channels
Get PRO
July '26
+49
in 0 channels
Get PRO
June '26
+27
in 0 channels
Get PRO
May '26
+10
in 0 channels
Get PRO
April '26
+7
in 0 channels
Get PRO
March '26
+1
in 0 channels
Get PRO
February '26
+12
in 0 channels
Get PRO
January '26
+4
in 0 channels
Get PRO
December '25
+28
in 1 channels
Get PRO
November '25
+36
in 1 channels
Get PRO
October '25
+41
in 2 channels
Get PRO
September '25
+56
in 1 channels
Get PRO
August '25
+44
in 0 channels
Get PRO
July '25
+20
in 0 channels
Get PRO
June '25
+15
in 0 channels
Get PRO
May '25
+25
in 1 channels
Get PRO
April '25
+18
in 0 channels
Get PRO
March '25
+30
in 0 channels
Get PRO
February '25
+19
in 0 channels
Get PRO
January '25
+42
in 0 channels
Get PRO
December '24
+34
in 0 channels
Get PRO
November '24
+36
in 0 channels
Get PRO
October '24
+27
in 0 channels
Get PRO
September '24
+17
in 0 channels
Get PRO
August '24
+23
in 0 channels
Get PRO
July '24
+48
in 0 channels
Get PRO
June '24
+39
in 0 channels
Get PRO
May '24
+44
in 0 channels
Get PRO
April '24
+32
in 0 channels
Get PRO
March '24
+60
in 0 channels
Get PRO
February '24
+82
in 1 channels
Get PRO
January '24
+48
in 2 channels
Get PRO
December '23
+30
in 0 channels
Get PRO
November '23
+7
in 0 channels
Get PRO
October '23
+10
in 0 channels
Get PRO
September '23
+7
in 0 channels
Get PRO
August '23
+5
in 0 channels
Get PRO
July '23
+10
in 0 channels
Get PRO
June '23
+7
in 0 channels
Get PRO
May '23
+1 042
in 0 channels
Get PRO
April '23
+5
in 0 channels
Get PRO
March '23
+9
in 0 channels
Get PRO
February '23
+15
in 0 channels
Get PRO
January '23
+14
in 0 channels
Get PRO
December '22
+1
in 0 channels
Get PRO
November '22
+8
in 0 channels
Get PRO
October '22
+11
in 0 channels
Get PRO
September '22
+7
in 0 channels
Get PRO
August '22
+13
in 0 channels
Get PRO
July '22
+14
in 0 channels
Get PRO
June '22
+11
in 0 channels
Get PRO
May '22
+18
in 0 channels
Get PRO
April '22
+14
in 0 channels
Get PRO
March '22
+8
in 0 channels
Get PRO
February '22
+12
in 0 channels
Get PRO
January '22
+12
in 0 channels
Get PRO
December '21
+12
in 0 channels
Get PRO
November '21
+38
in 0 channels
Get PRO
October '21
+5
in 0 channels
Get PRO
September '21
+25
in 0 channels
Get PRO
August '21
+27
in 0 channels
Get PRO
July '21
+554
in 0 channels
Get PRO
June '21
+14
in 0 channels
Get PRO
May '21
+39
in 0 channels
Get PRO
April '21
+58
in 0 channels
Get PRO
March '21
+88
in 0 channels
Get PRO
February '21
+112
in 0 channels
Get PRO
January '21
+692
in 0 channels
Get PRO
December '20
+2 352
in 0 channels
Date
Subscriber Growth
Mentions
Channels
03 September+1
02 September+2
01 September0
Channel Posts
⚙️ Stack Overflow در STM32 و RTOS — بخش دوم در بخش اول دیدیم که Stack Overflow زمانی اتفاق می‌افتد که مصرف Stack از ظرفیت اختصاص‌یافته بیشتر شود. اما در سیستم‌های Embedded مثل STM32، این موضوع اهمیت بسیار بیشتری دارد. چرا؟ چون منابعی مثل RAM بسیار محدود هستند. 🔹 Stack در STM32 فرض کنید برای یک Task در RTOS فقط:
Stack Size = 2 KB
در نظر گرفته‌ایم. حالا داخل Task یک آرایه بزرگ تعریف کنیم:
void task(void)
{
    uint8_t data[1500];

    process_data(data);
}
همین یک آرایه بخش قابل توجهی از Stack را مصرف می‌کند. اگر توابع دیگری هم فراخوانی شوند و آنها نیز Stack مصرف کنند، احتمال Overflow افزایش پیدا می‌کند. 🔥 مشکل فقط اندازه متغیرها نیست این ساختار را در نظر بگیرید:
Task
 ↓
function_A()
 ↓
function_B()
 ↓
function_C()
 ↓
function_D()
هر تابع می‌تواند Stack Frame خودش را ایجاد کند. بنابراین حتی اگر هیچ آرایه بزرگی هم نداشته باشیم، عمق زیاد Call Stack می‌تواند باعث مصرف قابل توجه Stack شود. ⚠️ Recursion در Embedded استفاده از Recursive Function در سیستم‌های Embedded باید با احتیاط انجام شود:
void task(void)
{
    task();
}
این کد در نهایت Stack را مصرف کرده و باعث Crash می‌شود. به همین دلیل در بسیاری از سیستم‌های Embedded، استفاده از Recursion بدون تحلیل دقیق Stack Depth انتخاب مناسبی نیست. 🔬 Stack و RTOS در RTOS معمولاً هر Task Stack مخصوص خودش را دارد:
RAM
│
├── Task A Stack
│
├── Task B Stack
│
├── Task C Stack
│
├── Kernel
│
└── Heap / Global Data
بنابراین اگر فقط Stack یک Task تمام شود، ممکن است همان Task دچار مشکل شود. این موضوع Debug کردن خطا را هم دشوار می‌کند؛ چون ممکن است برنامه در یک بخش کاملاً متفاوت Crash کند. 🛠 چگونه از Stack Overflow جلوگیری کنیم؟ ✅ اندازه Stack هر Task را متناسب با نیاز تعیین کنید. ✅ آرایه‌های بزرگ را بی‌دلیل Local تعریف نکنید. ✅ از Recursive Function بدون Base Case استفاده نکنید. ✅ عمق Call Stack را در توابع پیچیده بررسی کنید. ✅ در RTOS میزان Stack مصرف‌شده هر Task را Monitor کنید. ✅ در زمان Debug، Stack Pointer و Call Stack را بررسی کنید. 🧠 یک نکته مهم Stack Overflow و Stack Corruption را با هم اشتباه نگیریم. گاهی یک Buffer کوچک به دلیل دسترسی خارج از محدوده می‌تواند حافظه اطراف خود را خراب کند:
uint8_t buffer[10];

buffer[20] = 0xFF;
این کد یک Out-of-Bounds Write است و می‌تواند باعث Stack Corruption شود. یعنی همیشه Crash شدن برنامه به معنی Stack Overflow نیست. 🎯 جمع‌بندی در سیستم‌های Embedded، مدیریت Stack بخش مهمی از طراحی نرم‌افزار است. خصوصاً وقتی با: 🔹 STM32 🔹 RTOS 🔹 Interrupt 🔹 Recursive Function 🔹 Bufferهای بزرگ 🔹 Call Stackهای عمیق کار می‌کنیم. یک Stack کوچک می‌تواند باعث Crash شود و یک Buffer کوچک با دسترسی اشتباه می‌تواند کل Stack را خراب کند. پس در برنامه‌نویسی C فقط این مهم نیست که برنامه کار کند؛ باید بدانیم در سطح حافظه دقیقاً چه اتفاقی در حال رخ دادن است. @Amin_Techlab

2
🧠 مفهوم Stack Overflow در زبان C — بخش اول وقتی در زبان C یک تابع را فراخوانی می‌کنیم، برنامه برای مدیریت اجرای آن تابع به فضایی از حافظه به نام Stack نیاز دارد. اما اگر این فضا بیش از ظرفیت خود مصرف شود، چه اتفاقی می‌افتد؟ 💥 Stack Overflow 🔹 Stack چیست؟ Stack بخشی از حافظه RAM است که برای مدیریت اجرای توابع استفاده می‌شود. در زمان اجرای یک تابع، اطلاعاتی مانند: • متغیرهای Local • پارامترهای تابع • آدرس بازگشت • برخی Registerها و اطلاعات موقتی در Stack Frame مربوط به آن تابع قرار می‌گیرند. مثلاً: void test(void) { int x = 10; } متغیر x یک Local Variable است و در بسیاری از پیاده‌سازی‌ها فضای آن از Stack تأمین می‌شود. 🔥 Stack Overflow چگونه ایجاد می‌شود؟ یکی از رایج‌ترین دلایل، Recursive Function بدون شرط توقف است: void crash(void) { int buffer[1000]; crash(); } تابع crash() خودش را دوباره فراخوانی می‌کند. در نتیجه: crash() ↓ crash() ↓ crash() ↓ crash() ↓ ... هر فراخوانی جدید، یک Stack Frame جدید ایجاد می‌کند. بنابراین Stack دائماً رشد می‌کند: ┌──────────────┐ │ Frame #4 │ ├──────────────┤ │ Frame #3 │ ├──────────────┤ │ Frame #2 │ ├──────────────┤ │ Frame #1 │ ├──────────────┤ │ │ │ Free RAM │ └──────────────┘ تا جایی که دیگر فضای کافی برای ایجاد Stack Frame جدید وجود نداشته باشد. 💥 نتیجه معمولاً Crash شدن برنامه است. 🔹 فقط Recursion مشکل‌ساز نیست! تعریف متغیرهای Local بسیار بزرگ نیز می‌تواند Stack را پر کند: void process(void) { char buffer[1024 * 1024]; } اینجا برنامه تقریباً 1MB فضای Stack درخواست می‌کند. اگر Stack برنامه ظرفیت کافی نداشته باشد، احتمال بروز مشکل بسیار زیاد است. ⚠️ نکته مهم Stack Overflow با Heap Overflow متفاوت است. Stack بیشتر با اجرای توابع و متغیرهای Local سروکار دارد، در حالی که Heap برای حافظه Dynamic مانند: malloc() calloc() realloc() free() است. در بخش دوم می‌بینیم چرا این موضوع در STM32 و RTOS اهمیت بسیار بیشتری پیدا می‌کند و چطور می‌توان مصرف Stack را بررسی کرد. ادامه دارد... @Amin_Techlab
90
3
🧠 Lifetime و Storage Duration در زبان C — بخش دوم در بخش اول با Automatic و Static Storage Duration و همچنین تفاوت Scope و Lifetime آشنا شدیم. حالا برویم سراغ دو مفهوم دیگر: Allocated Thread و ببینیم این موضوع چگونه می‌تواند باعث Bugهای خطرناک در C شود. 🔹 3. Allocated Storage Duration وقتی با malloc() حافظه‌ای را تخصیص می‌دهیم، Storage مربوط به Object تا زمانی که آزاد شود باقی می‌ماند. مثلاً: int *p = malloc(sizeof(int)); *p = 100; free(p); به‌صورت مفهومی: malloc() ↓ Storage Allocated ↓ Object exists ↓ Use Object ↓ free() ↓ Lifetime Ends مشکل زمانی ایجاد می‌شود که free() را فراموش کنیم. مثلاً: int *p = malloc(sizeof(int)); *p = 100; /* free(p) فراموش شده */ اینجا با یک Memory Leak مواجه می‌شویم. ⚠️ چرا Dynamic Memory در Embedded مهم است؟ در سیستم‌های Embedded و مخصوصاً RTOS، استفاده نادرست از malloc() و free() می‌تواند مشکلاتی مثل: Memory Leak Memory Fragmentation Allocation Failure Unpredictable Timing ایجاد کند. به همین دلیل در بسیاری از سیستم‌های Real-Time، Dynamic Memory Allocation یا محدود می‌شود یا با طراحی بسیار کنترل‌شده استفاده می‌شود. 🔹 4. Thread Storage Duration در C11 نوع دیگری از Storage Duration وجود دارد: _Thread_local مثلاً: _Thread_local int counter; در این حالت هر Thread نسخه مخصوص خودش از Object را دارد. یعنی: Thread 1 → counter #1 Thread 2 → counter #2 Thread 3 → counter #3 این مفهوم در برنامه‌های Multithreaded و RTOS اهمیت پیدا می‌کند. 🔥 حالا یک Bug بسیار مهم به این کد نگاه کنید: int *get_value(void) { int value = 100; return &value; } این کد مشکل دارد. چرا؟ چون value یک Local Variable با Automatic Storage Duration است. وقتی تابع تمام شود: get_value() ↓ value created ↓ return ↓ function ends ↓ value lifetime ends بنابراین Pointer برگشتی دیگر به یک Object معتبر اشاره نمی‌کند. این وضعیت را Dangling Pointer می‌نامیم. ❌ کد خطرناک int *get_value(void) { int value = 100; return &value; } نباید به Objectی که Lifetime آن تمام شده، دسترسی داشته باشیم. ✅ یک روش متفاوت می‌توان از یک Static Object استفاده کرد: int *get_value(void) { static int value = 100; return &value; } در این حالت value دارای Static Storage Duration است و بعد از خروج از تابع همچنان وجود دارد. اما این روش هم باید با توجه به شرایط استفاده شود؛ مخصوصاً در برنامه‌های چندنخی، چون چند Thread می‌توانند به یک Object مشترک دسترسی داشته باشند. 🧠 Stack vs Heap یک نکته مهم: این عبارت‌ها را نباید با Storage Duration یکی بدانیم: Stack Heap Static Memory Storage Duration یک مفهوم استاندارد در زبان C است. اما Stack و Heap بیشتر به نحوه پیاده‌سازی و مدیریت حافظه توسط سیستم/Compiler/Runtime مربوط هستند. به‌صورت معمول: Automatic Object ↓ غالباً Stack malloc() ↓ Heap / Allocator Static Object ↓ Static Storage Area اما این mapping یک الزام مستقیم استاندارد C نیست. 🎯 جمع‌بندی نهایی چهار Storage Duration اصلی در C: ┌─────────────────────────┐ │ Automatic │ │ طول عمر مرتبط با Block │ ├─────────────────────────┤ │ Static │ │ طول اجرای برنامه │ ├─────────────────────────┤ │ Allocated │ │ تا زمان deallocation │ ├─────────────────────────┤ │ Thread │ │ مرتبط با Thread │ └─────────────────────────┘ و همیشه این سه مفهوم را از هم جدا کنید: Scope → نام کجا قابل دسترسی است؟ Storage Duration → Storage چه مدت وجود دارد؟ Lifetime → Object چه مدت وجود دارد؟ 💡 اگر در C با Pointer، static، malloc()، free() یا متغیرهای Local کار می‌کنید، همیشه این سؤال را از خودتان بپرسید: «این Object چه زمانی ایجاد می‌شود و دقیقاً چه زمانی Lifetime آن تمام می‌شود؟» درک همین موضوع می‌تواند جلوی بسیاری از مشکلات جدی در C، Embedded Systems، STM32 و RTOS را بگیرد. @Amin_Techlab
140
4
🧠مفهوم Lifetime و Storage Duration در زبان C — بخش اول یکی از مفاهیم مهم در زبان C، مخصوصاً در Embedded Systems، درک نحوه ایجاد و از بین رفتن Objectها در حافظه است. سه مفهوم مهم در این زمینه داریم: Scope Lifetime Storage Duration این سه مفهوم به هم مرتبط هستند، اما یکسان نیستند. 🔹 Storage Duration چیست؟ Storage Duration مشخص می‌کند که فضای ذخیره‌سازی یک Object چه مدت وجود دارد. در استاندارد C چهار نوع Storage Duration داریم: 1. Automatic 2. Static 3. Allocated 4. Thread در این بخش دو مورد مهم‌تر را بررسی می‌کنیم. 🔹 1. Automatic Storage Duration یک متغیر Local معمولی معمولاً Storage Duration از نوع Automatic دارد. مثلاً: void test(void) { int value = 10; printf("%d\n", value); } Object مربوط به value هنگام ورود به Block ایجاد می‌شود و با خروج از Block، Lifetime آن پایان پیدا می‌کند. به‌صورت ساده: Enter Block ↓ Object Created ↓ Use Object ↓ Exit Block ↓ Lifetime Ends در بسیاری از سیستم‌ها، چنین متغیرهایی معمولاً روی Stack قرار می‌گیرند؛ البته استاندارد C محل فیزیکی ذخیره‌سازی را مشخص نمی‌کند. 🔹 2. Static Storage Duration حالا به این مثال توجه کنید: void counter(void) { static int count = 0; count++; printf("%d\n", count); } اگر تابع را سه بار اجرا کنیم: counter(); counter(); counter(); خروجی: 1 2 3 چرا count هر بار از صفر شروع نمی‌شود؟ چون count دارای Static Storage Duration است. یعنی Object مربوط به آن در طول اجرای برنامه وجود دارد و با خروج از تابع از بین نمی‌رود. Program Start ↓ count exists ↓ counter() → 1 ↓ counter() → 2 ↓ counter() → 3 ↓ Program End ↓ count lifetime ends ⚠️ یک نکته بسیار مهم static را نباید صرفاً به معنی «ذخیره شدن در یک قسمت خاص از RAM» در نظر گرفت. استاندارد C درباره Storage Duration صحبت می‌کند، نه الزاماً محل فیزیکی حافظه. در یک سیستم Embedded، محل نهایی Object می‌تواند توسط Compiler و Linker تعیین شود. 🔥 Scope ≠ Lifetime یکی از اشتباهات رایج این است که Scope و Lifetime را یکی بدانیم. مثلاً: void test(void) { static int counter = 0; counter++; } نام counter فقط داخل همین Block قابل دسترسی است: Scope → نام counter کجا قابل مشاهده است؟ اما Object مربوط به آن: Static Storage Duration → در طول اجرای برنامه باقی می‌ماند. بنابراین: Scope → محدوده قابل مشاهده بودن نام Storage Duration → مدت وجود Storage Lifetime → مدت وجود یک Object مشخص ادامه دارد .... @Amin_Techlab
145
5
🚀 آشنایی با AhuraRTOS؛ یک RTOS ایرانی برای سیستم‌های Embedded در این ویدیو با AhuraRTOS آشنا می‌شویم؛ یک سیستم‌عامل بلادرنگ
🚀 آشنایی با AhuraRTOS؛ یک RTOS ایرانی برای سیستم‌های Embedded در این ویدیو با AhuraRTOS آشنا می‌شویم؛ یک سیستم‌عامل بلادرنگ (RTOS) با تمرکز بر توسعه سیستم‌های نهفته و Embedded. اگر به حوزه‌های Embedded Systems، میکروکنترلرها، RTOS، طراحی Firmware و سیستم‌های بلادرنگ علاقه‌مند هستید، این ویدیو می‌تواند شروع خوبی برای آشنایی با این پروژه باشد. دیدن پروژه‌هایی از این جنس، علاوه بر جنبه فنی، می‌تواند قدمی برای شکل‌گیری و توسعه اکوسیستم نرم‌افزارهای Embedded در ایران باشد. 🎥 تماشای ویدیو: معرفی AhuraRTOS | اولین RTOS ایرانی برای سیستم‌های Embedded @Amin_Techlab
387
6
🚀 نکات کوتاه و کاربردی زبان C اگه با C، میکروکنترلرها و سیستم‌های Embedded کار می‌کنی، این پلی‌لیست رو از دست نده! 👨‍💻⚡️ ت
🚀 نکات کوتاه و کاربردی زبان C اگه با C، میکروکنترلرها و سیستم‌های Embedded کار می‌کنی، این پلی‌لیست رو از دست نده! 👨‍💻⚡️ توی این مجموعه از YouTube Shorts، نکات، ترفندها و مفاهیم کاربردی زبان C رو در ویدیوهای کوتاه و سریع بررسی می‌کنیم؛ مناسب برای یادگیری و مرور سریع. 🎯 📌 C Programming Tips | نکات و ترفندهای زبان C ▶️ مشاهده پلی‌لیست: https://www.youtube.com/playlist?list=PLf9OiDN9PuA4 @Amin_Techlab
553
7
+2
🎧 بررسی عمیق‌تر AhuraRTOS در راستای معرفی و بررسی پروژه AhuraRTOS که توسعه‌ی آن توسط مهندس عسکری انجام شده، مطالبی که در ۵ بخش درباره‌ی معماری، هسته، زمان‌بندی، مدیریت منابع و قابلیت‌های این RTOS بررسی و جمع‌آوری کردم و در روزهای قبل به اشتراک گذاشتم را ، به همراه مستندات اصلی پروژه در اختیار NotebookLM قرار گرفت. نتیجه، تولید ۳ فایل صوتی تحلیلی و توضیحی است که موضوعات مطرح‌شده را از زاویه‌ای متفاوت و عمیق‌تر بررسی می‌کنند. گوش دادن به این فایل‌های صوتی خالی از لطف نیست و می‌تواند درک کامل‌تر و عمیق‌تری از ساختار و نحوه‌ی عملکرد AhuraRTOS ایجاد کند. @Amin_Techlab
846
8
⚙️ کالبدشکافی فنی AhuraRTOS بخش ۵ | Integration و جمع‌بندی نهایی 🔧 ۹. راهنمای یکپارچه‌سازی با STM32CubeMX اگر قصد دارید AhuraRTOS را به پروژه‌ای مبتنی بر STM32CubeMX اضافه کنید، دو نکته مهم را باید در نظر بگیرید: 1️⃣ PendSV باید در اختیار RTOS باشد در تنظیمات NVIC، تولید Handler مربوط به PendSV را غیرفعال کنید. چرا؟ چون AhuraRTOS از PendSV برای Context Switching استفاده می‌کند و Kernel باید کنترل این Exception را در اختیار داشته باشد. به‌صورت ساده: PendSV → AhuraRTOS Kernel نه Application. 2️⃣ انتقال HAL Timebase AhuraRTOS از SysTick برای Tick سیستم استفاده می‌کند. بنابراین بهتر است Timebase مربوط به STM32 HAL روی یک Timer جداگانه، مانند: TIM6 قرار بگیرد. در غیر این صورت، دو مکانیزم مختلف ممکن است از یک Timebase استفاده کنند و مدیریت Tick و توابعی مانند: HAL_Delay() با RTOS تداخل پیدا کند. نتیجه احتمالی این تداخل می‌تواند Timing Drift، تأخیرهای نادرست و رفتار غیرقابل‌پیش‌بینی باشد. 🎯 ۱۰. جمع‌بندی AhuraRTOS تلاش می‌کند با یک معماری شفاف، وابستگی‌های پنهان و پیچیدگی غیرضروری Kernel را کاهش دهد. مهم‌ترین ویژگی‌هایی که در این بررسی دیدیم: 🔹 O(1) Scheduler مبتنی بر Bitmap ۳۲ بیتی 🔹 استفاده از PendSV برای Context Switching 🔹 آزاد ماندن SVC برای Application 🔹 تفکیک دقیق Scheduler Lock و Critical Section 🔹 استفاده از PSPLIM برای محافظت از Stack در ARMv8-M 🔹 طراحی Kernel مستقل از جزئیات معماری 🔹 تمرکز بر Portability، Performance و Predictability در نهایت، فلسفه AhuraRTOS را می‌توان در یک جمله خلاصه کرد: Kernel باید ساده، قابل‌پیش‌بینی و مستقل از Application باشد؛ در حالی که کنترل منابع همچنان در اختیار مهندس سیستم باقی بماند. اگر با ARM Cortex-M، Firmware و سیستم‌های Real-Time کار می‌کنید، AhuraRTOS می‌تواند پروژه جالبی برای بررسی یک رویکرد متفاوت در طراحی RTOS باشد. 🔗 پروژه AhuraRTOS: https://github.com/AhuraRTOS/AhuraRTOS 👤 توسعه‌دهنده: مهندس عسگری (nimaltd) @Amin_Techlab
941
9
⚙️ کالبدشکافی فنی AhuraRTOS بخش ۴ | Security، TrustZone و فلسفه Debugging 🛡 ۷. امنیت و قابلیت‌های پیشرفته در نسل‌های جدید ARM، امنیت فقط یک قابلیت نرم‌افزاری نیست و بخشی از آن مستقیماً در سخت‌افزار پردازنده پیاده‌سازی شده است. در ARMv8-M و پردازنده‌هایی مانند Cortex-M33، قابلیت‌هایی مثل TrustZone امکان جداسازی محیط Secure و Non-Secure را فراهم می‌کنند. AhuraRTOS برای این معماری از قابلیت‌هایی مانند PSPLIM (Process Stack Pointer Limit) نیز استفاده می‌کند. PSPLIM یک Limit سخت‌افزاری برای Stack Pointer ایجاد می‌کند و می‌تواند در تشخیص Stack Overflow نقش داشته باشد. 🔐 TrustZone و Context برای پشتیبانی از TrustZone، AhuraRTOS امکان استفاده از Callbackهای: context_save() و context_restore() را فراهم می‌کند تا وضعیت مربوط به Secure State در زمان Context Switching مدیریت شود. البته پشتیبانی از این بخش در برخی پلتفرم‌ها هنوز نیازمند بررسی و اعتبارسنجی سخت‌افزاری است. 🧩 Core Affinity در سیستم‌های چند‌هسته‌ای، فقط انتخاب Task کافی نیست؛ گاهی باید مشخص شود هر Task روی کدام CPU اجرا شود. قابلیت Core Affinity اجازه می‌دهد اجرای یک Task به هسته یا مجموعه‌ای از هسته‌های مشخص محدود شود. این قابلیت در سیستم‌های چند‌هسته‌ای می‌تواند برای: ⚡️ مدیریت بهتر Performance 🔋 بهینه‌سازی مصرف توان 🎯 کنترل دقیق‌تر اجرای Taskها مورد استفاده قرار گیرد. 🧪 ۸. فلسفه Debugging و Linker Error یکی از تصمیم‌های جالب AhuraRTOS این است که بعضی خطاها را به‌جای زمان اجرا، در Link Time آشکار می‌کند. برای مثال، اگر یک Callback حیاتی مانند: os_assert_failed_cb() در Application پیاده‌سازی نشده باشد، پروژه ممکن است در مرحله Link با خطا مواجه شود. این رویکرد یک مزیت مهم دارد: ❌ خطای پنهان در Runtime ✅ خطای مشخص در Build/Link یعنی مشکل قبل از اجرای Firmware مشخص می‌شود و احتمال رسیدن سیستم به یک Silent Halt کاهش پیدا می‌کند. 📊 Self-Test و اندازه‌گیری Cycle-Accurate AhuraRTOS همچنین یک ماژول Self-Test دارد که برای بررسی عملکرد Kernel و Port روی سخت‌افزار جدید کاربرد دارد. این تست‌ها می‌توانند Benchmarkهای Cycle-Accurate ارائه کنند و حتی سربار خودِ عملیات اندازه‌گیری را در نظر بگیرند. در نتیجه مهندس می‌تواند قبل از توسعه Application، مواردی مانند: 🔹 عملکرد Port 🔹 هزینه Context Switch 🔹 زمان اجرای توابع Kernel 🔹 و Worst-Case Execution Time یا WCET را روی سخت‌افزار واقعی بررسی کند. 🎯 فلسفه کلی این بخش را می‌توان این‌طور خلاصه کرد: خطا را زودتر پیدا کن، عملکرد را اندازه بگیر و وابستگی به رفتارهای غیرقابل‌پیش‌بینی Runtime را کاهش بده. 🔜 ادامه دارد... @Amin_Techlab
638
10
⚙️ کالبدشکافی فنی AhuraRTOS بخش ۳ | IPC، Preemption، Atomics و مدیریت حافظه 🔐 ۵. ارتباطات بین‌تسکی و کنترل Preemption در یک RTOS، فقط انتقال داده بین Taskها مهم نیست؛ نحوه محافظت از داده‌های مشترک هم اهمیت زیادی دارد. AhuraRTOS برای این کار دو مکانیزم متفاوت در اختیار برنامه‌نویس قرار می‌دهد: 🔹 Scheduler Lock با: os_kernel_lock() Scheduler متوقف می‌شود، اما Interruptها همچنان فعال هستند. یعنی Task دیگری نمی‌تواند جای Task فعلی را بگیرد، اما ISRها می‌توانند اجرا شوند. این روش برای محافظت از داده‌هایی که فقط بین چند Task مشترک هستند مناسب است، چون باعث افزایش غیرضروری Interrupt Latency نمی‌شود. 🔹 Critical Section با: os_critical_enter() Interruptها نیز Mask می‌شوند. بنابراین زمانی کاربرد دارد که داده‌ای بین یک Task و ISR به‌صورت مشترک استفاده می‌شود و باید از دسترسی هم‌زمان جلوگیری شود. تفاوت کلیدی: Scheduler Lock → جلوگیری از Context Switch Critical Section → جلوگیری از Interrupt + Context Switch 🔒 Mutex و Priority Inheritance یکی از مشکلات کلاسیک RTOSها، Priority Inversion است. فرض کنید: Low Priority Task → Mutex را در اختیار دارد و هم‌زمان: High Priority Task → منتظر همان Mutex است در این حالت یک Task با Priority متوسط می‌تواند باعث شود Task با Priority بالا برای مدت طولانی منتظر بماند. AhuraRTOS برای کاهش این مشکل از Single-level Priority Inheritance استفاده می‌کند. یعنی Priority مالک Mutex، به‌صورت موقت تا سطح Task منتظر افزایش پیدا می‌کند و پس از آزاد شدن Mutex، Priority به حالت قبلی برمی‌گردد. 📬 Task Notification برای ارتباطات ساده و سریع، AhuraRTOS از Task Notification استفاده می‌کند. Notification مستقیماً داخل TCB (Task Control Block) قرار دارد و می‌تواند مانند یک Mailbox بسیار کوچک عمل کند. مزیت اصلی: ⚡️ بدون نیاز به ساخت یک Object جداگانه IPC ⚡️ مصرف حافظه کمتر ⚡️ مسیر سریع برای بیدار کردن یک Task ⚛️ ۶. اما Atomics و مدیریت حافظه AhuraRTOS بین معماری‌های مختلف ARM در پیاده‌سازی عملیات Atomic تفاوت قائل می‌شود. 🔹 ARMv6-M — Cortex-M0/M0+ به دلیل محدودیت‌های این معماری، عملیات Atomic با استفاده از Critical Section پیاده‌سازی می‌شود. 🔹 ARMv7-M و بالاتر از قابلیت‌های سخت‌افزاری ARM مانند LDREX/STREX برای پیاده‌سازی عملیات Atomic استفاده می‌شود و امکان اجرای Lock-free فراهم می‌شود. 🧠 مدیریت Kernel Heap مدیریت Heap در AhuraRTOS از الگویی مشابه heap_4 استفاده می‌کند، اما یک نکته مهم دارد: Address-ordered Free List بلوک‌های آزاد بر اساس آدرس مدیریت می‌شوند؛ بنابراین هنگام آزاد شدن حافظه، بلوک‌های مجاور می‌توانند با یکدیگر Coalesce شوند. نتیجه: Free Block + Adjacent Free Block → Larger Free Block این کار به کاهش Fragmentation کمک کرده و امکان استفاده مجدد بهتر از حافظه را فراهم می‌کند. 📦 Queue و جلوگیری از Silent Overflow در Queueهای Static، استفاده از: OS_QUEUE_DEFINE_STATIC باعث می‌شود اندازه آیتم و ظرفیت Queue مستقیماً از آرایه و با استفاده از sizeof مشخص شود. این رویکرد احتمال خطاهایی را کاهش می‌دهد که در آن توسعه‌دهنده ظرفیت Queue را بیشتر از حافظه واقعی تعریف می‌کند؛ خطایی که ممکن است در ظاهر بدون مشکل اجرا شود اما در زمان اجرا باعث Memory Corruption شود. 🎯 در این بخش دیدیم که AhuraRTOS فقط روی Scheduler تمرکز ندارد؛ بلکه در لایه‌های IPC، Synchronization، Atomic Operations و Memory Management نیز تلاش می‌کند سربار کم و رفتار قابل پیش‌بینی داشته باشد. 🔜 ادامه دارد... @Amin_Techlab
494
11
⚙️ کالبدشکافی فنی AhuraRTOS بخش ۲ | Scheduling، Priority و Context Switching 🧠 ۳. مکانیسم Scheduling و مدیریت Priority یکی از ویژگی‌های مهم AhuraRTOS، استفاده از Scheduler با پیچیدگی O(1) است. یعنی زمان انتخاب Task بعدی به تعداد Taskهای سیستم وابسته نیست؛ چه ۲ Task داشته باشیم و چه ۳۲ Task، انتخاب Task آماده با زمان ثابت انجام می‌شود. 🔹 ۳۲ سطح Priority AhuraRTOS از ۳۲ سطح اولویت، از 0 تا 31، استفاده می‌کند. این ساختار با یک 32-bit Bitmap هماهنگ است و وضعیت Taskهای Ready را به‌صورت فشرده نگهداری می‌کند. 🔹 Bitmap + CLZ برای پیدا کردن بالاترین Priority آماده، Bitmap بررسی می‌شود. در ARMv7-M و معماری‌های بالاتر، دستور سخت‌افزاری CLZ (Count Leading Zeros) می‌تواند برای پیدا کردن موقعیت بیت موردنظر استفاده شود. در نتیجه Scheduler به‌جای بررسی Priorityها به‌صورت ترتیبی، مستقیماً به Priority مناسب دسترسی پیدا می‌کند. 🔹 Round-Robin اگر چند Task دارای Priority یکسان باشند، AhuraRTOS امکان اجرای چرخشی آن‌ها را فراهم می‌کند. پارامتر: OS_CONFIG_TIME_SLICE_TICKS تعداد Tickهای مربوط به Time Slice را مشخص می‌کند. با قرار دادن مقدار آن روی 0، Round-Robin غیرفعال شده و سربار Context Switching کاهش پیدا می‌کند. 🛡 ۴. چرا PendSV و نه SVC؟ در بسیاری از RTOSها از SVC برای ورود به Kernel یا شروع اولین Task استفاده می‌شود. اما AhuraRTOS رویکرد متفاوتی دارد: SVC → Application PendSV → Context Switching در این طراحی، SVC برای Application آزاد باقی می‌ماند و RTOS برای Context Switch از PendSV استفاده می‌کند. حتی شروع اولین Task نیز از مسیر PendSV انجام می‌شود. Kernel با بررسی وضعیت PSP می‌تواند تشخیص دهد که آیا هنوز Taskای اجرا نشده است یا خیر. ⚡️ Context Switch در سطح پایین در PendSV، وضعیت Context مربوط به Task فعلی ذخیره و Context مربوط به Task بعدی بازیابی می‌شود. رجیسترهای: R4 – R11 در این فرآیند مدیریت می‌شوند. همچنین مدیریت FPU به‌صورت هوشمند انجام می‌شود تا در Taskهایی که از محاسبات Floating-Point استفاده نمی‌کنند، هزینه اضافی Context Switching ایجاد نشود. 🎯 در نهایت، این طراحی سه هدف مهم را دنبال می‌کند: O(1) Scheduling Context Switching بهینه آزاد ماندن SVC برای Application 🔜 ادامه دارد... @Amin_Techlab
478
12
🧩 کالبدشکافی فنی AhuraRTOS رویکردی نوین در طراحی RTOS برای ARM Cortex-M بخش ۱ | معماری Kernel و فلسفه Portability 🔹 ۱. فراتر از انتزاع‌های رایج در Embedded اگر با سیستم‌های نهفته کار کرده باشید، احتمالاً با یک سؤال مهم روبه‌رو شده‌اید: ❓ چرا با تغییر معماری یا مدل پردازنده، باید بخش‌هایی از Kernel یک RTOS را نیز تغییر دهیم؟ در بسیاری از RTOSهای سنتی، Port کردن سیستم‌عامل به یک معماری جدید فقط به تغییر HAL محدود نمی‌شود و گاهی بخش‌هایی از Kernel، Scheduler یا منطق داخلی سیستم‌عامل نیز تحت تأثیر قرار می‌گیرد. AhuraRTOS با یک فلسفه متفاوت طراحی شده است: 🎯 مرز مشخص و غیرقابل عبور بین Application و Kernel در AhuraRTOS، Kernel به‌گونه‌ای طراحی شده که فایل‌های داخلی آن نباید برای هر پروژه یا پردازنده ویرایش شوند. پیکربندی سیستم‌عامل از طریق یک فایل متمرکز در سمت Application انجام می‌شود: os_config.h این موضوع باعث می‌شود Kernel عملاً مانند یک Static Library مستقل عمل کند؛ یعنی منطق اصلی سیستم‌عامل وابستگی مستقیمی به جزئیات سخت‌افزار ندارد. ارتباط Kernel با معماری پردازنده نیز از طریق یک Port Interface مشخص انجام می‌شود. ⚙️ ۲. معماری Kernel و فلسفه Portability معماری AhuraRTOS بر پایه یک اصل مهم شکل گرفته است: Portable Kernel + Architecture-Specific Port یعنی منطق سیستم‌عامل تا حد ممکن در کد قابل‌حمل C باقی می‌ماند و فقط قسمت‌هایی که واقعاً به معماری CPU وابسته هستند، در لایه Port قرار می‌گیرند. نکته جالب اینجاست که خانواده گسترده ARM Cortex-M، از Cortex-M0 تا Cortex-M85، با تعداد محدودی پیاده‌سازی مشترک در لایه Port پوشش داده می‌شود. در این معماری، Port فقط یک لایه ساده برای اتصال Kernel به CPU نیست؛ بلکه مسئول انجام عملیات حساس و وابسته به معماری است. از طرف دیگر، استفاده گسترده از Inline Functions در این لایه می‌تواند سربار Function Call را کاهش دهد و مسیرهای حساس Kernel را سبک‌تر نگه دارد. 📌 تقسیم مسئولیت‌ها Kernel — Portable C 🔸 مدیریت Ready List و Scheduler با پیچیدگی O(1) 🔸 Mutex / Semaphore / Event و منطق IPC 🔸 Software Timer و Work Queue 🔸 مدیریت Heap 🔸 Notificationهای Task 🔸 مدیریت Priority و Priority Inheritance در مقابل: Port — Architecture Specific 🔸 Context Switch با استفاده از PendSV 🔸 مدیریت Tick و Timer Interrupt 🔸 Critical Section 🔸 عملیات Atomic وابسته به معماری 🔸 ایجاد Initial Stack Frame 🔸 مدیریت Registerهای خاص پردازنده مانند PSPLIM و FPU 💡 نتیجه این تفکیک چیست؟ اگر Kernel از جزئیات CPU بی‌خبر باشد، تغییر معماری نباید باعث تغییر منطق اصلی سیستم‌عامل شود. در چنین معماری‌ای: Application ⬇️ os_config.h ⬇️ Portable Kernel ⬇️ Port Interface ⬇️ ARM Cortex-M و این دقیقاً همان نقطه‌ای است که Portability واقعی از یک شعار معماری به یک تصمیم مهندسی تبدیل می‌شود. 🔜 ادامه دارد... @Amin_Techlab
504
13
🚀 معرفی یک پروژه مهم در دنیای Embedded Systems؛ AhuraRTOS دوستانی که در حوزه الکترونیک و سیستم‌های Embedded فعالیت می‌کنیم،
🚀 معرفی یک پروژه مهم در دنیای Embedded Systems؛ AhuraRTOS دوستانی که در حوزه الکترونیک و سیستم‌های Embedded فعالیت می‌کنیم، احتمالاً با پروژه‌ها و کتابخانه‌های مهندس عسگری (nimaltd) آشنا هستیم و در بسیاری از پروژه‌ها از کتابخانه‌های ایشان استفاده کرده‌ایم. حالا مهندس عسگری یک پروژه بزرگ و جذاب را توسعه داده‌اند با نام AhuraRTOS؛ یک پروژه در حوزه Real-Time Operating System برای سیستم‌های Embedded که ارزش بررسی و آشنایی بیشتری دارد. در پست‌های بعدی قصد داریم AhuraRTOS را قدم‌به‌قدم بررسی کنیم و درباره معماری، قابلیت‌ها، ساختار پروژه و نحوه استفاده از آن بیشتر صحبت کنیم. 🔗 GitHub: AhuraRTOS 👤 مهندس عسگری – nimaltd GitHub / nimaltd Instagram LinkedIn 📌 در ادامه این مجموعه، بیشتر با AhuraRTOS آشنا خواهیم شد. @Amin_Techlab
1 106
14
🚀 اگر هنوز FreeRTOS را فقط یک کتابخانه می‌دانید، این ویدیو را از دست ندهید! در پروژه‌های حرفه‌ای STM32H7، دیگر Super Loop پا
🚀 اگر هنوز FreeRTOS را فقط یک کتابخانه می‌دانید، این ویدیو را از دست ندهید! در پروژه‌های حرفه‌ای STM32H7، دیگر Super Loop پاسخگو نیست. اما چرا RTOS تا این حد اهمیت دارد؟ و چرا تقریباً تمام پروژه‌های صنعتی به سمت FreeRTOS رفته‌اند؟ در قسمت نهم مسترکلاس Embedded، بدون ورود به کدنویسی پیچیده، مفهوم RTOS را از پایه بررسی می‌کنیم و یاد می‌گیرید: ⚡️ تفاوت Bare-Metal و RTOS ⚡️ Task، Scheduler و Context Switch به زبان ساده ⚡️ دلیل اهمیت FreeRTOS در STM32H7 و سیستم‌های Dual-Core ⚡️ چرا یادگیری RTOS برای ورود به پروژه‌های صنعتی ضروری است. 🎥 تماشا در یوتیوب: https://youtu.be/C0GHtBfRsuY اگر قصد دارید STM32 را به‌صورت حرفه‌ای یاد بگیرید، این قسمت یکی از مهم‌ترین ویدیوهای این مجموعه است. 🔥 @Amin_Techlab
504
15
🚀 هوش مصنوعی را روی کامپیوتر خودتان اجرا کنید؛ بدون اینترنت، بدون API و کاملاً رایگان! اگر فکر می‌کنید برای استفاده از مدل‌ه
🚀 هوش مصنوعی را روی کامپیوتر خودتان اجرا کنید؛ بدون اینترنت، بدون API و کاملاً رایگان! اگر فکر می‌کنید برای استفاده از مدل‌های زبانی بزرگ (LLM) حتماً باید از سرویس‌های ابری استفاده کنید، وقت آن رسیده نظرتان عوض شود. در این آموزش، قدم‌به‌قدم یاد می‌گیرید چگونه با LM Studio مدل‌های متن‌باز هوش مصنوعی را به‌صورت کاملاً Local روی ویندوز، لینوکس یا macOS اجرا کنید. 💡 در این ویدیو یاد می‌گیرید: • چرا LM Studio برای بسیاری از کاربران جایگزین مناسبی برای Ollama است. • چگونه LM Studio را دانلود و نصب کنید. • چگونه مدل‌های محبوب مانند Llama، Mistral، Gemma، Qwen، DeepSeek و ده‌ها مدل دیگر را جستجو، دانلود و اجرا کنید. • نحوه مدیریت مدل‌ها و اجرای آن‌ها بدون نیاز به اینترنت یا API. • آشنایی با محیط توسعه (Developer Mode) و قابلیت‌های کاربردی LM Studio برای برنامه‌نویسان. ✅ مزایای اجرای Local AI: 🔹 بدون هزینه API 🔹 حفظ کامل حریم خصوصی 🔹 اجرای آفلاین 🔹 مناسب برای توسعه، تست و تحقیق 🔹 پشتیبانی از صدها مدل متن‌باز 🎥 مشاهده آموزش: https://youtu.be/qS1Lwh6BwSk کانال YouTube را سابسکرایب کنید . @Amin_Techlab
595
16
🚀 چرا یادگیری Vim هنوز یک مهارت ضروری است؟ اگر با Linux، SSH، DevOps، Embedded Linux یا مدیریت سرور کار می‌کنید، احتمالاً دیر یا زود در شرایطی قرار می‌گیرید که تنها ابزار در دسترس شما Vim باشد. تصور کنید با یک ارتباط SSH پر تأخیر (High Latency) به یک سرور متصل شده‌اید و فقط می‌خواهید فایل‌هایی مانند موارد زیر را ویرایش کنید: /etc/ssh/sshd_config /etc/nginx/nginx.conf /etc/fstab /etc/systemd/*.service در چنین شرایطی، ویرایشگرهای ساده مانند Nano برای فایل‌های بزرگ یا جابه‌جایی‌های متعدد چندان کارآمد نیستند. اما Vim دقیقاً برای چنین سناریوهایی طراحی شده است. چرا Vim؟ ✅ پرش مستقیم به هر خط :100 یا 100G بدون اسکرول کردن، مستقیماً به خط موردنظر می‌روید. ✅ جستجوی سریع در فایل /keyword و حرکت بین نتایج: n N ✅ جایگزینی سراسری متن :%s/old/new/g ✅ کپی، حذف و Paste تنها با چند کلید yy Copy Line dd Delete Line p Paste ✅ اجرای سریع روی تقریباً تمام توزیع‌های لینوکس در اکثر سرورها، ماشین‌های مجازی، تجهیزات شبکه، Embedded Linux و حتی محیط‌های Recovery، Vim به‌صورت پیش‌فرض نصب است و به رابط گرافیکی وابسته نیست. Vim فقط یک ویرایشگر متن نیست. Vim یک Modal Editor است؛ یعنی برای هر نوع عملیات (حرکت، ویرایش، انتخاب و فرمان‌ها) حالت‌های اختصاصی دارد. همین معماری باعث می‌شود پس از یادگیری، سرعت و دقت ویرایش فایل‌ها چندین برابر شود. به همین دلیل بسیاری از توسعه‌دهندگان Kernel، برنامه‌نویسان Embedded، مدیران سیستم و مهندسان DevOps هنوز هم Vim را ابزار اصلی خود می‌دانند. اگر می‌خواهید مهارت خود را تقویت کنید، این منابع را از دست ندهید: 🎯 Vim Genius https://vimgenius.com/ 🎮 Vim Hero https://www.vim-hero.com/ 📖 OpenVim https://openvim.com/ 🏌️ VimGolf AI https://vimgolf.ai/ 🕹 Vim Adventures (یادگیری Vim با بازی) https://vim-adventures.com 💡 نکته: شاید امروز از Nano استفاده کنید، اما روزی که مجبور شوید روی یک سرور Remote، یک Container، یک Router یا یک سیستم Recovery فقط با Vim کار کنید، از زمانی که برای یادگیری آن گذاشته‌اید، قدردانی خواهید کرد. @Amin_Techlab
552
17
آشنایی با glibc : کتابخانهٔ GNU C Library (glibc)، پیاده‌سازی رسمی پروژهٔ GNU از کتابخانهٔ استاندارد زبان C است. افزون‌براین، این کتابخانه علاوه بر توابع استاندارد ISO C، بخش بزرگی از رابط‌های برنامه‌نویسی POSIX و بسیاری از قابلیت‌های اختصاصی لینوکس را نیز در اختیار برنامه‌ها قرار می‌دهد. برای نمونه، هر زمان که در برنامهٔ خود از توابعی مانند: • printf() • malloc() • free() • open() • read() • write() • pthread_create() • getaddrinfo() استفاده می‌کنید، در اکثر توزیع‌های لینوکس این توابع توسط glibc پیاده‌سازی شده‌اند. اهمیت glibc : نخست، کرنل لینوکس تنها System Callها را در اختیار برنامه‌ها قرار می‌دهد و استفادهٔ مستقیم از آن‌ها چندان ساده نیست. در این میان، glibc نقش یک لایهٔ واسط را بر عهده می‌گیرد. در عمل، این کتابخانه به‌عنوان یک لایهٔ انتزاعی (Abstraction Layer) میان برنامه و کرنل قرار می‌گیرد و APIهای استاندارد و قابل‌حمل را در اختیار توسعه‌دهندگان قرار می‌دهد. در نتیجه، برنامه‌نویس بدون درگیر شدن با جزئیات معماری پردازنده یا فراخوانی مستقیم System Callها، تنها با استفاده از توابع استاندارد زبان C می‌تواند با سیستم‌عامل ارتباط برقرار کند. قابلیت‌های glibc : ✅ پشتیبانی کامل از استاندارد ISO C ✅ پشتیبانی گسترده از POSIX ✅ مدیریت حافظه (malloc و free) ✅ مدیریت رشته‌ها و کاراکترها ✅ مدیریت فایل و عملیات ورودی/خروجی ✅ پشتیبانی از شبکه و سوکت‌ها ✅ مدیریت Threadها با POSIX Threads ✅ بارگذاری کتابخانه‌های اشتراکی (Dynamic Loader) ✅ پشتیبانی از Locale و بین‌المللی‌سازی (Internationalization) جایگزین‌های glibc : البته، glibc تنها کتابخانهٔ استاندارد موجود برای لینوکس نیست. برای مثال، کتابخانه‌های زیر نیز توسعه یافته‌اند: • musl libc • uClibc-ng • Bionic (مورد استفاده در اندروید) بااین‌حال، glibc همچنان پرکاربردترین کتابخانهٔ استاندارد در توزیع‌هایی مانند Debian، Ubuntu، Fedora و RHEL محسوب می‌شود. ارزش یادگیری glibc : چنانچه در یکی از حوزه‌های زیر فعالیت می‌کنید: 🔹 برنامه‌نویسی سیستمی (System Programming) 🔹 توسعهٔ کرنل 🔹 Embedded Linux 🔹 امنیت نرم‌افزار 🔹 طراحی Runtime یا Compiler 🔹 مهندسی معکوس بدانید که مطالعهٔ مستندات و حتی کدهای glibc دید بسیار عمیق‌تری نسبت به نحوهٔ ارتباط برنامه‌ها با سیستم‌عامل در اختیار شما قرار می‌دهد. جالب است بدانید پروژهٔ glibc بیش از ۳۰ سال قدمت دارد و همچنان یکی از مهم‌ترین پروژه‌های متن‌باز دنیای لینوکس به شمار می‌رود. امروزه، تقریباً هر برنامه‌ای که روی یک توزیع لینوکسی اجرا می‌کنید، به‌صورت مستقیم یا غیرمستقیم به این کتابخانه وابسته است. به‌همین‌دلیل، شناخت glibc برای هر برنامه‌نویس سیستم، توسعه‌دهندهٔ لینوکس و حتی علاقه‌مندان به امنیت، یک مهارت بنیادی و ارزشمند محسوب می‌شود. @Amin_Techlab
447
18
راز پشت هر برنامه لینوکس glibC : اگر تاکنون با زبان‌های C یا ++C روی لینوکس برنامه‌نویسی کرده باشید، احتمالاً بدون اینکه متوج
راز پشت هر برنامه لینوکس glibC : اگر تاکنون با زبان‌های C یا ++C روی لینوکس برنامه‌نویسی کرده باشید، احتمالاً بدون اینکه متوجه شوید از glibc استفاده کرده‌اید. اما glibc دقیقاً چیست و چرا تا این اندازه اهمیت دارد؟ ادامه در پست بعد .... @Amin_Techlab
363
19
🚀 AMTerminal v1.0.0 منتشر شد! بعد از مدت‌ها توسعه، اولین نسخه عمومی AMTerminal آماده است. AMTerminal یک شل (Shell) و محیط خط
🚀 AMTerminal v1.0.0 منتشر شد! بعد از مدت‌ها توسعه، اولین نسخه عمومی AMTerminal  آماده است. AMTerminal  یک شل (Shell) و محیط خط فرمان (CLI) مدرن است که با زبان Rust  توسعه داده شده و روی Windows، Linux و macOS اجرا می‌شود. ✨ برخی از قابلیت‌ها: • پشتیبانی از Pipe (|) • پشتیبانی از Redirection (>, >>, <) • همراهPrompt هوشمند با نمایش وضعیت Git • تکمیل خودکار (Tab Completion) • ذخیره و جستجوی History • رنگ‌بندی و Prompt کاملاً قابل شخصی‌سازی • اجرای دستورات داخلی و خارجی • عملکرد سریع و سبک 📥 از شما دعوت می‌کنم نسخه اول را دانلود و امتحان کنید. https://github.com/Amin98Hosseini/AMTerminal_Rust/releases/tag/AMT-v1.0.0-rc.1 💬 اگر باگ، پیشنهاد یا ایده‌ای برای بهتر شدن AMTerminal دارید، حتماً در GitHub ثبت کنید یا برای من ارسال کنید. بازخورد شما نقش مهمی در توسعه نسخه‌های بعدی خواهد داشت. ⭐️ اگر پروژه را دوست داشتید، فراموش نکنید به آن در GitHub یک Star بدهید.   لینک گیت هاب پروژه : https://github.com/Amin98Hosseini/AMTerminal_Rust @Amin_Techlab
519
20
🦀 برسی کدهای اضافه شده Rust : یکی از قسمت‌های جالب این RFC، نحوه طراحی APIها در Rust است. تقریباً تمام بخش‌های Unsafe فقط در مرز ارتباط با کدهای C قرار گرفته‌اند و منطق Driver کاملاً با Safe Rust نوشته شده است. ۱- Wrapper ایمن روی APIهای C به جای اینکه Driver مستقیماً تابع C زیر را فراخوانی کند: i2c_smbus_read_byte_data(...) یک Wrapper امن در I2cClient اضافه شده است: pub fn smbus_read_byte_data(&self, command: u8) -> Result<u8> { let ret = unsafe { bindings::i2c_smbus_read_byte_data(self.as_raw(), command) }; if ret < 0 { Err(Error::from_errno(ret)) } else { Ok(ret as u8) } } در اینجا تنها بخش Unsafe همان فراخوانی تابع C است. بعد از آن، مقدار بازگشتی به یک Result<u8> استاندارد Rust تبدیل می‌شود و Driver دیگر نیازی به بررسی کدهای خطای C ندارد. ۲- پیاده‌سازی الگوی معروف Read → Modify → Write یکی از متدهای بسیار کاربردی که اضافه شده: pub fn smbus_update_bits(...) درون آن ابتدا مقدار رجیستر خوانده می‌شود: let old = self.smbus_read_byte_data(command)?; سپس فقط بیت‌های موردنظر تغییر می‌کنند: let new = (old & !mask) | (value & mask); و تنها در صورتی که مقدار واقعاً تغییر کرده باشد: if new != old { self.smbus_write_byte_data(command, new)?; } نوشتن روی سخت‌افزار انجام می‌شود. این دقیقاً همان الگویی است که تقریباً در اکثر Driverهای C لینوکس نیز دیده می‌شود. ۳- طراحی Driver با Trait به جای استفاده از Structهای متعدد و Callbackهای C، تنها کافی است Driver این Trait را پیاده‌سازی کند: pub trait Driver { const NAME: &'static CStr; const TYPE: Type; const PROPERTIES: &'static [Property]; fn get_property(...) } این طراحی باعث می‌شود هر Driver فقط روی منطق خود تمرکز کند و تمام جزئیات مربوط به Power Supply Core در پشت Abstraction پنهان بماند. ۴- استفاده از RAII برای مدیریت Driver در Rust یک Struct به نام Registration معرفی شده است. نکته جالب این است که هنگام از بین رفتن این شیء: impl Drop for Registration { fn drop(&mut self) { unsafe { bindings::power_supply_unregister(self.psy); } } } تابع power_supply_unregister() به صورت خودکار اجرا می‌شود. در نتیجه توسعه‌دهنده دیگر نگران آزادسازی منابع یا فراموش کردن Unregister کردن Driver نخواهد بود؛ این کار به کمک مکانیزم Drop در Rust انجام می‌شود. ۵- تعریف Driver واقعی فقط در چند خط در Driver مربوط به SMB347 تنها با چند ثابت می‌توان مشخص کرد که Driver چه قابلیت‌هایی دارد: const NAME: &'static CStr = c"smb347-mains"; const PROPERTIES: &'static [Property] = &[ PROP_STATUS, PROP_ONLINE, PROP_CHARGE_TYPE, ]; و سپس تنها تابعی که باید پیاده‌سازی شود: fn get_property(...) که وضعیت شارژر را از رجیسترهای سخت‌افزار می‌خواند و آن را به Power Supply Framework گزارش می‌دهد. این طراحی باعث شده حجم زیادی از کدهای تکراری Driverهای C حذف شوند و توسعه Driver بیشتر شبیه پیاده‌سازی یک Trait در Rust باشد تا کار با Callbackها و Pointerهای متعدد. ۶- نکته‌ای که توجه Maintainerها را جلب کرد یکی از جالب‌ترین قسمت‌های Review این RFC مربوط به همین چند خط بود: pub fn register<T: Driver + 'static>(dev: &Device) Alice Ryhl پیشنهاد داد که به جای &Device از &Device<Bound> استفاده شود تا از نظر Type System تضمین شود که Driver فقط روی Deviceهایی که کاملاً Bind شده‌اند ثبت می‌شود. همچنین پیشنهاد کرد این تابع به جای یک تابع آزاد، به شکل: Registration::new(...) بازطراحی شود تا با سایر APIهای Rust Kernel هماهنگ باشد. این بازخوردها نشان می‌دهد که در پروژه Rust for Linux، علاوه بر عملکرد، طراحی API و سازگاری با الگوهای Rust نیز اهمیت بسیار زیادی دارد. @Amin_Techlab
549