GPIO (output) freezes when running ADC and DMA in continuous mode (on stm32f411) - dma

I want to read 3 ADC channels (A0, A1, A2) and if the output goes below 2000 steps, B7 will be set to (1) and my LED will turn on.
I wrote a simple code to read ADC with DMA in continuous mode.
when I set to disable the DMA Continouos Request in CubeMX everything is OK.
But when I put it on Enabled, B7 or PC13 freezes and does not change bu ADC is OK.
I used STM32F411CEU blackpill
My Code :
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdlib.h"
#include "math.h"
#include "string.h"
#include "stdint.h"
#include "stdio.h"
uint32_t read_adc[6],buffer[3];
int i=0;
uint32_t buffer_tx;
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
for (int i=0; i<3; i++)
{
read_adc[i] = buffer[i];
}
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_ADC_Start_DMA(&hadc1, buffer, 3);
HAL_Delay(200);
for(i=0; i<3; i++)
{
sprintf(buffer_tx,"%u",read_adc[i]);
}
HAL_ADC_Stop_DMA(&hadc1);
if(read_adc[0] < 2000)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
}else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(200);
}
}
/* USER CODE END 3 */
}

Related

How to handle read data with MCC generated i2c driver?

I'm trying to use new (?) i2c driver for PIC18F45Q10. I don't understand how can I use it without modification. I just want to set my own function with state machine as callback to process incoming bytes.
I'm sending 2 bytes from Linux machine to microcontroller.
i2cset 1 0x12 0x01 0x02
Where:
1 is Linux I2C bus number
0x12 is 7-bit i2c address (my microcontroller)
0x01 is first byte of data
0x02 is second byte of data
My problem is that I2C2_SlaveRdCallBack(); is never being called (because rx buffer is always empty).
I2C configuration in MCC seems to be fine, because when I put a breakpoint at if(I2C2_SlaveIsRxBufFull()) line - it stops there and I see that i2c2RdData variable contains first byte of data. Linux machine can discover my microcontroller with i2cdetect command (i2cdetect sends all possible device addresses and when it receives ACK - it shows device as discovered).
How to use this driver? Is this code supposed to be working, or just some scaffolding / sample?
Main ISR handler from this driver:
static void I2C2_Isr()
{
I2C2_SlaveClearIrq();
// read SSPBUF to clear BF
i2c2RdData = I2C2_SlaveGetRxData(); // <- but there is my first ! (it reads hardware register)
if(I2C2_SlaveIsRead())
{
i2c2State = I2C2_TX;
}
else
{
i2c2State = I2C2_RX;
}
switch(i2c2State)
{
case I2C2_TX:
if(!I2C2_SlaveIsWriteCollision())
{
I2C2_SlaveWrCallBack();
}
else
{
I2C2_SlaveWrColCallBack();
I2C2_SlaveRestart();
}
i2c2NextState = I2C2_ADDR;
break;
case I2C2_RX:
if (I2C2_SlaveIsData()) <-- I have problem here
{
if(I2C2_SlaveIsRxBufFull()) <-- when the buffer is not full
{
I2C2_SlaveRdCallBack(); <-- read callback is not called
}
}
else
{
I2C2_SlaveAddrCallBack();
i2c2NextState = I2C2_ADDR;
}
break;
default:
break;
}
i2c2State = i2c2NextState;
I2C2_SlaveReleaseClock();
}
Full driver code:
/**
I2C2 Generated Driver File
#Company
Microchip Technology Inc.
#File Name
i2c2.c
#Summary
This is the generated driver implementation file for the I2C2 driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs
#Description
This header file provides implementations for driver APIs for I2C2.
Generation Information :
Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.78.1
Device : PIC18F45Q10
Driver Version : 1.0.0
The generated drivers are tested against the following:
Compiler : XC8 2.10 and above or later
MPLAB : MPLAB X 5.30
*/
/*
(c) 2018 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and any
derivatives exclusively with Microchip products. It is your responsibility to comply with third party
license terms applicable to your use of third party software (including open source software) that
may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY
IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS
FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP
HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO
THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL
CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT
OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS
SOFTWARE.
*/
#include "i2c2_slave.h"
#include <xc.h>
#define I2C2_SLAVE_ADDRESS 18
#define I2C2_SLAVE_MASK 127
/**
Section: Global Variables
*/
typedef enum
{
I2C2_ADDR,
I2C2_TX,
I2C2_RX
} i2c2_state_t;
static void I2C2_Isr(void);
static void I2C2_SlaveDefRdInterruptHandler(void);
static void I2C2_SlaveDefWrInterruptHandler(void);
static void I2C2_SlaveDefAddrInterruptHandler(void);
static void I2C2_SlaveDefWrColInterruptHandler(void);
static void I2C2_SlaveDefBusColInterruptHandler(void);
static void I2C2_SlaveRdCallBack(void);
static void I2C2_SlaveWrCallBack(void);
static void I2C2_SlaveAddrCallBack(void);
static void I2C2_SlaveWrColCallBack(void);
static void I2C2_SlaveBusColCallBack(void);
static inline bool I2C2_SlaveOpen();
static inline void I2C2_SlaveClose();
static inline void I2C2_SlaveSetSlaveAddr(uint8_t slaveAddr);
static inline void I2C2_SlaveSetSlaveMask(uint8_t maskAddr);
static inline void I2C2_SlaveEnableIrq(void);
static inline bool I2C2_SlaveIsAddr(void);
static inline bool I2C2_SlaveIsRead(void);
static inline void I2C2_SlaveClearBuff(void);
static inline void I2C2_SlaveClearIrq(void);
static inline void I2C2_SlaveReleaseClock(void);
static inline bool I2C2_SlaveIsWriteCollision(void);
static inline bool I2C2_SlaveIsTxBufEmpty(void);
static inline bool I2C2_SlaveIsData(void);
static inline void I2C2_SlaveRestart(void);
static inline bool I2C2_SlaveIsRxBufFull(void);
static inline void I2C2_SlaveSendTxData(uint8_t data);
static inline uint8_t I2C2_SlaveGetRxData(void);
static inline uint8_t I2C2_SlaveGetAddr(void);
static inline void I2C2_SlaveSendAck(void);
static inline void I2C2_SlaveSendNack(void);
static volatile i2c2_state_t i2c2State = I2C2_ADDR;
static volatile i2c2_state_t i2c2NextState = I2C2_ADDR;
volatile uint8_t i2c2WrData;
volatile uint8_t i2c2RdData;
volatile uint8_t i2c2SlaveAddr;
void I2C2_Initialize()
{
SSP2STAT = 0x40;
SSP2CON1 |= 0x06;
SSP2CON2 = 0x10;
SSP2CON1bits.SSPEN = 0;
}
void I2C2_Open()
{
I2C2_SlaveOpen();
I2C2_SlaveSetSlaveAddr(I2C2_SLAVE_ADDRESS << 1);
I2C2_SlaveSetSlaveMask(I2C2_SLAVE_MASK);
I2C2_SlaveSetIsrHandler(I2C2_Isr);
I2C2_SlaveSetBusColIntHandler(I2C2_SlaveDefBusColInterruptHandler);
I2C2_SlaveSetWriteIntHandler(I2C2_SlaveDefWrInterruptHandler);
I2C2_SlaveSetReadIntHandler(I2C2_SlaveDefRdInterruptHandler);
I2C2_SlaveSetAddrIntHandler(I2C2_SlaveDefAddrInterruptHandler);
I2C2_SlaveSetWrColIntHandler(I2C2_SlaveDefWrColInterruptHandler);
I2C2_SlaveEnableIrq();
}
void I2C2_Close()
{
I2C2_SlaveClose();
}
uint8_t I2C2_Read()
{
return I2C2_SlaveGetRxData();
}
void I2C2_Write(uint8_t data)
{
I2C2_SlaveSendTxData(data);
}
void I2C2_Enable()
{
I2C2_Initialize();
}
void I2C2_SendAck()
{
I2C2_SlaveSendAck();
}
void I2C2_SendNack()
{
I2C2_SlaveSendNack();
}
static void I2C2_Isr()
{
I2C2_SlaveClearIrq();
// read SSPBUF to clear BF
i2c2RdData = I2C2_SlaveGetRxData();
if(I2C2_SlaveIsRead())
{
i2c2State = I2C2_TX;
}
else
{
i2c2State = I2C2_RX;
}
switch(i2c2State)
{
case I2C2_TX:
if(!I2C2_SlaveIsWriteCollision())
{
I2C2_SlaveWrCallBack();
}
else
{
I2C2_SlaveWrColCallBack();
I2C2_SlaveRestart();
}
i2c2NextState = I2C2_ADDR;
break;
case I2C2_RX:
if (I2C2_SlaveIsData())
{
if(I2C2_SlaveIsRxBufFull())
{
I2C2_SlaveRdCallBack();
}
}
else
{
I2C2_SlaveAddrCallBack();
i2c2NextState = I2C2_ADDR;
}
break;
default:
break;
}
i2c2State = i2c2NextState;
I2C2_SlaveReleaseClock();
}
// Common Event Interrupt Handlers
void I2C2_SlaveSetIsrHandler(interruptHandler handler)
{
MSSP2_InterruptHandler = handler;
}
// Read Event Interrupt Handlers
void I2C2_SlaveSetReadIntHandler(interruptHandler handler) {
I2C2_SlaveRdInterruptHandler = handler;
}
static void I2C2_SlaveRdCallBack() {
// Add your custom callback code here
if (I2C2_SlaveRdInterruptHandler)
{
I2C2_SlaveRdInterruptHandler();
}
}
static void I2C2_SlaveDefRdInterruptHandler() {
i2c2RdData = I2C2_SlaveGetRxData();
}
// Write Event Interrupt Handlers
void I2C2_SlaveSetWriteIntHandler(interruptHandler handler) {
I2C2_SlaveWrInterruptHandler = handler;
}
static void I2C2_SlaveWrCallBack() {
// Add your custom callback code here
if (I2C2_SlaveWrInterruptHandler)
{
I2C2_SlaveWrInterruptHandler();
}
}
static void I2C2_SlaveDefWrInterruptHandler() {
I2C2_SlaveSendTxData(i2c2WrData);
}
// ADDRESS Event Interrupt Handlers
void I2C2_SlaveSetAddrIntHandler(interruptHandler handler){
I2C2_SlaveAddrInterruptHandler = handler;
}
static void I2C2_SlaveAddrCallBack() {
// Add your custom callback code here
if (I2C2_SlaveAddrInterruptHandler) {
I2C2_SlaveAddrInterruptHandler();
}
}
static void I2C2_SlaveDefAddrInterruptHandler() {
i2c2SlaveAddr = I2C2_SlaveGetAddr();
}
// Write Collision Event Interrupt Handlers
void I2C2_SlaveSetWrColIntHandler(interruptHandler handler){
I2C2_SlaveWrColInterruptHandler = handler;
}
static void I2C2_SlaveWrColCallBack() {
// Add your custom callback code here
if ( I2C2_SlaveWrColInterruptHandler)
{
I2C2_SlaveWrColInterruptHandler();
}
}
static void I2C2_SlaveDefWrColInterruptHandler() {
}
// Bus Collision Event Interrupt Handlers
void I2C2_SlaveSetBusColIntHandler(interruptHandler handler){
I2C2_SlaveBusColInterruptHandler = handler;
}
static void I2C2_SlaveBusColCallBack() {
// Add your custom callback code here
if ( I2C2_SlaveBusColInterruptHandler)
{
I2C2_SlaveBusColInterruptHandler();
}
}
static void I2C2_SlaveDefBusColInterruptHandler() {
}
static inline bool I2C2_SlaveOpen()
{
if(!SSP2CON1bits.SSPEN)
{
SSP2STAT = 0x40;
SSP2CON1 |= 0x06;
SSP2CON2 = 0x10;
SSP2CON1bits.SSPEN = 1;
return true;
}
return false;
}
static inline void I2C2_SlaveClose()
{
SSP2STAT = 0x40;
SSP2CON1 |= 0x06;
SSP2CON2 = 0x10;
SSP2CON1bits.SSPEN = 0;
}
static inline void I2C2_SlaveSetSlaveAddr(uint8_t slaveAddr)
{
SSP2ADD = slaveAddr;
}
static inline void I2C2_SlaveSetSlaveMask(uint8_t maskAddr)
{
SSP2MSK = maskAddr;
}
static inline void I2C2_SlaveEnableIrq()
{
PIE3bits.SSP2IE = 1;
}
static inline bool I2C2_SlaveIsAddr()
{
return !(SSP2STATbits.D_nA);
}
static inline bool I2C2_SlaveIsRead()
{
return (SSP2STATbits.R_nW);
}
static inline void I2C2_SlaveClearIrq()
{
PIR3bits.SSP2IF = 0;
}
static inline void I2C2_SlaveReleaseClock()
{
SSP2CON1bits.CKP = 1;
}
static inline bool I2C2_SlaveIsWriteCollision()
{
return SSP2CON1bits.WCOL;
}
static inline bool I2C2_SlaveIsData()
{
return SSP2STATbits.D_nA;
}
static inline void I2C2_SlaveRestart(void)
{
SSP2CON2bits.RSEN = 1;
}
static inline bool I2C2_SlaveIsTxBufEmpty()
{
return !SSP2STATbits.BF;
}
static inline bool I2C2_SlaveIsRxBufFull()
{
return SSP2STATbits.BF;
}
static inline void I2C2_SlaveSendTxData(uint8_t data)
{
SSP2BUF = data;
}
static inline uint8_t I2C2_SlaveGetRxData()
{
return SSP2BUF;
}
static inline uint8_t I2C2_SlaveGetAddr()
{
return SSP2ADD;
}
static inline void I2C2_SlaveSendAck()
{
SSP2CON2bits.ACKDT = 0;
SSP2CON2bits.ACKEN = 1;
}
static inline void I2C2_SlaveSendNack()
{
SSP2CON2bits.ACKDT = 1;
SSP2CON2bits.ACKEN = 1;
}
Header file:
/**
I2C2 Generated Driver API Header File
#Company
Microchip Technology Inc.
#File Name
i2c2_slave.h
#Summary
This is the generated header file for the I2C2 driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs
#Description
This header file provides APIs for driver for I2C2.
Generation Information :
Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.78.1
Device : PIC18F45Q10
Driver Version : 1.0.0
The generated drivers are tested against the following:
Compiler : XC8 2.10 and above or later
MPLAB : MPLAB X 5.30
*/
/*
(c) 2018 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and any
derivatives exclusively with Microchip products. It is your responsibility to comply with third party
license terms applicable to your use of third party software (including open source software) that
may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY
IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS
FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP
HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO
THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL
CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT
OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS
SOFTWARE.
*/
#ifndef I2C2_SLAVE_H
#define I2C2_SLAVE_H
#include <stdbool.h>
#include <stdint.h>
typedef void (*interruptHandler)(void);
/**
* \brief Initialize I2C2 interface
* If module is configured to disabled state, the clock to the I2C2 is disabled
* if this is supported by the device's clock system.
*
* \return None
*/
void I2C2_Initialize(void);
/**
* \brief Open the I2C2 for communication. Enables the module if disabled.
*
* \return Nothing
*/
void I2C2_Open(void);
/**
* \brief Close the I2C2 for communication. Disables the module if enabled.
* Disables address recognition.
*
* \return Nothing
*/
void I2C2_Close(void);
/**
* \brief Read data from I2C2 communication.
*
* \return Read Data
*/
uint8_t I2C2_Read(void);
/**
* \brief Write data over the communication.
*
* \return None
*/
void I2C2_Write(uint8_t data);
/**
* \brief Enable the communication by initialization of hardware
*
* \return None
*/
void I2C2_Enable(void);
/**
* \brief Send the Ack Signal to Master
*
* \return None
*/
void I2C2_SendAck(void);
/**
* \brief Send the Nack Signal to Master
*
* \return None
*/
void I2C2_SendNack(void);
/**
* \brief The function called by the I2C2 Irq handler.
* Can be called in a polling loop in a polled driver.
*
* \return Nothing
*/
void I2C2_SlaveSetIsrHandler(interruptHandler handler);
void I2C2_SlaveSetAddrIntHandler(interruptHandler handler);
void I2C2_SlaveSetReadIntHandler(interruptHandler handler);
void I2C2_SlaveSetWriteIntHandler(interruptHandler handler);
void I2C2_SlaveSetBusColIntHandler(interruptHandler handler);
void I2C2_SlaveSetWrColIntHandler(interruptHandler handler);
void (*MSSP2_InterruptHandler)(void);
void (*I2C2_SlaveRdInterruptHandler)(void);
void (*I2C2_SlaveWrInterruptHandler)(void);
void (*I2C2_SlaveAddrInterruptHandler)(void);
void (*I2C2_SlaveBusColInterruptHandler)(void);
void (*I2C2_SlaveWrColInterruptHandler)(void);
#endif /* I2C2_SLAVE_H */
You shoud not do this line in "I2C2_Isr()"
i2c2RdData = I2C2_SlaveGetRxData(); // <- but there is my first !
(it reads hardware register)
It will copy data from hardware register then this register will be empty.
So that why your " I2C2_SlaveRdCallBack();" is never be called.
This default handle will be auto call.
static void I2C2_SlaveDefRdInterruptHandler() {
i2c2RdData = I2C2_SlaveGetRxData();
}
So if you want to get data then copy to your variable, you should be do here
static void I2C2_SlaveRdCallBack() {
// Add your custom callback code here
if (I2C2_SlaveRdInterruptHandler)
{
I2C2_SlaveRdInterruptHandler();
}
// Copy i2c data to your variable here
}
Sorry for my poor English

How to use this API "xTaskCreate" to create multiple tasks?

I have read in link, This xTaskCreate FreeRTOS API is used to create a task. Using this API we can create more number of tasks:
/* Task to be created. */
/* Task to be created. */
void vTaskCode( void * pvParameters )
{
/* The parameter value is expected to be 1 as 1 is passed in the
pvParameters value in the call to xTaskCreate() below.
configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
for( ;; )
{
/* Task code goes here. */
}
}
I have seen this program example. I want to create two tasks. First task blink led1, second task blink led2.
I don't understand how to write program for two tasks.
to create the second task just call xTaskCreate twice, like below:
void vTaskLedGreen( void * pvParameters )
{
/* The parameter value is expected to be 1 as 1 is passed in the
pvParameters value in the call to xTaskCreate() below.
configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
for( ;; )
{
vTaskDelay(pdMS_TO_TICKS(1000));
GreenLedOff();
vTaskDelay(pdMS_TO_TICKS(1000));
GreenLedOn();
}
}
void vTaskLedRed( void * pvParameters )
{
/* The parameter value is expected to be 1 as 1 is passed in the
pvParameters value in the call to xTaskCreate() below.
configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
for( ;; )
{
vTaskDelay(pdMS_TO_TICKS(1000));
RedLedOff();
vTaskDelay(pdMS_TO_TICKS(1000));
RedLedOn();
}
}
/* Function that creates a task. */
void main( void )
{
BaseType_t xReturned;
TaskHandle_t xHandle = NULL;
xReturned = xTaskCreate(
vTaskLedRed, /* Function that implements the task. */
"RedLed", /* Text name for the task. */
STACK_SIZE, /* Stack size in words, not bytes. */
( void * ) 1, /* Parameter passed into the task. */
tskIDLE_PRIORITY,/* Priority at which the task is created. */
&xHandle ); /* Used to pass out the created task's handle. */
if( xReturned != pdPASS )
{
ErrorHandler();
}
xReturned = xTaskCreate(
vTaskLedGreen, /* Function that implements the task. */
"GreenLed", /* Text name for the task. */
STACK_SIZE, /* Stack size in words, not bytes. */
( void * ) 1, /* Parameter passed into the task. */
tskIDLE_PRIORITY,/* Priority at which the task is created. */
&xHandle ); /* Used to pass out the created task's handle. */
if( xReturned != pdPASS )
{
ErrorHandler();
}
// Start the real time scheduler.
vTaskStartScheduler();
}

Xcode 5 empty project has a unknown path in header search paths setting

The path is
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
where a FlexLexer.h is there. Don't know why this path or this header file is necessary. Here is source code of FlexLexer.h:
// -*-C++-*-
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
// by flex
// Copyright (c) 1993 The Regents of the University of California.
// All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
// This file defines FlexLexer, an abstract class which specifies the
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
// which defines a particular lexer class.
//
// If you want to create multiple lexer classes, you use the -P flag
// to rename each yyFlexLexer to some other xxFlexLexer. You then
// include <FlexLexer.h> in your other sources once per lexer class:
//
// #undef yyFlexLexer
// #define yyFlexLexer xxFlexLexer
// #include <FlexLexer.h>
//
// #undef yyFlexLexer
// #define yyFlexLexer zzFlexLexer
// #include <FlexLexer.h>
// ...
#ifndef __FLEX_LEXER_H
// Never included before - need to define base class.
#define __FLEX_LEXER_H
#include <iostream>
# ifndef FLEX_STD
# define FLEX_STD std::
# endif
extern "C++" {
struct yy_buffer_state;
typedef int yy_state_type;
class FlexLexer {
public:
virtual ~FlexLexer() { }
const char* YYText() const { return yytext; }
size_t YYLeng() const { return yyleng; }
virtual void
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
virtual struct yy_buffer_state*
yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
virtual void yyrestart( FLEX_STD istream* s ) = 0;
virtual int yylex() = 0;
// Call yylex with new input/output sources.
int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
{
switch_streams( new_in, new_out );
return yylex();
}
// Switch to new input/output streams. A nil stream pointer
// indicates "keep the current one".
virtual void switch_streams( FLEX_STD istream* new_in = 0,
FLEX_STD ostream* new_out = 0 ) = 0;
int lineno() const { return yylineno; }
int debug() const { return yy_flex_debug; }
void set_debug( int flag ) { yy_flex_debug = flag; }
protected:
char* yytext;
size_t yyleng;
int yylineno; // only maintained if you use %option yylineno
int yy_flex_debug; // only has effect with -d or "%option debug"
};
}
#endif // FLEXLEXER_H
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
// Either this is the first time through (yyFlexLexerOnce not defined),
// or this is a repeated include to define a different flavor of
// yyFlexLexer, as discussed in the flex manual.
#define yyFlexLexerOnce
extern "C++" {
class yyFlexLexer : public FlexLexer {
public:
// arg_yyin and arg_yyout default to the cin and cout, but we
// only make that assignment when initializing in yylex().
yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
virtual ~yyFlexLexer();
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
void yy_delete_buffer( struct yy_buffer_state* b );
void yyrestart( FLEX_STD istream* s );
void yypush_buffer_state( struct yy_buffer_state* new_buffer );
void yypop_buffer_state();
virtual int yylex();
virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
virtual int yywrap();
protected:
virtual size_t LexerInput( char* buf, size_t max_size );
virtual void LexerOutput( const char* buf, size_t size );
virtual void LexerError( const char* msg );
void yyunput( int c, char* buf_ptr );
int yyinput();
void yy_load_buffer_state();
void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
void yy_flush_buffer( struct yy_buffer_state* b );
int yy_start_stack_ptr;
int yy_start_stack_depth;
int* yy_start_stack;
void yy_push_state( int new_state );
void yy_pop_state();
int yy_top_state();
yy_state_type yy_get_previous_state();
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
int yy_get_next_buffer();
FLEX_STD istream* yyin; // input source for default LexerInput
FLEX_STD ostream* yyout; // output sink for default LexerOutput
// yy_hold_char holds the character lost when yytext is formed.
char yy_hold_char;
// Number of characters read into yy_ch_buf.
size_t yy_n_chars;
// Points to current character in buffer.
char* yy_c_buf_p;
int yy_init; // whether we need to initialize
int yy_start; // start state number
// Flag which is used to allow yywrap()'s to do buffer switches
// instead of setting up a fresh yyin. A bit of a hack ...
int yy_did_buffer_switch_on_eof;
size_t yy_buffer_stack_top; /**< index of top of stack. */
size_t yy_buffer_stack_max; /**< capacity of stack. */
struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
void yyensure_buffer_stack(void);
// The following are not always needed, but may be depending
// on use of certain flex features (like REJECT or yymore()).
yy_state_type yy_last_accepting_state;
char* yy_last_accepting_cpos;
yy_state_type* yy_state_buf;
yy_state_type* yy_state_ptr;
char* yy_full_match;
int* yy_full_state;
int yy_full_lp;
int yy_lp;
int yy_looking_for_trail_begin;
int yy_more_flag;
int yy_more_len;
int yy_more_offset;
int yy_prev_more_offset;
};
}
#endif // yyFlexLexer || ! yyFlexLexerOnce

shared object in pthread

I want to write a sample program in which 16 threads have access to a shared object with huge size like 10gb. I know that I can use pthread_mutex_t to get the lock on the object, but how can I make it efficient so that two or more thread can modify disjoint part of the shared object simultaneously?
Maybe you can create an array of 10 pthread_mutex_t's, one for each 1gb range, and lock the appropriate mutex for the range you'll be modifying?
What about using a sempahore. You can initialize semaphore with number of threads that shares the resources.
/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
#include <semaphore.h> /* Semaphore */
void semhandler ( void *ptr );
sem_t mutex;
int cntr=0; /* shared variable */
int main()
{
int arg[2];
pthread_t thread1;
pthread_t thread2;
arg[0] = 0;
arg[1] = 1;
/* initialize mutex to 2 to share resource with two threads*/
/* Seconds Argumnet "0" makes the semaphore local to the process */
sem_init(&mutex, 0, 2);
pthread_create (&thread1, NULL, (void *) &semhandler, (void *) &arg[0]);
pthread_create (&thread2, NULL, (void *) &semhandler, (void *) &arg[1]);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
sem_destroy(&mutex);
exit(0);
} /* main() */
void semhandler ( void *ptr )
{
int x;
x = *((int *) ptr);
printf("Thrd %d: Waiting to enter critical region...\n", x);
sem_wait(&mutex); /* down semaphore */
if( x == 1 )
cntr++;
/* START CRITICAL REGION */
printf("Thrd %d: Now in critical region...\n", x);
printf("Thrd %d: New Counter Value: %d\n", x, cntr);
printf("Thrd %d: Exiting critical region...\n", x);
/* END CRITICAL REGION */
sem_post(&mutex); /* up semaphore */
pthread_exit(0); /* exit thread */
}

Pushing an executable function pointer?

Usually one would only push 'userdata' when the data isn't any of Lua's standard types (number, string, bool, etc).
But how would you push an actually Function pointer to Lua (not as userdata; since userdata is not executable as function in Lua), assuming the function looks like so:
void nothing(const char* stuff)
{
do_magic_things_with(stuff);
}
The returned value should behave like the returned value from this native Lua function:
function things()
return function(stuff)
do_magic_things_with(stuff)
end
end
Is this possible to do with the C API? If yes, how (Examples would be appreciated)?
EDIT: To add some clarity, The value is supposed to be returned by a function exposed to Lua through the C API.
Use lua_pushcfunction
Examples are included in PiL
Here is an example that follows the form of the currently accepted answer.
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>
/* this is the C function you want to return */
static void
cfunction(const char *s)
{
puts(s);
}
/* this is the proxy function that acts like cfunction */
static int
proxy(lua_State *L)
{
cfunction(luaL_checkstring(L, 1));
return 0;
}
/* this global function returns "cfunction" to Lua. */
static int
getproxy(lua_State *L)
{
lua_pushcfunction(L, &proxy);
return 1;
}
int
main(int argc, char **argv)
{
lua_State *L;
L = luaL_newstate();
/* set the global function that returns the proxy */
lua_pushcfunction(L, getproxy);
lua_setglobal(L, "getproxy");
/* see if it works */
luaL_dostring(L, "p = getproxy() p('Hello, world!')");
lua_close(L);
return 0;
}
You could return a userdata with a metatable that proxies your C function through the __call metamethod. That way the userdata could be called like a function. Below is a full program example.
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>
/* this is the C function you want to return */
static void
cfunction(const char *s)
{
puts(s);
}
/* this is the proxy function that will be used as the __call metamethod */
static int
proxy(lua_State *L)
{
luaL_checkudata(L, 1, "proxy");
cfunction(luaL_checkstring(L, 2));
return 0;
}
/* this global function returns the C function with a userdata proxy */
static int
getproxy(lua_State *L)
{
lua_newuserdata(L, sizeof (int));
luaL_getmetatable(L, "proxy");
lua_setmetatable(L, -2);
return 1;
}
int
main(int argc, char **argv)
{
lua_State *L;
L = luaL_newstate();
/* create the proxy metatable */
luaL_newmetatable(L, "proxy");
lua_pushcfunction(L, proxy);
lua_setfield(L, -2, "__call");
/* set the global function that returns the proxy */
lua_pushcfunction(L, getproxy);
lua_setglobal(L, "getproxy");
/* see if it works */
luaL_dostring(L, "p = getproxy() p('Hello, world!')");
lua_close(L);
return 0;
}
In retrospect, I completely over-thought what you are asking. All you really need to do is to create a function of type lua_CFunction that pulls the parameters from the Lua stack and passes them on to the target C function. The code above answers your question literally, but it is probably overkill for what you really need to accomplish.

Resources